osbot-utils 2.62.0__py3-none-any.whl → 2.63.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,4 +1,5 @@
1
1
  import random
2
+ from osbot_utils.type_safe.Type_Safe__Primitive import Type_Safe__Primitive
2
3
 
3
4
  _hex_table = [f"{i:02x}" for i in range(256)]
4
5
 
@@ -14,7 +15,7 @@ def is_obj_id(value: str):
14
15
  def new_obj_id():
15
16
  return hex(random.getrandbits(32))[2:].zfill(8) # slice off '0x' and pad
16
17
 
17
- class Obj_Id(str):
18
+ class Obj_Id(Type_Safe__Primitive,str):
18
19
  def __new__(cls, value: str=None):
19
20
  if value:
20
21
  if is_obj_id(value):
@@ -1,6 +1,6 @@
1
1
  from osbot_utils.type_safe.Type_Safe__Primitive import Type_Safe__Primitive
2
- from osbot_utils.utils.Misc import random_id_short
3
- from osbot_utils.utils.Str import safe_id
2
+ from osbot_utils.utils.Misc import random_id_short
3
+ from osbot_utils.utils.Str import safe_id
4
4
 
5
5
  SAFE_ID__MAX_LENGTH = 512
6
6
 
@@ -1,6 +1,8 @@
1
- from osbot_utils.type_safe.Type_Safe__Base import Type_Safe__Base, type_str
1
+ from typing import Type
2
+ from osbot_utils.type_safe.Type_Safe__Base import Type_Safe__Base, type_str
2
3
 
3
4
  class Type_Safe__List(Type_Safe__Base, list):
5
+ expected_type : Type
4
6
 
5
7
  def __init__(self, expected_type, *args):
6
8
  super().__init__(*args)
@@ -21,7 +23,7 @@ class Type_Safe__List(Type_Safe__Base, list):
21
23
  try:
22
24
  self.is_instance_of_type(item, self.expected_type)
23
25
  except TypeError as e:
24
- raise TypeError(f"In Type_Safe__List: Invalid type for item: {e}")
26
+ raise TypeError(f"In Type_Safe__List: Invalid type for item: {e}") from None
25
27
  super().append(item)
26
28
 
27
29
 
@@ -185,5 +185,5 @@ class Type_Safe__Method:
185
185
  base_type = expected_type
186
186
 
187
187
  if not isinstance(param_value, base_type):
188
- raise ValueError(f"Parameter '{param_name}' expected type {expected_type}, but got {type(param_value)}")
188
+ raise ValueError(f"Parameter '{param_name}' expected type {expected_type}, but got {type(param_value)}") from None
189
189
  return True
@@ -9,6 +9,19 @@ class Type_Safe__Primitive:
9
9
  cls.__primitive_base__ = base
10
10
  break
11
11
 
12
+ def __add__(self, other):
13
+ """Override addition/concatenation to maintain type safety"""
14
+ if self.__primitive_base__ is str: # For string concatenation
15
+ result = super().__add__(other) # Perform the operation
16
+ return type(self)(result) # Return instance of the safe type
17
+ else: # For numeric types (int, float)
18
+ result = super().__add__(other)
19
+ try:
20
+ return type(self)(result) # Try to create safe type
21
+ except (ValueError, TypeError):
22
+ return result # Fall back to primitive if constraints violated
23
+
24
+
12
25
  def __eq__(self, other):
13
26
  if type(self) is type(other): # Same type → compare values
14
27
  return super().__eq__(other)
@@ -22,7 +35,30 @@ class Type_Safe__Primitive:
22
35
  def __hash__(self): # Include type in hash to maintain hash/eq contract , This works for str, int, float subclasses
23
36
  return hash((type(self).__name__, super().__hash__()))
24
37
 
25
- def __repr__(self): # Enhanced repr to show type information in assertions
26
- value_repr = super().__repr__()
27
- return f"{type(self).__name__}({value_repr})"
38
+ def __radd__(self, other):
39
+ """Reverse addition/concatenation for when safe type is on the right"""
40
+ if self.__primitive_base__ is str:
41
+ result = other + str(self) # Perform string concatenation
42
+ return type(self)(result) # Return instance of the safe type
43
+ else:
44
+ result = other + self.__primitive_base__(self)
45
+ try:
46
+ return type(self)(result)
47
+ except (ValueError, TypeError):
48
+ return result
49
+
50
+ def __str__(self): # Return the primitive string representation"""
51
+ if self.__primitive_base__ is float: # Format the value using the primitive type's string formatting
52
+ return format(float(self), '')
53
+ elif self.__primitive_base__ is int:
54
+ return format(int(self), '')
55
+ elif self.__primitive_base__ is str:
56
+ return str.__str__(self)
57
+ return super().__str__()
28
58
 
