osbot-utils 2.3.0__py3-none-any.whl → 2.5.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/helpers/Guid.py +0 -1
- osbot_utils/type_safe/Type_Safe.py +11 -3
- osbot_utils/type_safe/{Type_Safe_Method.py → Type_Safe__Method.py} +1 -1
- osbot_utils/type_safe/decorators/type_safe.py +2 -2
- osbot_utils/type_safe/validators/Validator__Max.py +1 -1
- osbot_utils/type_safe/validators/Validator__Min.py +1 -1
- osbot_utils/type_safe/validators/Validator__One_Of.py +1 -1
- osbot_utils/type_safe/validators/Validator__Regex.py +1 -1
- osbot_utils/utils/Objects.py +20 -3
- osbot_utils/version +1 -1
- {osbot_utils-2.3.0.dist-info → osbot_utils-2.5.0.dist-info}/METADATA +2 -2
- {osbot_utils-2.3.0.dist-info → osbot_utils-2.5.0.dist-info}/RECORD +15 -15
- /osbot_utils/type_safe/{Type_Safe__Validator.py → validators/Type_Safe__Validator.py} +0 -0
- {osbot_utils-2.3.0.dist-info → osbot_utils-2.5.0.dist-info}/LICENSE +0 -0
- {osbot_utils-2.3.0.dist-info → osbot_utils-2.5.0.dist-info}/WHEEL +0 -0
osbot_utils/helpers/Guid.py
CHANGED
@@ -88,7 +88,7 @@ class Type_Safe:
|
|
88
88
|
from osbot_utils.utils.Objects import convert_to_value_from_obj_annotation
|
89
89
|
from osbot_utils.utils.Objects import value_type_matches_obj_annotation_for_attr
|
90
90
|
from osbot_utils.utils.Objects import value_type_matches_obj_annotation_for_union_and_annotated
|
91
|
-
from osbot_utils.type_safe.Type_Safe__Validator import Type_Safe__Validator
|
91
|
+
from osbot_utils.type_safe.validators.Type_Safe__Validator import Type_Safe__Validator
|
92
92
|
|
93
93
|
annotations = all_annotations(self)
|
94
94
|
if not annotations: # can't do type safety checks if the class does not have annotations
|
@@ -142,7 +142,7 @@ class Type_Safe:
|
|
142
142
|
from enum import EnumMeta
|
143
143
|
from osbot_utils.utils.Objects import obj_is_type_union_compatible
|
144
144
|
|
145
|
-
IMMUTABLE_TYPES = (bool, int, float, complex, str, tuple, frozenset, bytes, NoneType, EnumMeta)
|
145
|
+
IMMUTABLE_TYPES = (bool, int, float, complex, str, tuple, frozenset, bytes, NoneType, EnumMeta, type)
|
146
146
|
|
147
147
|
|
148
148
|
kwargs = {}
|
@@ -172,7 +172,15 @@ class Type_Safe:
|
|
172
172
|
if var_value is not None: # allow None assignments on ctor since that is a valid use case
|
173
173
|
if get_origin(var_type) is Annotated:
|
174
174
|
continue
|
175
|
-
if var_type
|
175
|
+
if get_origin(var_type) is type: # Special handling for Type[T]
|
176
|
+
if not isinstance(var_value, type):
|
177
|
+
exception_message = f"variable '{var_name}' is defined as Type[T] but has value '{var_value}' which is not a type"
|
178
|
+
raise ValueError(exception_message)
|
179
|
+
type_arg = get_args(var_type)[0]
|
180
|
+
if not issubclass(var_value, type_arg):
|
181
|
+
exception_message = f"variable '{var_name}' is defined as {var_type} but value {var_value} is not a subclass of {type_arg}"
|
182
|
+
raise ValueError(exception_message)
|
183
|
+
elif var_type and not isinstance(var_value, var_type): # check type
|
176
184
|
exception_message = f"variable '{var_name}' is defined as type '{var_type}' but has value '{var_value}' of type '{type(var_value)}'"
|
177
185
|
raise ValueError(exception_message)
|
178
186
|
if var_type not in IMMUTABLE_TYPES and var_name.startswith('__') is False: # if var_type is not one of the IMMUTABLE_TYPES or is an __ internal
|
@@ -3,7 +3,7 @@ from enum import Enum
|
|
3
3
|
from typing import get_args, get_origin, Union, List, Any # For type hinting utilities
|
4
4
|
|
5
5
|
|
6
|
-
class
|
6
|
+
class Type_Safe__Method: # Class to handle method type safety validation
|
7
7
|
def __init__(self, func): # Initialize with function
|
8
8
|
self.func = func # Store original function
|
9
9
|
self.sig = inspect.signature(func) # Get function signature
|
@@ -1,10 +1,10 @@
|
|
1
1
|
import functools # For wrapping functions
|
2
|
-
from osbot_utils.type_safe.
|
2
|
+
from osbot_utils.type_safe.Type_Safe__Method import Type_Safe__Method
|
3
3
|
|
4
4
|
def type_safe(func): # Main decorator function
|
5
5
|
@functools.wraps(func) # Preserve function metadata
|
6
6
|
def wrapper(*args, **kwargs): # Wrapper function
|
7
|
-
type_checker =
|
7
|
+
type_checker = Type_Safe__Method(func) # Create type checker instance
|
8
8
|
bound_args = type_checker.handle_type_safety(args, kwargs) # Validate type safety
|
9
9
|
return func(**bound_args.arguments) # Call original function
|
10
10
|
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from typing import Any
|
2
|
-
from osbot_utils.type_safe.Type_Safe__Validator import Type_Safe__Validator
|
2
|
+
from osbot_utils.type_safe.validators.Type_Safe__Validator import Type_Safe__Validator
|
3
3
|
|
4
4
|
|
5
5
|
class Validator__Max(Type_Safe__Validator): # Validates that a numeric value is at most the specified maximum."""
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from typing import Any
|
2
|
-
from osbot_utils.type_safe.Type_Safe__Validator import Type_Safe__Validator
|
2
|
+
from osbot_utils.type_safe.validators.Type_Safe__Validator import Type_Safe__Validator
|
3
3
|
|
4
4
|
class Validator__Min(Type_Safe__Validator): # Validates that a value is at least the specified minimum. Works with any type that supports the < operator (numbers, strings, lists, etc.)
|
5
5
|
min_value: Any
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from typing import Any
|
2
|
-
from osbot_utils.type_safe.Type_Safe__Validator import Type_Safe__Validator
|
2
|
+
from osbot_utils.type_safe.validators.Type_Safe__Validator import Type_Safe__Validator
|
3
3
|
|
4
4
|
|
5
5
|
class Validator__One_Of(Type_Safe__Validator): # Validates that a value is one of a set of allowed values."""
|
@@ -1,5 +1,5 @@
|
|
1
1
|
from typing import Any
|
2
|
-
from osbot_utils.type_safe.Type_Safe__Validator import Type_Safe__Validator
|
2
|
+
from osbot_utils.type_safe.validators.Type_Safe__Validator import Type_Safe__Validator
|
3
3
|
|
4
4
|
class Validator__Regex(Type_Safe__Validator): # Validates that a string matches the specified regex pattern.
|
5
5
|
pattern : str
|
osbot_utils/utils/Objects.py
CHANGED
@@ -25,7 +25,7 @@ if sys.version_info < (3, 8):
|
|
25
25
|
else:
|
26
26
|
return ()
|
27
27
|
else:
|
28
|
-
from typing import get_origin, get_args, List, Tuple, Dict
|
28
|
+
from typing import get_origin, get_args, List, Tuple, Dict, Type, _GenericAlias, ForwardRef
|
29
29
|
|
30
30
|
|
31
31
|
def are_types_compatible_for_assigment(source_type, target_type):
|
@@ -128,6 +128,16 @@ def convert_to_value_from_obj_annotation(target, attr_name, value):
|
|
128
128
|
if hasattr(obj_annotations,'get'):
|
129
129
|
attribute_annotation = obj_annotations.get(attr_name)
|
130
130
|
if attribute_annotation:
|
131
|
+
origin = get_origin(attribute_annotation) # Add handling for Type[T] annotations
|
132
|
+
if origin is type and isinstance(value, str):
|
133
|
+
try: # Convert string path to actual type
|
134
|
+
if len(value.rsplit('.', 1)) > 1:
|
135
|
+
module_name, class_name = value.rsplit('.', 1)
|
136
|
+
module = __import__(module_name, fromlist=[class_name])
|
137
|
+
return getattr(module, class_name)
|
138
|
+
except (ValueError, ImportError, AttributeError) as e:
|
139
|
+
raise ValueError(f"Could not convert '{value}' to type: {str(e)}")
|
140
|
+
|
131
141
|
if attribute_annotation in TYPE_SAFE__CONVERT_VALUE__SUPPORTED_TYPES: # for now hard-coding this to just these types until we understand the side effects
|
132
142
|
return attribute_annotation(value)
|
133
143
|
return value
|
@@ -373,6 +383,8 @@ def obj_is_type_union_compatible(var_type, compatible_types):
|
|
373
383
|
from typing import Union
|
374
384
|
|
375
385
|
origin = get_origin(var_type)
|
386
|
+
if isinstance(var_type, _GenericAlias) and origin is type: # Add handling for Type[T]
|
387
|
+
return type in compatible_types # Allow if 'type' is in compatible types
|
376
388
|
if origin is Union: # For Union types, including Optionals
|
377
389
|
args = get_args(var_type) # Get the argument types
|
378
390
|
for arg in args: # Iterate through each argument in the Union
|
@@ -454,8 +466,13 @@ def value_type_matches_obj_annotation_for_attr(target, attr_name, value):
|
|
454
466
|
annotations = all_annotations(target)
|
455
467
|
attr_type = annotations.get(attr_name)
|
456
468
|
if attr_type:
|
457
|
-
origin_attr_type = get_origin(attr_type)
|
458
|
-
if origin_attr_type is
|
469
|
+
origin_attr_type = get_origin(attr_type) # to handle when type definition contains a generic
|
470
|
+
if origin_attr_type is type: # Add handling for Type[T]
|
471
|
+
type_arg = get_args(attr_type)[0] # Get T from Type[T]
|
472
|
+
if isinstance(type_arg, (str, ForwardRef)): # Handle forward reference
|
473
|
+
type_arg = target.__class__ # If it's a forward reference, the target class should be the containing class
|
474
|
+
return isinstance(value, type) and issubclass(value, type_arg) # Check that value is a type and is subclass of type_arg
|
475
|
+
if origin_attr_type is Annotated: # if the type is Annotated
|
459
476
|
args = get_args(attr_type)
|
460
477
|
origin_attr_type = args[0]
|
461
478
|
|
osbot_utils/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
v2.
|
1
|
+
v2.5.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: osbot_utils
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.5.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
|
|
@@ -36,7 +36,7 @@ osbot_utils/helpers/CFormat.py,sha256=QviXlx3cQF7Wq6bNQmvWPHknDDMQXg5bh5dsRncrg-
|
|
36
36
|
osbot_utils/helpers/CPrint.py,sha256=ztKPNmT8BGxeyPXSQKRs63PqqbgxKDz_BiZmzFMup9g,1413
|
37
37
|
osbot_utils/helpers/Dependency_Manager.py,sha256=79YRYnVfchewq8iSMJ5dzwW2D5u8chWcIqYE-G9YrSo,1337
|
38
38
|
osbot_utils/helpers/Dict_To_Attr.py,sha256=NdhXl5mJH7-NaBk213amzc5Nfy3tJgW-N_uYIRE4hoc,208
|
39
|
-
osbot_utils/helpers/Guid.py,sha256=
|
39
|
+
osbot_utils/helpers/Guid.py,sha256=0Ay3TYYk2nPr-JRVRCMFxbr8OvoQomv5HjT7o5B7cos,827
|
40
40
|
osbot_utils/helpers/Hashicorp_Secrets.py,sha256=e2fWWHK6bubpAm1sw5y8X5kh2Hk5d4JyZCnUovZip5A,4232
|
41
41
|
osbot_utils/helpers/Local_Cache.py,sha256=0JZZX3fFImcwtbBvxAQl-EbBegSNJRhRMYF6ovTH6zY,3141
|
42
42
|
osbot_utils/helpers/Local_Caches.py,sha256=aQmi1HSM0TH6WQPedG2fbz4KCCJ3DQTU9d18rB1jR0M,1885
|
@@ -277,19 +277,19 @@ osbot_utils/testing/Temp_Zip_In_Memory.py,sha256=ibDIWt3K4CX558PbkLbX3InHyWYZcwQ
|
|
277
277
|
osbot_utils/testing/Unit_Test.py,sha256=MReR_wDGbbXFDPz7cmuGflcTxRB6TBnO9mYqRpSq8Pk,1304
|
278
278
|
osbot_utils/testing/Unzip_File.py,sha256=V5H97XO9rlvG5EYOSzAH4kTtAH1ohZ8R8ImvJh46ZNg,1177
|
279
279
|
osbot_utils/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
280
|
-
osbot_utils/type_safe/Type_Safe.py,sha256=
|
281
|
-
osbot_utils/type_safe/Type_Safe_Method.py,sha256=JLB7NkeuY4x_lIWJyvG1bDApCM_VyAQqrzQXhH7Z-8A,10969
|
280
|
+
osbot_utils/type_safe/Type_Safe.py,sha256=icn7r8mS1hkeo30uJ3NVJ7kms8P6MeHbA0ldz_MMXps,30430
|
282
281
|
osbot_utils/type_safe/Type_Safe__Base.py,sha256=mL8GMaR9tsaUfwk8d-8zp2g-A8kNKiN6kroEFaNvMOk,5518
|
283
282
|
osbot_utils/type_safe/Type_Safe__Dict.py,sha256=I_Ac0JH-ahmQrkADFVyiobTlH1JI31MKHaNszQW4PBo,2396
|
284
283
|
osbot_utils/type_safe/Type_Safe__List.py,sha256=SzSIBkwSOAEpW_V2qh4-f0YHzmgB0T8PczBLbDgZGvg,1340
|
285
|
-
osbot_utils/type_safe/
|
284
|
+
osbot_utils/type_safe/Type_Safe__Method.py,sha256=wn05pjmdnjhXVFIUaxm6YfWJZGoTzs-IhJ534JKFiV0,10970
|
286
285
|
osbot_utils/type_safe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
287
286
|
osbot_utils/type_safe/decorators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
288
|
-
osbot_utils/type_safe/decorators/type_safe.py,sha256=
|
289
|
-
osbot_utils/type_safe/validators/
|
290
|
-
osbot_utils/type_safe/validators/
|
291
|
-
osbot_utils/type_safe/validators/
|
292
|
-
osbot_utils/type_safe/validators/
|
287
|
+
osbot_utils/type_safe/decorators/type_safe.py,sha256=ERFfJuAIo5qLp03YEDu2zu5wxu65OhR7hOybwuTfLlc,1006
|
288
|
+
osbot_utils/type_safe/validators/Type_Safe__Validator.py,sha256=cJIPSBarjV716SZUOLvz7Mthjk-aUYKUQtRDtKUBmN4,779
|
289
|
+
osbot_utils/type_safe/validators/Validator__Max.py,sha256=pCvYF5Jb_cBgn1ArGhf6FNUB-NGCXPq3D36oYDCyAzg,1275
|
290
|
+
osbot_utils/type_safe/validators/Validator__Min.py,sha256=_-9MdAX2Jc2U0VzCHpEQLA8OVxuNe2y8uaJ6bQttimE,1981
|
291
|
+
osbot_utils/type_safe/validators/Validator__One_Of.py,sha256=YVdZv3Fw4vpJGXRSXFmTktFgzcLlUK7bkVSBV6Fxl-4,681
|
292
|
+
osbot_utils/type_safe/validators/Validator__Regex.py,sha256=oO_NKTcrcl7wjs5-HB-ovSV9S-3XOZjsa04rdUPsOMg,1008
|
293
293
|
osbot_utils/type_safe/validators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
294
294
|
osbot_utils/utils/Assert.py,sha256=u9XLgYn91QvNWZGyPi29SjPJSXRHlm9andIn3NJEVog,1745
|
295
295
|
osbot_utils/utils/Call_Stack.py,sha256=awhWstC2mJCrOjNqNheTe2B7at-JFP6XG7VkMPpPNOE,6647
|
@@ -305,7 +305,7 @@ osbot_utils/utils/Json.py,sha256=0t7Hwefx8bg4JiZVr-xIbWP3BAk6_ZsnY7iV5pnRLDQ,713
|
|
305
305
|
osbot_utils/utils/Json_Cache.py,sha256=mLPkkDZN-3ZVJiDvV1KBJXILtKkTZ4OepzOsDoBPhWg,2006
|
306
306
|
osbot_utils/utils/Lists.py,sha256=tPz5x5s3sRO97WZ_nsxREBPC5cwaHrhgaYBhsrffTT8,5599
|
307
307
|
osbot_utils/utils/Misc.py,sha256=H_xexJgiTxB3jDeDiW8efGQbO0Zuy8MM0iQ7qXC92JI,17363
|
308
|
-
osbot_utils/utils/Objects.py,sha256=
|
308
|
+
osbot_utils/utils/Objects.py,sha256=KN04fgKTlPtKr1d84ESDNlYMQikunyWJ3-I2VKZ8jjw,23661
|
309
309
|
osbot_utils/utils/Png.py,sha256=V1juGp6wkpPigMJ8HcxrPDIP4bSwu51oNkLI8YqP76Y,1172
|
310
310
|
osbot_utils/utils/Process.py,sha256=lr3CTiEkN3EiBx3ZmzYmTKlQoPdkgZBRjPulMxG-zdo,2357
|
311
311
|
osbot_utils/utils/Python_Logger.py,sha256=M9Oi62LxfnRSlCN8GhaiwiBINvcSdGy39FCWjyDD-Xg,12792
|
@@ -317,8 +317,8 @@ osbot_utils/utils/Toml.py,sha256=Rxl8gx7mni5CvBAK-Ai02EKw-GwtJdd3yeHT2kMloik,166
|
|
317
317
|
osbot_utils/utils/Version.py,sha256=Ww6ChwTxqp1QAcxOnztkTicShlcx6fbNsWX5xausHrg,422
|
318
318
|
osbot_utils/utils/Zip.py,sha256=pR6sKliUY0KZXmqNzKY2frfW-YVQEVbLKiyqQX_lc-8,14052
|
319
319
|
osbot_utils/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
320
|
-
osbot_utils/version,sha256=
|
321
|
-
osbot_utils-2.
|
322
|
-
osbot_utils-2.
|
323
|
-
osbot_utils-2.
|
324
|
-
osbot_utils-2.
|
320
|
+
osbot_utils/version,sha256=ry5x0al4PtQq-0dv-mNU4Gk_sTAHYopdKOQmdWyn-ZE,7
|
321
|
+
osbot_utils-2.5.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
322
|
+
osbot_utils-2.5.0.dist-info/METADATA,sha256=Ow8znW_Olql05eKUGfwxkJDw5XMf0o_wwXjdS7J2In0,1315
|
323
|
+
osbot_utils-2.5.0.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
|
324
|
+
osbot_utils-2.5.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|