summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJelle Zijlstra <jelle.zijlstra@gmail.com>2022-02-02 02:48:55 (GMT)
committerGitHub <noreply@github.com>2022-02-02 02:48:55 (GMT)
commitabcc3d75f6e570519cb37c62130a2295c6928bff (patch)
tree8298821cb060cd892de9354eb386ddcf89ae0379
parentb1288964e31069bdf81abe560c82874f6f620928 (diff)
downloadcpython-abcc3d75f6e570519cb37c62130a2295c6928bff.zip
cpython-abcc3d75f6e570519cb37c62130a2295c6928bff.tar.gz
cpython-abcc3d75f6e570519cb37c62130a2295c6928bff.tar.bz2
bpo-46414: Add typing.reveal_type (#30646)
Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
-rw-r--r--Doc/library/typing.rst31
-rw-r--r--Lib/test/test_typing.py11
-rw-r--r--Lib/typing.py21
-rw-r--r--Misc/NEWS.d/next/Library/2022-01-17-10-00-02.bpo-46414.Ld0b_y.rst1
4 files changed, 63 insertions, 1 deletions
diff --git a/Doc/library/typing.rst b/Doc/library/typing.rst
index cdfd403..9007c0d 100644
--- a/Doc/library/typing.rst
+++ b/Doc/library/typing.rst
@@ -1932,6 +1932,37 @@ Functions and decorators
runtime we intentionally don't check anything (we want this
to be as fast as possible).
+.. function:: reveal_type(obj)
+
+ Reveal the inferred static type of an expression.
+
+ When a static type checker encounters a call to this function,
+ it emits a diagnostic with the type of the argument. For example::
+
+ x: int = 1
+ reveal_type(x) # Revealed type is "builtins.int"
+
+ This can be useful when you want to debug how your type checker
+ handles a particular piece of code.
+
+ The function returns its argument unchanged, which allows using
+ it within an expression::
+
+ x = reveal_type(1) # Revealed type is "builtins.int"
+
+ Most type checkers support ``reveal_type()`` anywhere, even if the
+ name is not imported from ``typing``. Importing the name from
+ ``typing`` allows your code to run without runtime errors and
+ communicates intent more clearly.
+
+ At runtime, this function prints the runtime type of its argument to stderr
+ and returns it unchanged::
+
+ x = reveal_type(1) # prints "Runtime type is int"
+ print(x) # prints "1"
+
+ .. versionadded:: 3.11
+
.. decorator:: overload
The ``@overload`` decorator allows describing functions and methods
diff --git a/Lib/test/test_typing.py b/Lib/test/test_typing.py
index 090d4c7..85f7406 100644
--- a/Lib/test/test_typing.py
+++ b/Lib/test/test_typing.py
@@ -20,6 +20,7 @@ from typing import cast, runtime_checkable
from typing import get_type_hints
from typing import get_origin, get_args
from typing import is_typeddict
+from typing import reveal_type
from typing import no_type_check, no_type_check_decorator
from typing import Type
from typing import NamedTuple, TypedDict
@@ -34,7 +35,7 @@ import typing
import weakref
import types
-from test.support import import_helper
+from test.support import import_helper, captured_stderr
from test import mod_generics_cache
from test import _typed_dict_helper
@@ -5289,6 +5290,14 @@ class SpecialAttrsTests(BaseTestCase):
self.assertIn('baz', dir(Foo[int]))
+class RevealTypeTests(BaseTestCase):
+ def test_reveal_type(self):
+ obj = object()
+ with captured_stderr() as stderr:
+ self.assertIs(obj, reveal_type(obj))
+ self.assertEqual(stderr.getvalue(), "Runtime type is 'object'\n")
+
+
class AllTests(BaseTestCase):
"""Tests for __all__."""
diff --git a/Lib/typing.py b/Lib/typing.py
index dac9c6c..0cf9755 100644
--- a/Lib/typing.py
+++ b/Lib/typing.py
@@ -130,6 +130,7 @@ __all__ = [
'overload',
'ParamSpecArgs',
'ParamSpecKwargs',
+ 'reveal_type',
'runtime_checkable',
'Text',
'TYPE_CHECKING',
@@ -2675,3 +2676,23 @@ class re(metaclass=_DeprecatedType):
re.__name__ = __name__ + '.re'
sys.modules[re.__name__] = re
+
+
+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
diff --git a/Misc/NEWS.d/next/Library/2022-01-17-10-00-02.bpo-46414.Ld0b_y.rst b/Misc/NEWS.d/next/Library/2022-01-17-10-00-02.bpo-46414.Ld0b_y.rst
new file mode 100644
index 0000000..0fdbfa7
--- /dev/null
+++ b/Misc/NEWS.d/next/Library/2022-01-17-10-00-02.bpo-46414.Ld0b_y.rst
@@ -0,0 +1 @@
+Add :func:`typing.reveal_type`. Patch by Jelle Zijlstra.