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
Exemple #12
0
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"}
Exemple #13
0
def test_member_entry_sub_types() -> None:
    entry = MemberEntry("List", sub_members={MemberEntry("str")})

    assert str(entry) == "List[str]"
Exemple #14
0
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]]"
Exemple #15
0
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"}
Exemple #16
0
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")
    }
Exemple #17
0
def test_member_entry_base_output() -> None:
    entry = MemberEntry("str")

    assert str(entry) == "str"
Exemple #18
0
def test_member_entry_sub_types_union() -> None:
    entry = MemberEntry("List", sub_members={MemberEntry("str"), MemberEntry("int")})

    assert str(entry) == "List[Union[int, str]]"
Exemple #19
0
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]]"