Aluode/PerceptionLabPortable
0
1import abc2import builtins3import collections4import collections.abc5import contextlib6import enum7import functools8import inspect9import io10import keyword11import operator12import sys13import types as _types14import typing15import warnings16 17# Breakpoint: https://github.com/python/cpython/pull/11989118if sys.version_info >= (3, 14):19 import annotationlib20 21__all__ = [22 # Super-special typing primitives.23 'Any',24 'ClassVar',25 'Concatenate',26 'Final',27 'LiteralString',28 'ParamSpec',29 'ParamSpecArgs',30 'ParamSpecKwargs',31 'Self',32 'Type',33 'TypeVar',34 'TypeVarTuple',35 'Unpack',36 37 # ABCs (from collections.abc).38 'Awaitable',39 'AsyncIterator',40 'AsyncIterable',41 'Coroutine',42 'AsyncGenerator',43 'AsyncContextManager',44 'Buffer',45 'ChainMap',46 47 # Concrete collection types.48 'ContextManager',49 'Counter',50 'Deque',51 'DefaultDict',52 'NamedTuple',53 'OrderedDict',54 'TypedDict',55 56 # Structural checks, a.k.a. protocols.57 'SupportsAbs',58 'SupportsBytes',59 'SupportsComplex',60 'SupportsFloat',61 'SupportsIndex',62 'SupportsInt',63 'SupportsRound',64 'Reader',65 'Writer',66 67 # One-off things.68 'Annotated',69 'assert_never',70 'assert_type',71 'clear_overloads',72 'dataclass_transform',73 'deprecated',74 'disjoint_base',75 'Doc',76 'evaluate_forward_ref',77 'get_overloads',78 'final',79 'Format',80 'get_annotations',81 'get_args',82 'get_origin',83 'get_original_bases',84 'get_protocol_members',85 'get_type_hints',86 'IntVar',87 'is_protocol',88 'is_typeddict',89 'Literal',90 'NewType',91 'overload',92 'override',93 'Protocol',94 'Sentinel',95 'reveal_type',96 'runtime',97 'runtime_checkable',98 'Text',99 'TypeAlias',100 'TypeAliasType',101 'TypeForm',102 'TypeGuard',103 'TypeIs',104 'TYPE_CHECKING',105 'type_repr',106 'Never',107 'NoReturn',108 'ReadOnly',109 'Required',110 'NotRequired',111 'NoDefault',112 'NoExtraItems',113 114 # Pure aliases, have always been in typing115 'AbstractSet',116 'AnyStr',117 'BinaryIO',118 'Callable',119 'Collection',120 'Container',121 'Dict',122 'ForwardRef',123 'FrozenSet',124 'Generator',125 'Generic',126 'Hashable',127 'IO',128 'ItemsView',129 'Iterable',130 'Iterator',131 'KeysView',132 'List',133 'Mapping',134 'MappingView',135 'Match',136 'MutableMapping',137 'MutableSequence',138 'MutableSet',139 'Optional',140 'Pattern',141 'Reversible',142 'Sequence',143 'Set',144 'Sized',145 'TextIO',146 'Tuple',147 'Union',148 'ValuesView',149 'cast',150 'no_type_check',151 'no_type_check_decorator',152]153 154# for backward compatibility155PEP_560 = True156GenericMeta = type157# Breakpoint: https://github.com/python/cpython/pull/116129158_PEP_696_IMPLEMENTED = sys.version_info >= (3, 13, 0, "beta")159 160# Added with bpo-45166 to 3.10.1+ and some 3.9 versions161_FORWARD_REF_HAS_CLASS = "__forward_is_class__" in typing.ForwardRef.__slots__162 163# The functions below are modified copies of typing internal helpers.164# They are needed by _ProtocolMeta and they provide support for PEP 646.165 166 167class _Sentinel:168 def __repr__(self):169 return "<sentinel>"170 171 172_marker = _Sentinel()173 174 175# Breakpoint: https://github.com/python/cpython/pull/27342176if sys.version_info >= (3, 10):177 def _should_collect_from_parameters(t):178 return isinstance(179 t, (typing._GenericAlias, _types.GenericAlias, _types.UnionType)180 )181else:182 def _should_collect_from_parameters(t):183 return isinstance(t, (typing._GenericAlias, _types.GenericAlias))184 185 186NoReturn = typing.NoReturn187 188# Some unconstrained type variables. These are used by the container types.189# (These are not for export.)190T = typing.TypeVar('T') # Any type.191KT = typing.TypeVar('KT') # Key type.192VT = typing.TypeVar('VT') # Value type.193T_co = typing.TypeVar('T_co', covariant=True) # Any type covariant containers.194T_contra = typing.TypeVar('T_contra', contravariant=True) # Ditto contravariant.195 196 197# Breakpoint: https://github.com/python/cpython/pull/31841198if sys.version_info >= (3, 11):199 from typing import Any200else:201 202 class _AnyMeta(type):203 def __instancecheck__(self, obj):204 if self is Any:205 raise TypeError("typing_extensions.Any cannot be used with isinstance()")206 return super().__instancecheck__(obj)207 208 def __repr__(self):209 if self is Any:210 return "typing_extensions.Any"211 return super().__repr__()212 213 class Any(metaclass=_AnyMeta):214 """Special type indicating an unconstrained type.215 - Any is compatible with every type.216 - Any assumed to have all methods.217 - All values assumed to be instances of Any.218 Note that all the above statements are true from the point of view of219 static type checkers. At runtime, Any should not be used with instance220 checks.221 """222 def __new__(cls, *args, **kwargs):223 if cls is Any:224 raise TypeError("Any cannot be instantiated")225 return super().__new__(cls, *args, **kwargs)226 227 228ClassVar = typing.ClassVar229 230# Vendored from cpython typing._SpecialFrom231# Having a separate class means that instances will not be rejected by232# typing._type_check.233class _SpecialForm(typing._Final, _root=True):234 __slots__ = ('_name', '__doc__', '_getitem')235 236 def __init__(self, getitem):237 self._getitem = getitem238 self._name = getitem.__name__239 self.__doc__ = getitem.__doc__240 241 def __getattr__(self, item):242 if item in {'__name__', '__qualname__'}:243 return self._name244 245 raise AttributeError(item)246 247 def __mro_entries__(self, bases):248 raise TypeError(f"Cannot subclass {self!r}")249 250 def __repr__(self):251 return f'typing_extensions.{self._name}'252 253 def __reduce__(self):254 return self._name255 256 def __call__(self, *args, **kwds):257 raise TypeError(f"Cannot instantiate {self!r}")258 259 def __or__(self, other):260 return typing.Union[self, other]261 262 def __ror__(self, other):263 return typing.Union[other, self]264 265 def __instancecheck__(self, obj):266 raise TypeError(f"{self} cannot be used with isinstance()")267 268 def __subclasscheck__(self, cls):269 raise TypeError(f"{self} cannot be used with issubclass()")270 271 @typing._tp_cache272 def __getitem__(self, parameters):273 return self._getitem(self, parameters)274 275 276# Note that inheriting from this class means that the object will be277# rejected by typing._type_check, so do not use it if the special form278# is arguably valid as a type by itself.279class _ExtensionsSpecialForm(typing._SpecialForm, _root=True):280 def __repr__(self):281 return 'typing_extensions.' + self._name282 283 284Final = typing.Final285 286# Breakpoint: https://github.com/python/cpython/pull/30530287if sys.version_info >= (3, 11):288 final = typing.final289else:290 # @final exists in 3.8+, but we backport it for all versions291 # before 3.11 to keep support for the __final__ attribute.292 # See https://bugs.python.org/issue46342293 def final(f):294 """This decorator can be used to indicate to type checkers that295 the decorated method cannot be overridden, and decorated class296 cannot be subclassed. For example:297 298 class Base:299 @final300 def done(self) -> None:301 ...302 class Sub(Base):303 def done(self) -> None: # Error reported by type checker304 ...305 @final306 class Leaf:307 ...308 class Other(Leaf): # Error reported by type checker309 ...310 311 There is no runtime checking of these properties. The decorator312 sets the ``__final__`` attribute to ``True`` on the decorated object313 to allow runtime introspection.314 """315 try:316 f.__final__ = True317 except (AttributeError, TypeError):318 # Skip the attribute silently if it is not writable.319 # AttributeError happens if the object has __slots__ or a320 # read-only property, TypeError if it's a builtin class.321 pass322 return f323 324 325if hasattr(typing, "disjoint_base"): # 3.15326 disjoint_base = typing.disjoint_base327else:328 def disjoint_base(cls):329 """This decorator marks a class as a disjoint base.330 331 Child classes of a disjoint base cannot inherit from other disjoint bases that are332 not parent classes of the disjoint base.333 334 For example:335 336 @disjoint_base337 class Disjoint1: pass338 339 @disjoint_base340 class Disjoint2: pass341 342 class Disjoint3(Disjoint1, Disjoint2): pass # Type checker error343 344 Type checkers can use knowledge of disjoint bases to detect unreachable code345 and determine when two types can overlap.346 347 See PEP 800."""348 cls.__disjoint_base__ = True349 return cls350 351 352def IntVar(name):353 return typing.TypeVar(name)354 355 356# A Literal bug was fixed in 3.11.0, 3.10.1 and 3.9.8357# Breakpoint: https://github.com/python/cpython/pull/29334358if sys.version_info >= (3, 10, 1):359 Literal = typing.Literal360else:361 def _flatten_literal_params(parameters):362 """An internal helper for Literal creation: flatten Literals among parameters"""363 params = []364 for p in parameters:365 if isinstance(p, _LiteralGenericAlias):366 params.extend(p.__args__)367 else:368 params.append(p)369 return tuple(params)370 371 def _value_and_type_iter(params):372 for p in params:373 yield p, type(p)374 375 class _LiteralGenericAlias(typing._GenericAlias, _root=True):376 def __eq__(self, other):377 if not isinstance(other, _LiteralGenericAlias):378 return NotImplemented379 these_args_deduped = set(_value_and_type_iter(self.__args__))380 other_args_deduped = set(_value_and_type_iter(other.__args__))381 return these_args_deduped == other_args_deduped382 383 def __hash__(self):384 return hash(frozenset(_value_and_type_iter(self.__args__)))385 386 class _LiteralForm(_ExtensionsSpecialForm, _root=True):387 def __init__(self, doc: str):388 self._name = 'Literal'389 self._doc = self.__doc__ = doc390 391 def __getitem__(self, parameters):392 if not isinstance(parameters, tuple):393 parameters = (parameters,)394 395 parameters = _flatten_literal_params(parameters)396 397 val_type_pairs = list(_value_and_type_iter(parameters))398 try:399 deduped_pairs = set(val_type_pairs)400 except TypeError:401 # unhashable parameters402 pass403 else:404 # similar logic to typing._deduplicate on Python 3.9+405 if len(deduped_pairs) < len(val_type_pairs):406 new_parameters = []407 for pair in val_type_pairs:408 if pair in deduped_pairs:409 new_parameters.append(pair[0])410 deduped_pairs.remove(pair)411 assert not deduped_pairs, deduped_pairs412 parameters = tuple(new_parameters)413 414 return _LiteralGenericAlias(self, parameters)415 416 Literal = _LiteralForm(doc="""\417 A type that can be used to indicate to type checkers418 that the corresponding value has a value literally equivalent419 to the provided parameter. For example:420 421 var: Literal[4] = 4422 423 The type checker understands that 'var' is literally equal to424 the value 4 and no other value.425 426 Literal[...] cannot be subclassed. There is no runtime427 checking verifying that the parameter is actually a value428 instead of a type.""")429 430 431_overload_dummy = typing._overload_dummy432 433 434if hasattr(typing, "get_overloads"): # 3.11+435 overload = typing.overload436 get_overloads = typing.get_overloads437 clear_overloads = typing.clear_overloads438else:439 # {module: {qualname: {firstlineno: func}}}440 _overload_registry = collections.defaultdict(441 functools.partial(collections.defaultdict, dict)442 )443 444 def overload(func):445 """Decorator for overloaded functions/methods.446 447 In a stub file, place two or more stub definitions for the same448 function in a row, each decorated with @overload. For example:449 450 @overload451 def utf8(value: None) -> None: ...452 @overload453 def utf8(value: bytes) -> bytes: ...454 @overload455 def utf8(value: str) -> bytes: ...456 457 In a non-stub file (i.e. a regular .py file), do the same but458 follow it with an implementation. The implementation should *not*459 be decorated with @overload. For example:460 461 @overload462 def utf8(value: None) -> None: ...463 @overload464 def utf8(value: bytes) -> bytes: ...465 @overload466 def utf8(value: str) -> bytes: ...467 def utf8(value):468 # implementation goes here469 470 The overloads for a function can be retrieved at runtime using the471 get_overloads() function.472 """473 # classmethod and staticmethod474 f = getattr(func, "__func__", func)475 try:476 _overload_registry[f.__module__][f.__qualname__][477 f.__code__.co_firstlineno478 ] = func479 except AttributeError:480 # Not a normal function; ignore.481 pass482 return _overload_dummy483 484 def get_overloads(func):485 """Return all defined overloads for *func* as a sequence."""486 # classmethod and staticmethod487 f = getattr(func, "__func__", func)488 if f.__module__ not in _overload_registry:489 return []490 mod_dict = _overload_registry[f.__module__]491 if f.__qualname__ not in mod_dict:492 return []493 return list(mod_dict[f.__qualname__].values())494 495 def clear_overloads():496 """Clear all overloads in the registry."""497 _overload_registry.clear()498 499 500# This is not a real generic class. Don't use outside annotations.501Type = typing.Type502 503# Various ABCs mimicking those in collections.abc.504# A few are simply re-exported for completeness.505Awaitable = typing.Awaitable506Coroutine = typing.Coroutine507AsyncIterable = typing.AsyncIterable508AsyncIterator = typing.AsyncIterator509Deque = typing.Deque510DefaultDict = typing.DefaultDict511OrderedDict = typing.OrderedDict512Counter = typing.Counter513ChainMap = typing.ChainMap514Text = typing.Text515TYPE_CHECKING = typing.TYPE_CHECKING516 517 518# Breakpoint: https://github.com/python/cpython/pull/118681519if sys.version_info >= (3, 13, 0, "beta"):520 from typing import AsyncContextManager, AsyncGenerator, ContextManager, Generator521else:522 def _is_dunder(attr):523 return attr.startswith('__') and attr.endswith('__')524 525 526 class _SpecialGenericAlias(typing._SpecialGenericAlias, _root=True):527 def __init__(self, origin, nparams, *, inst=True, name=None, defaults=()):528 super().__init__(origin, nparams, inst=inst, name=name)529 self._defaults = defaults530 531 def __setattr__(self, attr, val):532 allowed_attrs = {'_name', '_inst', '_nparams', '_defaults'}533 if _is_dunder(attr) or attr in allowed_attrs:534 object.__setattr__(self, attr, val)535 else:536 setattr(self.__origin__, attr, val)537 538 @typing._tp_cache539 def __getitem__(self, params):540 if not isinstance(params, tuple):541 params = (params,)542 msg = "Parameters to generic types must be types."543 params = tuple(typing._type_check(p, msg) for p in params)544 if (545 self._defaults546 and len(params) < self._nparams547 and len(params) + len(self._defaults) >= self._nparams548 ):549 params = (*params, *self._defaults[len(params) - self._nparams:])550 actual_len = len(params)551 552 if actual_len != self._nparams:553 if self._defaults:554 expected = f"at least {self._nparams - len(self._defaults)}"555 else:556 expected = str(self._nparams)557 if not self._nparams:558 raise TypeError(f"{self} is not a generic class")559 raise TypeError(560 f"Too {'many' if actual_len > self._nparams else 'few'}"561 f" arguments for {self};"562 f" actual {actual_len}, expected {expected}"563 )564 return self.copy_with(params)565 566 _NoneType = type(None)567 Generator = _SpecialGenericAlias(568 collections.abc.Generator, 3, defaults=(_NoneType, _NoneType)569 )570 AsyncGenerator = _SpecialGenericAlias(571 collections.abc.AsyncGenerator, 2, defaults=(_NoneType,)572 )573 ContextManager = _SpecialGenericAlias(574 contextlib.AbstractContextManager,575 2,576 name="ContextManager",577 defaults=(typing.Optional[bool],)578 )579 AsyncContextManager = _SpecialGenericAlias(580 contextlib.AbstractAsyncContextManager,581 2,582 name="AsyncContextManager",583 defaults=(typing.Optional[bool],)584 )585 586 587_PROTO_ALLOWLIST = {588 'collections.abc': [589 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable',590 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', 'Buffer',591 ],592 'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'],593 'typing_extensions': ['Buffer'],594}595 596 597_EXCLUDED_ATTRS = frozenset(typing.EXCLUDED_ATTRIBUTES) | {598 "__match_args__", "__protocol_attrs__", "__non_callable_proto_members__",599 "__final__",600}601 602 603def _get_protocol_attrs(cls):604 attrs = set()605 for base in cls.__mro__[:-1]: # without object606 if base.__name__ in {'Protocol', 'Generic'}:607 continue608 annotations = getattr(base, '__annotations__', {})609 for attr in (*base.__dict__, *annotations):610 if (not attr.startswith('_abc_') and attr not in _EXCLUDED_ATTRS):611 attrs.add(attr)612 return attrs613 614 615def _caller(depth=1, default='__main__'):616 try:617 return sys._getframemodulename(depth + 1) or default618 except AttributeError: # For platforms without _getframemodulename()619 pass620 try:621 return sys._getframe(depth + 1).f_globals.get('__name__', default)622 except (AttributeError, ValueError): # For platforms without _getframe()623 pass624 return None625 626 627# `__match_args__` attribute was removed from protocol members in 3.13,628# we want to backport this change to older Python versions.629# Breakpoint: https://github.com/python/cpython/pull/110683630if sys.version_info >= (3, 13):631 Protocol = typing.Protocol632else:633 def _allow_reckless_class_checks(depth=2):634 """Allow instance and class checks for special stdlib modules.635 The abc and functools modules indiscriminately call isinstance() and636 issubclass() on the whole MRO of a user class, which may contain protocols.637 """638 return _caller(depth) in {'abc', 'functools', None}639 640 def _no_init(self, *args, **kwargs):641 if type(self)._is_protocol:642 raise TypeError('Protocols cannot be instantiated')643 644 def _type_check_issubclass_arg_1(arg):645 """Raise TypeError if `arg` is not an instance of `type`646 in `issubclass(arg, <protocol>)`.647 648 In most cases, this is verified by type.__subclasscheck__.649 Checking it again unnecessarily would slow down issubclass() checks,650 so, we don't perform this check unless we absolutely have to.651 652 For various error paths, however,653 we want to ensure that *this* error message is shown to the user654 where relevant, rather than a typing.py-specific error message.655 """656 if not isinstance(arg, type):657 # Same error message as for issubclass(1, int).658 raise TypeError('issubclass() arg 1 must be a class')659 660 # Inheriting from typing._ProtocolMeta isn't actually desirable,661 # but is necessary to allow typing.Protocol and typing_extensions.Protocol662 # to mix without getting TypeErrors about "metaclass conflict"663 class _ProtocolMeta(type(typing.Protocol)):664 # This metaclass is somewhat unfortunate,665 # but is necessary for several reasons...666 #667 # NOTE: DO NOT call super() in any methods in this class668 # That would call the methods on typing._ProtocolMeta on Python <=3.11669 # and those are slow670 def __new__(mcls, name, bases, namespace, **kwargs):671 if name == "Protocol" and len(bases) < 2:672 pass673 elif {Protocol, typing.Protocol} & set(bases):674 for base in bases:675 if not (676 base in {object, typing.Generic, Protocol, typing.Protocol}677 or base.__name__ in _PROTO_ALLOWLIST.get(base.__module__, [])678 or is_protocol(base)679 ):680 raise TypeError(681 f"Protocols can only inherit from other protocols, "682 f"got {base!r}"683 )684 return abc.ABCMeta.__new__(mcls, name, bases, namespace, **kwargs)685 686 def __init__(cls, *args, **kwargs):687 abc.ABCMeta.__init__(cls, *args, **kwargs)688 if getattr(cls, "_is_protocol", False):689 cls.__protocol_attrs__ = _get_protocol_attrs(cls)690 691 def __subclasscheck__(cls, other):692 if cls is Protocol:693 return type.__subclasscheck__(cls, other)694 if (695 getattr(cls, '_is_protocol', False)696 and not _allow_reckless_class_checks()697 ):698 if not getattr(cls, '_is_runtime_protocol', False):699 _type_check_issubclass_arg_1(other)700 raise TypeError(701 "Instance and class checks can only be used with "702 "@runtime_checkable protocols"703 )704 if (705 # this attribute is set by @runtime_checkable:706 cls.__non_callable_proto_members__707 and cls.__dict__.get("__subclasshook__") is _proto_hook708 ):709 _type_check_issubclass_arg_1(other)710 non_method_attrs = sorted(cls.__non_callable_proto_members__)711 raise TypeError(712 "Protocols with non-method members don't support issubclass()."713 f" Non-method members: {str(non_method_attrs)[1:-1]}."714 )715 return abc.ABCMeta.__subclasscheck__(cls, other)716 717 def __instancecheck__(cls, instance):718 # We need this method for situations where attributes are719 # assigned in __init__.720 if cls is Protocol:721 return type.__instancecheck__(cls, instance)722 if not getattr(cls, "_is_protocol", False):723 # i.e., it's a concrete subclass of a protocol724 return abc.ABCMeta.__instancecheck__(cls, instance)725 726 if (727 not getattr(cls, '_is_runtime_protocol', False) and728 not _allow_reckless_class_checks()729 ):730 raise TypeError("Instance and class checks can only be used with"731 " @runtime_checkable protocols")732 733 if abc.ABCMeta.__instancecheck__(cls, instance):734 return True735 736 for attr in cls.__protocol_attrs__:737 try:738 val = inspect.getattr_static(instance, attr)739 except AttributeError:740 break741 # this attribute is set by @runtime_checkable:742 if val is None and attr not in cls.__non_callable_proto_members__:743 break744 else:745 return True746 747 return False748 749 def __eq__(cls, other):750 # Hack so that typing.Generic.__class_getitem__751 # treats typing_extensions.Protocol752 # as equivalent to typing.Protocol753 if abc.ABCMeta.__eq__(cls, other) is True:754 return True755 return cls is Protocol and other is typing.Protocol756 757 # This has to be defined, or the abc-module cache758 # complains about classes with this metaclass being unhashable,759 # if we define only __eq__!760 def __hash__(cls) -> int:761 return type.__hash__(cls)762 763 @classmethod764 def _proto_hook(cls, other):765 if not cls.__dict__.get('_is_protocol', False):766 return NotImplemented767 768 for attr in cls.__protocol_attrs__:769 for base in other.__mro__:770 # Check if the members appears in the class dictionary...771 if attr in base.__dict__:772 if base.__dict__[attr] is None:773 return NotImplemented774 break775 776 # ...or in annotations, if it is a sub-protocol.777 annotations = getattr(base, '__annotations__', {})778 if (779 isinstance(annotations, collections.abc.Mapping)780 and attr in annotations781 and is_protocol(other)782 ):783 break784 else:785 return NotImplemented786 return True787 788 class Protocol(typing.Generic, metaclass=_ProtocolMeta):789 __doc__ = typing.Protocol.__doc__790 __slots__ = ()791 _is_protocol = True792 _is_runtime_protocol = False793 794 def __init_subclass__(cls, *args, **kwargs):795 super().__init_subclass__(*args, **kwargs)796 797 # Determine if this is a protocol or a concrete subclass.798 if not cls.__dict__.get('_is_protocol', False):799 cls._is_protocol = any(b is Protocol for b in cls.__bases__)800 801 # Set (or override) the protocol subclass hook.802 if '__subclasshook__' not in cls.__dict__:803 cls.__subclasshook__ = _proto_hook804 805 # Prohibit instantiation for protocol classes806 if cls._is_protocol and cls.__init__ is Protocol.__init__:807 cls.__init__ = _no_init808 809 810# Breakpoint: https://github.com/python/cpython/pull/113401811if sys.version_info >= (3, 13):812 runtime_checkable = typing.runtime_checkable813else:814 def runtime_checkable(cls):815 """Mark a protocol class as a runtime protocol.816 817 Such protocol can be used with isinstance() and issubclass().818 Raise TypeError if applied to a non-protocol class.819 This allows a simple-minded structural check very similar to820 one trick ponies in collections.abc such as Iterable.821 822 For example::823 824 @runtime_checkable825 class Closable(Protocol):826 def close(self): ...827 828 assert isinstance(open('/some/file'), Closable)829 830 Warning: this will check only the presence of the required methods,831 not their type signatures!832 """833 if not issubclass(cls, typing.Generic) or not getattr(cls, '_is_protocol', False):834 raise TypeError(f'@runtime_checkable can be only applied to protocol classes,'835 f' got {cls!r}')836 cls._is_runtime_protocol = True837 838 # typing.Protocol classes on <=3.11 break if we execute this block,839 # because typing.Protocol classes on <=3.11 don't have a840 # `__protocol_attrs__` attribute, and this block relies on the841 # `__protocol_attrs__` attribute. Meanwhile, typing.Protocol classes on 3.12.2+842 # break if we *don't* execute this block, because *they* assume that all843 # protocol classes have a `__non_callable_proto_members__` attribute844 # (which this block sets)845 if isinstance(cls, _ProtocolMeta) or sys.version_info >= (3, 12, 2):846 # PEP 544 prohibits using issubclass()847 # with protocols that have non-method members.848 # See gh-113320 for why we compute this attribute here,849 # rather than in `_ProtocolMeta.__init__`850 cls.__non_callable_proto_members__ = set()851 for attr in cls.__protocol_attrs__:852 try:853 is_callable = callable(getattr(cls, attr, None))854 except Exception as e:855 raise TypeError(856 f"Failed to determine whether protocol member {attr!r} "857 "is a method member"858 ) from e859 else:860 if not is_callable:861 cls.__non_callable_proto_members__.add(attr)862 863 return cls864 865 866# The "runtime" alias exists for backwards compatibility.867runtime = runtime_checkable868 869 870# Our version of runtime-checkable protocols is faster on Python <=3.11871# Breakpoint: https://github.com/python/cpython/pull/112717872if sys.version_info >= (3, 12):873 SupportsInt = typing.SupportsInt874 SupportsFloat = typing.SupportsFloat875 SupportsComplex = typing.SupportsComplex876 SupportsBytes = typing.SupportsBytes877 SupportsIndex = typing.SupportsIndex878 SupportsAbs = typing.SupportsAbs879 SupportsRound = typing.SupportsRound880else:881 @runtime_checkable882 class SupportsInt(Protocol):883 """An ABC with one abstract method __int__."""884 __slots__ = ()885 886 @abc.abstractmethod887 def __int__(self) -> int:888 pass889 890 @runtime_checkable891 class SupportsFloat(Protocol):892 """An ABC with one abstract method __float__."""893 __slots__ = ()894 895 @abc.abstractmethod896 def __float__(self) -> float:897 pass898 899 @runtime_checkable900 class SupportsComplex(Protocol):901 """An ABC with one abstract method __complex__."""902 __slots__ = ()903 904 @abc.abstractmethod905 def __complex__(self) -> complex:906 pass907 908 @runtime_checkable909 class SupportsBytes(Protocol):910 """An ABC with one abstract method __bytes__."""911 __slots__ = ()912 913 @abc.abstractmethod914 def __bytes__(self) -> bytes:915 pass916 917 @runtime_checkable918 class SupportsIndex(Protocol):919 __slots__ = ()920 921 @abc.abstractmethod922 def __index__(self) -> int:923 pass924 925 @runtime_checkable926 class SupportsAbs(Protocol[T_co]):927 """928 An ABC with one abstract method __abs__ that is covariant in its return type.929 """930 __slots__ = ()931 932 @abc.abstractmethod933 def __abs__(self) -> T_co:934 pass935 936 @runtime_checkable937 class SupportsRound(Protocol[T_co]):938 """939 An ABC with one abstract method __round__ that is covariant in its return type.940 """941 __slots__ = ()942 943 @abc.abstractmethod944 def __round__(self, ndigits: int = 0) -> T_co:945 pass946 947 948if hasattr(io, "Reader") and hasattr(io, "Writer"):949 Reader = io.Reader950 Writer = io.Writer951else:952 @runtime_checkable953 class Reader(Protocol[T_co]):954 """Protocol for simple I/O reader instances.955 956 This protocol only supports blocking I/O.957 """958 959 __slots__ = ()960 961 @abc.abstractmethod962 def read(self, size: int = ..., /) -> T_co:963 """Read data from the input stream and return it.964 965 If *size* is specified, at most *size* items (bytes/characters) will be966 read.967 """968 969 @runtime_checkable970 class Writer(Protocol[T_contra]):971 """Protocol for simple I/O writer instances.972 973 This protocol only supports blocking I/O.974 """975 976 __slots__ = ()977 978 @abc.abstractmethod979 def write(self, data: T_contra, /) -> int:980 """Write *data* to the output stream and return the number of items written.""" # noqa: E501981 982 983_NEEDS_SINGLETONMETA = (984 not hasattr(typing, "NoDefault") or not hasattr(typing, "NoExtraItems")985)986 987if _NEEDS_SINGLETONMETA:988 class SingletonMeta(type):989 def __setattr__(cls, attr, value):990 # TypeError is consistent with the behavior of NoneType991 raise TypeError(992 f"cannot set {attr!r} attribute of immutable type {cls.__name__!r}"993 )994 995 996if hasattr(typing, "NoDefault"):997 NoDefault = typing.NoDefault998else:999 class NoDefaultType(metaclass=SingletonMeta):1000 """The type of the NoDefault singleton."""1001 1002 __slots__ = ()1003 1004 def __new__(cls):1005 return globals().get("NoDefault") or object.__new__(cls)1006 1007 def __repr__(self):1008 return "typing_extensions.NoDefault"1009 1010 def __reduce__(self):1011 return "NoDefault"1012 1013 NoDefault = NoDefaultType()1014 del NoDefaultType1015 1016if hasattr(typing, "NoExtraItems"):1017 NoExtraItems = typing.NoExtraItems1018else:1019 class NoExtraItemsType(metaclass=SingletonMeta):1020 """The type of the NoExtraItems singleton."""1021 1022 __slots__ = ()1023 1024 def __new__(cls):1025 return globals().get("NoExtraItems") or object.__new__(cls)1026 1027 def __repr__(self):1028 return "typing_extensions.NoExtraItems"1029 1030 def __reduce__(self):1031 return "NoExtraItems"1032 1033 NoExtraItems = NoExtraItemsType()1034 del NoExtraItemsType1035 1036if _NEEDS_SINGLETONMETA:1037 del SingletonMeta1038 1039 1040# Update this to something like >=3.13.0b1 if and when1041# PEP 728 is implemented in CPython1042_PEP_728_IMPLEMENTED = False1043 1044if _PEP_728_IMPLEMENTED:1045 # The standard library TypedDict in Python 3.9.0/1 does not honour the "total"1046 # keyword with old-style TypedDict(). See https://bugs.python.org/issue420591047 # The standard library TypedDict below Python 3.11 does not store runtime1048 # information about optional and required keys when using Required or NotRequired.1049 # Generic TypedDicts are also impossible using typing.TypedDict on Python <3.11.1050 # Aaaand on 3.12 we add __orig_bases__ to TypedDict1051 # to enable better runtime introspection.1052 # On 3.13 we deprecate some odd ways of creating TypedDicts.1053 # Also on 3.13, PEP 705 adds the ReadOnly[] qualifier.1054 # PEP 728 (still pending) makes more changes.1055 TypedDict = typing.TypedDict1056 _TypedDictMeta = typing._TypedDictMeta1057 is_typeddict = typing.is_typeddict1058else:1059 # 3.10.0 and later1060 _TAKES_MODULE = "module" in inspect.signature(typing._type_check).parameters1061 1062 def _get_typeddict_qualifiers(annotation_type):1063 while True:1064 annotation_origin = get_origin(annotation_type)1065 if annotation_origin is Annotated:1066 annotation_args = get_args(annotation_type)1067 if annotation_args:1068 annotation_type = annotation_args[0]1069 else:1070 break1071 elif annotation_origin is Required:1072 yield Required1073 annotation_type, = get_args(annotation_type)1074 elif annotation_origin is NotRequired:1075 yield NotRequired1076 annotation_type, = get_args(annotation_type)1077 elif annotation_origin is ReadOnly:1078 yield ReadOnly1079 annotation_type, = get_args(annotation_type)1080 else:1081 break1082 1083 class _TypedDictMeta(type):1084 1085 def __new__(cls, name, bases, ns, *, total=True, closed=None,1086 extra_items=NoExtraItems):1087 """Create new typed dict class object.1088 1089 This method is called when TypedDict is subclassed,1090 or when TypedDict is instantiated. This way1091 TypedDict supports all three syntax forms described in its docstring.1092 Subclasses and instances of TypedDict return actual dictionaries.1093 """1094 for base in bases:1095 if type(base) is not _TypedDictMeta and base is not typing.Generic:1096 raise TypeError('cannot inherit from both a TypedDict type '1097 'and a non-TypedDict base class')1098 if closed is not None and extra_items is not NoExtraItems:1099 raise TypeError(f"Cannot combine closed={closed!r} and extra_items")1100 1101 if any(issubclass(b, typing.Generic) for b in bases):1102 generic_base = (typing.Generic,)1103 else:1104 generic_base = ()1105 1106 ns_annotations = ns.pop('__annotations__', None)1107 1108 # typing.py generally doesn't let you inherit from plain Generic, unless1109 # the name of the class happens to be "Protocol"1110 tp_dict = type.__new__(_TypedDictMeta, "Protocol", (*generic_base, dict), ns)1111 tp_dict.__name__ = name1112 if tp_dict.__qualname__ == "Protocol":1113 tp_dict.__qualname__ = name1114 1115 if not hasattr(tp_dict, '__orig_bases__'):1116 tp_dict.__orig_bases__ = bases1117 1118 annotations = {}1119 own_annotate = None1120 if ns_annotations is not None:1121 own_annotations = ns_annotations1122 elif sys.version_info >= (3, 14):1123 if hasattr(annotationlib, "get_annotate_from_class_namespace"):1124 own_annotate = annotationlib.get_annotate_from_class_namespace(ns)1125 else:1126 # 3.14.0a7 and earlier1127 own_annotate = ns.get("__annotate__")1128 if own_annotate is not None:1129 own_annotations = annotationlib.call_annotate_function(1130 own_annotate, Format.FORWARDREF, owner=tp_dict1131 )1132 else:1133 own_annotations = {}1134 else:1135 own_annotations = {}1136 msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type"1137 if _TAKES_MODULE:1138 own_checked_annotations = {1139 n: typing._type_check(tp, msg, module=tp_dict.__module__)1140 for n, tp in own_annotations.items()1141 }1142 else:1143 own_checked_annotations = {1144 n: typing._type_check(tp, msg)1145 for n, tp in own_annotations.items()1146 }1147 required_keys = set()1148 optional_keys = set()1149 readonly_keys = set()1150 mutable_keys = set()1151 extra_items_type = extra_items1152 1153 for base in bases:1154 base_dict = base.__dict__1155 1156 if sys.version_info <= (3, 14):1157 annotations.update(base_dict.get('__annotations__', {}))1158 required_keys.update(base_dict.get('__required_keys__', ()))1159 optional_keys.update(base_dict.get('__optional_keys__', ()))1160 readonly_keys.update(base_dict.get('__readonly_keys__', ()))1161 mutable_keys.update(base_dict.get('__mutable_keys__', ()))1162 1163 # This was specified in an earlier version of PEP 728. Support1164 # is retained for backwards compatibility, but only for Python1165 # 3.13 and lower.1166 if (closed and sys.version_info < (3, 14)1167 and "__extra_items__" in own_checked_annotations):1168 annotation_type = own_checked_annotations.pop("__extra_items__")1169 qualifiers = set(_get_typeddict_qualifiers(annotation_type))1170 if Required in qualifiers:1171 raise TypeError(1172 "Special key __extra_items__ does not support "1173 "Required"1174 )1175 if NotRequired in qualifiers:1176 raise TypeError(1177 "Special key __extra_items__ does not support "1178 "NotRequired"1179 )1180 extra_items_type = annotation_type1181 1182 annotations.update(own_checked_annotations)1183 for annotation_key, annotation_type in own_checked_annotations.items():1184 qualifiers = set(_get_typeddict_qualifiers(annotation_type))1185 1186 if Required in qualifiers:1187 required_keys.add(annotation_key)1188 elif NotRequired in qualifiers:1189 optional_keys.add(annotation_key)1190 elif total:1191 required_keys.add(annotation_key)1192 else:1193 optional_keys.add(annotation_key)1194 if ReadOnly in qualifiers:1195 mutable_keys.discard(annotation_key)1196 readonly_keys.add(annotation_key)1197 else:1198 mutable_keys.add(annotation_key)1199 readonly_keys.discard(annotation_key)1200 