osbot-utils 2.4.0__py3-none-any.whl → 2.6.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/type_safe/Type_Safe.py +1 -1
- osbot_utils/type_safe/{Type_Safe_Method.py → Type_Safe__Method.py} +40 -11
- 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 +3 -1
- osbot_utils/version +1 -1
- {osbot_utils-2.4.0.dist-info → osbot_utils-2.6.0.dist-info}/METADATA +2 -2
- {osbot_utils-2.4.0.dist-info → osbot_utils-2.6.0.dist-info}/RECORD +14 -14
- /osbot_utils/type_safe/{Type_Safe__Validator.py → validators/Type_Safe__Validator.py} +0 -0
- {osbot_utils-2.4.0.dist-info → osbot_utils-2.6.0.dist-info}/LICENSE +0 -0
- {osbot_utils-2.4.0.dist-info → osbot_utils-2.6.0.dist-info}/WHEEL +0 -0
@@ -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
|
@@ -1,9 +1,9 @@
|
|
1
1
|
import inspect # For function introspection
|
2
|
-
from enum
|
3
|
-
from typing
|
2
|
+
from enum import Enum
|
3
|
+
from typing import get_args, get_origin, Union, List, Any, Dict # 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
|
@@ -88,8 +88,10 @@ class Type_Safe_Method:
|
|
88
88
|
def is_union_type(self, origin_type: Any, is_optional: bool) -> bool: # Check if type is a Union
|
89
89
|
return origin_type is Union and not is_optional # Must be Union but not Optional
|
90
90
|
|
91
|
-
def validate_union_type(self, param_name: str,
|
92
|
-
|
91
|
+
def validate_union_type(self, param_name : str,
|
92
|
+
param_value : Any,
|
93
|
+
expected_type: Any): # validate Union type parameters
|
94
|
+
|
93
95
|
args_types = get_args(expected_type) # Get allowed types
|
94
96
|
if not any(isinstance(param_value, arg_type) for arg_type in args_types): # Check if value matches any type
|
95
97
|
raise ValueError(f"Parameter '{param_name}' expected one of types {args_types}, but got {type(param_value)}") # Raise error if no match
|
@@ -110,10 +112,37 @@ class Type_Safe_Method:
|
|
110
112
|
except Exception: # Handle conversion failure
|
111
113
|
pass # Continue without conversion
|
112
114
|
return False # Return failure
|
113
|
-
|
115
|
+
# Return failure
|
116
|
+
|
117
|
+
def validate_direct_type(self, param_name: str, param_value: Any, expected_type: Any):
|
118
|
+
if expected_type is Any: # Handle typing.Any which accepts everything
|
119
|
+
return True
|
120
|
+
|
121
|
+
if param_value is None: # Handle None value case
|
122
|
+
is_optional = self.is_optional_type(expected_type) # Check if type is optional
|
123
|
+
has_default = self.has_default_value(param_name) # Check if has default value
|
124
|
+
self.validate_none_value(param_name, is_optional, has_default) # Validate None value
|
114
125
|
|
115
|
-
|
116
|
-
|
117
|
-
if
|
118
|
-
|
119
|
-
|
126
|
+
origin = get_origin(expected_type)
|
127
|
+
|
128
|
+
if origin is Union: # If it's a Union type
|
129
|
+
return True # there is another check that confirms it: todo: confirm this
|
130
|
+
|
131
|
+
if origin is not None: # If it's a generic type (like Dict, List, etc)
|
132
|
+
if origin in (dict, Dict): # Special handling for Dict
|
133
|
+
if not isinstance(param_value, dict):
|
134
|
+
raise ValueError(f"Parameter '{param_name}' expected dict but got {type(param_value)}")
|
135
|
+
key_type, value_type = get_args(expected_type)
|
136
|
+
for k, v in param_value.items():
|
137
|
+
if not isinstance(k, key_type):
|
138
|
+
raise ValueError(f"Dict key '{k}' expected type {key_type}, but got {type(k)}")
|
139
|
+
if not isinstance(v, value_type):
|
140
|
+
raise ValueError(f"Dict value for key '{k}' expected type {value_type}, but got {type(v)}")
|
141
|
+
return True
|
142
|
+
base_type = origin
|
143
|
+
else:
|
144
|
+
base_type = expected_type
|
145
|
+
|
146
|
+
if not isinstance(param_value, base_type):
|
147
|
+
raise ValueError(f"Parameter '{param_name}' expected type {expected_type}, but got {type(param_value)}")
|
148
|
+
return True
|
@@ -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, Type, _GenericAlias
|
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):
|
@@ -469,6 +469,8 @@ def value_type_matches_obj_annotation_for_attr(target, attr_name, value):
|
|
469
469
|
origin_attr_type = get_origin(attr_type) # to handle when type definition contains a generic
|
470
470
|
if origin_attr_type is type: # Add handling for Type[T]
|
471
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
|
472
474
|
return isinstance(value, type) and issubclass(value, type_arg) # Check that value is a type and is subclass of type_arg
|
473
475
|
if origin_attr_type is Annotated: # if the type is Annotated
|
474
476
|
args = get_args(attr_type)
|
osbot_utils/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
v2.
|
1
|
+
v2.6.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: osbot_utils
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.6.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
|
|
@@ -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=LOG2sqQyKBNNEiJxk_jngH6IWvpyVueouAzNTlj-_pY,12676
|
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=dngZhSwLPfXtj92IQJKmOr3AcG9xlHjFvq5HyQEcl_s,7
|
321
|
+
osbot_utils-2.6.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
322
|
+
osbot_utils-2.6.0.dist-info/METADATA,sha256=I0JH-4t4kPo3RIKeAMFjQp616AUaaXsWBjGkzq0oc5c,1315
|
323
|
+
osbot_utils-2.6.0.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
|
324
|
+
osbot_utils-2.6.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|