osbot-utils 1.94.0__py3-none-any.whl → 1.96.0__py3-none-any.whl
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.
- osbot_utils/base_classes/Type_Safe.py +9 -7
- osbot_utils/base_classes/Type_Safe__Dict.py +1 -1
- osbot_utils/helpers/Guid.py +1 -1
- osbot_utils/helpers/trace/Trace_Call__Handler.py +1 -0
- osbot_utils/utils/Objects.py +33 -22
- osbot_utils/version +1 -1
- {osbot_utils-1.94.0.dist-info → osbot_utils-1.96.0.dist-info}/METADATA +2 -2
- {osbot_utils-1.94.0.dist-info → osbot_utils-1.96.0.dist-info}/RECORD +10 -10
- {osbot_utils-1.94.0.dist-info → osbot_utils-1.96.0.dist-info}/LICENSE +0 -0
- {osbot_utils-1.94.0.dist-info → osbot_utils-1.96.0.dist-info}/WHEEL +0 -0
@@ -3,7 +3,8 @@
|
|
3
3
|
|
4
4
|
import sys
|
5
5
|
import types
|
6
|
-
from osbot_utils.utils.Objects import default_value
|
6
|
+
from osbot_utils.utils.Objects import default_value # todo: remove test mocking requirement for this to be here (instead of on the respective method)
|
7
|
+
from osbot_utils.utils.Objects import all_annotations
|
7
8
|
|
8
9
|
# Backport implementations of get_origin and get_args for Python 3.7
|
9
10
|
if sys.version_info < (3, 8): # pragma: no cover
|
@@ -89,7 +90,8 @@ class Type_Safe:
|
|
89
90
|
from osbot_utils.utils.Objects import value_type_matches_obj_annotation_for_union_and_annotated
|
90
91
|
from osbot_utils.helpers.type_safe.Type_Safe__Validator import Type_Safe__Validator
|
91
92
|
|
92
|
-
|
93
|
+
annotations = all_annotations(self)
|
94
|
+
if not annotations: # can't do type safety checks if the class does not have annotations
|
93
95
|
return super().__setattr__(name, value)
|
94
96
|
|
95
97
|
if value is not None:
|
@@ -101,20 +103,20 @@ class Type_Safe:
|
|
101
103
|
origin = get_origin(value)
|
102
104
|
if origin is not None:
|
103
105
|
value = origin
|
104
|
-
check_1 = value_type_matches_obj_annotation_for_attr
|
106
|
+
check_1 = value_type_matches_obj_annotation_for_attr (self, name, value)
|
105
107
|
check_2 = value_type_matches_obj_annotation_for_union_and_annotated(self, name, value)
|
106
108
|
if (check_1 is False and check_2 is None or
|
107
109
|
check_1 is None and check_2 is False or
|
108
110
|
check_1 is False and check_2 is False ): # fix for type safety assigment on Union vars
|
109
|
-
raise ValueError(f"Invalid type for attribute '{name}'. Expected '{
|
111
|
+
raise ValueError(f"Invalid type for attribute '{name}'. Expected '{annotations.get(name)}' but got '{type(value)}'")
|
110
112
|
else:
|
111
|
-
if hasattr(self, name) and
|
113
|
+
if hasattr(self, name) and annotations.get(name) : # don't allow previously set variables to be set to None
|
112
114
|
if getattr(self, name) is not None: # unless it is already set to None
|
113
115
|
raise ValueError(f"Can't set None, to a variable that is already set. Invalid type for attribute '{name}'. Expected '{self.__annotations__.get(name)}' but got '{type(value)}'")
|
114
116
|
|
115
117
|
# todo: refactor this to separate method
|
116
|
-
if hasattr(
|
117
|
-
annotation =
|
118
|
+
if hasattr(annotations, 'get'):
|
119
|
+
annotation = annotations.get(name)
|
118
120
|
if annotation and get_origin(annotation) is Annotated:
|
119
121
|
annotation_args = get_args(annotation)
|
120
122
|
target_type = annotation_args[0]
|
@@ -19,4 +19,4 @@ class Type_Safe__Dict(Type_Safe__Base, dict):
|
|
19
19
|
def __repr__(self):
|
20
20
|
key_type_name = type_str(self.expected_key_type)
|
21
21
|
value_type_name = type_str(self.expected_value_type)
|
22
|
-
return f"dict[{key_type_name}, {value_type_name}] with {len(self)} entries"
|
22
|
+
return f"dict[{key_type_name}, {value_type_name}] with {len(self)} entries"
|
osbot_utils/helpers/Guid.py
CHANGED
@@ -11,7 +11,7 @@ class Guid(str):
|
|
11
11
|
if is_guid(value):
|
12
12
|
guid = value
|
13
13
|
else:
|
14
|
-
guid = uuid.uuid5(GUID__NAMESPACE, value)
|
14
|
+
guid = uuid.uuid5(GUID__NAMESPACE, value) # Generate a UUID5 using the namespace and value
|
15
15
|
return super().__new__(cls, str(guid)) # Return a new instance of Guid initialized with the string version of the UUID
|
16
16
|
|
17
17
|
def __str__(self):
|
@@ -12,6 +12,7 @@ GLOBAL_FUNCTIONS_TO_IGNORE = ['value_type_matches_obj_annotation_for_attr'
|
|
12
12
|
'value_type_matches_obj_annotation_for_union_and_annotated' , # todo: map out and document why exactly these methods are ignore (and what is the side effect)
|
13
13
|
'are_types_compatible_for_assigment' ,
|
14
14
|
'obj_attribute_annotation' ,
|
15
|
+
'all_annotations' ,
|
15
16
|
'get_origin' ,
|
16
17
|
'getmro' ,
|
17
18
|
'default_value' ,
|
osbot_utils/utils/Objects.py
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# todo add tests
|
2
2
|
import sys
|
3
|
-
from types
|
3
|
+
from types import SimpleNamespace
|
4
|
+
from osbot_utils.helpers.python_compatibility.python_3_8 import Annotated
|
5
|
+
|
4
6
|
|
5
7
|
class __(SimpleNamespace):
|
6
8
|
pass
|
@@ -439,29 +441,38 @@ def pickle_load_from_bytes(pickled_data: bytes):
|
|
439
441
|
except Exception:
|
440
442
|
return {}
|
441
443
|
|
444
|
+
def all_annotations(target):
|
445
|
+
annotations = {}
|
446
|
+
if hasattr(target.__class__, '__mro__'):
|
447
|
+
for base in reversed(target.__class__.__mro__):
|
448
|
+
if hasattr(base, '__annotations__'):
|
449
|
+
annotations.update(base.__annotations__)
|
450
|
+
return annotations
|
451
|
+
|
442
452
|
def value_type_matches_obj_annotation_for_attr(target, attr_name, value):
|
443
453
|
import typing
|
444
|
-
|
445
|
-
|
446
|
-
|
447
|
-
|
448
|
-
|
449
|
-
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
|
455
|
-
|
456
|
-
|
457
|
-
|
458
|
-
|
459
|
-
|
460
|
-
|
461
|
-
|
462
|
-
|
463
|
-
|
464
|
-
|
454
|
+
annotations = all_annotations(target)
|
455
|
+
attr_type = annotations.get(attr_name)
|
456
|
+
if attr_type:
|
457
|
+
origin_attr_type = get_origin(attr_type) # to handle when type definition contains a generic
|
458
|
+
if origin_attr_type is Annotated: # if the type is Annotated
|
459
|
+
args = get_args(attr_type)
|
460
|
+
origin_attr_type = args[0]
|
461
|
+
|
462
|
+
elif origin_attr_type is typing.Union:
|
463
|
+
args = get_args(attr_type)
|
464
|
+
if len(args)==2 and args[1] is type(None): # todo: find a better way to do this, since this is handling an edge case when origin_attr_type is Optional (which is an shorthand for Union[X, None] )
|
465
|
+
attr_type = args[0]
|
466
|
+
origin_attr_type = get_origin(attr_type)
|
467
|
+
|
468
|
+
if origin_attr_type:
|
469
|
+
attr_type = origin_attr_type
|
470
|
+
value_type = type(value)
|
471
|
+
if are_types_compatible_for_assigment(source_type=value_type, target_type=attr_type):
|
472
|
+
return True
|
473
|
+
if are_types_magic_mock(source_type=value_type, target_type=attr_type):
|
474
|
+
return True
|
475
|
+
return value_type is attr_type
|
465
476
|
return None
|
466
477
|
|
467
478
|
|
osbot_utils/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
v1.
|
1
|
+
v1.96.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: osbot_utils
|
3
|
-
Version: 1.
|
3
|
+
Version: 1.96.0
|
4
4
|
Summary: OWASP Security Bot - Utils
|
5
5
|
Home-page: https://github.com/owasp-sbot/OSBot-Utils
|
6
6
|
License: MIT
|
@@ -23,7 +23,7 @@ Description-Content-Type: text/markdown
|
|
23
23
|
|
24
24
|
Powerful Python util methods and classes that simplify common apis and tasks.
|
25
25
|
|
26
|
-

|
27
27
|
[](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
|
28
28
|
|
29
29
|
|
@@ -2,9 +2,9 @@ osbot_utils/__init__.py,sha256=DdJDmQc9zbQUlPVyTJOww6Ixrn9n4bD3ami5ItQfzJI,16
|
|
2
2
|
osbot_utils/base_classes/Cache_Pickle.py,sha256=kPCwrgUbf_dEdxUz7vW1GuvIPwlNXxuRhb-H3AbSpII,5884
|
3
3
|
osbot_utils/base_classes/Kwargs_To_Disk.py,sha256=HHoy05NC_w35WcT-OnSKoSIV_cLqaU9rdjH0_KNTM0E,1096
|
4
4
|
osbot_utils/base_classes/Kwargs_To_Self.py,sha256=weFNsBfBNV9W_qBkN-IdBD4yYcJV_zgTxBRO-ZlcPS4,141
|
5
|
-
osbot_utils/base_classes/Type_Safe.py,sha256=
|
5
|
+
osbot_utils/base_classes/Type_Safe.py,sha256=cfpLk3x0TQNeRMSRda91_DAO_m14_QtYcRrGMWZ8dmU,29076
|
6
6
|
osbot_utils/base_classes/Type_Safe__Base.py,sha256=CFPYe8_i5vvTLyc7s8CXbY4n_dY6sqVfBY8w9Vo77ZA,5468
|
7
|
-
osbot_utils/base_classes/Type_Safe__Dict.py,sha256=
|
7
|
+
osbot_utils/base_classes/Type_Safe__Dict.py,sha256=yB9dSNPh_PARqXhNLg1HBFXgMsB-o-PC7h-BUE8njg0,1106
|
8
8
|
osbot_utils/base_classes/Type_Safe__List.py,sha256=pXDzJJttpEQQ9oTdsw7BykMB4VIX2rZzi1ZrnCzMZ8M,650
|
9
9
|
osbot_utils/base_classes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
10
10
|
osbot_utils/context_managers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -41,7 +41,7 @@ osbot_utils/helpers/CFormat.py,sha256=1_XvqGwgU6qC97MbzcKF0o7s9mCXpU5Kq9Yf-1ixUw
|
|
41
41
|
osbot_utils/helpers/CPrint.py,sha256=ztKPNmT8BGxeyPXSQKRs63PqqbgxKDz_BiZmzFMup9g,1413
|
42
42
|
osbot_utils/helpers/Dependency_Manager.py,sha256=79YRYnVfchewq8iSMJ5dzwW2D5u8chWcIqYE-G9YrSo,1337
|
43
43
|
osbot_utils/helpers/Dict_To_Attr.py,sha256=NdhXl5mJH7-NaBk213amzc5Nfy3tJgW-N_uYIRE4hoc,208
|
44
|
-
osbot_utils/helpers/Guid.py,sha256=
|
44
|
+
osbot_utils/helpers/Guid.py,sha256=fqiCYHrYff3yZ_Df-WJdXHl1RQtJHb4oCmDkJpcGN_k,828
|
45
45
|
osbot_utils/helpers/Hashicorp_Secrets.py,sha256=zjXa_dQvfR9L1uoulWJ8nYYaDvznV6o_QPPS4zmb6mo,4235
|
46
46
|
osbot_utils/helpers/Local_Cache.py,sha256=0JZZX3fFImcwtbBvxAQl-EbBegSNJRhRMYF6ovTH6zY,3141
|
47
47
|
osbot_utils/helpers/Local_Caches.py,sha256=aQmi1HSM0TH6WQPedG2fbz4KCCJ3DQTU9d18rB1jR0M,1885
|
@@ -239,7 +239,7 @@ osbot_utils/helpers/ssh/TestCase__SSH.py,sha256=MD8sq0_kI4f6pEmEO0cLq2mQOhIqbP45
|
|
239
239
|
osbot_utils/helpers/ssh/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
240
240
|
osbot_utils/helpers/trace/Trace_Call.py,sha256=O_y6cncgneYrj3ARDMz-o9Yi1LjsESibUqkGFAg0Jk0,8886
|
241
241
|
osbot_utils/helpers/trace/Trace_Call__Config.py,sha256=UAjdsDEqsPBBsu-h4_QKYL4UMukJmQYBBWGYTmSKS40,3361
|
242
|
-
osbot_utils/helpers/trace/Trace_Call__Handler.py,sha256=
|
242
|
+
osbot_utils/helpers/trace/Trace_Call__Handler.py,sha256=lXMk_7M9SK7s13qNpLuk5qx9CJJ3lzMJGdI8tB-nO-c,12744
|
243
243
|
osbot_utils/helpers/trace/Trace_Call__Print_Lines.py,sha256=cy7zLv0_JNxdOIQPfZk6J9bv6AkIW6O643w0ykClXbw,4820
|
244
244
|
osbot_utils/helpers/trace/Trace_Call__Print_Traces.py,sha256=2LGeWMGP1uhSojGMmJmL3bH2B5LFIlfYEqEPNqoyKJw,8628
|
245
245
|
osbot_utils/helpers/trace/Trace_Call__Stack.py,sha256=pIvZ2yP4tymOQraUR2N5R-qlmg5QijyLxt85zmMajUs,7462
|
@@ -304,7 +304,7 @@ osbot_utils/utils/Json.py,sha256=0t7Hwefx8bg4JiZVr-xIbWP3BAk6_ZsnY7iV5pnRLDQ,713
|
|
304
304
|
osbot_utils/utils/Json_Cache.py,sha256=mLPkkDZN-3ZVJiDvV1KBJXILtKkTZ4OepzOsDoBPhWg,2006
|
305
305
|
osbot_utils/utils/Lists.py,sha256=tPz5x5s3sRO97WZ_nsxREBPC5cwaHrhgaYBhsrffTT8,5599
|
306
306
|
osbot_utils/utils/Misc.py,sha256=H_xexJgiTxB3jDeDiW8efGQbO0Zuy8MM0iQ7qXC92JI,17363
|
307
|
-
osbot_utils/utils/Objects.py,sha256=
|
307
|
+
osbot_utils/utils/Objects.py,sha256=7QS_rBiLMLiD28be_br-7NrLfR7LtxFImjUGko8MqXM,21933
|
308
308
|
osbot_utils/utils/Png.py,sha256=V1juGp6wkpPigMJ8HcxrPDIP4bSwu51oNkLI8YqP76Y,1172
|
309
309
|
osbot_utils/utils/Process.py,sha256=lr3CTiEkN3EiBx3ZmzYmTKlQoPdkgZBRjPulMxG-zdo,2357
|
310
310
|
osbot_utils/utils/Python_Logger.py,sha256=tx8N6wRKL3RDHboDRKZn8SirSJdSAE9cACyJkxrThZ8,12792
|
@@ -316,8 +316,8 @@ osbot_utils/utils/Toml.py,sha256=Rxl8gx7mni5CvBAK-Ai02EKw-GwtJdd3yeHT2kMloik,166
|
|
316
316
|
osbot_utils/utils/Version.py,sha256=Ww6ChwTxqp1QAcxOnztkTicShlcx6fbNsWX5xausHrg,422
|
317
317
|
osbot_utils/utils/Zip.py,sha256=pR6sKliUY0KZXmqNzKY2frfW-YVQEVbLKiyqQX_lc-8,14052
|
318
318
|
osbot_utils/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
319
|
-
osbot_utils/version,sha256=
|
320
|
-
osbot_utils-1.
|
321
|
-
osbot_utils-1.
|
322
|
-
osbot_utils-1.
|
323
|
-
osbot_utils-1.
|
319
|
+
osbot_utils/version,sha256=idBQWZKGK2d1XFMMuNvvIctFv7Fbwu_HFj9LNFyYPr0,8
|
320
|
+
osbot_utils-1.96.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
321
|
+
osbot_utils-1.96.0.dist-info/METADATA,sha256=lidaLHgX0Z8-vuoHwr9SvH7LJnjQ2X2KKqLHQpV6PKQ,1317
|
322
|
+
osbot_utils-1.96.0.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
323
|
+
osbot_utils-1.96.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|