Skip to content

Commit

Permalink
Merge pull request #250 from specklesystems/gergo/nonGenericTFix
Browse files Browse the repository at this point in the history
fix(typing): fix non generic typedefed lists and tuples
  • Loading branch information
gjedlicska authored Jan 9, 2023
2 parents 65c8294 + 4628f11 commit 4095692
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 0 deletions.
16 changes: 16 additions & 0 deletions src/specklepy/objects/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,15 @@ def _validate_type(t: Optional[type], value: Any) -> Tuple[bool, Any]:
return False, value
if value == {}:
return True, value
if not getattr(t, "__args__", None):
return True, value
t_key, t_value = t.__args__ # type: ignore

if (
getattr(t_key, "__name__", None),
getattr(t_value, "__name__", None),
) == ("KT", "VT"):
return True, value
# we're only checking the first item, but the for loop and return after
# evaluating the first item is the fastest way
for dict_key, dict_value in value.items():
Expand All @@ -251,7 +259,11 @@ def _validate_type(t: Optional[type], value: Any) -> Tuple[bool, Any]:
return False, value
if value == []:
return True, value
if not hasattr(t, "__args__"):
return True, value
t_items = t.__args__[0] # type: ignore
if getattr(t_items, "__name__", None) == "T":
return True, value
first_item_valid, _ = _validate_type(t_items, value[0])
if first_item_valid:
return True, value
Expand All @@ -260,7 +272,11 @@ def _validate_type(t: Optional[type], value: Any) -> Tuple[bool, Any]:
if origin is tuple:
if not isinstance(value, tuple):
return False, value
if not hasattr(t, "__args__"):
return True, value
args = t.__args__ # type: ignore
if args == tuple():
return True, value
# we're not checking for empty tuple, cause tuple lengths must match
if len(args) != len(value):
return False, value
Expand Down
3 changes: 3 additions & 0 deletions tests/unit/test_type_validation.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,14 +64,17 @@ class FakeIntEnum(IntEnum):
# same as the dict typing below...
(List[int], [None, 2], True, [None, 2]),
(List[Optional[int]], [None, 2], True, [None, 2]),
(List, ["foo", 2, "bar"], True, ["foo", 2, "bar"]),
(Dict[str, int], {"foo": 1}, True, {"foo": 1}),
(Dict, {"foo": 1}, True, {"foo": 1}),
(Dict[str, Optional[int]], {"foo": None}, True, {"foo": None}),
# this case should be
# (Dict[int, Base], {1: None}, False, {1: None}),
# but type checking currently allows everything to be None
(Dict[int, Base], {1: None}, True, {1: None}),
(Dict[int, Base], {1: test_base}, True, {1: test_base}),
(Tuple[int, str, str], (1, "foo", "bar"), True, (1, "foo", "bar")),
(Tuple, (1, "foo", "bar"), True, (1, "foo", "bar")),
# given our current rules, this is the reality. Its just sad...
(Tuple[str, str, str], (1, "foo", "bar"), True, ("1", "foo", "bar")),
(Tuple[str, Optional[str], str], (1, None, "bar"), True, ("1", None, "bar")),
Expand Down

0 comments on commit 4095692

Please sign in to comment.