From f1ab15fbf3e2d5819b50c5d8280b50d6f83e4329 Mon Sep 17 00:00:00 2001 From: Autumn Date: Tue, 23 Jul 2024 02:23:23 -0700 Subject: [PATCH] fix: handle fixed tuples correctly --- instruct/typedef.py | 8 ++++++-- tests/test_typedef.py | 7 +++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/instruct/typedef.py b/instruct/typedef.py index 07541e6..b9c4793 100644 --- a/instruct/typedef.py +++ b/instruct/typedef.py @@ -956,13 +956,14 @@ def test_func_homogenous_tuple(value): test_types = flatten( (parse_typedef(some_type) for some_type in value_types), eager=True ) + parsed_value_types = tuple(parse_typedef(x) for x in value_types) def test_func_heterogenous_tuple(value): if not isinstance(value, container_cls): return False - if len(value) != len(test_types): + if len(value) != len(parsed_value_types): return False - for index, (item, item_type) in enumerate(zip(value, test_types)): + for index, (item, item_type) in enumerate(zip(value, parsed_value_types)): if not isinstance(item, item_type): return False return True @@ -1194,6 +1195,9 @@ def parse_typedef( ) type_args = get_args(typehint) if type_args or as_origin_cls is None: + assert all( + isinstance(x, (type, type(Ellipsis))) or is_typing_definition(x) for x in type_args + ), f"{typehint!r} vs {type_args!r}" if as_origin_cls is not None: cls = create_custom_type(as_origin_cls, *type_args, check_ranges=check_ranges) else: diff --git a/tests/test_typedef.py b/tests/test_typedef.py index 996a764..8b76480 100644 --- a/tests/test_typedef.py +++ b/tests/test_typedef.py @@ -287,3 +287,10 @@ def test_parse_typedef_generics(): assert isinstance((1, "str"), parse_typedef(SomeGenericSeq[int, str])) assert not isinstance((1, 1), parse_typedef(SomeGenericSeq[int, str])) assert not isinstance((1, 1), parse_typedef(Tuple[int, str])) + + +def test_strict_heterogenous(): + t = parse_typedef(Tuple[Union[Literal["a", "b"], str], Union[int, float]]) + assert isinstance(("", -1), t) + assert isinstance(("a", 1.0), t) + assert isinstance(("b", 4), t)