osbot-utils 2.80.0__py3-none-any.whl → 2.81.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__Base.py +8 -1
- osbot_utils/type_safe/type_safe_core/methods/Type_Safe__Method.py +31 -32
- osbot_utils/type_safe/type_safe_core/shared/Type_Safe__Validation.py +40 -12
- osbot_utils/type_safe/type_safe_core/steps/Type_Safe__Step__Set_Attr.py +35 -7
- osbot_utils/version +1 -1
- {osbot_utils-2.80.0.dist-info → osbot_utils-2.81.0.dist-info}/METADATA +2 -2
- {osbot_utils-2.80.0.dist-info → osbot_utils-2.81.0.dist-info}/RECORD +9 -9
- {osbot_utils-2.80.0.dist-info → osbot_utils-2.81.0.dist-info}/LICENSE +0 -0
- {osbot_utils-2.80.0.dist-info → osbot_utils-2.81.0.dist-info}/WHEEL +0 -0
@@ -1,5 +1,5 @@
|
|
1
1
|
import types
|
2
|
-
from typing import get_args, Union, Optional, Any, ForwardRef
|
2
|
+
from typing import get_args, Union, Optional, Any, ForwardRef, Literal
|
3
3
|
from osbot_utils.helpers.Obj_Id import Obj_Id
|
4
4
|
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Cache import type_safe_cache
|
5
5
|
|
@@ -13,6 +13,13 @@ class Type_Safe__Base:
|
|
13
13
|
return True
|
14
14
|
origin = type_safe_cache.get_origin(expected_type)
|
15
15
|
args = get_args(expected_type)
|
16
|
+
|
17
|
+
if origin is Literal: # Add Literal support
|
18
|
+
if item not in args:
|
19
|
+
allowed_values = ', '.join(repr(v) for v in args)
|
20
|
+
raise ValueError(f"Literal value must be one of {allowed_values}, got {repr(item)}")
|
21
|
+
return True
|
22
|
+
|
16
23
|
if origin is None:
|
17
24
|
if expected_type in EXACT_TYPE_MATCH:
|
18
25
|
if type(item) is expected_type:
|
@@ -101,45 +101,44 @@ class Type_Safe__Method:
|
|
101
101
|
def is_list_type(self, origin_type: Any) -> bool: # Check if type is a List
|
102
102
|
return origin_type is list or origin_type is List # Check against list types
|
103
103
|
|
104
|
-
def validate_list_type(self, param_name: str,
|
105
|
-
param_value: Any, expected_type: Any):
|
106
|
-
if not isinstance(param_value, list):
|
107
|
-
raise ValueError(f"Parameter '{param_name}' expected a list but got {type(param_value)}")
|
108
|
-
|
109
|
-
item_type = get_args(expected_type)[0]
|
110
|
-
item_origin = get_origin(item_type)
|
111
|
-
|
112
|
-
if item_origin is dict or item_origin is Dict:
|
113
|
-
key_type, value_type = get_args(item_type)
|
114
|
-
for i, item in enumerate(param_value):
|
115
|
-
if not isinstance(item, dict):
|
116
|
-
raise ValueError(f"List item at index {i} expected dict but got {type(item)}")
|
117
|
-
if key_type is Any and value_type is Any:
|
118
|
-
continue
|
119
|
-
for k, v in item.items():
|
120
|
-
if key_type is not Any and not isinstance(k, key_type):
|
121
|
-
raise ValueError(f"Dict key '{k}' at index {i} expected type {key_type}, but got {type(k)}")
|
122
|
-
if value_type is not Any and not isinstance(v, value_type):
|
123
|
-
raise ValueError(f"Dict value for key '{k}' at index {i} expected type {value_type}, but got {type(v)}")
|
124
|
-
elif item_origin is collections.abc.Callable:
|
125
|
-
for i, item in enumerate(param_value):
|
126
|
-
if not callable(item):
|
127
|
-
raise ValueError(f"List item at index {i} expected callable but got {type(item)}")
|
104
|
+
def validate_list_type(self, param_name: str, # Validate list type and contents
|
105
|
+
param_value: Any, expected_type: Any): # List parameters
|
106
|
+
if not isinstance(param_value, list): # Check if value is a list
|
107
|
+
raise ValueError(f"Parameter '{param_name}' expected a list but got {type(param_value)}") # Raise error if not list
|
108
|
+
|
109
|
+
item_type = get_args(expected_type)[0] # Get list item type
|
110
|
+
item_origin = get_origin(item_type) # Get origin of item type
|
111
|
+
|
112
|
+
if item_origin is dict or item_origin is Dict: # Handle Dict[K, V] items
|
113
|
+
key_type, value_type = get_args(item_type) # Extract key and value types
|
114
|
+
for i, item in enumerate(param_value): # Validate each dict in list
|
115
|
+
if not isinstance(item, dict): # Check item is a dict
|
116
|
+
raise ValueError(f"List item at index {i} expected dict but got {type(item)}") # Raise error if not dict
|
117
|
+
if key_type is Any and value_type is Any: # Skip validation if both are Any
|
118
|
+
continue # No type checking needed
|
119
|
+
for k, v in item.items(): # Validate dict contents
|
120
|
+
if key_type is not Any and not isinstance(k, key_type): # Check key type if not Any
|
121
|
+
raise ValueError(f"Dict key '{k}' at index {i} expected type {key_type}, but got {type(k)}") # Raise error for invalid key
|
122
|
+
if value_type is not Any and not isinstance(v, value_type): # Check value type if not Any
|
123
|
+
raise ValueError(f"Dict value for key '{k}' at index {i} expected type {value_type}, but got {type(v)}") # Raise error for invalid value
|
124
|
+
elif item_origin is collections.abc.Callable: # Handle Callable[[...], ...] items
|
125
|
+
for i, item in enumerate(param_value): # Validate each callable in list
|
126
|
+
if not callable(item): # Check item is callable
|
127
|
+
raise ValueError(f"List item at index {i} expected callable but got {type(item)}") # Raise error if not callable
|
128
128
|
# Note: Full signature validation would require is_callable_compatible method
|
129
|
-
elif item_origin is not None:
|
129
|
+
elif item_origin is not None: # Handle other subscripted types
|
130
130
|
raise NotImplementedError(f"Validation for list items with subscripted type"
|
131
131
|
f" '{item_type}' is not yet supported "
|
132
|
-
f"in parameter '{param_name}'.")
|
133
|
-
else:
|
134
|
-
for i, item in enumerate(param_value):
|
135
|
-
if not isinstance(item, item_type):
|
136
|
-
raise ValueError(f"List item at index {i} expected type {item_type}, but got {type(item)}")
|
132
|
+
f"in parameter '{param_name}'.") # todo: add support for checking for subscripted types
|
133
|
+
else: # Handle non-subscripted types
|
134
|
+
for i, item in enumerate(param_value): # Check each list item
|
135
|
+
if not isinstance(item, item_type): # Validate item type
|
136
|
+
raise ValueError(f"List item at index {i} expected type {item_type}, but got {type(item)}") # Raise error for invalid item
|
137
137
|
|
138
|
-
def validate_type_parameter(self, param_name: str, param_value: Any, expected_type: Any):
|
138
|
+
def validate_type_parameter(self, param_name: str, param_value: Any, expected_type: Any): # Validate a Type[T] parameter
|
139
139
|
if not isinstance(param_value, type):
|
140
140
|
raise ValueError(f"Parameter '{param_name}' expected a type class but got {type(param_value)}")
|
141
141
|
|
142
|
-
|
143
142
|
type_args = get_args(expected_type) # Extract the T from Type[T]
|
144
143
|
if type_args:
|
145
144
|
required_base = type_args[0] # get direct type (this doesn't handle Forward refs)
|
@@ -3,7 +3,7 @@ import inspect
|
|
3
3
|
import types
|
4
4
|
import typing
|
5
5
|
from enum import EnumMeta
|
6
|
-
from typing import Any, Annotated, Optional, get_args, get_origin, ForwardRef, Type, Dict, _GenericAlias
|
6
|
+
from typing import Any, Annotated, Optional, get_args, get_origin, ForwardRef, Type, Dict, _GenericAlias # noqa (_GenericAlias does exist)
|
7
7
|
from osbot_utils.type_safe.Type_Safe__Primitive import Type_Safe__Primitive
|
8
8
|
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Annotations import type_safe_annotations
|
9
9
|
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Cache import type_safe_cache
|
@@ -50,12 +50,21 @@ class Type_Safe__Validation:
|
|
50
50
|
return True
|
51
51
|
if target_type is MagicMock:
|
52
52
|
return True
|
53
|
-
# if class_full_name(source_type) == 'unittest.mock.MagicMock':
|
54
|
-
# return True
|
55
|
-
# if class_full_name(target_type) == 'unittest.mock.MagicMock':
|
56
|
-
# return True
|
57
53
|
return False
|
58
54
|
|
55
|
+
def obj_is_type_literal_compatible(self, var_type) -> bool: # Check if a Literal type contains only immutable values
|
56
|
+
from typing import Literal
|
57
|
+
|
58
|
+
origin = get_origin(var_type)
|
59
|
+
if origin is not Literal:
|
60
|
+
return False
|
61
|
+
|
62
|
+
literal_values = get_args(var_type)
|
63
|
+
for value in literal_values:
|
64
|
+
if value is not None and type(value) not in (bool, int, float, complex, str, bytes):
|
65
|
+
return False
|
66
|
+
return True
|
67
|
+
|
59
68
|
def obj_is_type_union_compatible(self, var_type, compatible_types):
|
60
69
|
from typing import Union
|
61
70
|
|
@@ -92,7 +101,7 @@ class Type_Safe__Validation:
|
|
92
101
|
return None
|
93
102
|
|
94
103
|
def check_if__value_is__special_generic_alias(self, value):
|
95
|
-
from typing import _SpecialGenericAlias # todo see if there is a better way to do this since typing is showing as not having _SpecialGenericAlias (this is to handle case like List, Dict, etc...)
|
104
|
+
from typing import _SpecialGenericAlias # noqa todo see if there is a better way to do this since typing is showing as not having _SpecialGenericAlias (this is to handle case like List, Dict, etc...)
|
96
105
|
return value is not None and type(value) is not _SpecialGenericAlias
|
97
106
|
|
98
107
|
def check_if__type_matches__union_type(self, annotation : Any, # Union type annotation
|
@@ -163,6 +172,10 @@ class Type_Safe__Validation:
|
|
163
172
|
if attr_type:
|
164
173
|
origin_attr_type = get_origin(attr_type) # to handle when type definition contains a generic
|
165
174
|
|
175
|
+
if origin_attr_type is typing.Literal: # Add Literal support
|
176
|
+
literal_values = get_args(attr_type)
|
177
|
+
return value in literal_values
|
178
|
+
|
166
179
|
if origin_attr_type is collections.abc.Callable: # Handle Callable types
|
167
180
|
return self.is_callable_compatible(value, attr_type) # ISSUE: THIS IS NEVER CALLED
|
168
181
|
|
@@ -286,12 +299,27 @@ class Type_Safe__Validation:
|
|
286
299
|
|
287
300
|
# todo: see if need to add cache support to this method (it looks like this method is not called very often)
|
288
301
|
def validate_type_immutability(self, var_name: str, var_type: Any) -> None: # Validates that type is immutable or in supported format
|
289
|
-
if var_type
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
302
|
+
if var_type in IMMUTABLE_TYPES or var_name.startswith('__'): # if var_type is not one of the IMMUTABLE_TYPES or is an __ internal
|
303
|
+
return
|
304
|
+
if self.obj_is_type_literal_compatible(var_type):
|
305
|
+
return
|
306
|
+
if self.obj_is_type_union_compatible(var_type, IMMUTABLE_TYPES) : # if var_type is not something like Optional[Union[int, str]]
|
307
|
+
return
|
308
|
+
if var_type in IMMUTABLE_TYPES:
|
309
|
+
return
|
310
|
+
if isinstance(var_type, EnumMeta):
|
311
|
+
return
|
312
|
+
if isinstance(var_type, type) and issubclass(var_type, (int,str, float)):
|
313
|
+
return
|
314
|
+
type_safe_raise_exception.immutable_type_error(var_name, var_type)
|
315
|
+
|
316
|
+
# def validate_type_immutability(self, var_name: str, var_type: Any) -> None: # Validates that type is immutable or in supported format
|
317
|
+
# 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
|
318
|
+
# if self.obj_is_type_union_compatible(var_type, IMMUTABLE_TYPES) is False: # if var_type is not something like Optional[Union[int, str]]
|
319
|
+
# if var_type not in IMMUTABLE_TYPES or type(var_type) not in IMMUTABLE_TYPES:
|
320
|
+
# if not isinstance(var_type, EnumMeta):
|
321
|
+
# if not (isinstance(var_type, type) and issubclass(var_type, (int,str, float))):
|
322
|
+
# type_safe_raise_exception.immutable_type_error(var_name, var_type)
|
295
323
|
|
296
324
|
def validate_variable_type(self, var_name, var_type, var_value): # Validate type compatibility
|
297
325
|
if type(var_type) is type and not isinstance(var_value, var_type):
|
@@ -1,10 +1,10 @@
|
|
1
|
-
from typing
|
2
|
-
from osbot_utils.type_safe.Type_Safe__Primitive
|
3
|
-
from osbot_utils.type_safe.type_safe_core.collections.Type_Safe__List
|
4
|
-
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Cache
|
5
|
-
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Convert
|
6
|
-
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Validation
|
7
|
-
from osbot_utils.type_safe.validators.Type_Safe__Validator
|
1
|
+
from typing import get_origin, Annotated, get_args, Literal, Union
|
2
|
+
from osbot_utils.type_safe.Type_Safe__Primitive import Type_Safe__Primitive
|
3
|
+
from osbot_utils.type_safe.type_safe_core.collections.Type_Safe__List import Type_Safe__List
|
4
|
+
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Cache import type_safe_cache
|
5
|
+
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Convert import type_safe_convert
|
6
|
+
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Validation import type_safe_validation
|
7
|
+
from osbot_utils.type_safe.validators.Type_Safe__Validator import Type_Safe__Validator
|
8
8
|
|
9
9
|
class Type_Safe__Step__Set_Attr:
|
10
10
|
|
@@ -20,6 +20,8 @@ class Type_Safe__Step__Set_Attr:
|
|
20
20
|
else:
|
21
21
|
value = self.resolve_value__from_origin(value)
|
22
22
|
|
23
|
+
self.validate_literal_value(annotations, name, value) # Check Literal value constraints before generic type checking
|
24
|
+
|
23
25
|
type_safe_validation.validate_type_compatibility(_self, annotations, name, value)
|
24
26
|
return value
|
25
27
|
|
@@ -111,5 +113,31 @@ class Type_Safe__Step__Set_Attr:
|
|
111
113
|
|
112
114
|
_super.__setattr__(name, value)
|
113
115
|
|
116
|
+
def validate_literal_value(self, annotations, name, value): # Check if a value is valid for a Literal type annotation
|
117
|
+
|
118
|
+
annotation = annotations.get(name)
|
119
|
+
if not annotation:
|
120
|
+
return
|
121
|
+
|
122
|
+
origin = get_origin(annotation)
|
123
|
+
|
124
|
+
if origin is Union: # Handle Optional[Literal[...]] by unwrapping the Optional
|
125
|
+
args = get_args(annotation)
|
126
|
+
if type(None) in args: # Check if it's Optional (Union with None)
|
127
|
+
for arg in args: # Find the non-None type
|
128
|
+
if arg is not type(None) and get_origin(arg) is Literal:
|
129
|
+
allowed_values = get_args(arg) # Found Literal inside Optional
|
130
|
+
if value is not None and value not in allowed_values:
|
131
|
+
allowed_str = ', '.join(repr(v) for v in allowed_values)
|
132
|
+
raise ValueError(f"Invalid value for '{name}': must be one of [{allowed_str}], got {repr(value)}")
|
133
|
+
return
|
134
|
+
|
135
|
+
|
136
|
+
elif origin is Literal: # Handle direct Literal[...]
|
137
|
+
allowed_values = get_args(annotation)
|
138
|
+
if value not in allowed_values:
|
139
|
+
allowed_str = ', '.join(repr(v) for v in allowed_values)
|
140
|
+
raise ValueError(f"Invalid value for '{name}': must be one of [{allowed_str}], got {repr(value)}")
|
141
|
+
|
114
142
|
|
115
143
|
type_safe_step_set_attr = Type_Safe__Step__Set_Attr()
|
osbot_utils/version
CHANGED
@@ -1 +1 @@
|
|
1
|
-
v2.
|
1
|
+
v2.81.0
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: osbot_utils
|
3
|
-
Version: 2.
|
3
|
+
Version: 2.81.0
|
4
4
|
Summary: OWASP Security Bot - Utils
|
5
5
|
License: MIT
|
6
6
|
Author: Dinis Cruz
|
@@ -21,7 +21,7 @@ Description-Content-Type: text/markdown
|
|
21
21
|
|
22
22
|
# OSBot-Utils
|
23
23
|
|
24
|
-

|
25
25
|

|
26
26
|

|
27
27
|

|
@@ -349,7 +349,7 @@ osbot_utils/testing/performance/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
|
|
349
349
|
osbot_utils/testing/test_data/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
350
350
|
osbot_utils/testing/test_data/const__test__data__html.py,sha256=_DmA7OoCwvl1xxxn2aS8mfvf3Ct4bOt1KTUyTDqtwaQ,1718
|
351
351
|
osbot_utils/type_safe/Type_Safe.py,sha256=G0HCBk52ehaJGhLYnt4cKUBsqfnxyRDxrY7_7YhktZg,6390
|
352
|
-
osbot_utils/type_safe/Type_Safe__Base.py,sha256=
|
352
|
+
osbot_utils/type_safe/Type_Safe__Base.py,sha256=cui8fIzUGaPsb-fnANj8nw9cYrVikdx1XZ8in3Y_-QU,9174
|
353
353
|
osbot_utils/type_safe/Type_Safe__Primitive.py,sha256=-GBUcuFBBBKrVRSf7cmjPRbAxo7vnL4tOvr9ktmbVj4,3829
|
354
354
|
osbot_utils/type_safe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
355
355
|
osbot_utils/type_safe/primitives/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -417,7 +417,7 @@ osbot_utils/type_safe/type_safe_core/collections/Type_Safe__Tuple.py,sha256=Kx7C
|
|
417
417
|
osbot_utils/type_safe/type_safe_core/collections/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
418
418
|
osbot_utils/type_safe/type_safe_core/decorators/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
419
419
|
osbot_utils/type_safe/type_safe_core/decorators/type_safe.py,sha256=wOTMvZBl5hWMz-HuIRZpPBGN0oSbXWd9wH5xxZkfLlA,1796
|
420
|
-
osbot_utils/type_safe/type_safe_core/methods/Type_Safe__Method.py,sha256=
|
420
|
+
osbot_utils/type_safe/type_safe_core/methods/Type_Safe__Method.py,sha256=U2YW4qT7T_w14ohLekRYGYXti1ygm9JfUhayeoG6g10,20192
|
421
421
|
osbot_utils/type_safe/type_safe_core/methods/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
422
422
|
osbot_utils/type_safe/type_safe_core/methods/type_safe_property.py,sha256=DcJkOIs6swJtkglsZVKLyFSczCGSJISOVwAmvjCOQvo,1425
|
423
423
|
osbot_utils/type_safe/type_safe_core/shared/Type_Safe__Annotations.py,sha256=kabSiRPYPjpMBJxfjDB5AFRTx-hX17tOznZAd_qQID4,1147
|
@@ -428,14 +428,14 @@ osbot_utils/type_safe/type_safe_core/shared/Type_Safe__Json_Compressor__Type_Reg
|
|
428
428
|
osbot_utils/type_safe/type_safe_core/shared/Type_Safe__Not_Cached.py,sha256=25FAl6SOLxdStco_rm9tgOYLfuKyBWheGdl7vVa56UU,800
|
429
429
|
osbot_utils/type_safe/type_safe_core/shared/Type_Safe__Raise_Exception.py,sha256=lEwW5bhOKnOB8KfuMkheLQy1Xb7iDtTOXIvActRDtD0,911
|
430
430
|
osbot_utils/type_safe/type_safe_core/shared/Type_Safe__Shared__Variables.py,sha256=SuZGl9LryQX6IpOE0I_lbzClT-h17UNylC__-M8ltTY,129
|
431
|
-
osbot_utils/type_safe/type_safe_core/shared/Type_Safe__Validation.py,sha256=
|
431
|
+
osbot_utils/type_safe/type_safe_core/shared/Type_Safe__Validation.py,sha256=cVfGNeZ7eriAghCpPTtS2bXqZT9GHLY9DK1uWMTSUdE,21124
|
432
432
|
osbot_utils/type_safe/type_safe_core/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
433
433
|
osbot_utils/type_safe/type_safe_core/steps/Type_Safe__Step__Class_Kwargs.py,sha256=BbMPfCv5-RUZzh-TbyLBvykXZkdkR91jCGJoZ4R697g,8237
|
434
434
|
osbot_utils/type_safe/type_safe_core/steps/Type_Safe__Step__Default_Kwargs.py,sha256=tzKXDUc0HVP5QvCWsmcPuuZodNvQZ9FeMDNI2x00Ngw,1943
|
435
435
|
osbot_utils/type_safe/type_safe_core/steps/Type_Safe__Step__Default_Value.py,sha256=mRu0yV3w7Ch1H8SOfXMRqMBp3ooY95yR_oni7JafJBc,4603
|
436
436
|
osbot_utils/type_safe/type_safe_core/steps/Type_Safe__Step__From_Json.py,sha256=GTZnGC7DvEBA_LxgLw_KZZ1iVUV0EwyIgcZzoh14Bro,15453
|
437
437
|
osbot_utils/type_safe/type_safe_core/steps/Type_Safe__Step__Init.py,sha256=lZpQCCTNt6JcqyWwDoj-9Zgrq10vHXIUBh9lx37vRkE,4990
|
438
|
-
osbot_utils/type_safe/type_safe_core/steps/Type_Safe__Step__Set_Attr.py,sha256=
|
438
|
+
osbot_utils/type_safe/type_safe_core/steps/Type_Safe__Step__Set_Attr.py,sha256=uIWa5j7NfYcPDt-QGXErxI29HfM26mXAB-ScHC6ruCU,8507
|
439
439
|
osbot_utils/type_safe/type_safe_core/steps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
440
440
|
osbot_utils/type_safe/validators/Type_Safe__Validator.py,sha256=cJIPSBarjV716SZUOLvz7Mthjk-aUYKUQtRDtKUBmN4,779
|
441
441
|
osbot_utils/type_safe/validators/Validator__Max.py,sha256=pCvYF5Jb_cBgn1ArGhf6FNUB-NGCXPq3D36oYDCyAzg,1275
|
@@ -469,8 +469,8 @@ osbot_utils/utils/Toml.py,sha256=grjWkVPIMVkawJ499FVIJKxQp8FJ2wcsd0Z3YIR4drM,114
|
|
469
469
|
osbot_utils/utils/Version.py,sha256=Ww6ChwTxqp1QAcxOnztkTicShlcx6fbNsWX5xausHrg,422
|
470
470
|
osbot_utils/utils/Zip.py,sha256=mG42lgTY0tnm14T3P1-DSAIZKkTiYoO3odZ1aOUdc1I,14394
|
471
471
|
osbot_utils/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
472
|
-
osbot_utils/version,sha256=
|
473
|
-
osbot_utils-2.
|
474
|
-
osbot_utils-2.
|
475
|
-
osbot_utils-2.
|
476
|
-
osbot_utils-2.
|
472
|
+
osbot_utils/version,sha256=mbIGfCYdUBYBX5IKj_GwRFeqsLHQ9YVfPa2A46aaruM,8
|
473
|
+
osbot_utils-2.81.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
474
|
+
osbot_utils-2.81.0.dist-info/METADATA,sha256=SxdVFb1ciwxBQdtsaYUtzLmGKHJAsJR7rSD9cRA4neM,7918
|
475
|
+
osbot_utils-2.81.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
|
476
|
+
osbot_utils-2.81.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|