def test_member_entry_sub_types_union_instead_of_optional_if_multiple_types() -> None: entry = MemberEntry( "List", sub_members={MemberEntry("str"), MemberEntry("int"), MemberEntry("None")}, ) assert str(entry) == "List[Union[None, int, str]]"
def test_sorting_member_entries_based_on_dependency() -> None: foo = MemberEntry(name="Foo") bar = MemberEntry(name="Bar", sub_members={foo}) baz = MemberEntry(name="Baz", sub_members={bar}) assert sorted([foo, bar, baz], key=key_to_dependency_cmp) == [foo, bar, baz] assert sorted([bar, foo, baz], key=key_to_dependency_cmp) == [foo, bar, baz] assert sorted([baz, bar, foo], key=key_to_dependency_cmp) == [foo, bar, baz]
def test_dict_entry_base_output() -> None: entry = DictEntry( "RootType", members={"foo": {MemberEntry("str")}, "bar": {MemberEntry("int")}} ) # fmt: off assert str(entry) == "\n".join([ "class RootType(TypedDict):", " foo: str", " bar: int", ])
def test_sorting_dict_entry_based_on_dependency() -> None: foo = MemberEntry(name="Foo") bar = MemberEntry(name="Bar", sub_members={foo}) baz = MemberEntry(name="int") entry = DictEntry("RootType", members={"foo": {foo}, "bar": {bar}, "baz": {baz}}) assert sorted([foo, baz, entry, bar], key=key_to_dependency_cmp) == [ foo, baz, bar, entry, ]
def test_dict_entry_get_imports_from_sub_members() -> None: sub_entry = DictEntry( "NestedType", members={ "foo": { MemberEntry( "List", sub_members={MemberEntry("int"), MemberEntry("str")} ) } }, ) entry = DictEntry("RootType", members={"sub": {sub_entry}}) assert entry.get_imports() == {"List", "Union"}
def test_dict_entry_alternative_output() -> None: entry = DictEntry( "RootType", members={"foo": {MemberEntry("str")}, "bar": {MemberEntry("int")}}, force_alternative=True, ) # fmt: off assert str(entry) == "\n".join([ 'RootType = TypedDict("RootType", {', ' "foo": str,', ' "bar": int,', '})', ])
def test_dict_entry_get_imports() -> None: base_entry = DictEntry("RootType", members={"foo": {MemberEntry("str")}}) base_entry_with_list = DictEntry( "RootType", members={ "bar": { MemberEntry( "List", sub_members={MemberEntry("int"), MemberEntry("str")} ) } }, ) assert base_entry.get_imports() == set() assert base_entry_with_list.get_imports() == {"List", "Union"}
def test_dict_entry_nested_dicts() -> None: sub_entry = DictEntry( "NestedType", members={ "foo": { MemberEntry( "List", sub_members={MemberEntry("int"), MemberEntry("str")} ) } }, ) entry = DictEntry("RootType", members={"sub": {sub_entry}}) # fmt: off assert str(entry) == "\n".join([ "class RootType(TypedDict):", " sub: NestedType", ])
def test_sorting_dict_entry_with_sub_entry() -> None: sub_entry = DictEntry( "NestedType", members={ "foo": { MemberEntry( "List", sub_members={MemberEntry("int"), MemberEntry("str")} ) } }, ) entry = DictEntry("RootType", members={"sub": {sub_entry}}) assert sub_entry.name in entry.depends_on assert entry.name not in sub_entry.depends_on assert sorted([entry, sub_entry], key=key_to_dependency_cmp) == [sub_entry, entry] assert sorted([sub_entry, entry], key=key_to_dependency_cmp) == [sub_entry, entry]
def _get_type(self, item: Any, key: str) -> Union[MemberEntry, DictEntry]: if item is None: return MemberEntry("None") if isinstance(item, BASE_TYPES): return MemberEntry(type(item).__name__) if isinstance(item, (list, set, tuple, frozenset)): if isinstance(item, list): sequence_type_name = "List" elif isinstance(item, set): sequence_type_name = "Set" elif isinstance(item, frozenset): sequence_type_name = "FrozenSet" else: sequence_type_name = "Tuple" list_item_types: Set[Union[MemberEntry, DictEntry]] = set() idx = 0 for value in item: item_type = self._get_type(value, key=f"{key}Item{idx}") if isinstance(item_type, DictEntry): if item_type.members not in (getattr(t, "members", None) for t in list_item_types): list_item_types.add(item_type) idx += 1 if isinstance(item_type, DictEntry): self._add_definition(item_type) else: list_item_types.add(item_type) return MemberEntry(sequence_type_name, sub_members=list_item_types) if isinstance(item, dict): return self._convert_dict( f"{key_to_class_name(key)}{self.type_postfix}", item) raise NotImplementedError( f"Type handling for '{type(item)}' not implemented")
def _convert_list(self, key: str, lst: List, item_name: str) -> MemberEntry: entry = MemberEntry(key) idx = 0 for item in lst: item_type = self._get_type(item, key=f"{item_name}{idx}") entry.sub_members.add(item_type) if isinstance(item_type, DictEntry): self._add_definition(item_type) idx += 1 return entry
def test_member_entry_get_imports_from_sub_members() -> None: sub_entry = DictEntry( "NestedType", members={ "foo": { MemberEntry( "List", sub_members={MemberEntry("int"), MemberEntry("str")} ) } }, ) entry = MemberEntry( "List", sub_members={sub_entry, MemberEntry("Set", sub_members={MemberEntry("int")})}, ) assert entry.get_imports() == {"List", "Union", "Set"}
def test_member_entry_sub_types() -> None: entry = MemberEntry("List", sub_members={MemberEntry("str")}) assert str(entry) == "List[str]"
def test_dict_entry_with_member_entry() -> None: dict_entry = DictEntry("SubType", members={"foo": {MemberEntry("str")}}) member_entry = MemberEntry("List", sub_members={dict_entry}) entry = MemberEntry("Set", sub_members={member_entry}) assert str(entry) == "Set[List[SubType]]"
def test_member_entry_get_imports() -> None: just_list = MemberEntry("List") just_list_one_item = MemberEntry("List", sub_members={MemberEntry("str")}) list_with_union = MemberEntry( "List", sub_members={MemberEntry("str"), MemberEntry("int")} ) list_with_optional = MemberEntry( "List", sub_members={MemberEntry("str"), MemberEntry("None")} ) assert just_list.get_imports() == {"List"} assert just_list_one_item.get_imports() == {"List"} assert list_with_union.get_imports() == {"List", "Union"} assert list_with_optional.get_imports() == {"List", "Optional"}
def test_member_entry_is_hashable_based_on_str_out() -> None: assert hash(MemberEntry("int")) == hash(MemberEntry("int")) hashed_list_int_1 = hash(MemberEntry("List", sub_members={MemberEntry("int")})) hashed_list_int_2 = hash(MemberEntry("List", sub_members={MemberEntry("int")})) hashed_list_str = hash(MemberEntry("List", sub_members={MemberEntry("str")})) assert hashed_list_int_1 == hashed_list_int_2 assert hashed_list_int_1 != hashed_list_str assert {MemberEntry("int"), MemberEntry("int"), MemberEntry("int")} == { MemberEntry("int") }
def test_member_entry_base_output() -> None: entry = MemberEntry("str") assert str(entry) == "str"
def test_member_entry_sub_types_union() -> None: entry = MemberEntry("List", sub_members={MemberEntry("str"), MemberEntry("int")}) assert str(entry) == "List[Union[int, str]]"
def test_member_entry_sub_types_optional_if_just_one_type() -> None: entry = MemberEntry("List", sub_members={MemberEntry("str"), MemberEntry("None")}) assert str(entry) == "List[Optional[str]]"