mirror of
https://github.com/python/cpython
synced 2026-09-29 12:10:30 +03:00
bpo-46414: Add typing.reveal_type (#30646)
Co-authored-by: Nikita Sobolev <mail@sobolevn.me>
This commit is contained in:
parent
b1288964e3
commit
abcc3d75f6
4 changed files with 63 additions and 1 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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__."""
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
Add :func:`typing.reveal_type`. Patch by Jelle Zijlstra.
|
||||
Loading…
Add table
Add a link
Reference in a new issue