Skip to content

Commit dc308a9

Browse files
committed
Implement as GetSpecialAttr.
1 parent 15358b8 commit dc308a9

3 files changed

Lines changed: 90 additions & 12 deletions

File tree

tests/test_type_eval.py

Lines changed: 66 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
GetArgs,
2828
GetAttr,
2929
GetName,
30+
GetSpecialAttr,
3031
GetType,
3132
GetAnnotations,
3233
IsSub,
@@ -40,7 +41,6 @@
4041
Slice,
4142
SpecialFormEllipsis,
4243
StrConcat,
43-
TypeName,
4444
Uppercase,
4545
_BoolLiteral,
4646
)
@@ -975,23 +975,82 @@ class Container2[T]: ...
975975
assert eval_typing(GetArg[t, Container, Literal[1]]) == Never
976976

977977

978+
class OuterType:
979+
class InnerType:
980+
pass
981+
982+
978983
def test_eval_typename_01():
979-
d = eval_typing(TypeName[int])
984+
d = eval_typing(GetSpecialAttr[int, Literal["__name__"]])
980985
assert d == Literal["int"]
981-
d = eval_typing(TypeName[str])
986+
d = eval_typing(GetSpecialAttr[str, Literal["__name__"]])
982987
assert d == Literal["str"]
983-
d = eval_typing(TypeName[list[int]])
988+
d = eval_typing(GetSpecialAttr[list[int], Literal["__name__"]])
984989
assert d == Literal["list"]
985-
d = eval_typing(TypeName[list[str]])
990+
d = eval_typing(GetSpecialAttr[list[str], Literal["__name__"]])
986991
assert d == Literal["list"]
987992

988993
class C:
989994
pass
990995

991-
d = eval_typing(TypeName[C])
996+
d = eval_typing(GetSpecialAttr[OuterType, Literal["__name__"]])
997+
assert d == Literal["OuterType"]
998+
d = eval_typing(GetSpecialAttr[OuterType.InnerType, Literal["__name__"]])
999+
assert d == Literal["InnerType"]
1000+
d = eval_typing(GetSpecialAttr[C, Literal["__name__"]])
9921001
assert d == Literal["C"]
9931002

994-
d = eval_typing(TypeName[GetA1[int, str]])
1003+
d = eval_typing(GetSpecialAttr[GetA1[int, str], Literal["__name__"]])
1004+
assert d == Literal["int"]
1005+
1006+
1007+
def test_eval_typename_02():
1008+
d = eval_typing(GetSpecialAttr[int, Literal["__module__"]])
1009+
assert d == Literal["builtins"]
1010+
d = eval_typing(GetSpecialAttr[str, Literal["__module__"]])
1011+
assert d == Literal["builtins"]
1012+
d = eval_typing(GetSpecialAttr[list[int], Literal["__module__"]])
1013+
assert d == Literal["builtins"]
1014+
d = eval_typing(GetSpecialAttr[list[str], Literal["__module__"]])
1015+
assert d == Literal["builtins"]
1016+
1017+
class C:
1018+
pass
1019+
1020+
d = eval_typing(GetSpecialAttr[OuterType, Literal["__module__"]])
1021+
assert d == Literal["tests.test_type_eval"]
1022+
d = eval_typing(GetSpecialAttr[OuterType.InnerType, Literal["__module__"]])
1023+
assert d == Literal["tests.test_type_eval"]
1024+
d = eval_typing(GetSpecialAttr[C, Literal["__module__"]])
1025+
assert d == Literal["tests.test_type_eval"]
1026+
1027+
d = eval_typing(GetSpecialAttr[GetA1[int, str], Literal["__module__"]])
1028+
assert d == Literal["builtins"]
1029+
1030+
1031+
def test_eval_typename_03():
1032+
d = eval_typing(GetSpecialAttr[int, Literal["__qualname__"]])
1033+
assert d == Literal["int"]
1034+
d = eval_typing(GetSpecialAttr[str, Literal["__qualname__"]])
1035+
assert d == Literal["str"]
1036+
d = eval_typing(GetSpecialAttr[list[int], Literal["__qualname__"]])
1037+
assert d == Literal["list"]
1038+
d = eval_typing(GetSpecialAttr[list[str], Literal["__qualname__"]])
1039+
assert d == Literal["list"]
1040+
1041+
class C:
1042+
pass
1043+
1044+
d = eval_typing(GetSpecialAttr[OuterType, Literal["__qualname__"]])
1045+
assert d == Literal["OuterType"]
1046+
d = eval_typing(
1047+
GetSpecialAttr[OuterType.InnerType, Literal["__qualname__"]]
1048+
)
1049+
assert d == Literal["OuterType.InnerType"]
1050+
d = eval_typing(GetSpecialAttr[C, Literal["__qualname__"]])
1051+
assert d == Literal["test_eval_typename_03.<locals>.C"]
1052+
1053+
d = eval_typing(GetSpecialAttr[GetA1[int, str], Literal["__qualname__"]])
9951054
assert d == Literal["int"]
9961055

9971056

typemap/type_eval/_eval_operators.py

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
GetArg,
2727
GetArgs,
2828
GetAttr,
29+
GetSpecialAttr,
2930
InitField,
3031
IsSubSimilar,
3132
IsSubtype,
@@ -40,7 +41,6 @@
4041
Slice,
4142
SpecialFormEllipsis,
4243
StrConcat,
43-
TypeName,
4444
Uncapitalize,
4545
Uppercase,
4646
_BoolLiteral,
@@ -907,10 +907,29 @@ def _eval_GetArgs(tp, base, *, ctx) -> typing.Any:
907907
return tuple[*args] # type: ignore[valid-type]
908908

909909

910-
@type_eval.register_evaluator(TypeName)
910+
@type_eval.register_evaluator(GetSpecialAttr)
911911
@_lift_over_unions
912-
def _eval_TypeName(tp, *, ctx) -> typing.Any:
913-
return typing.Literal[tp.__name__]
912+
def _eval_GetSpecialAttr(tp, attr, *, ctx) -> typing.Any:
913+
if not (
914+
_typing_inspect.is_generic_alias(attr)
915+
and attr.__origin__ is typing.Literal
916+
and isinstance(attr.__args__[0], str)
917+
):
918+
raise TypeError(
919+
f"Invalid type argument to GetSpecialAttr: "
920+
f"{attr} is not a string Literal"
921+
)
922+
if attr.__args__[0] == "__name__":
923+
return typing.Literal[tp.__name__]
924+
elif attr.__args__[0] == "__module__":
925+
return typing.Literal[tp.__module__]
926+
elif attr.__args__[0] == "__qualname__":
927+
return typing.Literal[tp.__qualname__]
928+
else:
929+
raise TypeError(
930+
f"Invalid type argument to GetSpecialAttr: "
931+
f"{attr} must be one of __name__, __module__, or __qualname__"
932+
)
914933

915934

916935
@type_eval.register_evaluator(GetAnnotations)

typemap/typing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ class GetArgs[Tp, Base]:
143143
pass
144144

145145

146-
class TypeName[T: type]:
146+
class GetSpecialAttr[T: type, Attr: str]:
147147
pass
148148

149149

0 commit comments

Comments
 (0)