Skip to content

Commit ef44d7a

Browse files
committed
added fix for edge case in Type_Safe__Method use of lists inside dicts
1 parent 88edede commit ef44d7a

File tree

4 files changed

+313
-25
lines changed

4 files changed

+313
-25
lines changed

osbot_utils/type_safe/type_safe_core/methods/Type_Safe__Method.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import inspect # For function introspection
33
from enum import Enum
44
from typing import get_args, get_origin, Union, List, Any, Dict # For type hinting utilities
5+
from osbot_utils.type_safe.Type_Safe__Base import Type_Safe__Base
56
from osbot_utils.type_safe.Type_Safe__Primitive import Type_Safe__Primitive
67
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Annotations import type_safe_annotations
78
from osbot_utils.type_safe.type_safe_core.shared.Type_Safe__Shared__Variables import IMMUTABLE_TYPES
@@ -244,18 +245,24 @@ def validate_direct_type(self, param_name: str, param_value: Any, expected_type:
244245

245246
if value_type is Any: # if value type is Any, we don't need to do any checks since they will all match
246247
return True
248+
249+
validator = Type_Safe__Base()
247250
for k, v in param_value.items():
248-
if get_origin(key_type) is None:
251+
if get_origin(key_type) is None: # Validate key (existing logic)
249252
if not isinstance(k, key_type):
250253
raise ValueError(f"Dict key '{k}' expected type {key_type}, but got {type(k)}")
251254
else:
252-
raise NotImplementedError(f"Validation for subscripted key type '{key_type}' not yet supported in parameter '{param_name}'")
255+
try:
256+
validator.is_instance_of_type(k, key_type)
257+
except TypeError as e:
258+
raise ValueError(f"Dict key '{k}' in parameter '{param_name}': {e}") from None
259+
260+
if value_type is not Any: # Validate value
261+
try:
262+
validator.is_instance_of_type(v, value_type)
263+
except TypeError as e:
264+
raise ValueError(f"Dict value for key '{k}' in parameter '{param_name}': {e}") from None
253265

254-
if get_origin(value_type) is None:
255-
if not isinstance(v, value_type):
256-
raise ValueError(f"Dict value for key '{k}' expected type {value_type}, but got {type(v)}")
257-
elif value_type is not Any:
258-
raise NotImplementedError(f"Validation for subscripted value type '{value_type}' not yet supported in parameter '{param_name}'")
259266
return True
260267
base_type = origin
261268
else:

tests/unit/type_safe/type_safe_core/decorators/test__decorator__type_safe__regression.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,8 @@ def an_method__static(attributes: Dict[str, An_Attribute]):
348348
# with pytest.raises(TypeError, match="Subscripted generics cannot be used with class and instance checks"):
349349
# an_method__static({'aaa': 'abc' }) # Fixed: BUG: should have failed with type safe check
350350

351-
with pytest.raises(ValueError, match=re.escape("Dict value for key 'aaa' expected type <class 'test__decorator__type_safe__regression.test_decorator__type_safe__regression.test__regression__dict_attribute_fail.<locals>.An_Attribute'>, but got <class 'str'>")):
351+
error_message = "Dict value for key 'aaa' in parameter 'attributes': Expected 'An_Attribute', but got 'str'"
352+
with pytest.raises(ValueError, match=re.escape(error_message)):
352353
an_method__static({'aaa': 'abc' }) # Fixed: BUG: should have failed with type safe check
353354
#
354355
# with pytest.raises(TypeError, match="Subscripted generics cannot be used with class and instance checks"):

tests/unit/type_safe/type_safe_core/methods/test_Type_Safe__Method.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,8 @@ def func_with_dict(data: Dict[str, int]) -> None:
160160
# Invalid: wrong value type
161161
with self.assertRaises(ValueError) as context:
162162
checker.validate_direct_type('data', {"key": "value"}, Dict[str, int])
163-
assert "Dict value for key 'key' expected type" in str(context.exception)
163+
#assert "Dict value for key 'key' expected type" in str(context.exception)
164+
assert str(context.exception) == "Dict value for key 'key' in parameter 'data': Expected 'int', but got 'str'"
164165

165166
# Test Any type handling
166167
def test_validate_direct_type__any_type(self): # Test that Any type accepts anything

0 commit comments

Comments
 (0)