osbot-utils 2.80.0__py3-none-any.whl → 2.82.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.
@@ -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:
@@ -2,6 +2,7 @@ import collections
2
2
  import inspect # For function introspection
3
3
  from enum import Enum
4
4
  from typing import get_args, get_origin, Union, List, Any, Dict # For type hinting utilities
5
+ from osbot_utils.type_safe.Type_Safe__Primitive import Type_Safe__Primitive
5
6
  from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Shared__Variables import IMMUTABLE_TYPES
6
7
 
7
8
 
@@ -18,24 +19,53 @@ class Type_Safe__Method:
18
19
  raise ValueError(f"Parameter '{param_name}' uses lowercase 'any' instead of 'Any' from typing module. "
19
20
  f"Please use 'from typing import Any' and annotate as '{param_name}: Any'")
20
21
 
21
- def handle_type_safety(self, args: tuple, kwargs: dict): # Main method to handle type safety
22
+ def convert_primitive_parameters(self, bound_args): # Convert parameters to Type_Safe__Primitive types where applicable
23
+
24
+ for param_name, param_value in bound_args.arguments.items():
25
+ if param_name == 'self' or param_name not in self.annotations:
26
+ continue
27
+
28
+ expected_type = self.annotations[param_name]
29
+
30
+ if not (isinstance(expected_type, type) and issubclass(expected_type, Type_Safe__Primitive)): # Check if expected type is a Type_Safe__Primitive subclass
31
+ continue
32
+
33
+ primitive_base = expected_type.__primitive_base__ # Try direct conversion for common cases
34
+
35
+ if primitive_base in (int, float) and isinstance(param_value, str): # Handle string to int/float conversion
36
+ try:
37
+ bound_args.arguments[param_name] = expected_type(param_value)
38
+ continue
39
+ except (ValueError, TypeError):
40
+ pass # Let normal validation handle the error
41
+
42
+ if primitive_base and isinstance(param_value, primitive_base): # Handle values that match the primitive base type
43
+ try:
44
+ bound_args.arguments[param_name] = expected_type(param_value)
45
+ except (ValueError, TypeError):
46
+ pass # Let normal validation handle the error
47
+
48
+ def handle_type_safety(self, args: tuple, kwargs: dict): # Main method to handle type safety
22
49
  self.check_for_any_use()
23
- bound_args = self.bind_args(args, kwargs) # Bind arguments to parameters
24
- for param_name, param_value in bound_args.arguments.items(): # Iterate through arguments
25
- if param_name != 'self': # Skip self parameter
26
- self.validate_parameter(param_name, param_value, bound_args) # Validate each parameter
27
- return bound_args # Return bound arguments
28
-
29
- def bind_args(self, args: tuple, kwargs: dict): # Bind args to parameters
30
- bound_args = self.sig.bind(*args, **kwargs) # Bind arguments to signature
31
- bound_args.apply_defaults() # Apply default values
32
- return bound_args # Return bound arguments
33
-
34
- def validate_parameter(self, param_name: str, param_value: Any, bound_args): # Validate a single parameter
35
- self.validate_immutable_parameter(param_name, param_value) # Validata the param_value (make sure if it set it is on of IMMUTABLE_TYPES)
36
- if param_name in self.annotations: # Check if parameter is annotated
37
- expected_type = self.annotations[param_name] # Get expected type
38
- self.check_parameter_value(param_name, param_value, expected_type, bound_args)# Check value against type
50
+ bound_args = self.bind_args(args, kwargs) # Bind arguments to parameters
51
+
52
+ self.convert_primitive_parameters(bound_args) # Pre-process primitive type conversions
53
+
54
+ for param_name, param_value in bound_args.arguments.items(): # Iterate through arguments
55
+ if param_name != 'self': # Skip self parameter
56
+ self.validate_parameter(param_name, param_value, bound_args) # Validate each parameter
57
+ return bound_args # Return bound arguments
58
+
59
+ def bind_args(self, args: tuple, kwargs: dict): # Bind args to parameters
60
+ bound_args = self.sig.bind(*args, **kwargs) # Bind arguments to signature
61
+ bound_args.apply_defaults() # Apply default values
62
+ return bound_args # Return bound arguments
63
+
64
+ def validate_parameter(self, param_name: str, param_value: Any, bound_args): # Validate a single parameter
65
+ self.validate_immutable_parameter(param_name, param_value) # Validata the param_value (make sure if it set it is on of IMMUTABLE_TYPES)
66
+ if param_name in self.annotations: # Check if parameter is annotated
67
+ expected_type = self.annotations[param_name] # Get expected type
68
+ self.check_parameter_value(param_name, param_value, expected_type, bound_args) # Check value against type
39
69
 
40
70
  def validate_immutable_parameter(self, param_name, param_value):
41
71
  param = self.sig.parameters.get(param_name) # Check if this is a default value from a mutable type
@@ -101,45 +131,44 @@ class Type_Safe__Method:
101
131
  def is_list_type(self, origin_type: Any) -> bool: # Check if type is a List
102
132
  return origin_type is list or origin_type is List # Check against list types
