ae-base 0.3.55__tar.gz → 0.3.57__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.
- {ae_base-0.3.55 → ae_base-0.3.57}/LICENSE.md +1 -1
- {ae_base-0.3.55/ae_base.egg-info → ae_base-0.3.57}/PKG-INFO +6 -6
- {ae_base-0.3.55 → ae_base-0.3.57}/README.md +5 -5
- {ae_base-0.3.55 → ae_base-0.3.57}/ae/base.py +28 -16
- {ae_base-0.3.55 → ae_base-0.3.57/ae_base.egg-info}/PKG-INFO +6 -6
- ae_base-0.3.57/setup.py +33 -0
- {ae_base-0.3.55 → ae_base-0.3.57}/tests/test_base.py +111 -30
- ae_base-0.3.55/setup.py +0 -18
- {ae_base-0.3.55 → ae_base-0.3.57}/ae_base.egg-info/SOURCES.txt +0 -0
- {ae_base-0.3.55 → ae_base-0.3.57}/ae_base.egg-info/dependency_links.txt +0 -0
- {ae_base-0.3.55 → ae_base-0.3.57}/ae_base.egg-info/requires.txt +0 -0
- {ae_base-0.3.55 → ae_base-0.3.57}/ae_base.egg-info/top_level.txt +0 -0
- {ae_base-0.3.55 → ae_base-0.3.57}/ae_base.egg-info/zip-safe +0 -0
- {ae_base-0.3.55 → ae_base-0.3.57}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ae_base
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.57
|
|
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
|
|
@@ -67,19 +67,19 @@ Dynamic: provides-extra
|
|
|
67
67
|
Dynamic: requires-python
|
|
68
68
|
Dynamic: summary
|
|
69
69
|
|
|
70
|
-
<!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.
|
|
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.
|
|
72
|
+
# base 0.3.57
|
|
73
73
|
|
|
74
74
|
[](
|
|
75
75
|
https://gitlab.com/ae-group/ae_base)
|
|
76
76
|
[](
|
|
78
|
+
https://gitlab.com/ae-group/ae_base/-/tree/release0.3.56)
|
|
79
79
|
[](
|
|
80
80
|
https://pypi.org/project/ae-base/#history)
|
|
81
81
|
|
|
82
|
-
>
|
|
82
|
+
>ae namespace module portion base: basic constants, helper functions and context manager.
|
|
83
83
|
|
|
84
84
|
[](
|
|
85
85
|
https://ae-group.gitlab.io/ae_base/coverage/index.html)
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
<!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.
|
|
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.
|
|
3
|
+
# base 0.3.57
|
|
4
4
|
|
|
5
5
|
[](
|
|
6
6
|
https://gitlab.com/ae-group/ae_base)
|
|
7
7
|
[](
|
|
9
|
+
https://gitlab.com/ae-group/ae_base/-/tree/release0.3.56)
|
|
10
10
|
[](
|
|
11
11
|
https://pypi.org/project/ae-base/#history)
|
|
12
12
|
|
|
13
|
-
>
|
|
13
|
+
>ae namespace module portion base: basic constants, helper functions and context manager.
|
|
14
14
|
|
|
15
15
|
[](
|
|
16
16
|
https://ae-group.gitlab.io/ae_base/coverage/index.html)
|
|
@@ -32,6 +32,9 @@ sortable and compact string from a timestamp.
|
|
|
32
32
|
base helper functions
|
|
33
33
|
---------------------
|
|
34
34
|
|
|
35
|
+
most programming languages providing a function to determine the sign of a number. the :func:`sign` functino,
|
|
36
|
+
provided by this module/portion is filling this gap in Python.
|
|
37
|
+
|
|
35
38
|
in order to convert and transfer Unicode character outside the 7-bit ASCII range via internet transport protocols,
|
|
36
39
|
like http, use the helper functions :func:`ascii_str` and :func:`str_ascii`.
|
|
37
40
|
|
|
@@ -165,10 +168,10 @@ from contextlib import contextmanager
|
|
|
165
168
|
from importlib.machinery import ModuleSpec
|
|
166
169
|
from inspect import getinnerframes, getouterframes, getsourcefile
|
|
167
170
|
from types import ModuleType
|
|
168
|
-
from typing import Any, Callable, Generator, Iterable, Optional, Union, cast
|
|
171
|
+
from typing import Any, Callable, Generator, Iterable, MutableMapping, Optional, Union, cast
|
|
169
172
|
|
|
170
173
|
|
|
171
|
-
__version__ = '0.3.
|
|
174
|
+
__version__ = '0.3.57'
|
|
172
175
|
|
|
173
176
|
|
|
174
177
|
os_path_abspath = os.path.abspath
|
|
@@ -630,24 +633,24 @@ def load_dotenvs():
|
|
|
630
633
|
|
|
631
634
|
.. hint:: call from the main module of project/app in order to also load ``.env`` files in/above the project folder.
|
|
632
635
|
"""
|
|
633
|
-
|
|
636
|
+
env_vars = os.environ
|
|
637
|
+
load_env_var_defaults(os.getcwd(), env_vars)
|
|
634
638
|
if file_name := stack_var('__file__'):
|
|
635
|
-
load_env_var_defaults(os_path_dirname(os_path_abspath(file_name)))
|
|
639
|
+
load_env_var_defaults(os_path_dirname(os_path_abspath(file_name)), env_vars)
|
|
636
640
|
|
|
637
641
|
|
|
638
|
-
def load_env_var_defaults(start_dir: str):
|
|
639
|
-
"""
|
|
642
|
+
def load_env_var_defaults(start_dir: str, env_vars: MutableMapping[str, str]):
|
|
643
|
+
""" load undeclared env var defaults from a chain of ``.env`` files starting in the specified folder or its parent.
|
|
640
644
|
|
|
641
|
-
:param start_dir: folder to start search of an ``.env`` file, if not found, then checks the parent
|
|
642
|
-
if
|
|
643
|
-
into
|
|
645
|
+
:param start_dir: folder to start search of an ``.env`` file, if not found, then also checks the parent
|
|
646
|
+
folder. if an ``.env `` file got found, then put their shell environment variable values
|
|
647
|
+
into the specified :paramref:`~load_env_var_defaults.env_vars` mapping if they are not
|
|
648
|
+
already there. after processing the first ``.env`` file, it repeats to check for
|
|
644
649
|
further ``.env`` files in the parent folder to load them too, until either detecting
|
|
645
650
|
a folder without an ``.env`` file or until an ``.env`` got loaded from the root folder.
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
value specified in the ``.env`` file to be loaded). the variable values declared in the subfolders
|
|
650
|
-
are having preference over the values declared in the parent folders.
|
|
651
|
+
:param env_vars: environment variables mapping to be amended with env variable values from any
|
|
652
|
+
found ``.env`` file. pass Python's :data:`os.environ` to amend this mapping directly
|
|
653
|
+
with all the already not declared environment variables.
|
|
651
654
|
"""
|
|
652
655
|
file_path = os_path_abspath(os_path_join(start_dir, DOTENV_FILE_NAME))
|
|
653
656
|
if not os_path_isfile(file_path):
|
|
@@ -655,8 +658,8 @@ def load_env_var_defaults(start_dir: str):
|
|
|
655
658
|
|
|
656
659
|
while os_path_isfile(file_path):
|
|
657
660
|
for var_nam, var_val in parse_dotenv(file_path).items():
|
|
658
|
-
if var_nam not in
|
|
659
|
-
|
|
661
|
+
if var_nam not in env_vars:
|
|
662
|
+
env_vars[var_nam] = var_val
|
|
660
663
|
|
|
661
664
|
if os.sep not in file_path:
|
|
662
665
|
break # pragma: no cover # prevent endless-loop for ``.env`` file in root dir (os.sep == '/')
|
|
@@ -1018,6 +1021,15 @@ def round_traditional(num_value: float, num_digits: int = 0) -> float:
|
|
|
1018
1021
|
return round(num_value + 10 ** (-len(str(num_value)) - 1), num_digits)
|
|
1019
1022
|
|
|
1020
1023
|
|
|
1024
|
+
def sign(number: float) -> int:
|
|
1025
|
+
""" return ths sign (-1, 0, 1) of a number.
|
|
1026
|
+
|
|
1027
|
+
:param number: any number of type float or int.
|
|
1028
|
+
:return: -1 if the number is negative, 0 if it is zero, or 1 if it is positive.
|
|
1029
|
+
"""
|
|
1030
|
+
return (number > 0) - (number < 0)
|
|
1031
|
+
|
|
1032
|
+
|
|
1021
1033
|
def snake_to_camel(name: str, back_convertible: bool = False) -> str:
|
|
1022
1034
|
""" convert name from snake_case to CamelCase.
|
|
1023
1035
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: ae_base
|
|
3
|
-
Version: 0.3.
|
|
3
|
+
Version: 0.3.57
|
|
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
|
|
@@ -67,19 +67,19 @@ Dynamic: provides-extra
|
|
|
67
67
|
Dynamic: requires-python
|
|
68
68
|
Dynamic: summary
|
|
69
69
|
|
|
70
|
-
<!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.
|
|
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.
|
|
72
|
+
# base 0.3.57
|
|
73
73
|
|
|
74
74
|
[](
|
|
75
75
|
https://gitlab.com/ae-group/ae_base)
|
|
76
76
|
[](
|
|
78
|
+
https://gitlab.com/ae-group/ae_base/-/tree/release0.3.56)
|
|
79
79
|
[](
|
|
80
80
|
https://pypi.org/project/ae-base/#history)
|
|
81
81
|
|
|
82
|
-
>
|
|
82
|
+
>ae namespace module portion base: basic constants, helper functions and context manager.
|
|
83
83
|
|
|
84
84
|
[](
|
|
85
85
|
https://ae-group.gitlab.io/ae_base/coverage/index.html)
|
ae_base-0.3.57/setup.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_project V0.3.35
|
|
2
|
+
""" setup of ae namespace module portion base: basic constants, helper functions and context manager. """
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
# noinspection PyUnresolvedReferences
|
|
7
|
+
import setuptools
|
|
8
|
+
|
|
9
|
+
setup_kwargs = {
|
|
10
|
+
'author': 'AndiEcker',
|
|
11
|
+
'author_email': 'aecker2@gmail.com',
|
|
12
|
+
'classifiers': ['Development Status :: 3 - Alpha', 'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)', 'Natural Language :: English', 'Operating System :: OS Independent', 'Programming Language :: Python', 'Programming Language :: Python :: 3', 'Programming Language :: Python :: 3.9', 'Topic :: Software Development :: Libraries :: Python Modules'],
|
|
13
|
+
'description': 'ae namespace module portion base: basic constants, helper functions and context manager',
|
|
14
|
+
'extras_require': {'dev': ['aedev_tpl_project', 'ae_ae', 'anybadge', 'coverage-badge', 'aedev_git_repo_manager', 'flake8', 'mypy', 'pylint', 'pytest', 'pytest-cov', 'pytest-django', 'typing', 'types-setuptools', 'wheel', 'twine'], 'docs': [], 'tests': ['anybadge', 'coverage-badge', 'aedev_git_repo_manager', 'flake8', 'mypy', 'pylint', 'pytest', 'pytest-cov', 'pytest-django', 'typing', 'types-setuptools', 'wheel', 'twine']},
|
|
15
|
+
'install_requires': [],
|
|
16
|
+
'keywords': ['configuration', 'development', 'environment', 'productivity'],
|
|
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[](\n https://gitlab.com/ae-group/ae_base)\n[](\n https://gitlab.com/ae-group/ae_base/-/tree/release0.3.56)\n[](\n https://pypi.org/project/ae-base/#history)\n\n>ae namespace module portion base: basic constants, helper functions and context manager.\n\n[](\n https://ae-group.gitlab.io/ae_base/coverage/index.html)\n[](\n https://ae-group.gitlab.io/ae_base/lineprecision.txt)\n[](\n https://ae-group.gitlab.io/ae_base/pylint.log)\n\n[](\n https://gitlab.com/ae-group/ae_base/)\n[](\n https://gitlab.com/ae-group/ae_base/)\n[](\n https://gitlab.com/ae-group/ae_base/)\n[](\n https://pypi.org/project/ae-base/)\n[](\n https://gitlab.com/ae-group/ae_base/-/blob/develop/LICENSE.md)\n[](\n https://libraries.io/pypi/ae-base)\n[](\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
|
+
'long_description_content_type': 'text/markdown',
|
|
20
|
+
'name': 'ae_base',
|
|
21
|
+
'package_data': {'': []},
|
|
22
|
+
'packages': ['ae'],
|
|
23
|
+
'project_urls': {'Bug Tracker': 'https://gitlab.com/ae-group/ae_base/-/issues', 'Documentation': 'https://ae.readthedocs.io/en/latest/_autosummary/ae.base.html', 'Repository': 'https://gitlab.com/ae-group/ae_base', 'Source': 'https://ae.readthedocs.io/en/latest/_modules/ae/base.html'},
|
|
24
|
+
'python_requires': '>=3.9',
|
|
25
|
+
'setup_requires': ['aedev_setup_project'],
|
|
26
|
+
'url': 'https://gitlab.com/ae-group/ae_base',
|
|
27
|
+
'version': '0.3.57',
|
|
28
|
+
'zip_safe': True,
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if __name__ == "__main__":
|
|
32
|
+
setuptools.setup(**setup_kwargs)
|
|
33
|
+
pass
|
|
@@ -18,15 +18,15 @@ from typing import cast
|
|
|
18
18
|
# noinspection PyProtectedMember
|
|
19
19
|
from ae.base import (
|
|
20
20
|
ASCII_TO_UNICODE, BUILD_CONFIG_FILE, DOTENV_FILE_NAME, PY_EXT, PY_INIT, PY_MAIN, TESTS_FOLDER, UNICODE_TO_ASCII,
|
|
21
|
-
UNSET,
|
|
22
|
-
|
|
21
|
+
UNSET, URI_SEP_CHAR,
|
|
22
|
+
app_name_guess, ascii_str, build_config_variable_values, camel_to_snake,
|
|
23
23
|
dedefuse, deep_dict_update, defuse, dummy_function, duplicates, env_str,
|
|
24
24
|
force_encoding, format_given, full_stack_trace, import_module, instantiate_config_parser, in_wd,
|
|
25
25
|
load_env_var_defaults, load_dotenvs, main_file_paths_parts, mask_secrets, module_attr,
|
|
26
26
|
module_file_path, module_name, norm_line_sep, norm_name, norm_path, now_str,
|
|
27
27
|
os_host_name, os_local_ip, _os_platform, os_user_name,
|
|
28
|
-
parse_dotenv, project_main_file, read_file, round_traditional,
|
|
29
|
-
str_ascii, sys_env_dict, sys_env_text, to_ascii, utc_datetime, write_file,
|
|
28
|
+
parse_dotenv, project_main_file, read_file, round_traditional, sign, snake_to_camel,
|
|
29
|
+
stack_frames, stack_var, stack_vars, str_ascii, sys_env_dict, sys_env_text, to_ascii, utc_datetime, write_file,
|
|
30
30
|
ErrorMsgMixin)
|
|
31
31
|
|
|
32
32
|
|
|
@@ -40,6 +40,7 @@ env_var_val = 'value of env var'
|
|
|
40
40
|
folder_name = 'fdr'
|
|
41
41
|
full_folders = (0, 1, 3)
|
|
42
42
|
|
|
43
|
+
|
|
43
44
|
@pytest.fixture
|
|
44
45
|
def os_env_test_env():
|
|
45
46
|
""" create .env files to test and backup os.environ. """
|
|
@@ -79,7 +80,7 @@ class TestErrorMsgMixin:
|
|
|
79
80
|
assert ins.cae is None # in test env is no console/gui app available
|
|
80
81
|
assert ins.po is ins.dpo is ins.vpo is print
|
|
81
82
|
|
|
82
|
-
with patch('ae.core.main_app_instance', lambda
|
|
83
|
+
with patch('ae.core.main_app_instance', lambda: None):
|
|
83
84
|
ins = ErrorMsgMixin()
|
|
84
85
|
assert ins
|
|
85
86
|
assert ins.cae is None
|
|
@@ -105,7 +106,7 @@ class TestErrorMsgMixin:
|
|
|
105
106
|
|
|
106
107
|
app_ins = _AppMock()
|
|
107
108
|
|
|
108
|
-
with patch('ae.core.main_app_instance', lambda
|
|
109
|
+
with patch('ae.core.main_app_instance', lambda: app_ins):
|
|
109
110
|
ins = ErrorMsgMixin()
|
|
110
111
|
assert ins.cae is app_ins
|
|
111
112
|
assert ins.po is not print
|
|
@@ -488,43 +489,64 @@ class TestBaseHelpers:
|
|
|
488
489
|
load_dotenvs()
|
|
489
490
|
assert env_var_name not in os.environ
|
|
490
491
|
|
|
491
|
-
def
|
|
492
|
+
def test_load_env_var_defaults_errors(self):
|
|
493
|
+
with pytest.raises(TypeError):
|
|
494
|
+
# noinspection PyArgumentList
|
|
495
|
+
load_env_var_defaults()
|
|
496
|
+
|
|
497
|
+
with pytest.raises(TypeError):
|
|
498
|
+
# noinspection PyTypeChecker
|
|
499
|
+
load_env_var_defaults(None, None)
|
|
500
|
+
|
|
501
|
+
# noinspection PyTypeChecker
|
|
502
|
+
load_env_var_defaults("inv:_ file path", ()) # NO ERROR EXCEPTIONS on these invalid arg values!!!
|
|
503
|
+
|
|
504
|
+
def test_load_env_var_defaults_not_loaded(self):
|
|
505
|
+
env_vars = {}
|
|
506
|
+
|
|
507
|
+
load_env_var_defaults('/', env_vars)
|
|
508
|
+
assert env_var_name not in env_vars
|
|
509
|
+
|
|
510
|
+
load_env_var_defaults('.', env_vars)
|
|
511
|
+
assert env_var_name not in env_vars
|
|
512
|
+
|
|
513
|
+
def test_load_env_var_defaults_not_loaded_in_os_environ(self, os_env_test_env):
|
|
492
514
|
assert env_var_name not in os.environ
|
|
493
515
|
|
|
494
|
-
load_env_var_defaults('/')
|
|
516
|
+
load_env_var_defaults('/', os.environ)
|
|
495
517
|
assert env_var_name not in os.environ
|
|
496
518
|
|
|
497
|
-
load_env_var_defaults('.')
|
|
519
|
+
load_env_var_defaults('.', os.environ)
|
|
498
520
|
assert env_var_name not in os.environ
|
|
499
521
|
|
|
500
|
-
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 5)))
|
|
522
|
+
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 5)), os.environ)
|
|
501
523
|
assert env_var_name not in os.environ
|
|
502
524
|
|
|
503
|
-
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 6)))
|
|
525
|
+
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 6)), os.environ) # too-deep path
|
|
504
526
|
assert env_var_name not in os.environ
|
|
505
527
|
|
|
506
528
|
def test_load_env_var_defaults_load_start_parent_first_no_chain(self, os_env_test_env):
|
|
507
|
-
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 4)))
|
|
529
|
+
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 4)), os.environ)
|
|
508
530
|
assert env_var_name in os.environ
|
|
509
531
|
assert os.environ[env_var_name] == env_var_val + '3'
|
|
510
532
|
|
|
511
533
|
def test_load_env_var_defaults_load_start_first_no_chain(self, os_env_test_env):
|
|
512
|
-
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 3)))
|
|
534
|
+
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 3)), os.environ)
|
|
513
535
|
assert env_var_name in os.environ
|
|
514
536
|
assert os.environ[env_var_name] == env_var_val + '3'
|
|
515
537
|
|
|
516
538
|
def test_load_env_var_defaults_load_start_parent_first_in_chain(self, os_env_test_env):
|
|
517
|
-
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 2)))
|
|
539
|
+
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 2)), os.environ)
|
|
518
540
|
assert env_var_name in os.environ
|
|
519
541
|
assert os.environ[env_var_name] == env_var_val + '1'
|
|
520
542
|
|
|
521
543
|
def test_load_env_var_defaults_load_start_no_parent_first_in_chain(self, os_env_test_env):
|
|
522
|
-
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 1)))
|
|
544
|
+
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 1)), os.environ)
|
|
523
545
|
assert env_var_name in os.environ
|
|
524
546
|
assert os.environ[env_var_name] == env_var_val + '1'
|
|
525
547
|
|
|
526
548
|
def test_load_env_var_defaults_load_start_on_second_within_chain(self, os_env_test_env):
|
|
527
|
-
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 0)))
|
|
549
|
+
load_env_var_defaults(os.path.join(os_env_test_env, *((folder_name, ) * 0)), os.environ)
|
|
528
550
|
assert env_var_name in os.environ
|
|
529
551
|
assert os.environ[env_var_name] == env_var_val + '0'
|
|
530
552
|
|
|
@@ -559,17 +581,15 @@ class TestBaseHelpers:
|
|
|
559
581
|
assert mask_secrets({'_token': "secret"}, fragments=('TOKEN', 'secret')) == {'_token': "secret"}
|
|
560
582
|
|
|
561
583
|
untouched = 'untouched_Pw_d_p_a_s_s_word'
|
|
562
|
-
dat = {'key1':
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
'passWord___': "secRet",
|
|
569
|
-
},
|
|
584
|
+
dat = {'key1': {'subKey1': (
|
|
585
|
+
{'host_Pwd': "secret"},
|
|
586
|
+
untouched,
|
|
587
|
+
),
|
|
588
|
+
'passWord___': "secRet",
|
|
589
|
+
},
|
|
570
590
|
'any_PASSWORD_to_hide': "Se",
|
|
571
591
|
untouched: untouched,
|
|
572
|
-
|
|
592
|
+
}
|
|
573
593
|
assert mask_secrets(dat) is dat
|
|
574
594
|
assert dat['key1']['subKey1'][0]['host_Pwd'] == "sec*********"
|
|
575
595
|
assert dat['key1']['passWord___'] == "sec*********"
|
|
@@ -634,6 +654,7 @@ class TestBaseHelpers:
|
|
|
634
654
|
finally:
|
|
635
655
|
os.environ.pop('ANDROID_ARGUMENT', None)
|
|
636
656
|
|
|
657
|
+
# noinspection PyUnreachableCode
|
|
637
658
|
try:
|
|
638
659
|
os.environ['KIVY_BUILD'] = 'android'
|
|
639
660
|
assert _os_platform() == 'android'
|
|
@@ -687,12 +708,20 @@ class TestBaseHelpers:
|
|
|
687
708
|
with tempfile.NamedTemporaryFile(mode="w") as fp:
|
|
688
709
|
fp.write('declaredVar = DeclaredValue\n')
|
|
689
710
|
fp.write('replacedVar = beforeTheDollar$declaredVar\n')
|
|
690
|
-
fp.write('uncutVar
|
|
711
|
+
fp.write('uncutVar=beforeTheDollar$afterTheDollar\n')
|
|
691
712
|
fp.seek(0)
|
|
692
713
|
loaded = parse_dotenv(fp.name)
|
|
693
714
|
assert loaded['replacedVar'] == "beforeTheDollarDeclaredValue"
|
|
694
715
|
assert loaded['uncutVar'] == "beforeTheDollar$afterTheDollar"
|
|
695
716
|
|
|
717
|
+
def test_parse_dotenv_double_in_single_value(self):
|
|
718
|
+
with tempfile.NamedTemporaryFile(mode="w") as fp:
|
|
719
|
+
fp.write("""var_nam='"var val"'""")
|
|
720
|
+
fp.seek(0)
|
|
721
|
+
loaded = parse_dotenv(fp.name)
|
|
722
|
+
assert 'var_nam' in loaded
|
|
723
|
+
assert loaded['var_nam'] == '"var val"'
|
|
724
|
+
|
|
696
725
|
def test_parse_dotenv_double_quoted_value(self):
|
|
697
726
|
with tempfile.NamedTemporaryFile(mode="w") as fp:
|
|
698
727
|
fp.write('var_nam="var val"')
|
|
@@ -708,6 +737,14 @@ class TestBaseHelpers:
|
|
|
708
737
|
loaded = parse_dotenv(fp.name)
|
|
709
738
|
assert 'var_nam' not in loaded # added warning
|
|
710
739
|
|
|
740
|
+
def test_parse_dotenv_single_in_double_quoted_value(self):
|
|
741
|
+
with tempfile.NamedTemporaryFile(mode="w") as fp:
|
|
742
|
+
fp.write('''var_nam="'var val'"''')
|
|
743
|
+
fp.seek(0)
|
|
744
|
+
loaded = parse_dotenv(fp.name)
|
|
745
|
+
assert 'var_nam' in loaded
|
|
746
|
+
assert loaded['var_nam'] == "'var val'"
|
|
747
|
+
|
|
711
748
|
def test_parse_dotenv_single_value(self):
|
|
712
749
|
with tempfile.NamedTemporaryFile(mode="w") as fp:
|
|
713
750
|
fp.write("var_nam='var val'")
|
|
@@ -716,6 +753,24 @@ class TestBaseHelpers:
|
|
|
716
753
|
assert 'var_nam' in loaded
|
|
717
754
|
assert loaded['var_nam'] == "var val"
|
|
718
755
|
|
|
756
|
+
def test_parse_dotenv_literal_dict_with_list(self):
|
|
757
|
+
with tempfile.NamedTemporaryFile(mode="w") as fp:
|
|
758
|
+
var_val = "{'key': {'sub-key': ['list-item', 'list-item with = char', ]}}"
|
|
759
|
+
fp.write("var_nam=" + var_val)
|
|
760
|
+
fp.seek(0)
|
|
761
|
+
loaded = parse_dotenv(fp.name)
|
|
762
|
+
assert 'var_nam' in loaded
|
|
763
|
+
assert loaded['var_nam'] == var_val
|
|
764
|
+
|
|
765
|
+
def test_parse_dotenv_literal_dict_with_list_quoted(self):
|
|
766
|
+
with tempfile.NamedTemporaryFile(mode="w") as fp:
|
|
767
|
+
var_val = "{'key': {'sub-key': ['list-item', 'list-item with = char']}}"
|
|
768
|
+
fp.write('var_nam="' + var_val + '"')
|
|
769
|
+
fp.seek(0)
|
|
770
|
+
loaded = parse_dotenv(fp.name)
|
|
771
|
+
assert 'var_nam' in loaded
|
|
772
|
+
assert loaded['var_nam'] == var_val
|
|
773
|
+
|
|
719
774
|
def test_parse_dotenv_start_parent_first_in_chain(self, os_env_test_env):
|
|
720
775
|
assert env_var_name not in os.environ
|
|
721
776
|
file_path = os.path.join(os_env_test_env, folder_name, DOTENV_FILE_NAME)
|
|
@@ -802,7 +857,7 @@ class TestBaseHelpers:
|
|
|
802
857
|
|
|
803
858
|
def test_parse_dotenv_var_not_expands_escaped_variables(self):
|
|
804
859
|
with tempfile.NamedTemporaryFile(mode="w") as fp:
|
|
805
|
-
fp.write("var_nam=var val \\$env_var
|
|
860
|
+
fp.write("var_nam=var val \\$env_var \\${env_var}")
|
|
806
861
|
fp.seek(0)
|
|
807
862
|
loaded = parse_dotenv(fp.name)
|
|
808
863
|
assert 'var_nam' in loaded
|
|
@@ -853,6 +908,31 @@ class TestBaseHelpers:
|
|
|
853
908
|
assert round_traditional(0.075, 2) == 0.08
|
|
854
909
|
assert round(0.075, 2) == 0.07
|
|
855
910
|
|
|
911
|
+
def test_sign_with_float_arg(self):
|
|
912
|
+
assert sign(1.11) == 1
|
|
913
|
+
assert sign(-0.000003) == -1
|
|
914
|
+
assert sign(0.0000000) == 0
|
|
915
|
+
assert sign(-0.0) == 0
|
|
916
|
+
|
|
917
|
+
def test_sign_with_int_arg(self):
|
|
918
|
+
assert sign(3) == 1
|
|
919
|
+
assert sign(-6) == -1
|
|
920
|
+
assert sign(0) == 0
|
|
921
|
+
assert sign(-0) == 0
|
|
922
|
+
|
|
923
|
+
def test_sign_with_invalid_arg(self):
|
|
924
|
+
with pytest.raises(TypeError):
|
|
925
|
+
# noinspection PyArgumentList
|
|
926
|
+
sign()
|
|
927
|
+
|
|
928
|
+
with pytest.raises(TypeError):
|
|
929
|
+
# noinspection PyArgumentList,PyTypeChecker
|
|
930
|
+
sign(None)
|
|
931
|
+
|
|
932
|
+
with pytest.raises(TypeError):
|
|
933
|
+
# noinspection PyArgumentList,PyTypeChecker
|
|
934
|
+
sign(UNSET)
|
|
935
|
+
|
|
856
936
|
def test_snake_to_camel(self):
|
|
857
937
|
assert snake_to_camel("_Any_Camel_Case_Name") == "AnyCamelCaseName"
|
|
858
938
|
assert snake_to_camel("any_Camel_Case_Name") == "AnyCamelCaseName"
|
|
@@ -981,6 +1061,7 @@ class TestModuleHelpers:
|
|
|
981
1061
|
os.remove(module_file)
|
|
982
1062
|
|
|
983
1063
|
# test already imported module
|
|
1064
|
+
# noinspection PyUnreachableCode
|
|
984
1065
|
callee = module_attr('textwrap', attr_name='indent')
|
|
985
1066
|
assert callable(callee)
|
|
986
1067
|
assert callee is textwrap.indent
|
|
@@ -1033,7 +1114,7 @@ class TestModuleHelpers:
|
|
|
1033
1114
|
os.remove(module_file)
|
|
1034
1115
|
|
|
1035
1116
|
def test_module_attr_not_exists_attr(self):
|
|
1036
|
-
""" first test with non-existing module, second test with non-existing function. """
|
|
1117
|
+
""" first test with a non-existing module, second test with a non-existing function. """
|
|
1037
1118
|
namespace = TESTS_FOLDER
|
|
1038
1119
|
mod_name = 'test_module_name'
|
|
1039
1120
|
att_name = 'test_module_func'
|
|
@@ -1060,7 +1141,7 @@ class TestModuleHelpers:
|
|
|
1060
1141
|
os.remove(module_file)
|
|
1061
1142
|
|
|
1062
1143
|
def test_module_attr_not_exists_module(self):
|
|
1063
|
-
""" first test with non-existing module, second test with non-existing function. """
|
|
1144
|
+
""" first test with a non-existing module, second test with a non-existing function. """
|
|
1064
1145
|
mod_name = 'non_existing_test_module_name'
|
|
1065
1146
|
att_name = 'non_existing_test_module_func'
|
|
1066
1147
|
assert module_attr(mod_name, attr_name=att_name) is None
|
|
@@ -1102,7 +1183,7 @@ class TestStackHelpers:
|
|
|
1102
1183
|
for frame in stack_frames():
|
|
1103
1184
|
assert frame
|
|
1104
1185
|
assert getattr(frame, 'f_globals')
|
|
1105
|
-
# if pytest runs from terminal then f_locals is missing in the highest frame:
|
|
1186
|
+
# if pytest runs from terminal, then f_locals is missing in the highest frame:
|
|
1106
1187
|
# assert getattr(frame, 'f_locals')
|
|
1107
1188
|
|
|
1108
1189
|
def test_stack_var_module(self):
|
ae_base-0.3.55/setup.py
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
# THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_project V0.3.32
|
|
2
|
-
""" setup this project with setuptools and aedev.setup_project. """
|
|
3
|
-
import pprint
|
|
4
|
-
import sys
|
|
5
|
-
|
|
6
|
-
import setuptools
|
|
7
|
-
|
|
8
|
-
from aedev.setup_project import project_env_vars # type: ignore
|
|
9
|
-
|
|
10
|
-
pev = project_env_vars(from_setup=True)
|
|
11
|
-
|
|
12
|
-
if __name__ == "__main__":
|
|
13
|
-
print("# EXECUTING SETUPTOOLS SETUP: argv, kwargs ###################")
|
|
14
|
-
print(pprint.pformat(sys.argv, indent=3, width=75, compact=True))
|
|
15
|
-
setup_kwargs = pev['setup_kwargs']
|
|
16
|
-
print(pprint.pformat(setup_kwargs, indent=3, width=75, compact=True))
|
|
17
|
-
setuptools.setup(**setup_kwargs)
|
|
18
|
-
print("# FINISHED SETUPTOOLS SETUP ##################################")
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|