mirror of
https://github.com/python/cpython.git
synced 2025-08-04 08:59:19 +00:00
bpo-46475: Add typing.Never and typing.assert_never (GH-30842)
This commit is contained in:
parent
1e6214dbd6
commit
243436f377
4 changed files with 151 additions and 19 deletions
|
@ -5,7 +5,7 @@ At large scale, the structure of the module is following:
|
|||
* Imports and exports, all public names should be explicitly added to __all__.
|
||||
* Internal helper functions: these should never be used in code outside this module.
|
||||
* _SpecialForm and its instances (special forms):
|
||||
Any, NoReturn, ClassVar, Union, Optional, Concatenate
|
||||
Any, NoReturn, Never, ClassVar, Union, Optional, Concatenate
|
||||
* Classes whose instances can be type arguments in addition to types:
|
||||
ForwardRef, TypeVar and ParamSpec
|
||||
* The core of internal generics API: _GenericAlias and _VariadicGenericAlias, the latter is
|
||||
|
@ -117,12 +117,14 @@ __all__ = [
|
|||
|
||||
# One-off things.
|
||||
'AnyStr',
|
||||
'assert_never',
|
||||
'cast',
|
||||
'final',
|
||||
'get_args',
|
||||
'get_origin',
|
||||
'get_type_hints',
|
||||
'is_typeddict',
|
||||
'Never',
|
||||
'NewType',
|
||||
'no_type_check',
|
||||
'no_type_check_decorator',
|
||||
|
@ -175,7 +177,7 @@ def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms=
|
|||
if (isinstance(arg, _GenericAlias) and
|
||||
arg.__origin__ in invalid_generic_forms):
|
||||
raise TypeError(f"{arg} is not valid as type argument")
|
||||
if arg in (Any, NoReturn, Self, ClassVar, Final, TypeAlias):
|
||||
if arg in (Any, NoReturn, Never, Self, ClassVar, Final, TypeAlias):
|
||||
return arg
|
||||
if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol):
|
||||
raise TypeError(f"Plain {arg} is not valid as type argument")
|
||||
|
@ -441,8 +443,39 @@ def NoReturn(self, parameters):
|
|||
def stop() -> NoReturn:
|
||||
raise Exception('no way')
|
||||
|
||||
This type is invalid in other positions, e.g., ``List[NoReturn]``
|
||||
will fail in static type checkers.
|
||||
NoReturn can also be used as a bottom type, a type that
|
||||
has no values. Starting in Python 3.11, the Never type should
|
||||
be used for this concept instead. Type checkers should treat the two
|
||||
equivalently.
|
||||
|
||||
"""
|
||||
raise TypeError(f"{self} is not subscriptable")
|
||||
|
||||
# This is semantically identical to NoReturn, but it is implemented
|
||||
# separately so that type checkers can distinguish between the two
|
||||
# if they want.
|
||||
@_SpecialForm
|
||||
def Never(self, parameters):
|
||||
"""The bottom type, a type that has no members.
|
||||
|
||||
This can be used to define a function that should never be
|
||||
called, or a function that never returns::
|
||||
|
||||
from typing import Never
|
||||
|
||||
def never_call_me(arg: Never) -> None:
|
||||
pass
|
||||
|
||||
def int_or_str(arg: int | str) -> None:
|
||||
never_call_me(arg) # type checker error
|
||||
match arg:
|
||||
case int():
|
||||
print("It's an int")
|
||||
case str():
|
||||
print("It's a str")
|
||||
case _:
|
||||
never_call_me(arg) # ok, arg is of type Never
|
||||
|
||||
"""
|
||||
raise TypeError(f"{self} is not subscriptable")
|
||||
|
||||
|
@ -2060,6 +2093,29 @@ def is_typeddict(tp):
|
|||
return isinstance(tp, _TypedDictMeta)
|
||||
|
||||
|
||||
def assert_never(arg: Never, /) -> Never:
|
||||
"""Statically assert that a line of code is unreachable.
|
||||
|
||||
Example::
|
||||
|
||||
def int_or_str(arg: int | str) -> None:
|
||||
match arg:
|
||||
case int():
|
||||
print("It's an int")
|
||||
case str():
|
||||
print("It's a str")
|
||||
case _:
|
||||
assert_never(arg)
|
||||
|
||||
If a type checker finds that a call to assert_never() is
|
||||
reachable, it will emit an error.
|
||||
|
||||
At runtime, this throws an exception when called.
|
||||
|
||||
"""
|
||||
raise AssertionError("Expected code to be unreachable")
|
||||
|
||||
|
||||
def no_type_check(arg):
|
||||
"""Decorator to indicate that annotations are not type hints.
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue