ae-base 0.3.55__tar.gz → 0.3.56__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,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ae_base
3
- Version: 0.3.55
3
+ Version: 0.3.56
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,17 +69,17 @@ Dynamic: summary
69
69
 
70
70
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.95 -->
71
71
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_namespace_root V0.3.14 -->
72
- # base 0.3.55
72
+ # base 0.3.56
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.54?logo=python)](
78
- https://gitlab.com/ae-group/ae_base/-/tree/release0.3.54)
77
+ https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.55?logo=python)](
78
+ https://gitlab.com/ae-group/ae_base/-/tree/release0.3.55)
79
79
  [![PyPIVersions](https://img.shields.io/pypi/v/ae_base)](
80
80
  https://pypi.org/project/ae-base/#history)
81
81
 
82
- >ae_base module 0.3.55.
82
+ >ae_base module 0.3.56.
83
83
 
84
84
  [![Coverage](https://ae-group.gitlab.io/ae_base/coverage.svg)](
85
85
  https://ae-group.gitlab.io/ae_base/coverage/index.html)
@@ -1,16 +1,16 @@
1
1
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.95 -->
2
2
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_namespace_root V0.3.14 -->
3
- # base 0.3.55
3
+ # base 0.3.56
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.54?logo=python)](
9
- https://gitlab.com/ae-group/ae_base/-/tree/release0.3.54)
8
+ https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.55?logo=python)](
9
+ https://gitlab.com/ae-group/ae_base/-/tree/release0.3.55)
10
10
  [![PyPIVersions](https://img.shields.io/pypi/v/ae_base)](
11
11
  https://pypi.org/project/ae-base/#history)
12
12
 
13
- >ae_base module 0.3.55.
13
+ >ae_base module 0.3.56.
14
14
 
15
15
  [![Coverage](https://ae-group.gitlab.io/ae_base/coverage.svg)](
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
 
@@ -168,7 +171,7 @@ from types import ModuleType
168
171
  from typing import Any, Callable, Generator, Iterable, Optional, Union, cast
169
172
 
170
173
 
171
- __version__ = '0.3.55'
174
+ __version__ = '0.3.56'
172
175
 
173
176
 
174
177
  os_path_abspath = os.path.abspath
@@ -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.55
3
+ Version: 0.3.56
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,17 +69,17 @@ Dynamic: summary
69
69
 
70
70
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project ae.ae V0.3.95 -->
71
71
  <!-- THIS FILE IS EXCLUSIVELY MAINTAINED by the project aedev.tpl_namespace_root V0.3.14 -->
72
- # base 0.3.55
72
+ # base 0.3.56
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.54?logo=python)](
78
- https://gitlab.com/ae-group/ae_base/-/tree/release0.3.54)
77
+ https://img.shields.io/gitlab/pipeline/ae-group/ae_base/release0.3.55?logo=python)](
78
+ https://gitlab.com/ae-group/ae_base/-/tree/release0.3.55)
79
79
  [![PyPIVersions](https://img.shields.io/pypi/v/ae_base)](
80
80
  https://pypi.org/project/ae-base/#history)
81
81
 
82
- >ae_base module 0.3.55.
82
+ >ae_base module 0.3.56.
83
83
 
84
84
  [![Coverage](https://ae-group.gitlab.io/ae_base/coverage.svg)](
85
85
  https://ae-group.gitlab.io/ae_base/coverage/index.html)
@@ -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
- URI_SEP_CHAR, app_name_guess, ascii_str, build_config_variable_values, camel_to_snake,
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, snake_to_camel, stack_frames, stack_var, stack_vars,
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 : None):
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 : app_ins):
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
@@ -559,17 +560,15 @@ class TestBaseHelpers:
559
560
  assert mask_secrets({'_token': "secret"}, fragments=('TOKEN', 'secret')) == {'_token': "secret"}
560
561
 
561
562
  untouched = 'untouched_Pw_d_p_a_s_s_word'
562
- dat = {'key1':
563
- {'subKey1':
564
- (
565
- {'host_Pwd': "secret"},
566
- untouched,
567
- ),
568
- 'passWord___': "secRet",
569
- },
563
+ dat = {'key1': {'subKey1': (
564
+ {'host_Pwd': "secret"},
565
+ untouched,
566
+ ),
567
+ 'passWord___': "secRet",
568
+ },
570
569
  'any_PASSWORD_to_hide': "Se",
571
570
  untouched: untouched,
572
- }
571
+ }
573
572
  assert mask_secrets(dat) is dat
574
573
  assert dat['key1']['subKey1'][0]['host_Pwd'] == "sec*********"
575
574
  assert dat['key1']['passWord___'] == "sec*********"
@@ -634,6 +633,7 @@ class TestBaseHelpers:
634
633
  finally:
635
634
  os.environ.pop('ANDROID_ARGUMENT', None)
636
635
 
636
+ # noinspection PyUnreachableCode
637
637
  try:
638
638
  os.environ['KIVY_BUILD'] = 'android'
639
639
  assert _os_platform() == 'android'
@@ -802,7 +802,7 @@ class TestBaseHelpers:
802
802
 
803
803
  def test_parse_dotenv_var_not_expands_escaped_variables(self):
804
804
  with tempfile.NamedTemporaryFile(mode="w") as fp:
805
- fp.write("var_nam=var val \\$env_var \${env_var}")
805
+ fp.write("var_nam=var val \\$env_var \\${env_var}")
806
806
  fp.seek(0)
807
807
  loaded = parse_dotenv(fp.name)
808
808
  assert 'var_nam' in loaded
@@ -853,6 +853,31 @@ class TestBaseHelpers:
853
853
  assert round_traditional(0.075, 2) == 0.08
854
854
  assert round(0.075, 2) == 0.07
855
855
 
856
+ def test_sign_with_float_arg(self):
857
+ assert sign(1.11) == 1
858
+ assert sign(-0.000003) == -1
859
+ assert sign(0.0000000) == 0
860
+ assert sign(-0.0) == 0
861
+
862
+ def test_sign_with_int_arg(self):
863
+ assert sign(3) == 1
864
+ assert sign(-6) == -1
865
+ assert sign(0) == 0
866
+ assert sign(-0) == 0
867
+
868
+ def test_sign_with_invalid_arg(self):
869
+ with pytest.raises(TypeError):
870
+ # noinspection PyArgumentList
871
+ sign()
872
+
873
+ with pytest.raises(TypeError):
874
+ # noinspection PyArgumentList,PyTypeChecker
875
+ sign(None)
876
+
877
+ with pytest.raises(TypeError):
878
+ # noinspection PyArgumentList,PyTypeChecker
879
+ sign(UNSET)
880
+
856
881
  def test_snake_to_camel(self):
857
882
  assert snake_to_camel("_Any_Camel_Case_Name") == "AnyCamelCaseName"
858
883
  assert snake_to_camel("any_Camel_Case_Name") == "AnyCamelCaseName"
@@ -981,6 +1006,7 @@ class TestModuleHelpers:
981
1006
  os.remove(module_file)
982
1007
 
983
1008
  # test already imported module
1009
+ # noinspection PyUnreachableCode
984
1010
  callee = module_attr('textwrap', attr_name='indent')
985
1011
  assert callable(callee)
986
1012
  assert callee is textwrap.indent
@@ -1033,7 +1059,7 @@ class TestModuleHelpers:
1033
1059
  os.remove(module_file)
1034
1060
 
1035
1061
  def test_module_attr_not_exists_attr(self):
1036
- """ first test with non-existing module, second test with non-existing function. """
1062
+ """ first test with a non-existing module, second test with a non-existing function. """
1037
1063
  namespace = TESTS_FOLDER
1038
1064
  mod_name = 'test_module_name'
1039
1065
  att_name = 'test_module_func'
@@ -1060,7 +1086,7 @@ class TestModuleHelpers:
1060
1086
  os.remove(module_file)
1061
1087
 
1062
1088
  def test_module_attr_not_exists_module(self):
1063
- """ first test with non-existing module, second test with non-existing function. """
1089
+ """ first test with a non-existing module, second test with a non-existing function. """
1064
1090
  mod_name = 'non_existing_test_module_name'
1065
1091
  att_name = 'non_existing_test_module_func'
1066
1092
  assert module_attr(mod_name, attr_name=att_name) is None
@@ -1102,7 +1128,7 @@ class TestStackHelpers:
1102
1128
  for frame in stack_frames():
1103
1129
  assert frame
1104
1130
  assert getattr(frame, 'f_globals')
1105
- # if pytest runs from terminal then f_locals is missing in the highest frame:
1131
+ # if pytest runs from terminal, then f_locals is missing in the highest frame:
1106
1132
  # assert getattr(frame, 'f_locals')
1107
1133
 
1108
1134
  def test_stack_var_module(self):
File without changes
File without changes
File without changes