osbot-utils 2.3.0__py3-none-any.whl → 2.4.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,4 @@
1
1
  import uuid
2
-
3
2
  from osbot_utils.utils.Misc import is_guid
4
3
 
5
4
  GUID__NAMESPACE = uuid.UUID('2cfec064-537a-4ff7-8fdc-2fc9e2606f3d')
@@ -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 and not isinstance(var_value, var_type): # check 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
@@ -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
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,11 @@ 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) # to handle when type definition contains a generic
458
- if origin_attr_type is Annotated: # if the type is Annotated
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
+ return isinstance(value, type) and issubclass(value, type_arg) # Check that value is a type and is subclass of type_arg
473
+ if origin_attr_type is Annotated: # if the type is Annotated
459
474
  args = get_args(attr_type)
460
475
  origin_attr_type = args[0]
461
476
 
osbot_utils/version CHANGED
@@ -1 +1 @@
1
- v2.3.0
1
+ v2.4.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: osbot_utils
3
- Version: 2.3.0
3
+ Version: 2.4.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
- ![Current Release](https://img.shields.io/badge/release-v2.3.0-blue)
26
+ ![Current Release](https://img.shields.io/badge/release-v2.4.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
 
@@ -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=fqiCYHrYff3yZ_Df-WJdXHl1RQtJHb4oCmDkJpcGN_k,828
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,7 +277,7 @@ 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=irrNiwWQHV4eP2dq9aKYDIETsG375U9U055YPZX1uQw,29658
280
+ osbot_utils/type_safe/Type_Safe.py,sha256=asybUt2JqDP34b7s6clCcurJpaJg_4oOI4Qt10PQ2bM,30419
281
281
  osbot_utils/type_safe/Type_Safe_Method.py,sha256=JLB7NkeuY4x_lIWJyvG1bDApCM_VyAQqrzQXhH7Z-8A,10969
282
282
  osbot_utils/type_safe/Type_Safe__Base.py,sha256=mL8GMaR9tsaUfwk8d-8zp2g-A8kNKiN6kroEFaNvMOk,5518
283
283
  osbot_utils/type_safe/Type_Safe__Dict.py,sha256=I_Ac0JH-ahmQrkADFVyiobTlH1JI31MKHaNszQW4PBo,2396
@@ -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=7QS_rBiLMLiD28be_br-7NrLfR7LtxFImjUGko8MqXM,21933
308
+ osbot_utils/utils/Objects.py,sha256=F3H0ux-IjfyMIA1ou-xc0Ra1Z7oON3fuYRH_qaGsQ4Y,23375
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=B-GHcA-4RPUOEZ4BIL3emPJuZ5J9E1aQPTmIXKecyHE,7
321
- osbot_utils-2.3.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
322
- osbot_utils-2.3.0.dist-info/METADATA,sha256=_sYtNzPStrMRoLTa5C1PaRTfEzeeOV7SeccUXx9GAFo,1315
323
- osbot_utils-2.3.0.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
324
- osbot_utils-2.3.0.dist-info/RECORD,,
320
+ osbot_utils/version,sha256=p1zoKgZOpZRdZ0kkLKwgWGFUdRL6IoXVo1tPBL0f9tY,7
321
+ osbot_utils-2.4.0.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
322
+ osbot_utils-2.4.0.dist-info/METADATA,sha256=M41QEpJLyE3h5hjXubqfqshQ7-wn0ioHXjgt7AKFuOU,1315
323
+ osbot_utils-2.4.0.dist-info/WHEEL,sha256=RaoafKOydTQ7I_I3JTrPCg6kUmTgtm4BornzOqyEfJ8,88
324
+ osbot_utils-2.4.0.dist-info/RECORD,,