59
+ def __repr__(self): # Enhanced repr for debugging that shows type information
60
+ value_str = self.__str__()
61
+ if self.__primitive_base__ is str:
62
+ return f"{type(self).__name__}('{value_str}')"
63
+ else:
64
+ return f"{type(self).__name__}({value_str})"
@@ -8,7 +8,7 @@ class Type_Safe__Raise_Exception:
8
8
  raise ValueError(exception_message)
9
9
 
10
10
  def immutable_type_error(self, var_name, var_type):
11
- exception_message = f"variable '{var_name}' is defined as type '{var_type}' which is not supported by Type_Safe, with only the following immutable types being supported: '{IMMUTABLE_TYPES}'"
11
+ exception_message = f"variable '{var_name}' is defined as type '{var_type}' which is not supported by Type_Safe, with only the following immutable types being supported: '{IMMUTABLE_TYPES}' and the following subclasses (int, float, str)"
12
12
  raise ValueError(exception_message)
13
13
 
14
14
  type_safe_raise_exception = Type_Safe__Raise_Exception()
@@ -289,7 +289,7 @@ class Type_Safe__Validation:
289
289
  if self.obj_is_type_union_compatible(var_type, IMMUTABLE_TYPES) is False: # if var_type is not something like Optional[Union[int, str]]
290
290
  if var_type not in IMMUTABLE_TYPES or type(var_type) not in IMMUTABLE_TYPES:
291
291
  if not isinstance(var_type, EnumMeta):
292
- if not issubclass(var_type, (int,str, float)):
292
+ if not (isinstance(var_type, type) and issubclass(var_type, (int,str, float))):
293
293
  type_safe_raise_exception.immutable_type_error(var_name, var_type)
294
294
 
295
295
  def validate_variable_type(self, var_name, var_type, var_value): # Validate type compatibility
@@ -25,7 +25,7 @@ class Type_Safe__Step__Init:
25
25
  setattr(__self, key, value)
26
26
  else:
27
27
  raise ValueError(f"{__self.__class__.__name__} has no attribute '{key}' and cannot be assigned the value '{value}'. "
28
- f"Use {__self.__class__.__name__}.__default_kwargs__() see what attributes are available")
28
+ f"Use {__self.__class__.__name__}.__default_kwargs__() see what attributes are available") from None
29
29
 
30
30
  def convert_value_to_type_safe_objects(self, __self, key, value):
31
31
  annotation = type_safe_annotations.obj_attribute_annotation(__self, key)
osbot_utils/version CHANGED
@@ -1 +1 @@
1
- v2.62.0
1
+ v2.63.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: osbot_utils
3
- Version: 2.62.0
3
+ Version: 2.63.0
4
4
  Summary: OWASP Security Bot - Utils
5
5
  License: MIT
6
6
  Author: Dinis Cruz
