From bdda22a93a9280e50fe3b7a639edb515ef98a7dd Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 2 Feb 2022 21:53:23 -0800 Subject: [PATCH] add support for typing.reveal_type --- mypy/semanal.py | 4 ++-- mypy/types.py | 6 ++++++ test-data/unit/check-expressions.test | 16 ++++++++++++++++ test-data/unit/lib-stub/typing.pyi | 2 ++ test-data/unit/lib-stub/typing_extensions.pyi | 2 ++ 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/mypy/semanal.py b/mypy/semanal.py index 2d7c4c7e3d4c..876866963e6b 100644 --- a/mypy/semanal.py +++ b/mypy/semanal.py @@ -98,7 +98,7 @@ CallableType, Overloaded, Instance, Type, AnyType, LiteralType, LiteralValue, TypeTranslator, TypeOfAny, TypeType, NoneType, PlaceholderType, TPDICT_NAMES, ProperType, get_proper_type, get_proper_types, TypeAliasType, TypeVarLikeType, - PROTOCOL_NAMES, TYPE_ALIAS_NAMES, FINAL_TYPE_NAMES, FINAL_DECORATOR_NAMES, + PROTOCOL_NAMES, TYPE_ALIAS_NAMES, FINAL_TYPE_NAMES, FINAL_DECORATOR_NAMES, REVEAL_TYPE_NAMES, is_named_instance, ) from mypy.typeops import function_type, get_type_vars @@ -3877,7 +3877,7 @@ def visit_call_expr(self, expr: CallExpr) -> None: expr.analyzed.line = expr.line expr.analyzed.column = expr.column expr.analyzed.accept(self) - elif refers_to_fullname(expr.callee, 'builtins.reveal_type'): + elif refers_to_fullname(expr.callee, REVEAL_TYPE_NAMES): if not self.check_fixed_args(expr, 1, 'reveal_type'): return expr.analyzed = RevealExpr(kind=REVEAL_TYPE, expr=expr.args[0]) diff --git a/mypy/types.py b/mypy/types.py index 1d7ab669a2d4..5aecb8194f9e 100644 --- a/mypy/types.py +++ b/mypy/types.py @@ -126,6 +126,12 @@ 'typing.Reversible', ) +REVEAL_TYPE_NAMES: Final = ( + 'builtins.reveal_type', + 'typing.reveal_type', + 'typing_extensions.reveal_type', +) + # A placeholder used for Bogus[...] parameters _dummy: Final[Any] = object() diff --git a/test-data/unit/check-expressions.test b/test-data/unit/check-expressions.test index a275de94c9be..543502e65115 100644 --- a/test-data/unit/check-expressions.test +++ b/test-data/unit/check-expressions.test @@ -1688,6 +1688,22 @@ main:1: note: Revealed type is "Any" def reveal_type(x: int) -> None: pass reveal_type("foo") # E: Argument 1 to "reveal_type" has incompatible type "str"; expected "int" +[case testTypingRevealType] +from typing import reveal_type +from typing import reveal_type as show_me_the_type + +reveal_type(1) # N: Revealed type is "Literal[1]?" +show_me_the_type(1) # N: Revealed type is "Literal[1]?" + +[case testTypingExtensionsRevealType] +from typing_extensions import reveal_type +from typing_extensions import reveal_type as show_me_the_type + +reveal_type(1) # N: Revealed type is "Literal[1]?" +show_me_the_type(1) # N: Revealed type is "Literal[1]?" + +[builtins fixtures/tuple.pyi] + [case testRevealTypeVar] reveal_type = 1 1 + "foo" # E: Unsupported operand types for + ("int" and "str") diff --git a/test-data/unit/lib-stub/typing.pyi b/test-data/unit/lib-stub/typing.pyi index b9f1752aee1b..7283b47a96e7 100644 --- a/test-data/unit/lib-stub/typing.pyi +++ b/test-data/unit/lib-stub/typing.pyi @@ -47,3 +47,5 @@ class Sequence(Iterable[T_co]): class Mapping(Iterable[T], Generic[T, T_co]): pass def final(meth: T) -> T: pass + +def reveal_type(__obj: T) -> T: pass diff --git a/test-data/unit/lib-stub/typing_extensions.pyi b/test-data/unit/lib-stub/typing_extensions.pyi index 5b32449e71cf..7c6e14e404cd 100644 --- a/test-data/unit/lib-stub/typing_extensions.pyi +++ b/test-data/unit/lib-stub/typing_extensions.pyi @@ -44,3 +44,5 @@ class _TypedDict(Mapping[str, object]): def __delitem__(self, k: NoReturn) -> None: ... def TypedDict(typename: str, fields: Dict[str, Type[_T]], *, total: Any = ...) -> Type[dict]: ... + +def reveal_type(__obj: T) -> T: pass