ae-base 0.3.57__tar.gz → 0.3.60__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_project V0.3.35 -->
1
+ <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_project V0.3.36 -->
2
2
  ### GNU GENERAL PUBLIC LICENSE
3
3
 
4
4
  Version 3, 29 June 2007
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ae_base
3
- Version: 0.3.57
3
+ Version: 0.3.60
4
4
  Summary: ae namespace module portion base: basic constants, helper functions and context manager
5
5
  Home-page: https://gitlab.com/ae-group/ae_base
6
6
  Author: AndiEcker
@@ -69,13 +69,13 @@ Dynamic: summary
69
69
 
70
70
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.96 -->
71
71
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_namespace_root V0.3.14 -->
72
- # base 0.3.57
72
+ # base 0.3.60
73
73
 
74
74
  [![GitLab develop](https://img.shields.io/gitlab/pipeline/ae-group/ae_base/develop?logo=python)](
75
75
  https://gitlab.com/ae-group/ae_base)
76
76
  [![LatestPyPIrelease](
77
- https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.56?logo=python)](
78
- https://gitlab.com/ae-group/ae_base/-/tree/release0.3.56)
77
+ https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.59?logo=python)](
78
+ https://gitlab.com/ae-group/ae_base/-/tree/release0.3.59)
79
79
  [![PyPIVersions](https://img.shields.io/pypi/v/ae_base)](
80
80
  https://pypi.org/project/ae-base/#history)
81
81
 
@@ -1,12 +1,12 @@
1
1
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.96 -->
2
2
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_namespace_root V0.3.14 -->
3
- # base 0.3.57
3
+ # base 0.3.60
4
4
 
5
5
  [![GitLab develop](https://img.shields.io/gitlab/pipeline/ae-group/ae_base/develop?logo=python)](
6
6
  https://gitlab.com/ae-group/ae_base)
7
7
  [![LatestPyPIrelease](
8
- https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.56?logo=python)](
9
- https://gitlab.com/ae-group/ae_base/-/tree/release0.3.56)
8
+ https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.59?logo=python)](
9
+ https://gitlab.com/ae-group/ae_base/-/tree/release0.3.59)
10
10
  [![PyPIVersions](https://img.shields.io/pypi/v/ae_base)](
11
11
  https://pypi.org/project/ae-base/#history)
12
12
 
@@ -171,7 +171,7 @@ from types import ModuleType
171
171
  from typing import Any, Callable, Generator, Iterable, MutableMapping, Optional, Union, cast
172
172
 
173
173
 
174
- __version__ = '0.3.57'
174
+ __version__ = '0.3.60'
175
175
 
176
176
 
177
177
  os_path_abspath = os.path.abspath
@@ -334,21 +334,21 @@ def camel_to_snake(name: str) -> str:
334
334
  return "".join(str_parts)
335
335
 
336
336
 
337
- def deep_dict_update(data: dict, update: dict):
337
+ def deep_dict_update(data: dict, update: dict, overwrite: bool = True):
338
338
  """ update the optionally nested data dict in-place with the items and subitems from the update dict.
339
339
 
340
340
  :param data: dict to be updated/extended. non-existing keys of dict-subitems will be added.
341
341
  :param update: dict with the [sub-]items to update in the :paramref:`~deep_dict_update.data` dict.
342
+ :param overwrite: pass False to not overwrite an already existing value.
342
343
 
343
- .. hint:: the module/portion :mod:`ae.deep` is providing more deep update helper functions.
344
-
344
+ .. hint:: see the module/portion :mod:`ae.deep` for more deep update helper functions.
345
345
  """
346
346
  for upd_key, upd_val in update.items():
347
347
  if isinstance(upd_val, dict):
348
348
  if upd_key not in data:
349
349
  data[upd_key] = {}
350
- deep_dict_update(data[upd_key], upd_val)
351
- else:
350
+ deep_dict_update(data[upd_key], upd_val, overwrite=overwrite)
351
+ elif overwrite or upd_key not in data:
352
352
  data[upd_key] = upd_val
353
353
 
354
354
 
@@ -652,7 +652,8 @@ def load_env_var_defaults(start_dir: str, env_vars: MutableMapping[str, str]):
652
652
  found ``.env`` file. pass Python's :data:`os.environ` to amend this mapping directly
653
653
  with all the already not declared environment variables.
654
654
  """
655
- file_path = os_path_abspath(os_path_join(start_dir, DOTENV_FILE_NAME))
655
+ start_dir = norm_path(start_dir)
656
+ file_path = os_path_join(start_dir, DOTENV_FILE_NAME)
656
657
  if not os_path_isfile(file_path):
657
658
  file_path = os_path_join(os_path_dirname(start_dir), DOTENV_FILE_NAME)
658
659
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ae_base
3
- Version: 0.3.57
3
+ Version: 0.3.60
4
4
  Summary: ae namespace module portion base: basic constants, helper functions and context manager
5
5
  Home-page: https://gitlab.com/ae-group/ae_base
6
6
  Author: AndiEcker
@@ -69,13 +69,13 @@ Dynamic: summary
69
69
 
70
70
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.96 -->
71
71
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_namespace_root V0.3.14 -->
72
- # base 0.3.57
72
+ # base 0.3.60
73
73
 
74
74
  [![GitLab develop](https://img.shields.io/gitlab/pipeline/ae-group/ae_base/develop?logo=python)](
75
75
  https://gitlab.com/ae-group/ae_base)
76
76
  [![LatestPyPIrelease](
77
- https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.56?logo=python)](
78
- https://gitlab.com/ae-group/ae_base/-/tree/release0.3.56)
77
+ https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.59?logo=python)](
78
+ https://gitlab.com/ae-group/ae_base/-/tree/release0.3.59)
79
79
  [![PyPIVersions](https://img.shields.io/pypi/v/ae_base)](
80
80
  https://pypi.org/project/ae-base/#history)
81
81
 
@@ -1,4 +1,4 @@
1
- # THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_project V0.3.35
1
+ # THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_project V0.3.36
2
2
  """ setup of ae namespace module portion base: basic constants, helper functions and context manager. """
3
3
 
4
4
 
@@ -15,7 +15,7 @@ setup_kwargs = {
15
15
  'install_requires': [],
16
16
  'keywords': ['configuration', 'development', 'environment', 'productivity'],
17
17
  'license': 'OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
18
- 'long_description': '<!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.96 -->\n<!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_namespace_root V0.3.14 -->\n# base 0.3.57\n\n[![GitLab develop](https://img.shields.io/gitlab/pipeline/ae-group/ae_base/develop?logo=python)](\n https://gitlab.com/ae-group/ae_base)\n[![LatestPyPIrelease](\n https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.56?logo=python)](\n https://gitlab.com/ae-group/ae_base/-/tree/release0.3.56)\n[![PyPIVersions](https://img.shields.io/pypi/v/ae_base)](\n https://pypi.org/project/ae-base/#history)\n\n>ae namespace module portion base: basic constants, helper functions and context manager.\n\n[![Coverage](https://ae-group.gitlab.io/ae_base/coverage.svg)](\n https://ae-group.gitlab.io/ae_base/coverage/index.html)\n[![MyPyPrecision](https://ae-group.gitlab.io/ae_base/mypy.svg)](\n https://ae-group.gitlab.io/ae_base/lineprecision.txt)\n[![PyLintScore](https://ae-group.gitlab.io/ae_base/pylint.svg)](\n https://ae-group.gitlab.io/ae_base/pylint.log)\n\n[![PyPIImplementation](https://img.shields.io/pypi/implementation/ae_base)](\n https://gitlab.com/ae-group/ae_base/)\n[![PyPIPyVersions](https://img.shields.io/pypi/pyversions/ae_base)](\n https://gitlab.com/ae-group/ae_base/)\n[![PyPIWheel](https://img.shields.io/pypi/wheel/ae_base)](\n https://gitlab.com/ae-group/ae_base/)\n[![PyPIFormat](https://img.shields.io/pypi/format/ae_base)](\n https://pypi.org/project/ae-base/)\n[![PyPILicense](https://img.shields.io/pypi/l/ae_base)](\n https://gitlab.com/ae-group/ae_base/-/blob/develop/LICENSE.md)\n[![PyPIStatus](https://img.shields.io/pypi/status/ae_base)](\n https://libraries.io/pypi/ae-base)\n[![PyPIDownloads](https://img.shields.io/pypi/dm/ae_base)](\n https://pypi.org/project/ae-base/#files)\n\n\n## installation\n\n\nexecute the following command to install the\nae.base module\nin the currently active virtual environment:\n \n```shell script\npip install ae-base\n```\n\nif you want to contribute to this portion then first fork\n[the ae_base repository at GitLab](\nhttps://gitlab.com/ae-group/ae_base "ae.base code repository").\nafter that pull it to your machine and finally execute the\nfollowing command in the root folder of this repository\n(ae_base):\n\n```shell script\npip install -e .[dev]\n```\n\nthe last command will install this module portion, along with the tools you need\nto develop and run tests or to extend the portion documentation. to contribute only to the unit tests or to the\ndocumentation of this portion, replace the setup extras key `dev` in the above command with `tests` or `docs`\nrespectively.\n\nmore detailed explanations on how to contribute to this project\n[are available here](\nhttps://gitlab.com/ae-group/ae_base/-/blob/develop/CONTRIBUTING.rst)\n\n\n## namespace portion documentation\n\ninformation on the features and usage of this portion are available at\n[ReadTheDocs](\nhttps://ae.readthedocs.io/en/latest/_autosummary/ae.base.html\n"ae_base documentation").\n',
18
+ 'long_description': '<!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.96 -->\n<!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_namespace_root V0.3.14 -->\n# base 0.3.60\n\n[![GitLab develop](https://img.shields.io/gitlab/pipeline/ae-group/ae_base/develop?logo=python)](\n https://gitlab.com/ae-group/ae_base)\n[![LatestPyPIrelease](\n https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.59?logo=python)](\n https://gitlab.com/ae-group/ae_base/-/tree/release0.3.59)\n[![PyPIVersions](https://img.shields.io/pypi/v/ae_base)](\n https://pypi.org/project/ae-base/#history)\n\n>ae namespace module portion base: basic constants, helper functions and context manager.\n\n[![Coverage](https://ae-group.gitlab.io/ae_base/coverage.svg)](\n https://ae-group.gitlab.io/ae_base/coverage/index.html)\n[![MyPyPrecision](https://ae-group.gitlab.io/ae_base/mypy.svg)](\n https://ae-group.gitlab.io/ae_base/lineprecision.txt)\n[![PyLintScore](https://ae-group.gitlab.io/ae_base/pylint.svg)](\n https://ae-group.gitlab.io/ae_base/pylint.log)\n\n[![PyPIImplementation](https://img.shields.io/pypi/implementation/ae_base)](\n https://gitlab.com/ae-group/ae_base/)\n[![PyPIPyVersions](https://img.shields.io/pypi/pyversions/ae_base)](\n https://gitlab.com/ae-group/ae_base/)\n[![PyPIWheel](https://img.shields.io/pypi/wheel/ae_base)](\n https://gitlab.com/ae-group/ae_base/)\n[![PyPIFormat](https://img.shields.io/pypi/format/ae_base)](\n https://pypi.org/project/ae-base/)\n[![PyPILicense](https://img.shields.io/pypi/l/ae_base)](\n https://gitlab.com/ae-group/ae_base/-/blob/develop/LICENSE.md)\n[![PyPIStatus](https://img.shields.io/pypi/status/ae_base)](\n https://libraries.io/pypi/ae-base)\n[![PyPIDownloads](https://img.shields.io/pypi/dm/ae_base)](\n https://pypi.org/project/ae-base/#files)\n\n\n## installation\n\n\nexecute the following command to install the\nae.base module\nin the currently active virtual environment:\n \n```shell script\npip install ae-base\n```\n\nif you want to contribute to this portion then first fork\n[the ae_base repository at GitLab](\nhttps://gitlab.com/ae-group/ae_base "ae.base code repository").\nafter that pull it to your machine and finally execute the\nfollowing command in the root folder of this repository\n(ae_base):\n\n```shell script\npip install -e .[dev]\n```\n\nthe last command will install this module portion, along with the tools you need\nto develop and run tests or to extend the portion documentation. to contribute only to the unit tests or to the\ndocumentation of this portion, replace the setup extras key `dev` in the above command with `tests` or `docs`\nrespectively.\n\nmore detailed explanations on how to contribute to this project\n[are available here](\nhttps://gitlab.com/ae-group/ae_base/-/blob/develop/CONTRIBUTING.rst)\n\n\n## namespace portion documentation\n\ninformation on the features and usage of this portion are available at\n[ReadTheDocs](\nhttps://ae.readthedocs.io/en/latest/_autosummary/ae.base.html\n"ae_base documentation").\n',
19
19
  'long_description_content_type': 'text/markdown',
20
20
  'name': 'ae_base',
21
21
  'package_data': {'': []},
@@ -24,7 +24,7 @@ setup_kwargs = {
24
24
  'python_requires': '>=3.9',
25
25
  'setup_requires': ['aedev_setup_project'],
26
26
  'url': 'https://gitlab.com/ae-group/ae_base',
27
- 'version': '0.3.57',
27
+ 'version': '0.3.60',
28
28
  'zip_safe': True,
29
29
  }
30
30
 
@@ -13,7 +13,7 @@ import textwrap
13
13
  from collections import OrderedDict
14
14
  from configparser import ConfigParser
15
15
  from types import ModuleType
16
- from typing import cast
16
+ from typing import cast, Any
17
17
 
18
18
  # noinspection PyProtectedMember
19
19
  from ae.base import (
@@ -215,52 +215,80 @@ class TestBaseHelpers:
215
215
 
216
216
  def test_deep_dict_update_empty(self):
217
217
  str_val = "str_val"
218
- pev = {}
219
218
  upd = {'setup_kwargs': {'entry_points': {'console_scripts': str_val}}}
220
219
 
221
- deep_dict_update(pev, upd)
222
- assert pev
223
- assert 'setup_kwargs' in pev
224
- assert 'entry_points' in pev['setup_kwargs']
225
- assert 'console_scripts' in pev['setup_kwargs']['entry_points']
226
- assert pev['setup_kwargs']['entry_points']['console_scripts'] == str_val
220
+ ori = {}
221
+ deep_dict_update(ori, upd)
222
+ assert ori
223
+ assert 'setup_kwargs' in ori
224
+ assert 'entry_points' in ori['setup_kwargs']
225
+ assert 'console_scripts' in ori['setup_kwargs']['entry_points']
226
+ assert ori['setup_kwargs']['entry_points']['console_scripts'] == str_val
227
+
228
+ ori = {}
229
+ deep_dict_update(ori, upd, overwrite=False)
230
+ assert ori
231
+ assert 'setup_kwargs' in ori
232
+ assert 'entry_points' in ori['setup_kwargs']
233
+ assert 'console_scripts' in ori['setup_kwargs']['entry_points']
234
+ assert ori['setup_kwargs']['entry_points']['console_scripts'] == str_val
227
235
 
228
236
  def test_deep_dict_update_half_empty_ordered(self):
229
237
  str_val = "str_val"
230
238
  lst_val = [str_val]
231
- pev = OrderedDict({'setup_kwargs': {'untouched_key1': "untouched val 1"}, 'untouched_key2': "untouched val 2"})
232
239
  upd = {'setup_kwargs': {'entry_points': {'console_scripts': lst_val}}}
233
240
 
234
- deep_dict_update(pev, upd)
235
- assert pev
236
- assert 'setup_kwargs' in pev
237
- assert 'entry_points' in pev['setup_kwargs']
238
- assert 'console_scripts' in pev['setup_kwargs']['entry_points']
239
- # noinspection PyTypeChecker
240
- assert pev['setup_kwargs']['entry_points']['console_scripts'] == lst_val
241
- # noinspection PyTypeChecker
242
- assert pev['setup_kwargs']['entry_points']['console_scripts'][0] == str_val
243
-
244
- assert pev['untouched_key2'] == "untouched val 2"
245
- assert pev['setup_kwargs']['untouched_key1'] == "untouched val 1"
246
-
247
- assert list(pev.keys()) == ['setup_kwargs', 'untouched_key2']
248
- assert list(pev['setup_kwargs'].keys()) == ['untouched_key1', 'entry_points']
241
+ ori: dict[str, Any] = OrderedDict({'setup_kwargs': {'untouched_key1': "untouched val 1"},
242
+ 'untouched_key2': "untouched val 2"})
243
+ deep_dict_update(ori, upd)
244
+ assert ori
245
+ assert 'setup_kwargs' in ori
246
+ assert 'entry_points' in ori['setup_kwargs']
247
+ assert 'console_scripts' in ori['setup_kwargs']['entry_points']
248
+ assert ori['setup_kwargs']['entry_points']['console_scripts'] == lst_val
249
+ assert ori['setup_kwargs']['entry_points']['console_scripts'][0] == str_val
250
+ assert ori['untouched_key2'] == "untouched val 2"
251
+ assert ori['setup_kwargs']['untouched_key1'] == "untouched val 1"
252
+ assert list(ori.keys()) == ['setup_kwargs', 'untouched_key2']
253
+ assert list(ori['setup_kwargs'].keys()) == ['untouched_key1', 'entry_points']
254
+
255
+ ori: dict[str, Any] = OrderedDict({'setup_kwargs': {'untouched_key1': "untouched val 1"},
256
+ 'untouched_key2': "untouched val 2"})
257
+ deep_dict_update(ori, upd, overwrite=False)
258
+ assert ori
259
+ assert 'setup_kwargs' in ori
260
+ assert 'entry_points' in ori['setup_kwargs']
261
+ assert 'console_scripts' in ori['setup_kwargs']['entry_points']
262
+ assert ori['setup_kwargs']['entry_points']['console_scripts'] == lst_val
263
+ assert ori['setup_kwargs']['entry_points']['console_scripts'][0] == str_val
264
+ assert ori['untouched_key2'] == "untouched val 2"
265
+ assert ori['setup_kwargs']['untouched_key1'] == "untouched val 1"
266
+ assert list(ori.keys()) == ['setup_kwargs', 'untouched_key2']
267
+ assert list(ori['setup_kwargs'].keys()) == ['untouched_key1', 'entry_points']
249
268
 
250
269
  def test_deep_dict_update_full(self):
251
270
  str_old = "old_val"
252
271
  str_new = "new_val"
253
272
  lst_val = [str_new]
254
- pev = {'setup_kwargs': {'entry_points': {'console_scripts': str_old}}}
255
273
  upd = {'setup_kwargs': {'entry_points': {'console_scripts': lst_val}}}
256
274
 
257
- deep_dict_update(pev, upd)
258
- assert pev
259
- assert 'setup_kwargs' in pev
260
- assert 'entry_points' in pev['setup_kwargs']
261
- assert 'console_scripts' in pev['setup_kwargs']['entry_points']
262
- assert pev['setup_kwargs']['entry_points']['console_scripts'] == lst_val
263
- assert pev['setup_kwargs']['entry_points']['console_scripts'][0] == str_new
275
+ ori = {'setup_kwargs': {'entry_points': {'console_scripts': str_old}}}
276
+ deep_dict_update(ori, upd)
277
+ assert ori
278
+ assert 'setup_kwargs' in ori
279
+ assert 'entry_points' in ori['setup_kwargs']
280
+ assert 'console_scripts' in ori['setup_kwargs']['entry_points']
281
+ assert ori['setup_kwargs']['entry_points']['console_scripts'] == lst_val
282
+ assert ori['setup_kwargs']['entry_points']['console_scripts'][0] == str_new
283
+
284
+ ori = {'setup_kwargs': {'entry_points': {'console_scripts': str_old}}}
285
+ deep_dict_update(ori, upd, overwrite=False)
286
+ assert ori
287
+ assert 'setup_kwargs' in ori
288
+ assert 'entry_points' in ori['setup_kwargs']
289
+ assert 'console_scripts' in ori['setup_kwargs']['entry_points']
290
+ assert ori['setup_kwargs']['entry_points']['console_scripts'] == str_old
291
+ assert ori['setup_kwargs']['entry_points']['console_scripts'][0] == str_old[0]
264
292
 
265
293
  def test_dedefuse_file_name(self):
266
294
  assert dedefuse(tst_fna1) == tst_uri1
@@ -496,7 +524,9 @@ class TestBaseHelpers:
496
524
 
497
525
  with pytest.raises(TypeError):
498
526
  # noinspection PyTypeChecker
499
- load_env_var_defaults(None, None)
527
+ load_env_var_defaults(None, None) # STRANGE: raising TypeError in Python 3.9.21/local but not in 3.9.23/CI
528
+ # noinspection PyArgumentList
529
+ load_env_var_defaults(None) # HOTFIX ensuring failure - could not find any changelog notes )
500
530
 
501
531
  # noinspection PyTypeChecker
502
532
  load_env_var_defaults("inv:_ file path", ()) # NO ERROR EXCEPTIONS on these invalid arg values!!!
@@ -526,9 +556,14 @@ class TestBaseHelpers:
526
556
  assert env_var_name not in os.environ
527
557
 
528
558
  def test_load_env_var_defaults_load_start_parent_first_no_chain(self, os_env_test_env):
529
- load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 4)), os.environ)
530
- assert env_var_name in os.environ
531
- assert os.environ[env_var_name] == env_var_val + '3'
559
+ old_cwd = os.getcwd()
560
+ try:
561
+ os.chdir(os.path.join(os_env_test_env, *((folder_name, ) * 4)))
562
+ load_env_var_defaults("", os.environ)
563
+ assert env_var_name in os.environ
564
+ assert os.environ[env_var_name] == env_var_val + '3'
565
+ finally:
566
+ os.chdir(old_cwd)
532
567
 
533
568
  def test_load_env_var_defaults_load_start_first_no_chain(self, os_env_test_env):
534
569
  load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 3)), os.environ)
File without changes