@@ -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
- ![Current Release](https://img.shields.io/badge/release-v2.62.0-blue)
26
+ ![Current Release](https://img.shields.io/badge/release-v2.63.0-blue)
27
27
  [![codecov](https://codecov.io/gh/owasp-sbot/OSBot-Utils/graph/badge.svg?token=GNVW0COX1N)](https://codecov.io/gh/owasp-sbot/OSBot-Utils)
28
28
 
29
29
 
@@ -38,13 +38,13 @@ osbot_utils/helpers/Guid.py,sha256=0Ay3TYYk2nPr-JRVRCMFxbr8OvoQomv5HjT7o5B7cos,8
38
38
  osbot_utils/helpers/Hashicorp_Secrets.py,sha256=e2fWWHK6bubpAm1sw5y8X5kh2Hk5d4JyZCnUovZip5A,4232
39
39
  osbot_utils/helpers/Local_Cache.py,sha256=67qmeVXUBhfqLUQhjFBE9Pjt5dcjpQYhqCTGQNWgVSU,3232
40
40
  osbot_utils/helpers/Local_Caches.py,sha256=LUeNJX07Ccnp1SIhYvhqqQFVF6r_Ez7bWha8ssomuvY,1957
41
- osbot_utils/helpers/Obj_Id.py,sha256=sdKlSmEUpie0kn9X4pnM0MjUr6sLu4WZLSNqsD8ynBg,926
41
+ osbot_utils/helpers/Obj_Id.py,sha256=T6HF8khO7u1C688Ref_8Li2zxowRc9pIghUkMwb6H1c,1023
42
42
  osbot_utils/helpers/Print_Table.py,sha256=LEXbyqGg_6WSraI4cob4bNNSu18ddqvALp1zGK7bPhs,19126
43
43
  osbot_utils/helpers/Python_Audit.py,sha256=shpZlluJwqJBAlad6xN01FkgC1TsQ48RLvR5ZjmrKa4,1539
44
44
  osbot_utils/helpers/Random_Guid.py,sha256=86xnlevsiitCzFB-VjjBmXXV14pbcKd67YWEDsYTCFk,483
45
45
  osbot_utils/helpers/Random_Guid_Short.py,sha256=YP_k5OLuYvXWGU2OEnQHk_OGViBQofTWKm3pUdQaJao,404
46
46
  osbot_utils/helpers/Random_Seed.py,sha256=14btja8LDN9cMGWaz4fCNcMRU_eyx49gas-_PQvHgy4,634
47
- osbot_utils/helpers/Safe_Id.py,sha256=C7IcE8GwyvLbhzc6ImIafmdlCcR6vV7aQU9-oq-kIJE,656
47
+ osbot_utils/helpers/Safe_Id.py,sha256=Mj66QVcEHqUKDFb0cdl7cbMOlQKxfFuRxnupmKo6UG8,696
48
48
  osbot_utils/helpers/Str_ASCII.py,sha256=PRqyu449XnKrLn6b9Miii1Hv-GO5OAa1UhhgvlRcC2M,704
49
49
  osbot_utils/helpers/Timestamp_Now.py,sha256=OZwSwmYA1pZAnVglpx2lBL5t8Pu_HxzmYdNEJnmTqKI,536
50
50
  osbot_utils/helpers/Type_Registry.py,sha256=Ajk3SyMSKDi2g9SJYUtTgg7PZkAgydaHcpbGuEN3S94,311
@@ -367,9 +367,9 @@ osbot_utils/testing/performance/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JC
367
367
  osbot_utils/type_safe/Type_Safe.py,sha256=LOWRGOGpnRU2iTRLP47vUoyalK0vjFrWlnaghBIogWg,6267
368
368
  osbot_utils/type_safe/Type_Safe__Base.py,sha256=UTMipTL6mXoetAEUCI5hs8RqXp4NDYOvoAiYoFOt5jg,8807
369
369
  osbot_utils/type_safe/Type_Safe__Dict.py,sha256=QB200L5eNWT3FnUv8sm5kncj1wXJsJ9uRycNFl9xb6Y,3077
370
- osbot_utils/type_safe/Type_Safe__List.py,sha256=KyK_DpRM-ACHWPhIaqrNh0cNZhLC9vcsEhcxMi1UF9s,1799
371
- osbot_utils/type_safe/Type_Safe__Method.py,sha256=PRV4enbwuD81QKP_5UtUA3OAp0m0xSiUhwkCoseZoq4,15687
372
- osbot_utils/type_safe/Type_Safe__Primitive.py,sha256=RpogRqGJF2qzlsXsgDhyXkez_SjY_IsVIJBn7mmkSiU,1569
370
+ osbot_utils/type_safe/Type_Safe__List.py,sha256=y_lp7Ai0HfQCqC8Bxn0g6_M9MP5lPOXy5Dhkuj2fJvQ,1891
371
+ osbot_utils/type_safe/Type_Safe__Method.py,sha256=lHBCpW5nf2ikybm9oucvq6L67VXNO4qEvzGskJ1hGHs,15697
372
+ osbot_utils/type_safe/Type_Safe__Primitive.py,sha256=CJ4LP2W5i9utSSzuiiJrwqvwdMv1DeQ6dIZICtYfLTY,3635
373
373
  osbot_utils/type_safe/Type_Safe__Set.py,sha256=j12fc8cbd9-s_a13ysaz723rNEW4Dt6hObCd0S-AjIg,1432
374
374
  osbot_utils/type_safe/Type_Safe__Tuple.py,sha256=Kx7C4YfHybRbMmVMcmV6yFLi4T48pb592vEZfjjyLxo,1710
375
375
  osbot_utils/type_safe/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -383,15 +383,15 @@ osbot_utils/type_safe/shared/Type_Safe__Convert.py,sha256=q1ds7AqgNhZX1pW0SNq_VN
383
383
  osbot_utils/type_safe/shared/Type_Safe__Json_Compressor.py,sha256=TDbot_NNzCPXBQv0l5mksWueJNfxlVFDBGxIH8Jf_XY,5426
384
384
  osbot_utils/type_safe/shared/Type_Safe__Json_Compressor__Type_Registry.py,sha256=wYOCg7F1nTrRn8HlnZvrs_8A8WL4gxRYRLnXZpGIiuk,1119
385
385
  osbot_utils/type_safe/shared/Type_Safe__Not_Cached.py,sha256=25FAl6SOLxdStco_rm9tgOYLfuKyBWheGdl7vVa56UU,800
386
- osbot_utils/type_safe/shared/Type_Safe__Raise_Exception.py,sha256=pbru8k8CTQMNUfmFBndiJhg2KkqEYzFvJAPcNZHeHfQ,829
386
+ osbot_utils/type_safe/shared/Type_Safe__Raise_Exception.py,sha256=9OaPZNZeJzuSvyDqDq-7UBSIlXCdktuxl10C3EEC2Io,876
387
387
  osbot_utils/type_safe/shared/Type_Safe__Shared__Variables.py,sha256=SuZGl9LryQX6IpOE0I_lbzClT-h17UNylC__-M8ltTY,129
388
- osbot_utils/type_safe/shared/Type_Safe__Validation.py,sha256=xkpcj04owSap5DSG9m9FM1bnTje2I_xRFUfsH-R6mrQ,19509
388
+ osbot_utils/type_safe/shared/Type_Safe__Validation.py,sha256=1XvbWJmRfyqBcdOTuYZ5fiItyMF0ttSPFnWjqZTGbYE,19542
389
389
  osbot_utils/type_safe/shared/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
390
390
  osbot_utils/type_safe/steps/Type_Safe__Step__Class_Kwargs.py,sha256=snoyJKvZ1crgF2fp0zexwNPnV_E63RfyRIsMAZdrKNY,6995
391
391
  osbot_utils/type_safe/steps/Type_Safe__Step__Default_Kwargs.py,sha256=tzKXDUc0HVP5QvCWsmcPuuZodNvQZ9FeMDNI2x00Ngw,1943
392
392
  osbot_utils/type_safe/steps/Type_Safe__Step__Default_Value.py,sha256=b5vsgM8eg9yq2KM0wRMntVHma6OhN_HnU76LxhEIpoA,4483
393
393
  osbot_utils/type_safe/steps/Type_Safe__Step__From_Json.py,sha256=AguNcZwKKnyNY87bSAF1xLwYW5h_IDfUad70QqIiK3I,14622
394
- osbot_utils/type_safe/steps/Type_Safe__Step__Init.py,sha256=dQRwFxEMdmoW2ogmYZ6ZxLOvt1XnALx41LPpIB6yp3s,4473
394
+ osbot_utils/type_safe/steps/Type_Safe__Step__Init.py,sha256=wBdShMavx8Ja5IACyW8dP3_fq_iqrMp8HHziOqjgxqU,4483
395
395
  osbot_utils/type_safe/steps/Type_Safe__Step__Set_Attr.py,sha256=Nm1cleC-IDez6HFDejTfMprrnOfTvmEopO_pW6w1vFM,5507
396
396
  osbot_utils/type_safe/steps/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
397
397
  osbot_utils/type_safe/validators/Type_Safe__Validator.py,sha256=cJIPSBarjV716SZUOLvz7Mthjk-aUYKUQtRDtKUBmN4,779
@@ -426,8 +426,8 @@ osbot_utils/utils/Toml.py,sha256=Rxl8gx7mni5CvBAK-Ai02EKw-GwtJdd3yeHT2kMloik,166
426
426
  osbot_utils/utils/Version.py,sha256=Ww6ChwTxqp1QAcxOnztkTicShlcx6fbNsWX5xausHrg,422
427
427
  osbot_utils/utils/Zip.py,sha256=pR6sKliUY0KZXmqNzKY2frfW-YVQEVbLKiyqQX_lc-8,14052
428
428
  osbot_utils/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
429
- osbot_utils/version,sha256=D2jMsR4GCqKXka6mERWlFlF_-L6bTp87Q1u4_8a3Gac,8
430
- osbot_utils-2.62.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
431
- osbot_utils-2.62.0.dist-info/METADATA,sha256=Tv5eyV42q8-AugMV48XSad5KlGiBsNe-V__dipVAkko,1329
432
- osbot_utils-2.62.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
433
- osbot_utils-2.62.0.dist-info/RECORD,,
429
+ osbot_utils/version,sha256=IWixd7YBcbxa1wEG9NtDCaSq5I9PLdGT6l-PYSH_4Nk,8
430
+ osbot_utils-2.63.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
431
+ osbot_utils-2.63.0.dist-info/METADATA,sha256=l32825CMqXSK4LT9FOklpDdDAUtX-shMbOiC82HjVh4,1329
432
+ osbot_utils-2.63.0.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
433
+ osbot_utils-2.63.0.dist-info/RECORD,,