Skip to content

Commit db20497

Browse files
Add assert_type (#1103)
1 parent 07fb800 commit db20497

File tree

4 files changed

+40
-2
lines changed

4 files changed

+40
-2
lines changed

typing_extensions/CHANGELOG

+1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
# Unreleased
22

3+
- Add `typing.assert_type`. Backport from bpo-46480.
34
- Drop support for Python 3.6. Original patch by Adam Turner (@AA-Turner).
45

56
# Release 4.1.1 (February 13, 2022)

typing_extensions/README.rst

+1
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ This module currently contains the following:
4646
- In ``typing`` since Python 3.11
4747

4848
- ``assert_never``
49+
- ``assert_type``
4950
- ``LiteralString`` (see PEP 675)
5051
- ``Never``
5152
- ``NotRequired`` (see PEP 655)

typing_extensions/src/test_typing_extensions.py

+17-2
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
from unittest import TestCase, main, skipUnless, skipIf
1313
from test import ann_module, ann_module2, ann_module3
1414
import typing
15-
from typing import TypeVar, Optional, Union, Any
15+
from typing import TypeVar, Optional, Union, Any, AnyStr
1616
from typing import T, KT, VT # Not in __all__.
1717
from typing import Tuple, List, Dict, Iterable, Iterator, Callable
1818
from typing import Generic, NamedTuple
@@ -23,7 +23,7 @@
2323
from typing_extensions import Awaitable, AsyncIterator, AsyncContextManager, Required, NotRequired
2424
from typing_extensions import Protocol, runtime, runtime_checkable, Annotated, overload, final, is_typeddict
2525
from typing_extensions import TypeVarTuple, Unpack, dataclass_transform, reveal_type, Never, assert_never, LiteralString
26-
from typing_extensions import get_type_hints, get_origin, get_args
26+
from typing_extensions import assert_type, get_type_hints, get_origin, get_args
2727

2828
# Flags used to mark tests that only apply after a specific
2929
# version of the typing module.
@@ -425,6 +425,21 @@ def blah():
425425
blah()
426426

427427

428+
class AssertTypeTests(BaseTestCase):
429+
430+
def test_basics(self):
431+
arg = 42
432+
self.assertIs(assert_type(arg, int), arg)
433+
self.assertIs(assert_type(arg, Union[str, float]), arg)
434+
self.assertIs(assert_type(arg, AnyStr), arg)
435+
self.assertIs(assert_type(arg, None), arg)
436+
437+
def test_errors(self):
438+
# Bogus calls are not expected to fail.
439+
arg = 42
440+
self.assertIs(assert_type(arg, 42), arg)
441+
self.assertIs(assert_type(arg, 'hello'), arg)
442+
428443

429444
T_a = TypeVar('T_a')
430445

typing_extensions/src/typing_extensions.py

+21
Original file line numberDiff line numberDiff line change
@@ -717,6 +717,27 @@ class Film(TypedDict):
717717
"""
718718
return isinstance(tp, tuple(_TYPEDDICT_TYPES))
719719

720+
721+
if hasattr(typing, "assert_type"):
722+
assert_type = typing.assert_type
723+
724+
else:
725+
def assert_type(__val, __typ):
726+
"""Assert (to the type checker) that the value is of the given type.
727+
728+
When the type checker encounters a call to assert_type(), it
729+
emits an error if the value is not of the specified type::
730+
731+
def greet(name: str) -> None:
732+
assert_type(name, str) # ok
733+
assert_type(name, int) # type checker error
734+
735+
At runtime this returns the first argument unchanged and otherwise
736+
does nothing.
737+
"""
738+
return __val
739+
740+
720741
if hasattr(typing, "Required"):
721742
get_type_hints = typing.get_type_hints
722743
else:

0 commit comments

Comments
 (0)