From 8d98960bedf8b062be11ea96a5de37236975a5e6 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 2 Feb 2022 20:17:48 -0800 Subject: [PATCH 1/2] add reveal_type --- typing_extensions/CHANGELOG | 1 + typing_extensions/README.rst | 4 ++++ .../src/test_typing_extensions.py | 7 ++++++ typing_extensions/src/typing_extensions.py | 23 +++++++++++++++++++ 4 files changed, 35 insertions(+) diff --git a/typing_extensions/CHANGELOG b/typing_extensions/CHANGELOG index 026ba598..6af2879b 100644 --- a/typing_extensions/CHANGELOG +++ b/typing_extensions/CHANGELOG @@ -1,5 +1,6 @@ # Release 4.x.x +- Add `reveal_type`. Backport from bpo-46414. - `Annotated` can now wrap `ClassVar` and `Final`. Backport from bpo-46491. Patch by Gregory Beauregard (@GBeauregard). - Add missed `Required` and `NotRequired` to `__all__`. Patch by diff --git a/typing_extensions/README.rst b/typing_extensions/README.rst index d5d4128f..18c09f97 100644 --- a/typing_extensions/README.rst +++ b/typing_extensions/README.rst @@ -39,6 +39,10 @@ This module currently contains the following: - ``NotRequired`` (see PEP 655) - ``Required`` (see PEP 655) + +- In ``typing`` since Python 3.11 + + - ``reveal_type`` - ``Self`` (see PEP 673) - In ``typing`` since Python 3.10 diff --git a/typing_extensions/src/test_typing_extensions.py b/typing_extensions/src/test_typing_extensions.py index f92bb135..670a1c7f 100644 --- a/typing_extensions/src/test_typing_extensions.py +++ b/typing_extensions/src/test_typing_extensions.py @@ -22,6 +22,7 @@ from typing_extensions import TypeAlias, ParamSpec, Concatenate, ParamSpecArgs, ParamSpecKwargs, TypeGuard from typing_extensions import Awaitable, AsyncIterator, AsyncContextManager, Required, NotRequired from typing_extensions import Protocol, runtime, runtime_checkable, Annotated, overload, final, is_typeddict +from typing_extensions import reveal_type try: from typing_extensions import get_type_hints except ImportError: @@ -2345,6 +2346,12 @@ def cached(self): ... self.assertIs(True, Methods.cached.__final__) +class RevealTypeTests(BaseTestCase): + def test_reveal_type(self): + obj = object() + self.assertIs(obj, reveal_type(obj)) + + class AllTests(BaseTestCase): def test_typing_extensions_includes_standard(self): diff --git a/typing_extensions/src/typing_extensions.py b/typing_extensions/src/typing_extensions.py index dab53d43..bd5197b3 100644 --- a/typing_extensions/src/typing_extensions.py +++ b/typing_extensions/src/typing_extensions.py @@ -77,6 +77,7 @@ def _check_generic(cls, parameters): 'NewType', 'overload', 'Protocol', + 'reveal_type', 'runtime', 'runtime_checkable', 'Text', @@ -2341,3 +2342,25 @@ class Movie(TypedDict): Required = _Required(_root=True) NotRequired = _NotRequired(_root=True) + +if hasattr(typing, "reveal_type"): + reveal_type = typing.reveal_type +else: + def reveal_type(obj: T, /) -> T: + """Reveal the inferred type of a variable. + + When a static type checker encounters a call to ``reveal_type()``, + it will emit the inferred type of the argument:: + + x: int = 1 + reveal_type(x) + + Running a static type checker (e.g., ``mypy``) on this example + will produce output similar to 'Revealed type is "builtins.int"'. + + At runtime, the function prints the runtime type of the + argument and returns it unchanged. + + """ + print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr) + return obj From 53d17885dd7af7856962dbe23232dd018831bf91 Mon Sep 17 00:00:00 2001 From: Jelle Zijlstra Date: Wed, 2 Feb 2022 20:24:20 -0800 Subject: [PATCH 2/2] fix pos-only arg --- typing_extensions/src/typing_extensions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/typing_extensions/src/typing_extensions.py b/typing_extensions/src/typing_extensions.py index 8480d9c9..b594e33f 100644 --- a/typing_extensions/src/typing_extensions.py +++ b/typing_extensions/src/typing_extensions.py @@ -2347,7 +2347,7 @@ class Movie(TypedDict): if hasattr(typing, "reveal_type"): reveal_type = typing.reveal_type else: - def reveal_type(obj: T, /) -> T: + def reveal_type(__obj: T) -> T: """Reveal the inferred type of a variable. When a static type checker encounters a call to ``reveal_type()``, @@ -2363,8 +2363,8 @@ def reveal_type(obj: T, /) -> T: argument and returns it unchanged. """ - print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr) - return obj + print(f"Runtime type is {type(__obj).__name__!r}", file=sys.stderr) + return __obj if hasattr(typing, 'dataclass_transform'):