103
133
 
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
134
+ def validate_list_type(self, param_name: str, # Validate list type and contents
135
+ param_value: Any, expected_type: Any): # List parameters
136
+ if not isinstance(param_value, list): # Check if value is a list
137
+ raise ValueError(f"Parameter '{param_name}' expected a list but got {type(param_value)}") # Raise error if not list
138
+
139
+ item_type = get_args(expected_type)[0] # Get list item type
140
+ item_origin = get_origin(item_type) # Get origin of item type
141
+
142
+ if item_origin is dict or item_origin is Dict: # Handle Dict[K, V] items
143
+ key_type, value_type = get_args(item_type) # Extract key and value types
144
+ for i, item in enumerate(param_value): # Validate each dict in list
145
+ if not isinstance(item, dict): # Check item is a dict
146
+ raise ValueError(f"List item at index {i} expected dict but got {type(item)}") # Raise error if not dict
147
+ if key_type is Any and value_type is Any: # Skip validation if both are Any
148
+ continue # No type checking needed
149
+ for k, v in item.items(): # Validate dict contents
150
+ if key_type is not Any and not isinstance(k, key_type): # Check key type if not Any
151
+ raise ValueError(f"Dict key '{k}' at index {i} expected type {key_type}, but got {type(k)}") # Raise error for invalid key
152
+ if value_type is not Any and not isinstance(v, value_type): # Check value type if not Any
153
+ raise ValueError(f"Dict value for key '{k}' at index {i} expected type {value_type}, but got {type(v)}") # Raise error for invalid value
154
+ elif item_origin is collections.abc.Callable: # Handle Callable[[...], ...] items
155
+ for i, item in enumerate(param_value): # Validate each callable in list
156
+ if not callable(item): # Check item is callable
157
+ raise ValueError(f"List item at index {i} expected callable but got {type(item)}") # Raise error if not callable
128
158
  # Note: Full signature validation would require is_callable_compatible method
129
- elif item_origin is not None: # Handle other subscripted types
159
+ elif item_origin is not None: # Handle other subscripted types
130
160
  raise NotImplementedError(f"Validation for list items with subscripted type"
131
161
  f" '{item_type}' is not yet supported "
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
162
+ f"in parameter '{param_name}'.") # todo: add support for checking for subscripted types
163
+ else: # Handle non-subscripted types
164
+ for i, item in enumerate(param_value): # Check each list item
165
+ if not isinstance(item, item_type): # Validate item type
166
+ raise ValueError(f"List item at index {i} expected type {item_type}, but got {type(item)}") # Raise error for invalid item
137
167
 
138
- def validate_type_parameter(self, param_name: str, param_value: Any, expected_type: Any): # Validate a Type[T] parameter
168
+ def validate_type_parameter(self, param_name: str, param_value: Any, expected_type: Any): # Validate a Type[T] parameter
139
169
  if not isinstance(param_value, type):
140
170
  raise ValueError(f"Parameter '{param_name}' expected a type class but got {type(param_value)}")
141
171
 
142
-
143
172
  type_args = get_args(expected_type) # Extract the T from Type[T]
144
173
  if type_args:
145
174
  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 not in IMMUTABLE_TYPES and var_name.startswith('__') is False: # if var_type is not one of the IMMUTABLE_TYPES or is an __ internal
290
- if self.obj_is_type_union_compatible(var_type, IMMUTABLE_TYPES) is False: # if var_type is not something like Optional[Union[int, str]]
291
- if var_type not in IMMUTABLE_TYPES or type(var_type) not in IMMUTABLE_TYPES:
292
- if not isinstance(var_type, EnumMeta):
293
- if not (isinstance(var_type, type) and issubclass(var_type, (int,str, float))):
294
- type_safe_raise_exception.immutable_type_error(var_name, var_type)
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 import get_origin, Annotated, get_args
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
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.80.0
1
+ v2.82.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: osbot_utils
3
- Version: 2.80.0
3
+ Version: 2.82.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
- ![Current Release](https://img.shields.io/badge/release-v2.80.0-blue)
24
+ ![Current Release](https://img.shields.io/badge/release-v2.82.0-blue)
25
25
  ![Python](https://img.shields.io/badge/python-3.8+-green)
26
26
  ![Type-Safe](https://img.shields.io/badge/Type--Safe-✓-brightgreen)
27
27
  ![Caching](https://img.shields.io/badge/Caching-Built--In-orange)
@@ -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=IQ7ZRXG8k0mFz4bSfYZwnxdPifXaiTm2X3pHLvGc17A,8849
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=J5hKfNdF2CPiaiC2Sb1qVd_VwfZcavo77DQ48NOUS50,19030
420
+ osbot_utils/type_safe/type_safe_core/methods/Type_Safe__Method.py,sha256=2xW4x3Hy_g3-Fs5rqyOWPHsmb8pBIqMG1iRe0qjjKW0,22154
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=aKtlqYU5uaobgpoOnzU4kKqR7mzVLeG8YcUUbWp7n-g,19648
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=24uezozenxBx3jGokdOwiOcksGocDejeebKK7YSIZmc,6723
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=OvhuEsV_06ng4M340O91vaNZ7flMDhiGOxhvz2bAo34,8
473
- osbot_utils-2.80.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
474
- osbot_utils-2.80.0.dist-info/METADATA,sha256=7S4iF13GsJEefH8A1UQ82gfoVP83vDdw_JLCoJWCMWQ,7918
475
- osbot_utils-2.80.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
476
- osbot_utils-2.80.0.dist-info/RECORD,,
472
+ osbot_utils/version,sha256=qTe6foGALmPxx0zKmfZb_cxkz5FH_-oA-y4_stF2cqY,8
473
+ osbot_utils-2.82.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
474
+ osbot_utils-2.82.0.dist-info/METADATA,sha256=8Ugc0xBnuAYes9fAMJtnLyfCFxvsYqIzgloK_mEaN00,7918
475
+ osbot_utils-2.82.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
476
+ osbot_utils-2.82.0.dist-info/RECORD,,