codekingpro/portable-devtools
114k
1"""2The typing module: Support for gradual typing as defined by PEP 484 and subsequent PEPs.3 4Among other things, the module includes the following:5* Generic, Protocol, and internal machinery to support generic aliases.6 All subscripted types like X[int], Union[int, str] are generic aliases.7* Various "special forms" that have unique meanings in type annotations:8 NoReturn, Never, ClassVar, Self, Concatenate, Unpack, and others.9* Classes whose instances can be type arguments to generic classes and functions:10 TypeVar, ParamSpec, TypeVarTuple.11* Public helper functions: get_type_hints, overload, cast, final, and others.12* Several protocols to support duck-typing:13 SupportsFloat, SupportsIndex, SupportsAbs, and others.14* Special types: NewType, NamedTuple, TypedDict.15* Deprecated aliases for builtin types and collections.abc ABCs.16 17Any name not present in __all__ is an implementation detail18that may be changed without notice. Use at your own risk!19"""20 21from abc import abstractmethod, ABCMeta22import collections23from collections import defaultdict24import collections.abc25import copyreg26import functools27import operator28import sys29import types30from types import GenericAlias31 32from _typing import (33 _idfunc,34 TypeVar,35 ParamSpec,36 TypeVarTuple,37 ParamSpecArgs,38 ParamSpecKwargs,39 TypeAliasType,40 Generic,41 Union,42 NoDefault,43)44 45# Please keep __all__ alphabetized within each category.46__all__ = [47 # Super-special typing primitives.48 'Annotated',49 'Any',50 'Callable',51 'ClassVar',52 'Concatenate',53 'Final',54 'ForwardRef',55 'Generic',56 'Literal',57 'Optional',58 'ParamSpec',59 'Protocol',60 'Tuple',61 'Type',62 'TypeVar',63 'TypeVarTuple',64 'Union',65 66 # ABCs (from collections.abc).67 'AbstractSet', # collections.abc.Set.68 'ByteString',69 'Container',70 'ContextManager',71 'Hashable',72 'ItemsView',73 'Iterable',74 'Iterator',75 'KeysView',76 'Mapping',77 'MappingView',78 'MutableMapping',79 'MutableSequence',80 'MutableSet',81 'Sequence',82 'Sized',83 'ValuesView',84 'Awaitable',85 'AsyncIterator',86 'AsyncIterable',87 'Coroutine',88 'Collection',89 'AsyncGenerator',90 'AsyncContextManager',91 92 # Structural checks, a.k.a. protocols.93 'Reversible',94 'SupportsAbs',95 'SupportsBytes',96 'SupportsComplex',97 'SupportsFloat',98 'SupportsIndex',99 'SupportsInt',100 'SupportsRound',101 102 # Concrete collection types.103 'ChainMap',104 'Counter',105 'Deque',106 'Dict',107 'DefaultDict',108 'List',109 'OrderedDict',110 'Set',111 'FrozenSet',112 'NamedTuple', # Not really a type.113 'TypedDict', # Not really a type.114 'Generator',115 116 # Other concrete types.117 'BinaryIO',118 'IO',119 'Match',120 'Pattern',121 'TextIO',122 123 # One-off things.124 'AnyStr',125 'assert_type',126 'assert_never',127 'cast',128 'clear_overloads',129 'dataclass_transform',130 'evaluate_forward_ref',131 'final',132 'get_args',133 'get_origin',134 'get_overloads',135 'get_protocol_members',136 'get_type_hints',137 'is_protocol',138 'is_typeddict',139 'LiteralString',140 'Never',141 'NewType',142 'no_type_check',143 'no_type_check_decorator',144 'NoDefault',145 'NoReturn',146 'NotRequired',147 'overload',148 'override',149 'ParamSpecArgs',150 'ParamSpecKwargs',151 'ReadOnly',152 'Required',153 'reveal_type',154 'runtime_checkable',155 'Self',156 'Text',157 'TYPE_CHECKING',158 'TypeAlias',159 'TypeGuard',160 'TypeIs',161 'TypeAliasType',162 'Unpack',163]164 165class _LazyAnnotationLib:166 def __getattr__(self, attr):167 global _lazy_annotationlib168 import annotationlib169 _lazy_annotationlib = annotationlib170 return getattr(annotationlib, attr)171 172_lazy_annotationlib = _LazyAnnotationLib()173 174 175def _type_convert(arg, module=None, *, allow_special_forms=False, owner=None):176 """For converting None to type(None), and strings to ForwardRef."""177 if arg is None:178 return type(None)179 if isinstance(arg, str):180 return _make_forward_ref(arg, module=module, is_class=allow_special_forms, owner=owner)181 return arg182 183 184def _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms=False, owner=None):185 """Check that the argument is a type, and return it (internal helper).186 187 As a special case, accept None and return type(None) instead. Also wrap strings188 into ForwardRef instances. Consider several corner cases, for example plain189 special forms like Union are not valid, while Union[int, str] is OK, etc.190 The msg argument is a human-readable error message, e.g.::191 192 "Union[arg, ...]: arg should be a type."193 194 We append the repr() of the actual value (truncated to 100 chars).195 """196 invalid_generic_forms = (Generic, Protocol)197 if not allow_special_forms:198 invalid_generic_forms += (ClassVar,)199 if is_argument:200 invalid_generic_forms += (Final,)201 202 arg = _type_convert(arg, module=module, allow_special_forms=allow_special_forms, owner=owner)203 if (isinstance(arg, _GenericAlias) and204 arg.__origin__ in invalid_generic_forms):205 raise TypeError(f"{arg} is not valid as type argument")206 if arg in (Any, LiteralString, NoReturn, Never, Self, TypeAlias):207 return arg208 if allow_special_forms and arg in (ClassVar, Final):209 return arg210 if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol):211 raise TypeError(f"Plain {arg} is not valid as type argument")212 if type(arg) is tuple:213 raise TypeError(f"{msg} Got {arg!r:.100}.")214 return arg215 216 217def _is_param_expr(arg):218 return arg is ... or isinstance(arg,219 (tuple, list, ParamSpec, _ConcatenateGenericAlias))220 221 222def _should_unflatten_callable_args(typ, args):223 """Internal helper for munging collections.abc.Callable's __args__.224 225 The canonical representation for a Callable's __args__ flattens the226 argument types, see https://github.com/python/cpython/issues/86361.227 228 For example::229 230 >>> import collections.abc231 >>> P = ParamSpec('P')232 >>> collections.abc.Callable[[int, int], str].__args__ == (int, int, str)233 True234 >>> collections.abc.Callable[P, str].__args__ == (P, str)235 True236 237 As a result, if we need to reconstruct the Callable from its __args__,238 we need to unflatten it.239 """240 return (241 typ.__origin__ is collections.abc.Callable242 and not (len(args) == 2 and _is_param_expr(args[0]))243 )244 245 246def _type_repr(obj):247 """Return the repr() of an object, special-casing types (internal helper).248 249 If obj is a type, we return a shorter version than the default250 type.__repr__, based on the module and qualified name, which is251 typically enough to uniquely identify a type. For everything252 else, we fall back on repr(obj).253 """254 if isinstance(obj, tuple):255 # Special case for `repr` of types with `ParamSpec`:256 return '[' + ', '.join(_type_repr(t) for t in obj) + ']'257 return _lazy_annotationlib.type_repr(obj)258 259 260def _collect_type_parameters(args, *, enforce_default_ordering: bool = True):261 """Collect all type parameters in args262 in order of first appearance (lexicographic order).263 264 For example::265 266 >>> P = ParamSpec('P')267 >>> T = TypeVar('T')268 >>> _collect_type_parameters((T, Callable[P, T]))269 (~T, ~P)270 """271 # required type parameter cannot appear after parameter with default272 default_encountered = False273 # or after TypeVarTuple274 type_var_tuple_encountered = False275 parameters = []276 for t in args:277 if isinstance(t, type):278 # We don't want __parameters__ descriptor of a bare Python class.279 pass280 elif isinstance(t, tuple):281 # `t` might be a tuple, when `ParamSpec` is substituted with282 # `[T, int]`, or `[int, *Ts]`, etc.283 for x in t:284 for collected in _collect_type_parameters([x]):285 if collected not in parameters:286 parameters.append(collected)287 elif hasattr(t, '__typing_subst__'):288 if t not in parameters:289 if enforce_default_ordering:290 if type_var_tuple_encountered and t.has_default():291 raise TypeError('Type parameter with a default'292 ' follows TypeVarTuple')293 294 if t.has_default():295 default_encountered = True296 elif default_encountered:297 raise TypeError(f'Type parameter {t!r} without a default'298 ' follows type parameter with a default')299 300 parameters.append(t)301 else:302 if _is_unpacked_typevartuple(t):303 type_var_tuple_encountered = True304 for x in getattr(t, '__parameters__', ()):305 if x not in parameters:306 parameters.append(x)307 return tuple(parameters)308 309 310def _check_generic_specialization(cls, arguments):311 """Check correct count for parameters of a generic cls (internal helper).312 313 This gives a nice error message in case of count mismatch.314 """315 expected_len = len(cls.__parameters__)316 if not expected_len:317 raise TypeError(f"{cls} is not a generic class")318 actual_len = len(arguments)319 if actual_len != expected_len:320 # deal with defaults321 if actual_len < expected_len:322 # If the parameter at index `actual_len` in the parameters list323 # has a default, then all parameters after it must also have324 # one, because we validated as much in _collect_type_parameters().325 # That means that no error needs to be raised here, despite326 # the number of arguments being passed not matching the number327 # of parameters: all parameters that aren't explicitly328 # specialized in this call are parameters with default values.329 if cls.__parameters__[actual_len].has_default():330 return331 332 expected_len -= sum(p.has_default() for p in cls.__parameters__)333 expect_val = f"at least {expected_len}"334 else:335 expect_val = expected_len336 337 raise TypeError(f"Too {'many' if actual_len > expected_len else 'few'} arguments"338 f" for {cls}; actual {actual_len}, expected {expect_val}")339 340 341def _unpack_args(*args):342 newargs = []343 for arg in args:344 subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)345 if subargs is not None and not (subargs and subargs[-1] is ...):346 newargs.extend(subargs)347 else:348 newargs.append(arg)349 return newargs350 351def _deduplicate(params, *, unhashable_fallback=False):352 # Weed out strict duplicates, preserving the first of each occurrence.353 try:354 return dict.fromkeys(params)355 except TypeError:356 if not unhashable_fallback:357 raise358 # Happens for cases like `Annotated[dict, {'x': IntValidator()}]`359 new_unhashable = []360 for t in params:361 if t not in new_unhashable:362 new_unhashable.append(t)363 return new_unhashable364 365def _flatten_literal_params(parameters):366 """Internal helper for Literal creation: flatten Literals among parameters."""367 params = []368 for p in parameters:369 if isinstance(p, _LiteralGenericAlias):370 params.extend(p.__args__)371 else:372 params.append(p)373 return tuple(params)374 375 376_cleanups = []377_caches = {}378 379 380def _tp_cache(func=None, /, *, typed=False):381 """Internal wrapper caching __getitem__ of generic types.382 383 For non-hashable arguments, the original function is used as a fallback.384 """385 def decorator(func):386 # The callback 'inner' references the newly created lru_cache387 # indirectly by performing a lookup in the global '_caches' dictionary.388 # This breaks a reference that can be problematic when combined with389 # C API extensions that leak references to types. See GH-98253.390 391 cache = functools.lru_cache(typed=typed)(func)392 _caches[func] = cache393 _cleanups.append(cache.cache_clear)394 del cache395 396 @functools.wraps(func)397 def inner(*args, **kwds):398 try:399 return _caches[func](*args, **kwds)400 except TypeError:401 pass # All real errors (not unhashable args) are raised below.402 return func(*args, **kwds)403 return inner404 405 if func is not None:406 return decorator(func)407 408 return decorator409 410 411def _deprecation_warning_for_no_type_params_passed(funcname: str) -> None:412 import warnings413 414 depr_message = (415 f"Failing to pass a value to the 'type_params' parameter "416 f"of {funcname!r} is deprecated, as it leads to incorrect behaviour "417 f"when calling {funcname} on a stringified annotation "418 f"that references a PEP 695 type parameter. "419 f"It will be disallowed in Python 3.15."420 )421 warnings.warn(depr_message, category=DeprecationWarning, stacklevel=3)422 423 424class _Sentinel:425 __slots__ = ()426 def __repr__(self):427 return '<sentinel>'428 429 430_sentinel = _Sentinel()431 432 433def _eval_type(t, globalns, localns, type_params=_sentinel, *, recursive_guard=frozenset(),434 format=None, owner=None, parent_fwdref=None, prefer_fwd_module=False):435 """Evaluate all forward references in the given type t.436 437 For use of globalns and localns see the docstring for get_type_hints().438 recursive_guard is used to prevent infinite recursion with a recursive439 ForwardRef.440 """441 if type_params is _sentinel:442 _deprecation_warning_for_no_type_params_passed("typing._eval_type")443 type_params = ()444 if isinstance(t, _lazy_annotationlib.ForwardRef):445 # If the forward_ref has __forward_module__ set, evaluate() infers the globals446 # from the module, and it will probably pick better than the globals we have here.447 # We do this only for calls from get_type_hints() (which opts in through the448 # prefer_fwd_module flag), so that the default behavior remains more straightforward.449 if prefer_fwd_module and t.__forward_module__ is not None:450 globalns = None451 # If there are type params on the owner, we need to add them back, because452 # annotationlib won't.453 if owner_type_params := getattr(owner, "__type_params__", None):454 globalns = getattr(455 sys.modules.get(t.__forward_module__, None), "__dict__", None456 )457 if globalns is not None:458 globalns = dict(globalns)459 for type_param in owner_type_params:460 globalns[type_param.__name__] = type_param461 return evaluate_forward_ref(t, globals=globalns, locals=localns,462 type_params=type_params, owner=owner,463 _recursive_guard=recursive_guard, format=format)464 if isinstance(t, (_GenericAlias, GenericAlias, Union)):465 if isinstance(t, GenericAlias):466 args = tuple(467 _make_forward_ref(arg, parent_fwdref=parent_fwdref) if isinstance(arg, str) else arg468 for arg in t.__args__469 )470 is_unpacked = t.__unpacked__471 if _should_unflatten_callable_args(t, args):472 t = t.__origin__[(args[:-1], args[-1])]473 else:474 t = t.__origin__[args]475 if is_unpacked:476 t = Unpack[t]477 478 ev_args = tuple(479 _eval_type(480 a, globalns, localns, type_params, recursive_guard=recursive_guard,481 format=format, owner=owner, prefer_fwd_module=prefer_fwd_module,482 )483 for a in t.__args__484 )485 if ev_args == t.__args__:486 return t487 if isinstance(t, GenericAlias):488 return GenericAlias(t.__origin__, ev_args)489 if isinstance(t, Union):490 return functools.reduce(operator.or_, ev_args)491 else:492 return t.copy_with(ev_args)493 return t494 495 496class _Final:497 """Mixin to prohibit subclassing."""498 499 __slots__ = ('__weakref__',)500 501 def __init_subclass__(cls, /, *args, **kwds):502 if '_root' not in kwds:503 raise TypeError("Cannot subclass special typing classes")504 505 506class _NotIterable:507 """Mixin to prevent iteration, without being compatible with Iterable.508 509 That is, we could do::510 511 def __iter__(self): raise TypeError()512 513 But this would make users of this mixin duck type-compatible with514 collections.abc.Iterable - isinstance(foo, Iterable) would be True.515 516 Luckily, we can instead prevent iteration by setting __iter__ to None, which517 is treated specially.518 """519 520 __slots__ = ()521 __iter__ = None522 523 524# Internal indicator of special typing constructs.525# See __doc__ instance attribute for specific docs.526class _SpecialForm(_Final, _NotIterable, _root=True):527 __slots__ = ('_name', '__doc__', '_getitem')528 529 def __init__(self, getitem):530 self._getitem = getitem531 self._name = getitem.__name__532 self.__doc__ = getitem.__doc__533 534 def __getattr__(self, item):535 if item in {'__name__', '__qualname__'}:536 return self._name537 538 raise AttributeError(item)539 540 def __mro_entries__(self, bases):541 raise TypeError(f"Cannot subclass {self!r}")542 543 def __repr__(self):544 return 'typing.' + self._name545 546 def __reduce__(self):547 return self._name548 549 def __call__(self, *args, **kwds):550 raise TypeError(f"Cannot instantiate {self!r}")551 552 def __or__(self, other):553 return Union[self, other]554 555 def __ror__(self, other):556 return Union[other, self]557 558 def __instancecheck__(self, obj):559 raise TypeError(f"{self} cannot be used with isinstance()")560 561 def __subclasscheck__(self, cls):562 raise TypeError(f"{self} cannot be used with issubclass()")563 564 @_tp_cache565 def __getitem__(self, parameters):566 return self._getitem(self, parameters)567 568 569class _TypedCacheSpecialForm(_SpecialForm, _root=True):570 def __getitem__(self, parameters):571 if not isinstance(parameters, tuple):572 parameters = (parameters,)573 return self._getitem(self, *parameters)574 575 576class _AnyMeta(type):577 def __instancecheck__(self, obj):578 if self is Any:579 raise TypeError("typing.Any cannot be used with isinstance()")580 return super().__instancecheck__(obj)581 582 def __repr__(self):583 if self is Any:584 return "typing.Any"585 return super().__repr__() # respect to subclasses586 587 588class Any(metaclass=_AnyMeta):589 """Special type indicating an unconstrained type.590 591 - Any is compatible with every type.592 - Any assumed to have all methods.593 - All values assumed to be instances of Any.594 595 Note that all the above statements are true from the point of view of596 static type checkers. At runtime, Any should not be used with instance597 checks.598 """599 600 def __new__(cls, *args, **kwargs):601 if cls is Any:602 raise TypeError("Any cannot be instantiated")603 return super().__new__(cls)604 605 606@_SpecialForm607def NoReturn(self, parameters):608 """Special type indicating functions that never return.609 610 Example::611 612 from typing import NoReturn613 614 def stop() -> NoReturn:615 raise Exception('no way')616 617 NoReturn can also be used as a bottom type, a type that618 has no values. Starting in Python 3.11, the Never type should619 be used for this concept instead. Type checkers should treat the two620 equivalently.621 """622 raise TypeError(f"{self} is not subscriptable")623 624# This is semantically identical to NoReturn, but it is implemented625# separately so that type checkers can distinguish between the two626# if they want.627@_SpecialForm628def Never(self, parameters):629 """The bottom type, a type that has no members.630 631 This can be used to define a function that should never be632 called, or a function that never returns::633 634 from typing import Never635 636 def never_call_me(arg: Never) -> None:637 pass638 639 def int_or_str(arg: int | str) -> None:640 never_call_me(arg) # type checker error641 match arg:642 case int():643 print("It's an int")644 case str():645 print("It's a str")646 case _:647 never_call_me(arg) # OK, arg is of type Never648 """649 raise TypeError(f"{self} is not subscriptable")650 651 652@_SpecialForm653def Self(self, parameters):654 """Used to spell the type of "self" in classes.655 656 Example::657 658 from typing import Self659 660 class Foo:661 def return_self(self) -> Self:662 ...663 return self664 665 This is especially useful for:666 - classmethods that are used as alternative constructors667 - annotating an `__enter__` method which returns self668 """669 raise TypeError(f"{self} is not subscriptable")670 671 672@_SpecialForm673def LiteralString(self, parameters):674 """Represents an arbitrary literal string.675 676 Example::677 678 from typing import LiteralString679 680 def run_query(sql: LiteralString) -> None:681 ...682 683 def caller(arbitrary_string: str, literal_string: LiteralString) -> None:684 run_query("SELECT * FROM students") # OK685 run_query(literal_string) # OK686 run_query("SELECT * FROM " + literal_string) # OK687 run_query(arbitrary_string) # type checker error688 run_query( # type checker error689 f"SELECT * FROM students WHERE name = {arbitrary_string}"690 )691 692 Only string literals and other LiteralStrings are compatible693 with LiteralString. This provides a tool to help prevent694 security issues such as SQL injection.695 """696 raise TypeError(f"{self} is not subscriptable")697 698 699@_SpecialForm700def ClassVar(self, parameters):701 """Special type construct to mark class variables.702 703 An annotation wrapped in ClassVar indicates that a given704 attribute is intended to be used as a class variable and705 should not be set on instances of that class.706 707 Usage::708 709 class Starship:710 stats: ClassVar[dict[str, int]] = {} # class variable711 damage: int = 10 # instance variable712 713 ClassVar accepts only types and cannot be further subscribed.714 715 Note that ClassVar is not a class itself, and should not716 be used with isinstance() or issubclass().717 """718 item = _type_check(parameters, f'{self} accepts only single type.', allow_special_forms=True)719 return _GenericAlias(self, (item,))720 721@_SpecialForm722def Final(self, parameters):723 """Special typing construct to indicate final names to type checkers.724 725 A final name cannot be re-assigned or overridden in a subclass.726 727 For example::728 729 MAX_SIZE: Final = 9000730 MAX_SIZE += 1 # Error reported by type checker731 732 class Connection:733 TIMEOUT: Final[int] = 10734 735 class FastConnector(Connection):736 TIMEOUT = 1 # Error reported by type checker737 738 There is no runtime checking of these properties.739 """740 item = _type_check(parameters, f'{self} accepts only single type.', allow_special_forms=True)741 return _GenericAlias(self, (item,))742 743@_SpecialForm744def Optional(self, parameters):745 """Optional[X] is equivalent to Union[X, None]."""746 arg = _type_check(parameters, f"{self} requires a single type.")747 return Union[arg, type(None)]748 749@_TypedCacheSpecialForm750@_tp_cache(typed=True)751def Literal(self, *parameters):752 """Special typing form to define literal types (a.k.a. value types).753 754 This form can be used to indicate to type checkers that the corresponding755 variable or function parameter has a value equivalent to the provided756 literal (or one of several literals)::757 758 def validate_simple(data: Any) -> Literal[True]: # always returns True759 ...760 761 MODE = Literal['r', 'rb', 'w', 'wb']762 def open_helper(file: str, mode: MODE) -> str:763 ...764 765 open_helper('/some/path', 'r') # Passes type check766 open_helper('/other/path', 'typo') # Error in type checker767 768 Literal[...] cannot be subclassed. At runtime, an arbitrary value769 is allowed as type argument to Literal[...], but type checkers may770 impose restrictions.771 """772 # There is no '_type_check' call because arguments to Literal[...] are773 # values, not types.774 parameters = _flatten_literal_params(parameters)775 776 try:777 parameters = tuple(p for p, _ in _deduplicate(list(_value_and_type_iter(parameters))))778 except TypeError: # unhashable parameters779 pass780 781 return _LiteralGenericAlias(self, parameters)782 783 784@_SpecialForm785def TypeAlias(self, parameters):786 """Special form for marking type aliases.787 788 Use TypeAlias to indicate that an assignment should789 be recognized as a proper type alias definition by type790 checkers.791 792 For example::793 794 Predicate: TypeAlias = Callable[..., bool]795 796 It's invalid when used anywhere except as in the example above.797 """798 raise TypeError(f"{self} is not subscriptable")799 800 801@_SpecialForm802def Concatenate(self, parameters):803 """Special form for annotating higher-order functions.804 805 ``Concatenate`` can be used in conjunction with ``ParamSpec`` and806 ``Callable`` to represent a higher-order function which adds, removes or807 transforms the parameters of a callable.808 809 For example::810 811 Callable[Concatenate[int, P], int]812 813 See PEP 612 for detailed information.814 """815 if parameters == ():816 raise TypeError("Cannot take a Concatenate of no types.")817 if not isinstance(parameters, tuple):818 parameters = (parameters,)819 if not (parameters[-1] is ... or isinstance(parameters[-1], ParamSpec)):820 raise TypeError("The last parameter to Concatenate should be a "821 "ParamSpec variable or ellipsis.")822 msg = "Concatenate[arg, ...]: each arg must be a type."823 parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1])824 return _ConcatenateGenericAlias(self, parameters)825 826 827@_SpecialForm828def TypeGuard(self, parameters):829 """Special typing construct for marking user-defined type predicate functions.830 831 ``TypeGuard`` can be used to annotate the return type of a user-defined832 type predicate function. ``TypeGuard`` only accepts a single type argument.833 At runtime, functions marked this way should return a boolean.834 835 ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static836 type checkers to determine a more precise type of an expression within a837 program's code flow. Usually type narrowing is done by analyzing838 conditional code flow and applying the narrowing to a block of code. The839 conditional expression here is sometimes referred to as a "type predicate".840 841 Sometimes it would be convenient to use a user-defined boolean function842 as a type predicate. Such a function should use ``TypeGuard[...]`` or843 ``TypeIs[...]`` as its return type to alert static type checkers to844 this intention. ``TypeGuard`` should be used over ``TypeIs`` when narrowing845 from an incompatible type (e.g., ``list[object]`` to ``list[int]``) or when846 the function does not return ``True`` for all instances of the narrowed type.847 848 Using ``-> TypeGuard[NarrowedType]`` tells the static type checker that849 for a given function:850 851 1. The return value is a boolean.852 2. If the return value is ``True``, the type of its argument853 is ``NarrowedType``.854 855 For example::856 857 def is_str_list(val: list[object]) -> TypeGuard[list[str]]:858 '''Determines whether all objects in the list are strings'''859 return all(isinstance(x, str) for x in val)860 861 def func1(val: list[object]):862 if is_str_list(val):863 # Type of ``val`` is narrowed to ``list[str]``.864 print(" ".join(val))865 else:866 # Type of ``val`` remains as ``list[object]``.867 print("Not a list of strings!")868 869 Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower870 form of ``TypeA`` (it can even be a wider form) and this may lead to871 type-unsafe results. The main reason is to allow for things like872 narrowing ``list[object]`` to ``list[str]`` even though the latter is not873 a subtype of the former, since ``list`` is invariant. The responsibility of874 writing type-safe type predicates is left to the user.875 876 ``TypeGuard`` also works with type variables. For more information, see877 PEP 647 (User-Defined Type Guards).878 """879 item = _type_check(parameters, f'{self} accepts only single type.')880 return _GenericAlias(self, (item,))881 882 883@_SpecialForm884def TypeIs(self, parameters):885 """Special typing construct for marking user-defined type predicate functions.886 887 ``TypeIs`` can be used to annotate the return type of a user-defined888 type predicate function. ``TypeIs`` only accepts a single type argument.889 At runtime, functions marked this way should return a boolean and accept890 at least one argument.891 892 ``TypeIs`` aims to benefit *type narrowing* -- a technique used by static893 type checkers to determine a more precise type of an expression within a894 program's code flow. Usually type narrowing is done by analyzing895 conditional code flow and applying the narrowing to a block of code. The896 conditional expression here is sometimes referred to as a "type predicate".897 898 Sometimes it would be convenient to use a user-defined boolean function899 as a type predicate. Such a function should use ``TypeIs[...]`` or900 ``TypeGuard[...]`` as its return type to alert static type checkers to901 this intention. ``TypeIs`` usually has more intuitive behavior than902 ``TypeGuard``, but it cannot be used when the input and output types903 are incompatible (e.g., ``list[object]`` to ``list[int]``) or when the904 function does not return ``True`` for all instances of the narrowed type.905 906 Using ``-> TypeIs[NarrowedType]`` tells the static type checker that for907 a given function:908 909 1. The return value is a boolean.910 2. If the return value is ``True``, the type of its argument911 is the intersection of the argument's original type and912 ``NarrowedType``.913 3. If the return value is ``False``, the type of its argument914 is narrowed to exclude ``NarrowedType``.915 916 For example::917 918 from typing import assert_type, final, TypeIs919 920 class Parent: pass921 class Child(Parent): pass922 @final923 class Unrelated: pass924 925 def is_parent(val: object) -> TypeIs[Parent]:926 return isinstance(val, Parent)927 928 def run(arg: Child | Unrelated):929 if is_parent(arg):930 # Type of ``arg`` is narrowed to the intersection931 # of ``Parent`` and ``Child``, which is equivalent to932 # ``Child``.933 assert_type(arg, Child)934 else:935 # Type of ``arg`` is narrowed to exclude ``Parent``,936 # so only ``Unrelated`` is left.937 assert_type(arg, Unrelated)938 939 The type inside ``TypeIs`` must be consistent with the type of the940 function's argument; if it is not, static type checkers will raise941 an error. An incorrectly written ``TypeIs`` function can lead to942 unsound behavior in the type system; it is the user's responsibility943 to write such functions in a type-safe manner.944 945 ``TypeIs`` also works with type variables. For more information, see946 PEP 742 (Narrowing types with ``TypeIs``).947 """948 item = _type_check(parameters, f'{self} accepts only single type.')949 return _GenericAlias(self, (item,))950 951 952def _make_forward_ref(code, *, parent_fwdref=None, **kwargs):953 if parent_fwdref is not None:954 if parent_fwdref.__forward_module__ is not None:955 kwargs['module'] = parent_fwdref.__forward_module__956 if parent_fwdref.__owner__ is not None:957 kwargs['owner'] = parent_fwdref.__owner__958 forward_ref = _lazy_annotationlib.ForwardRef(code, **kwargs)959 # For compatibility, eagerly compile the forwardref's code.960 forward_ref.__forward_code__961 return forward_ref962 963 964def evaluate_forward_ref(965 forward_ref,966 *,967 owner=None,968 globals=None,969 locals=None,970 type_params=None,971 format=None,972 _recursive_guard=frozenset(),973):974 """Evaluate a forward reference as a type hint.975 976 This is similar to calling the ForwardRef.evaluate() method,977 but unlike that method, evaluate_forward_ref() also978 recursively evaluates forward references nested within the type hint.979 980 *forward_ref* must be an instance of ForwardRef. *owner*, if given,981 should be the object that holds the annotations that the forward reference982 derived from, such as a module, class object, or function. It is used to983 infer the namespaces to use for looking up names. *globals* and *locals*984 can also be explicitly given to provide the global and local namespaces.985 *type_params* is a tuple of type parameters that are in scope when986 evaluating the forward reference. This parameter should be provided (though987 it may be an empty tuple) if *owner* is not given and the forward reference988 does not already have an owner set. *format* specifies the format of the989 annotation and is a member of the annotationlib.Format enum, defaulting to990 VALUE.991 992 """993 if format == _lazy_annotationlib.Format.STRING:994 return forward_ref.__forward_arg__995 if forward_ref.__forward_arg__ in _recursive_guard:996 return forward_ref997 998 if format is None:999 format = _lazy_annotationlib.Format.VALUE1000 value = forward_ref.evaluate(globals=globals, locals=locals,1001 type_params=type_params, owner=owner, format=format)1002 1003 if (isinstance(value, _lazy_annotationlib.ForwardRef)1004 and format == _lazy_annotationlib.Format.FORWARDREF):1005 return value1006 1007 if isinstance(value, str):1008 value = _make_forward_ref(value, module=forward_ref.__forward_module__,1009 owner=owner or forward_ref.__owner__,1010 is_argument=forward_ref.__forward_is_argument__,1011 is_class=forward_ref.__forward_is_class__)1012 if owner is None:1013 owner = forward_ref.__owner__1014 return _eval_type(1015 value,1016 globals,1017 locals,1018 type_params,1019 recursive_guard=_recursive_guard | {forward_ref.__forward_arg__},1020 format=format,1021 owner=owner,1022 parent_fwdref=forward_ref,1023 )1024 1025 1026def _is_unpacked_typevartuple(x: Any) -> bool:1027 # Need to check 'is True' here1028 # See: https://github.com/python/cpython/issues/1377061029 return ((not isinstance(x, type)) and1030 getattr(x, '__typing_is_unpacked_typevartuple__', False) is True)1031 1032 1033def _is_typevar_like(x: Any) -> bool:1034 return isinstance(x, (TypeVar, ParamSpec)) or _is_unpacked_typevartuple(x)1035 1036 1037def _typevar_subst(self, arg):1038 msg = "Parameters to generic types must be types."1039 arg = _type_check(arg, msg, is_argument=True)1040 if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or1041 (isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))):1042 raise TypeError(f"{arg} is not valid as type argument")1043 return arg1044 1045 1046def _typevartuple_prepare_subst(self, alias, args):1047 params = alias.__parameters__1048 typevartuple_index = params.index(self)1049 for param in params[typevartuple_index + 1:]:1050 if isinstance(param, TypeVarTuple):1051 raise TypeError(f"More than one TypeVarTuple parameter in {alias}")1052 1053 alen = len(args)1054 plen = len(params)1055 left = typevartuple_index1056 right = plen - typevartuple_index - 11057 var_tuple_index = None1058 fillarg = None1059 for k, arg in enumerate(args):1060 if not isinstance(arg, type):1061 subargs = getattr(arg, '__typing_unpacked_tuple_args__', None)1062 if subargs and len(subargs) == 2 and subargs[-1] is ...:1063 if var_tuple_index is not None:1064 raise TypeError("More than one unpacked arbitrary-length tuple argument")1065 var_tuple_index = k1066 fillarg = subargs[0]1067 if var_tuple_index is not None:1068 left = min(left, var_tuple_index)1069 right = min(right, alen - var_tuple_index - 1)1070 elif left + right > alen:1071 raise TypeError(f"Too few arguments for {alias};"1072 f" actual {alen}, expected at least {plen-1}")1073 if left == alen - right and self.has_default():1074 replacement = _unpack_args(self.__default__)1075 else:1076 replacement = args[left: alen - right]1077 1078 return (1079 *args[:left],1080 *([fillarg]*(typevartuple_index - left)),1081 replacement,1082 *([fillarg]*(plen - right - left - typevartuple_index - 1)),1083 *args[alen - right:],1084 )1085 1086 1087def _paramspec_subst(self, arg):1088 if isinstance(arg, (list, tuple)):1089 arg = tuple(_type_check(a, "Expected a type.") for a in arg)1090 elif not _is_param_expr(arg):1091 raise TypeError(f"Expected a list of types, an ellipsis, "1092 f"ParamSpec, or Concatenate. Got {arg}")1093 return arg1094 1095 1096def _paramspec_prepare_subst(self, alias, args):1097 params = alias.__parameters__1098 i = params.index(self)1099 if i == len(args) and self.has_default():1100 args = (*args, self.__default__)1101 if i >= len(args):1102 raise TypeError(f"Too few arguments for {alias}")1103 # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612.1104 if len(params) == 1 and not _is_param_expr(args[0]):1105 assert i == 01106 args = (args,)1107 # Convert lists to tuples to help other libraries cache the results.1108 elif isinstance(args[i], list):1109 args = (*args[:i], tuple(args[i]), *args[i+1:])1110 return args1111 1112 1113@_tp_cache1114def _generic_class_getitem(cls, args):1115 """Parameterizes a generic class.1116 1117 At least, parameterizing a generic class is the *main* thing this method1118 does. For example, for some generic class `Foo`, this is called when we1119 do `Foo[int]` - there, with `cls=Foo` and `args=int`.1120 1121 However, note that this method is also called when defining generic1122 classes in the first place with `class Foo(Generic[T]): ...`.1123 """1124 if not isinstance(args, tuple):1125 args = (args,)1126 1127 args = tuple(_type_convert(p) for p in args)1128 is_generic_or_protocol = cls in (Generic, Protocol)1129 1130 if is_generic_or_protocol:1131 # Generic and Protocol can only be subscripted with unique type variables.1132 if not args:1133 raise TypeError(1134 f"Parameter list to {cls.__qualname__}[...] cannot be empty"1135 )1136 if not all(_is_typevar_like(p) for p in args):1137 raise TypeError(1138 f"Parameters to {cls.__name__}[...] must all be type variables "1139 f"or parameter specification variables.")1140 if len(set(args)) != len(args):1141 raise TypeError(1142 f"Parameters to {cls.__name__}[...] must all be unique")1143 else:1144 # Subscripting a regular Generic subclass.1145 try:1146 parameters = cls.__parameters__1147 except AttributeError as e:1148 init_subclass = getattr(cls, '__init_subclass__', None)1149 if init_subclass not in {None, Generic.__init_subclass__}:1150 e.add_note(1151 f"Note: this exception may have been caused by "1152 f"{init_subclass.__qualname__!r} (or the "1153 f"'__init_subclass__' method on a superclass) not "1154 f"calling 'super().__init_subclass__()'"1155 )1156 raise1157 for param in parameters:1158 prepare = getattr(param, '__typing_prepare_subst__', None)1159 if prepare is not None:1160 args = prepare(cls, args)1161 _check_generic_specialization(cls, args)1162 1163 new_args = []1164 for param, new_arg in zip(parameters, args):1165 if isinstance(param, TypeVarTuple):1166 new_args.extend(new_arg)1167 else:1168 new_args.append(new_arg)1169 args = tuple(new_args)1170 1171 return _GenericAlias(cls, args)1172 1173 1174def _generic_init_subclass(cls, *args, **kwargs):1175 super(Generic, cls).__init_subclass__(*args, **kwargs)1176 tvars = []1177 if '__orig_bases__' in cls.__dict__:1178 error = Generic in cls.__orig_bases__1179 else:1180 error = (Generic in cls.__bases__ and1181 cls.__name__ != 'Protocol' and1182 type(cls) != _TypedDictMeta)1183 if error:1184 raise TypeError("Cannot inherit from plain Generic")1185 if '__orig_bases__' in cls.__dict__:1186 tvars = _collect_type_parameters(cls.__orig_bases__)1187 # Look for Generic[T1, ..., Tn].1188 # If found, tvars must be a subset of it.1189 # If not found, tvars is it.1190 # Also check for and reject plain Generic,1191 # and reject multiple Generic[...].1192 gvars = None1193 for base in cls.__orig_bases__:1194 if (isinstance(base, _GenericAlias) and1195 base.__origin__ is Generic):1196 if gvars is not None:1197 raise TypeError(1198 "Cannot inherit from Generic[...] multiple times.")1199 gvars = base.__parameters__1200 if gvars is not None: