1*cda5da8dSAndroid Build Coastguard Worker""" 2*cda5da8dSAndroid Build Coastguard WorkerThe typing module: Support for gradual typing as defined by PEP 484 and subsequent PEPs. 3*cda5da8dSAndroid Build Coastguard Worker 4*cda5da8dSAndroid Build Coastguard WorkerAny name not present in __all__ is an implementation detail 5*cda5da8dSAndroid Build Coastguard Workerthat may be changed without notice. Use at your own risk! 6*cda5da8dSAndroid Build Coastguard Worker 7*cda5da8dSAndroid Build Coastguard WorkerAmong other things, the module includes the following: 8*cda5da8dSAndroid Build Coastguard Worker* Generic, Protocol, and internal machinery to support generic aliases. 9*cda5da8dSAndroid Build Coastguard Worker All subscripted types like X[int], Union[int, str] are generic aliases. 10*cda5da8dSAndroid Build Coastguard Worker* Various "special forms" that have unique meanings in type annotations: 11*cda5da8dSAndroid Build Coastguard Worker NoReturn, Never, ClassVar, Self, Concatenate, Unpack, and others. 12*cda5da8dSAndroid Build Coastguard Worker* Classes whose instances can be type arguments to generic classes and functions: 13*cda5da8dSAndroid Build Coastguard Worker TypeVar, ParamSpec, TypeVarTuple. 14*cda5da8dSAndroid Build Coastguard Worker* Public helper functions: get_type_hints, overload, cast, final, and others. 15*cda5da8dSAndroid Build Coastguard Worker* Several protocols to support duck-typing: 16*cda5da8dSAndroid Build Coastguard Worker SupportsFloat, SupportsIndex, SupportsAbs, and others. 17*cda5da8dSAndroid Build Coastguard Worker* Special types: NewType, NamedTuple, TypedDict. 18*cda5da8dSAndroid Build Coastguard Worker* Deprecated wrapper submodules for re and io related types. 19*cda5da8dSAndroid Build Coastguard Worker* Deprecated aliases for builtin types and collections.abc ABCs. 20*cda5da8dSAndroid Build Coastguard Worker""" 21*cda5da8dSAndroid Build Coastguard Worker 22*cda5da8dSAndroid Build Coastguard Workerfrom abc import abstractmethod, ABCMeta 23*cda5da8dSAndroid Build Coastguard Workerimport collections 24*cda5da8dSAndroid Build Coastguard Workerfrom collections import defaultdict 25*cda5da8dSAndroid Build Coastguard Workerimport collections.abc 26*cda5da8dSAndroid Build Coastguard Workerimport contextlib 27*cda5da8dSAndroid Build Coastguard Workerimport functools 28*cda5da8dSAndroid Build Coastguard Workerimport operator 29*cda5da8dSAndroid Build Coastguard Workerimport re as stdlib_re # Avoid confusion with the re we export. 30*cda5da8dSAndroid Build Coastguard Workerimport sys 31*cda5da8dSAndroid Build Coastguard Workerimport types 32*cda5da8dSAndroid Build Coastguard Workerimport warnings 33*cda5da8dSAndroid Build Coastguard Workerfrom types import WrapperDescriptorType, MethodWrapperType, MethodDescriptorType, GenericAlias 34*cda5da8dSAndroid Build Coastguard Worker 35*cda5da8dSAndroid Build Coastguard Worker 36*cda5da8dSAndroid Build Coastguard Workertry: 37*cda5da8dSAndroid Build Coastguard Worker from _typing import _idfunc 38*cda5da8dSAndroid Build Coastguard Workerexcept ImportError: 39*cda5da8dSAndroid Build Coastguard Worker def _idfunc(_, x): 40*cda5da8dSAndroid Build Coastguard Worker return x 41*cda5da8dSAndroid Build Coastguard Worker 42*cda5da8dSAndroid Build Coastguard Worker# Please keep __all__ alphabetized within each category. 43*cda5da8dSAndroid Build Coastguard Worker__all__ = [ 44*cda5da8dSAndroid Build Coastguard Worker # Super-special typing primitives. 45*cda5da8dSAndroid Build Coastguard Worker 'Annotated', 46*cda5da8dSAndroid Build Coastguard Worker 'Any', 47*cda5da8dSAndroid Build Coastguard Worker 'Callable', 48*cda5da8dSAndroid Build Coastguard Worker 'ClassVar', 49*cda5da8dSAndroid Build Coastguard Worker 'Concatenate', 50*cda5da8dSAndroid Build Coastguard Worker 'Final', 51*cda5da8dSAndroid Build Coastguard Worker 'ForwardRef', 52*cda5da8dSAndroid Build Coastguard Worker 'Generic', 53*cda5da8dSAndroid Build Coastguard Worker 'Literal', 54*cda5da8dSAndroid Build Coastguard Worker 'Optional', 55*cda5da8dSAndroid Build Coastguard Worker 'ParamSpec', 56*cda5da8dSAndroid Build Coastguard Worker 'Protocol', 57*cda5da8dSAndroid Build Coastguard Worker 'Tuple', 58*cda5da8dSAndroid Build Coastguard Worker 'Type', 59*cda5da8dSAndroid Build Coastguard Worker 'TypeVar', 60*cda5da8dSAndroid Build Coastguard Worker 'TypeVarTuple', 61*cda5da8dSAndroid Build Coastguard Worker 'Union', 62*cda5da8dSAndroid Build Coastguard Worker 63*cda5da8dSAndroid Build Coastguard Worker # ABCs (from collections.abc). 64*cda5da8dSAndroid Build Coastguard Worker 'AbstractSet', # collections.abc.Set. 65*cda5da8dSAndroid Build Coastguard Worker 'ByteString', 66*cda5da8dSAndroid Build Coastguard Worker 'Container', 67*cda5da8dSAndroid Build Coastguard Worker 'ContextManager', 68*cda5da8dSAndroid Build Coastguard Worker 'Hashable', 69*cda5da8dSAndroid Build Coastguard Worker 'ItemsView', 70*cda5da8dSAndroid Build Coastguard Worker 'Iterable', 71*cda5da8dSAndroid Build Coastguard Worker 'Iterator', 72*cda5da8dSAndroid Build Coastguard Worker 'KeysView', 73*cda5da8dSAndroid Build Coastguard Worker 'Mapping', 74*cda5da8dSAndroid Build Coastguard Worker 'MappingView', 75*cda5da8dSAndroid Build Coastguard Worker 'MutableMapping', 76*cda5da8dSAndroid Build Coastguard Worker 'MutableSequence', 77*cda5da8dSAndroid Build Coastguard Worker 'MutableSet', 78*cda5da8dSAndroid Build Coastguard Worker 'Sequence', 79*cda5da8dSAndroid Build Coastguard Worker 'Sized', 80*cda5da8dSAndroid Build Coastguard Worker 'ValuesView', 81*cda5da8dSAndroid Build Coastguard Worker 'Awaitable', 82*cda5da8dSAndroid Build Coastguard Worker 'AsyncIterator', 83*cda5da8dSAndroid Build Coastguard Worker 'AsyncIterable', 84*cda5da8dSAndroid Build Coastguard Worker 'Coroutine', 85*cda5da8dSAndroid Build Coastguard Worker 'Collection', 86*cda5da8dSAndroid Build Coastguard Worker 'AsyncGenerator', 87*cda5da8dSAndroid Build Coastguard Worker 'AsyncContextManager', 88*cda5da8dSAndroid Build Coastguard Worker 89*cda5da8dSAndroid Build Coastguard Worker # Structural checks, a.k.a. protocols. 90*cda5da8dSAndroid Build Coastguard Worker 'Reversible', 91*cda5da8dSAndroid Build Coastguard Worker 'SupportsAbs', 92*cda5da8dSAndroid Build Coastguard Worker 'SupportsBytes', 93*cda5da8dSAndroid Build Coastguard Worker 'SupportsComplex', 94*cda5da8dSAndroid Build Coastguard Worker 'SupportsFloat', 95*cda5da8dSAndroid Build Coastguard Worker 'SupportsIndex', 96*cda5da8dSAndroid Build Coastguard Worker 'SupportsInt', 97*cda5da8dSAndroid Build Coastguard Worker 'SupportsRound', 98*cda5da8dSAndroid Build Coastguard Worker 99*cda5da8dSAndroid Build Coastguard Worker # Concrete collection types. 100*cda5da8dSAndroid Build Coastguard Worker 'ChainMap', 101*cda5da8dSAndroid Build Coastguard Worker 'Counter', 102*cda5da8dSAndroid Build Coastguard Worker 'Deque', 103*cda5da8dSAndroid Build Coastguard Worker 'Dict', 104*cda5da8dSAndroid Build Coastguard Worker 'DefaultDict', 105*cda5da8dSAndroid Build Coastguard Worker 'List', 106*cda5da8dSAndroid Build Coastguard Worker 'OrderedDict', 107*cda5da8dSAndroid Build Coastguard Worker 'Set', 108*cda5da8dSAndroid Build Coastguard Worker 'FrozenSet', 109*cda5da8dSAndroid Build Coastguard Worker 'NamedTuple', # Not really a type. 110*cda5da8dSAndroid Build Coastguard Worker 'TypedDict', # Not really a type. 111*cda5da8dSAndroid Build Coastguard Worker 'Generator', 112*cda5da8dSAndroid Build Coastguard Worker 113*cda5da8dSAndroid Build Coastguard Worker # Other concrete types. 114*cda5da8dSAndroid Build Coastguard Worker 'BinaryIO', 115*cda5da8dSAndroid Build Coastguard Worker 'IO', 116*cda5da8dSAndroid Build Coastguard Worker 'Match', 117*cda5da8dSAndroid Build Coastguard Worker 'Pattern', 118*cda5da8dSAndroid Build Coastguard Worker 'TextIO', 119*cda5da8dSAndroid Build Coastguard Worker 120*cda5da8dSAndroid Build Coastguard Worker # One-off things. 121*cda5da8dSAndroid Build Coastguard Worker 'AnyStr', 122*cda5da8dSAndroid Build Coastguard Worker 'assert_type', 123*cda5da8dSAndroid Build Coastguard Worker 'assert_never', 124*cda5da8dSAndroid Build Coastguard Worker 'cast', 125*cda5da8dSAndroid Build Coastguard Worker 'clear_overloads', 126*cda5da8dSAndroid Build Coastguard Worker 'dataclass_transform', 127*cda5da8dSAndroid Build Coastguard Worker 'final', 128*cda5da8dSAndroid Build Coastguard Worker 'get_args', 129*cda5da8dSAndroid Build Coastguard Worker 'get_origin', 130*cda5da8dSAndroid Build Coastguard Worker 'get_overloads', 131*cda5da8dSAndroid Build Coastguard Worker 'get_type_hints', 132*cda5da8dSAndroid Build Coastguard Worker 'is_typeddict', 133*cda5da8dSAndroid Build Coastguard Worker 'LiteralString', 134*cda5da8dSAndroid Build Coastguard Worker 'Never', 135*cda5da8dSAndroid Build Coastguard Worker 'NewType', 136*cda5da8dSAndroid Build Coastguard Worker 'no_type_check', 137*cda5da8dSAndroid Build Coastguard Worker 'no_type_check_decorator', 138*cda5da8dSAndroid Build Coastguard Worker 'NoReturn', 139*cda5da8dSAndroid Build Coastguard Worker 'NotRequired', 140*cda5da8dSAndroid Build Coastguard Worker 'overload', 141*cda5da8dSAndroid Build Coastguard Worker 'ParamSpecArgs', 142*cda5da8dSAndroid Build Coastguard Worker 'ParamSpecKwargs', 143*cda5da8dSAndroid Build Coastguard Worker 'Required', 144*cda5da8dSAndroid Build Coastguard Worker 'reveal_type', 145*cda5da8dSAndroid Build Coastguard Worker 'runtime_checkable', 146*cda5da8dSAndroid Build Coastguard Worker 'Self', 147*cda5da8dSAndroid Build Coastguard Worker 'Text', 148*cda5da8dSAndroid Build Coastguard Worker 'TYPE_CHECKING', 149*cda5da8dSAndroid Build Coastguard Worker 'TypeAlias', 150*cda5da8dSAndroid Build Coastguard Worker 'TypeGuard', 151*cda5da8dSAndroid Build Coastguard Worker 'Unpack', 152*cda5da8dSAndroid Build Coastguard Worker] 153*cda5da8dSAndroid Build Coastguard Worker 154*cda5da8dSAndroid Build Coastguard Worker# The pseudo-submodules 're' and 'io' are part of the public 155*cda5da8dSAndroid Build Coastguard Worker# namespace, but excluded from __all__ because they might stomp on 156*cda5da8dSAndroid Build Coastguard Worker# legitimate imports of those modules. 157*cda5da8dSAndroid Build Coastguard Worker 158*cda5da8dSAndroid Build Coastguard Worker 159*cda5da8dSAndroid Build Coastguard Workerdef _type_convert(arg, module=None, *, allow_special_forms=False): 160*cda5da8dSAndroid Build Coastguard Worker """For converting None to type(None), and strings to ForwardRef.""" 161*cda5da8dSAndroid Build Coastguard Worker if arg is None: 162*cda5da8dSAndroid Build Coastguard Worker return type(None) 163*cda5da8dSAndroid Build Coastguard Worker if isinstance(arg, str): 164*cda5da8dSAndroid Build Coastguard Worker return ForwardRef(arg, module=module, is_class=allow_special_forms) 165*cda5da8dSAndroid Build Coastguard Worker return arg 166*cda5da8dSAndroid Build Coastguard Worker 167*cda5da8dSAndroid Build Coastguard Worker 168*cda5da8dSAndroid Build Coastguard Workerdef _type_check(arg, msg, is_argument=True, module=None, *, allow_special_forms=False): 169*cda5da8dSAndroid Build Coastguard Worker """Check that the argument is a type, and return it (internal helper). 170*cda5da8dSAndroid Build Coastguard Worker 171*cda5da8dSAndroid Build Coastguard Worker As a special case, accept None and return type(None) instead. Also wrap strings 172*cda5da8dSAndroid Build Coastguard Worker into ForwardRef instances. Consider several corner cases, for example plain 173*cda5da8dSAndroid Build Coastguard Worker special forms like Union are not valid, while Union[int, str] is OK, etc. 174*cda5da8dSAndroid Build Coastguard Worker The msg argument is a human-readable error message, e.g.:: 175*cda5da8dSAndroid Build Coastguard Worker 176*cda5da8dSAndroid Build Coastguard Worker "Union[arg, ...]: arg should be a type." 177*cda5da8dSAndroid Build Coastguard Worker 178*cda5da8dSAndroid Build Coastguard Worker We append the repr() of the actual value (truncated to 100 chars). 179*cda5da8dSAndroid Build Coastguard Worker """ 180*cda5da8dSAndroid Build Coastguard Worker invalid_generic_forms = (Generic, Protocol) 181*cda5da8dSAndroid Build Coastguard Worker if not allow_special_forms: 182*cda5da8dSAndroid Build Coastguard Worker invalid_generic_forms += (ClassVar,) 183*cda5da8dSAndroid Build Coastguard Worker if is_argument: 184*cda5da8dSAndroid Build Coastguard Worker invalid_generic_forms += (Final,) 185*cda5da8dSAndroid Build Coastguard Worker 186*cda5da8dSAndroid Build Coastguard Worker arg = _type_convert(arg, module=module, allow_special_forms=allow_special_forms) 187*cda5da8dSAndroid Build Coastguard Worker if (isinstance(arg, _GenericAlias) and 188*cda5da8dSAndroid Build Coastguard Worker arg.__origin__ in invalid_generic_forms): 189*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{arg} is not valid as type argument") 190*cda5da8dSAndroid Build Coastguard Worker if arg in (Any, LiteralString, NoReturn, Never, Self, TypeAlias): 191*cda5da8dSAndroid Build Coastguard Worker return arg 192*cda5da8dSAndroid Build Coastguard Worker if allow_special_forms and arg in (ClassVar, Final): 193*cda5da8dSAndroid Build Coastguard Worker return arg 194*cda5da8dSAndroid Build Coastguard Worker if isinstance(arg, _SpecialForm) or arg in (Generic, Protocol): 195*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Plain {arg} is not valid as type argument") 196*cda5da8dSAndroid Build Coastguard Worker if type(arg) is tuple: 197*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{msg} Got {arg!r:.100}.") 198*cda5da8dSAndroid Build Coastguard Worker return arg 199*cda5da8dSAndroid Build Coastguard Worker 200*cda5da8dSAndroid Build Coastguard Worker 201*cda5da8dSAndroid Build Coastguard Workerdef _is_param_expr(arg): 202*cda5da8dSAndroid Build Coastguard Worker return arg is ... or isinstance(arg, 203*cda5da8dSAndroid Build Coastguard Worker (tuple, list, ParamSpec, _ConcatenateGenericAlias)) 204*cda5da8dSAndroid Build Coastguard Worker 205*cda5da8dSAndroid Build Coastguard Worker 206*cda5da8dSAndroid Build Coastguard Workerdef _should_unflatten_callable_args(typ, args): 207*cda5da8dSAndroid Build Coastguard Worker """Internal helper for munging collections.abc.Callable's __args__. 208*cda5da8dSAndroid Build Coastguard Worker 209*cda5da8dSAndroid Build Coastguard Worker The canonical representation for a Callable's __args__ flattens the 210*cda5da8dSAndroid Build Coastguard Worker argument types, see https://bugs.python.org/issue42195. For example:: 211*cda5da8dSAndroid Build Coastguard Worker 212*cda5da8dSAndroid Build Coastguard Worker collections.abc.Callable[[int, int], str].__args__ == (int, int, str) 213*cda5da8dSAndroid Build Coastguard Worker collections.abc.Callable[ParamSpec, str].__args__ == (ParamSpec, str) 214*cda5da8dSAndroid Build Coastguard Worker 215*cda5da8dSAndroid Build Coastguard Worker As a result, if we need to reconstruct the Callable from its __args__, 216*cda5da8dSAndroid Build Coastguard Worker we need to unflatten it. 217*cda5da8dSAndroid Build Coastguard Worker """ 218*cda5da8dSAndroid Build Coastguard Worker return ( 219*cda5da8dSAndroid Build Coastguard Worker typ.__origin__ is collections.abc.Callable 220*cda5da8dSAndroid Build Coastguard Worker and not (len(args) == 2 and _is_param_expr(args[0])) 221*cda5da8dSAndroid Build Coastguard Worker ) 222*cda5da8dSAndroid Build Coastguard Worker 223*cda5da8dSAndroid Build Coastguard Worker 224*cda5da8dSAndroid Build Coastguard Workerdef _type_repr(obj): 225*cda5da8dSAndroid Build Coastguard Worker """Return the repr() of an object, special-casing types (internal helper). 226*cda5da8dSAndroid Build Coastguard Worker 227*cda5da8dSAndroid Build Coastguard Worker If obj is a type, we return a shorter version than the default 228*cda5da8dSAndroid Build Coastguard Worker type.__repr__, based on the module and qualified name, which is 229*cda5da8dSAndroid Build Coastguard Worker typically enough to uniquely identify a type. For everything 230*cda5da8dSAndroid Build Coastguard Worker else, we fall back on repr(obj). 231*cda5da8dSAndroid Build Coastguard Worker """ 232*cda5da8dSAndroid Build Coastguard Worker if isinstance(obj, types.GenericAlias): 233*cda5da8dSAndroid Build Coastguard Worker return repr(obj) 234*cda5da8dSAndroid Build Coastguard Worker if isinstance(obj, type): 235*cda5da8dSAndroid Build Coastguard Worker if obj.__module__ == 'builtins': 236*cda5da8dSAndroid Build Coastguard Worker return obj.__qualname__ 237*cda5da8dSAndroid Build Coastguard Worker return f'{obj.__module__}.{obj.__qualname__}' 238*cda5da8dSAndroid Build Coastguard Worker if obj is ...: 239*cda5da8dSAndroid Build Coastguard Worker return('...') 240*cda5da8dSAndroid Build Coastguard Worker if isinstance(obj, types.FunctionType): 241*cda5da8dSAndroid Build Coastguard Worker return obj.__name__ 242*cda5da8dSAndroid Build Coastguard Worker return repr(obj) 243*cda5da8dSAndroid Build Coastguard Worker 244*cda5da8dSAndroid Build Coastguard Worker 245*cda5da8dSAndroid Build Coastguard Workerdef _collect_parameters(args): 246*cda5da8dSAndroid Build Coastguard Worker """Collect all type variables and parameter specifications in args 247*cda5da8dSAndroid Build Coastguard Worker in order of first appearance (lexicographic order). 248*cda5da8dSAndroid Build Coastguard Worker 249*cda5da8dSAndroid Build Coastguard Worker For example:: 250*cda5da8dSAndroid Build Coastguard Worker 251*cda5da8dSAndroid Build Coastguard Worker assert _collect_parameters((T, Callable[P, T])) == (T, P) 252*cda5da8dSAndroid Build Coastguard Worker """ 253*cda5da8dSAndroid Build Coastguard Worker parameters = [] 254*cda5da8dSAndroid Build Coastguard Worker for t in args: 255*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, type): 256*cda5da8dSAndroid Build Coastguard Worker # We don't want __parameters__ descriptor of a bare Python class. 257*cda5da8dSAndroid Build Coastguard Worker pass 258*cda5da8dSAndroid Build Coastguard Worker elif isinstance(t, tuple): 259*cda5da8dSAndroid Build Coastguard Worker # `t` might be a tuple, when `ParamSpec` is substituted with 260*cda5da8dSAndroid Build Coastguard Worker # `[T, int]`, or `[int, *Ts]`, etc. 261*cda5da8dSAndroid Build Coastguard Worker for x in t: 262*cda5da8dSAndroid Build Coastguard Worker for collected in _collect_parameters([x]): 263*cda5da8dSAndroid Build Coastguard Worker if collected not in parameters: 264*cda5da8dSAndroid Build Coastguard Worker parameters.append(collected) 265*cda5da8dSAndroid Build Coastguard Worker elif hasattr(t, '__typing_subst__'): 266*cda5da8dSAndroid Build Coastguard Worker if t not in parameters: 267*cda5da8dSAndroid Build Coastguard Worker parameters.append(t) 268*cda5da8dSAndroid Build Coastguard Worker else: 269*cda5da8dSAndroid Build Coastguard Worker for x in getattr(t, '__parameters__', ()): 270*cda5da8dSAndroid Build Coastguard Worker if x not in parameters: 271*cda5da8dSAndroid Build Coastguard Worker parameters.append(x) 272*cda5da8dSAndroid Build Coastguard Worker return tuple(parameters) 273*cda5da8dSAndroid Build Coastguard Worker 274*cda5da8dSAndroid Build Coastguard Worker 275*cda5da8dSAndroid Build Coastguard Workerdef _check_generic(cls, parameters, elen): 276*cda5da8dSAndroid Build Coastguard Worker """Check correct count for parameters of a generic cls (internal helper). 277*cda5da8dSAndroid Build Coastguard Worker 278*cda5da8dSAndroid Build Coastguard Worker This gives a nice error message in case of count mismatch. 279*cda5da8dSAndroid Build Coastguard Worker """ 280*cda5da8dSAndroid Build Coastguard Worker if not elen: 281*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{cls} is not a generic class") 282*cda5da8dSAndroid Build Coastguard Worker alen = len(parameters) 283*cda5da8dSAndroid Build Coastguard Worker if alen != elen: 284*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Too {'many' if alen > elen else 'few'} arguments for {cls};" 285*cda5da8dSAndroid Build Coastguard Worker f" actual {alen}, expected {elen}") 286*cda5da8dSAndroid Build Coastguard Worker 287*cda5da8dSAndroid Build Coastguard Workerdef _unpack_args(args): 288*cda5da8dSAndroid Build Coastguard Worker newargs = [] 289*cda5da8dSAndroid Build Coastguard Worker for arg in args: 290*cda5da8dSAndroid Build Coastguard Worker subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) 291*cda5da8dSAndroid Build Coastguard Worker if subargs is not None and not (subargs and subargs[-1] is ...): 292*cda5da8dSAndroid Build Coastguard Worker newargs.extend(subargs) 293*cda5da8dSAndroid Build Coastguard Worker else: 294*cda5da8dSAndroid Build Coastguard Worker newargs.append(arg) 295*cda5da8dSAndroid Build Coastguard Worker return newargs 296*cda5da8dSAndroid Build Coastguard Worker 297*cda5da8dSAndroid Build Coastguard Workerdef _deduplicate(params): 298*cda5da8dSAndroid Build Coastguard Worker # Weed out strict duplicates, preserving the first of each occurrence. 299*cda5da8dSAndroid Build Coastguard Worker all_params = set(params) 300*cda5da8dSAndroid Build Coastguard Worker if len(all_params) < len(params): 301*cda5da8dSAndroid Build Coastguard Worker new_params = [] 302*cda5da8dSAndroid Build Coastguard Worker for t in params: 303*cda5da8dSAndroid Build Coastguard Worker if t in all_params: 304*cda5da8dSAndroid Build Coastguard Worker new_params.append(t) 305*cda5da8dSAndroid Build Coastguard Worker all_params.remove(t) 306*cda5da8dSAndroid Build Coastguard Worker params = new_params 307*cda5da8dSAndroid Build Coastguard Worker assert not all_params, all_params 308*cda5da8dSAndroid Build Coastguard Worker return params 309*cda5da8dSAndroid Build Coastguard Worker 310*cda5da8dSAndroid Build Coastguard Worker 311*cda5da8dSAndroid Build Coastguard Workerdef _remove_dups_flatten(parameters): 312*cda5da8dSAndroid Build Coastguard Worker """Internal helper for Union creation and substitution. 313*cda5da8dSAndroid Build Coastguard Worker 314*cda5da8dSAndroid Build Coastguard Worker Flatten Unions among parameters, then remove duplicates. 315*cda5da8dSAndroid Build Coastguard Worker """ 316*cda5da8dSAndroid Build Coastguard Worker # Flatten out Union[Union[...], ...]. 317*cda5da8dSAndroid Build Coastguard Worker params = [] 318*cda5da8dSAndroid Build Coastguard Worker for p in parameters: 319*cda5da8dSAndroid Build Coastguard Worker if isinstance(p, (_UnionGenericAlias, types.UnionType)): 320*cda5da8dSAndroid Build Coastguard Worker params.extend(p.__args__) 321*cda5da8dSAndroid Build Coastguard Worker else: 322*cda5da8dSAndroid Build Coastguard Worker params.append(p) 323*cda5da8dSAndroid Build Coastguard Worker 324*cda5da8dSAndroid Build Coastguard Worker return tuple(_deduplicate(params)) 325*cda5da8dSAndroid Build Coastguard Worker 326*cda5da8dSAndroid Build Coastguard Worker 327*cda5da8dSAndroid Build Coastguard Workerdef _flatten_literal_params(parameters): 328*cda5da8dSAndroid Build Coastguard Worker """Internal helper for Literal creation: flatten Literals among parameters.""" 329*cda5da8dSAndroid Build Coastguard Worker params = [] 330*cda5da8dSAndroid Build Coastguard Worker for p in parameters: 331*cda5da8dSAndroid Build Coastguard Worker if isinstance(p, _LiteralGenericAlias): 332*cda5da8dSAndroid Build Coastguard Worker params.extend(p.__args__) 333*cda5da8dSAndroid Build Coastguard Worker else: 334*cda5da8dSAndroid Build Coastguard Worker params.append(p) 335*cda5da8dSAndroid Build Coastguard Worker return tuple(params) 336*cda5da8dSAndroid Build Coastguard Worker 337*cda5da8dSAndroid Build Coastguard Worker 338*cda5da8dSAndroid Build Coastguard Worker_cleanups = [] 339*cda5da8dSAndroid Build Coastguard Worker 340*cda5da8dSAndroid Build Coastguard Worker 341*cda5da8dSAndroid Build Coastguard Workerdef _tp_cache(func=None, /, *, typed=False): 342*cda5da8dSAndroid Build Coastguard Worker """Internal wrapper caching __getitem__ of generic types with a fallback to 343*cda5da8dSAndroid Build Coastguard Worker original function for non-hashable arguments. 344*cda5da8dSAndroid Build Coastguard Worker """ 345*cda5da8dSAndroid Build Coastguard Worker def decorator(func): 346*cda5da8dSAndroid Build Coastguard Worker cached = functools.lru_cache(typed=typed)(func) 347*cda5da8dSAndroid Build Coastguard Worker _cleanups.append(cached.cache_clear) 348*cda5da8dSAndroid Build Coastguard Worker 349*cda5da8dSAndroid Build Coastguard Worker @functools.wraps(func) 350*cda5da8dSAndroid Build Coastguard Worker def inner(*args, **kwds): 351*cda5da8dSAndroid Build Coastguard Worker try: 352*cda5da8dSAndroid Build Coastguard Worker return cached(*args, **kwds) 353*cda5da8dSAndroid Build Coastguard Worker except TypeError: 354*cda5da8dSAndroid Build Coastguard Worker pass # All real errors (not unhashable args) are raised below. 355*cda5da8dSAndroid Build Coastguard Worker return func(*args, **kwds) 356*cda5da8dSAndroid Build Coastguard Worker return inner 357*cda5da8dSAndroid Build Coastguard Worker 358*cda5da8dSAndroid Build Coastguard Worker if func is not None: 359*cda5da8dSAndroid Build Coastguard Worker return decorator(func) 360*cda5da8dSAndroid Build Coastguard Worker 361*cda5da8dSAndroid Build Coastguard Worker return decorator 362*cda5da8dSAndroid Build Coastguard Worker 363*cda5da8dSAndroid Build Coastguard Workerdef _eval_type(t, globalns, localns, recursive_guard=frozenset()): 364*cda5da8dSAndroid Build Coastguard Worker """Evaluate all forward references in the given type t. 365*cda5da8dSAndroid Build Coastguard Worker 366*cda5da8dSAndroid Build Coastguard Worker For use of globalns and localns see the docstring for get_type_hints(). 367*cda5da8dSAndroid Build Coastguard Worker recursive_guard is used to prevent infinite recursion with a recursive 368*cda5da8dSAndroid Build Coastguard Worker ForwardRef. 369*cda5da8dSAndroid Build Coastguard Worker """ 370*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, ForwardRef): 371*cda5da8dSAndroid Build Coastguard Worker return t._evaluate(globalns, localns, recursive_guard) 372*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, (_GenericAlias, GenericAlias, types.UnionType)): 373*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, GenericAlias): 374*cda5da8dSAndroid Build Coastguard Worker args = tuple( 375*cda5da8dSAndroid Build Coastguard Worker ForwardRef(arg) if isinstance(arg, str) else arg 376*cda5da8dSAndroid Build Coastguard Worker for arg in t.__args__ 377*cda5da8dSAndroid Build Coastguard Worker ) 378*cda5da8dSAndroid Build Coastguard Worker is_unpacked = t.__unpacked__ 379*cda5da8dSAndroid Build Coastguard Worker if _should_unflatten_callable_args(t, args): 380*cda5da8dSAndroid Build Coastguard Worker t = t.__origin__[(args[:-1], args[-1])] 381*cda5da8dSAndroid Build Coastguard Worker else: 382*cda5da8dSAndroid Build Coastguard Worker t = t.__origin__[args] 383*cda5da8dSAndroid Build Coastguard Worker if is_unpacked: 384*cda5da8dSAndroid Build Coastguard Worker t = Unpack[t] 385*cda5da8dSAndroid Build Coastguard Worker ev_args = tuple(_eval_type(a, globalns, localns, recursive_guard) for a in t.__args__) 386*cda5da8dSAndroid Build Coastguard Worker if ev_args == t.__args__: 387*cda5da8dSAndroid Build Coastguard Worker return t 388*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, GenericAlias): 389*cda5da8dSAndroid Build Coastguard Worker return GenericAlias(t.__origin__, ev_args) 390*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, types.UnionType): 391*cda5da8dSAndroid Build Coastguard Worker return functools.reduce(operator.or_, ev_args) 392*cda5da8dSAndroid Build Coastguard Worker else: 393*cda5da8dSAndroid Build Coastguard Worker return t.copy_with(ev_args) 394*cda5da8dSAndroid Build Coastguard Worker return t 395*cda5da8dSAndroid Build Coastguard Worker 396*cda5da8dSAndroid Build Coastguard Worker 397*cda5da8dSAndroid Build Coastguard Workerclass _Final: 398*cda5da8dSAndroid Build Coastguard Worker """Mixin to prohibit subclassing.""" 399*cda5da8dSAndroid Build Coastguard Worker 400*cda5da8dSAndroid Build Coastguard Worker __slots__ = ('__weakref__',) 401*cda5da8dSAndroid Build Coastguard Worker 402*cda5da8dSAndroid Build Coastguard Worker def __init_subclass__(cls, /, *args, **kwds): 403*cda5da8dSAndroid Build Coastguard Worker if '_root' not in kwds: 404*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Cannot subclass special typing classes") 405*cda5da8dSAndroid Build Coastguard Worker 406*cda5da8dSAndroid Build Coastguard Workerclass _Immutable: 407*cda5da8dSAndroid Build Coastguard Worker """Mixin to indicate that object should not be copied.""" 408*cda5da8dSAndroid Build Coastguard Worker 409*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 410*cda5da8dSAndroid Build Coastguard Worker 411*cda5da8dSAndroid Build Coastguard Worker def __copy__(self): 412*cda5da8dSAndroid Build Coastguard Worker return self 413*cda5da8dSAndroid Build Coastguard Worker 414*cda5da8dSAndroid Build Coastguard Worker def __deepcopy__(self, memo): 415*cda5da8dSAndroid Build Coastguard Worker return self 416*cda5da8dSAndroid Build Coastguard Worker 417*cda5da8dSAndroid Build Coastguard Worker 418*cda5da8dSAndroid Build Coastguard Workerclass _NotIterable: 419*cda5da8dSAndroid Build Coastguard Worker """Mixin to prevent iteration, without being compatible with Iterable. 420*cda5da8dSAndroid Build Coastguard Worker 421*cda5da8dSAndroid Build Coastguard Worker That is, we could do:: 422*cda5da8dSAndroid Build Coastguard Worker 423*cda5da8dSAndroid Build Coastguard Worker def __iter__(self): raise TypeError() 424*cda5da8dSAndroid Build Coastguard Worker 425*cda5da8dSAndroid Build Coastguard Worker But this would make users of this mixin duck type-compatible with 426*cda5da8dSAndroid Build Coastguard Worker collections.abc.Iterable - isinstance(foo, Iterable) would be True. 427*cda5da8dSAndroid Build Coastguard Worker 428*cda5da8dSAndroid Build Coastguard Worker Luckily, we can instead prevent iteration by setting __iter__ to None, which 429*cda5da8dSAndroid Build Coastguard Worker is treated specially. 430*cda5da8dSAndroid Build Coastguard Worker """ 431*cda5da8dSAndroid Build Coastguard Worker 432*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 433*cda5da8dSAndroid Build Coastguard Worker __iter__ = None 434*cda5da8dSAndroid Build Coastguard Worker 435*cda5da8dSAndroid Build Coastguard Worker 436*cda5da8dSAndroid Build Coastguard Worker# Internal indicator of special typing constructs. 437*cda5da8dSAndroid Build Coastguard Worker# See __doc__ instance attribute for specific docs. 438*cda5da8dSAndroid Build Coastguard Workerclass _SpecialForm(_Final, _NotIterable, _root=True): 439*cda5da8dSAndroid Build Coastguard Worker __slots__ = ('_name', '__doc__', '_getitem') 440*cda5da8dSAndroid Build Coastguard Worker 441*cda5da8dSAndroid Build Coastguard Worker def __init__(self, getitem): 442*cda5da8dSAndroid Build Coastguard Worker self._getitem = getitem 443*cda5da8dSAndroid Build Coastguard Worker self._name = getitem.__name__ 444*cda5da8dSAndroid Build Coastguard Worker self.__doc__ = getitem.__doc__ 445*cda5da8dSAndroid Build Coastguard Worker 446*cda5da8dSAndroid Build Coastguard Worker def __getattr__(self, item): 447*cda5da8dSAndroid Build Coastguard Worker if item in {'__name__', '__qualname__'}: 448*cda5da8dSAndroid Build Coastguard Worker return self._name 449*cda5da8dSAndroid Build Coastguard Worker 450*cda5da8dSAndroid Build Coastguard Worker raise AttributeError(item) 451*cda5da8dSAndroid Build Coastguard Worker 452*cda5da8dSAndroid Build Coastguard Worker def __mro_entries__(self, bases): 453*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Cannot subclass {self!r}") 454*cda5da8dSAndroid Build Coastguard Worker 455*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 456*cda5da8dSAndroid Build Coastguard Worker return 'typing.' + self._name 457*cda5da8dSAndroid Build Coastguard Worker 458*cda5da8dSAndroid Build Coastguard Worker def __reduce__(self): 459*cda5da8dSAndroid Build Coastguard Worker return self._name 460*cda5da8dSAndroid Build Coastguard Worker 461*cda5da8dSAndroid Build Coastguard Worker def __call__(self, *args, **kwds): 462*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Cannot instantiate {self!r}") 463*cda5da8dSAndroid Build Coastguard Worker 464*cda5da8dSAndroid Build Coastguard Worker def __or__(self, other): 465*cda5da8dSAndroid Build Coastguard Worker return Union[self, other] 466*cda5da8dSAndroid Build Coastguard Worker 467*cda5da8dSAndroid Build Coastguard Worker def __ror__(self, other): 468*cda5da8dSAndroid Build Coastguard Worker return Union[other, self] 469*cda5da8dSAndroid Build Coastguard Worker 470*cda5da8dSAndroid Build Coastguard Worker def __instancecheck__(self, obj): 471*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{self} cannot be used with isinstance()") 472*cda5da8dSAndroid Build Coastguard Worker 473*cda5da8dSAndroid Build Coastguard Worker def __subclasscheck__(self, cls): 474*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{self} cannot be used with issubclass()") 475*cda5da8dSAndroid Build Coastguard Worker 476*cda5da8dSAndroid Build Coastguard Worker @_tp_cache 477*cda5da8dSAndroid Build Coastguard Worker def __getitem__(self, parameters): 478*cda5da8dSAndroid Build Coastguard Worker return self._getitem(self, parameters) 479*cda5da8dSAndroid Build Coastguard Worker 480*cda5da8dSAndroid Build Coastguard Worker 481*cda5da8dSAndroid Build Coastguard Workerclass _LiteralSpecialForm(_SpecialForm, _root=True): 482*cda5da8dSAndroid Build Coastguard Worker def __getitem__(self, parameters): 483*cda5da8dSAndroid Build Coastguard Worker if not isinstance(parameters, tuple): 484*cda5da8dSAndroid Build Coastguard Worker parameters = (parameters,) 485*cda5da8dSAndroid Build Coastguard Worker return self._getitem(self, *parameters) 486*cda5da8dSAndroid Build Coastguard Worker 487*cda5da8dSAndroid Build Coastguard Worker 488*cda5da8dSAndroid Build Coastguard Workerclass _AnyMeta(type): 489*cda5da8dSAndroid Build Coastguard Worker def __instancecheck__(self, obj): 490*cda5da8dSAndroid Build Coastguard Worker if self is Any: 491*cda5da8dSAndroid Build Coastguard Worker raise TypeError("typing.Any cannot be used with isinstance()") 492*cda5da8dSAndroid Build Coastguard Worker return super().__instancecheck__(obj) 493*cda5da8dSAndroid Build Coastguard Worker 494*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 495*cda5da8dSAndroid Build Coastguard Worker if self is Any: 496*cda5da8dSAndroid Build Coastguard Worker return "typing.Any" 497*cda5da8dSAndroid Build Coastguard Worker return super().__repr__() # respect to subclasses 498*cda5da8dSAndroid Build Coastguard Worker 499*cda5da8dSAndroid Build Coastguard Worker 500*cda5da8dSAndroid Build Coastguard Workerclass Any(metaclass=_AnyMeta): 501*cda5da8dSAndroid Build Coastguard Worker """Special type indicating an unconstrained type. 502*cda5da8dSAndroid Build Coastguard Worker 503*cda5da8dSAndroid Build Coastguard Worker - Any is compatible with every type. 504*cda5da8dSAndroid Build Coastguard Worker - Any assumed to have all methods. 505*cda5da8dSAndroid Build Coastguard Worker - All values assumed to be instances of Any. 506*cda5da8dSAndroid Build Coastguard Worker 507*cda5da8dSAndroid Build Coastguard Worker Note that all the above statements are true from the point of view of 508*cda5da8dSAndroid Build Coastguard Worker static type checkers. At runtime, Any should not be used with instance 509*cda5da8dSAndroid Build Coastguard Worker checks. 510*cda5da8dSAndroid Build Coastguard Worker """ 511*cda5da8dSAndroid Build Coastguard Worker 512*cda5da8dSAndroid Build Coastguard Worker def __new__(cls, *args, **kwargs): 513*cda5da8dSAndroid Build Coastguard Worker if cls is Any: 514*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Any cannot be instantiated") 515*cda5da8dSAndroid Build Coastguard Worker return super().__new__(cls, *args, **kwargs) 516*cda5da8dSAndroid Build Coastguard Worker 517*cda5da8dSAndroid Build Coastguard Worker 518*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 519*cda5da8dSAndroid Build Coastguard Workerdef NoReturn(self, parameters): 520*cda5da8dSAndroid Build Coastguard Worker """Special type indicating functions that never return. 521*cda5da8dSAndroid Build Coastguard Worker 522*cda5da8dSAndroid Build Coastguard Worker Example:: 523*cda5da8dSAndroid Build Coastguard Worker 524*cda5da8dSAndroid Build Coastguard Worker from typing import NoReturn 525*cda5da8dSAndroid Build Coastguard Worker 526*cda5da8dSAndroid Build Coastguard Worker def stop() -> NoReturn: 527*cda5da8dSAndroid Build Coastguard Worker raise Exception('no way') 528*cda5da8dSAndroid Build Coastguard Worker 529*cda5da8dSAndroid Build Coastguard Worker NoReturn can also be used as a bottom type, a type that 530*cda5da8dSAndroid Build Coastguard Worker has no values. Starting in Python 3.11, the Never type should 531*cda5da8dSAndroid Build Coastguard Worker be used for this concept instead. Type checkers should treat the two 532*cda5da8dSAndroid Build Coastguard Worker equivalently. 533*cda5da8dSAndroid Build Coastguard Worker """ 534*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{self} is not subscriptable") 535*cda5da8dSAndroid Build Coastguard Worker 536*cda5da8dSAndroid Build Coastguard Worker# This is semantically identical to NoReturn, but it is implemented 537*cda5da8dSAndroid Build Coastguard Worker# separately so that type checkers can distinguish between the two 538*cda5da8dSAndroid Build Coastguard Worker# if they want. 539*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 540*cda5da8dSAndroid Build Coastguard Workerdef Never(self, parameters): 541*cda5da8dSAndroid Build Coastguard Worker """The bottom type, a type that has no members. 542*cda5da8dSAndroid Build Coastguard Worker 543*cda5da8dSAndroid Build Coastguard Worker This can be used to define a function that should never be 544*cda5da8dSAndroid Build Coastguard Worker called, or a function that never returns:: 545*cda5da8dSAndroid Build Coastguard Worker 546*cda5da8dSAndroid Build Coastguard Worker from typing import Never 547*cda5da8dSAndroid Build Coastguard Worker 548*cda5da8dSAndroid Build Coastguard Worker def never_call_me(arg: Never) -> None: 549*cda5da8dSAndroid Build Coastguard Worker pass 550*cda5da8dSAndroid Build Coastguard Worker 551*cda5da8dSAndroid Build Coastguard Worker def int_or_str(arg: int | str) -> None: 552*cda5da8dSAndroid Build Coastguard Worker never_call_me(arg) # type checker error 553*cda5da8dSAndroid Build Coastguard Worker match arg: 554*cda5da8dSAndroid Build Coastguard Worker case int(): 555*cda5da8dSAndroid Build Coastguard Worker print("It's an int") 556*cda5da8dSAndroid Build Coastguard Worker case str(): 557*cda5da8dSAndroid Build Coastguard Worker print("It's a str") 558*cda5da8dSAndroid Build Coastguard Worker case _: 559*cda5da8dSAndroid Build Coastguard Worker never_call_me(arg) # ok, arg is of type Never 560*cda5da8dSAndroid Build Coastguard Worker """ 561*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{self} is not subscriptable") 562*cda5da8dSAndroid Build Coastguard Worker 563*cda5da8dSAndroid Build Coastguard Worker 564*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 565*cda5da8dSAndroid Build Coastguard Workerdef Self(self, parameters): 566*cda5da8dSAndroid Build Coastguard Worker """Used to spell the type of "self" in classes. 567*cda5da8dSAndroid Build Coastguard Worker 568*cda5da8dSAndroid Build Coastguard Worker Example:: 569*cda5da8dSAndroid Build Coastguard Worker 570*cda5da8dSAndroid Build Coastguard Worker from typing import Self 571*cda5da8dSAndroid Build Coastguard Worker 572*cda5da8dSAndroid Build Coastguard Worker class Foo: 573*cda5da8dSAndroid Build Coastguard Worker def return_self(self) -> Self: 574*cda5da8dSAndroid Build Coastguard Worker ... 575*cda5da8dSAndroid Build Coastguard Worker return self 576*cda5da8dSAndroid Build Coastguard Worker 577*cda5da8dSAndroid Build Coastguard Worker This is especially useful for: 578*cda5da8dSAndroid Build Coastguard Worker - classmethods that are used as alternative constructors 579*cda5da8dSAndroid Build Coastguard Worker - annotating an `__enter__` method which returns self 580*cda5da8dSAndroid Build Coastguard Worker """ 581*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{self} is not subscriptable") 582*cda5da8dSAndroid Build Coastguard Worker 583*cda5da8dSAndroid Build Coastguard Worker 584*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 585*cda5da8dSAndroid Build Coastguard Workerdef LiteralString(self, parameters): 586*cda5da8dSAndroid Build Coastguard Worker """Represents an arbitrary literal string. 587*cda5da8dSAndroid Build Coastguard Worker 588*cda5da8dSAndroid Build Coastguard Worker Example:: 589*cda5da8dSAndroid Build Coastguard Worker 590*cda5da8dSAndroid Build Coastguard Worker from typing import LiteralString 591*cda5da8dSAndroid Build Coastguard Worker 592*cda5da8dSAndroid Build Coastguard Worker def run_query(sql: LiteralString) -> ... 593*cda5da8dSAndroid Build Coastguard Worker ... 594*cda5da8dSAndroid Build Coastguard Worker 595*cda5da8dSAndroid Build Coastguard Worker def caller(arbitrary_string: str, literal_string: LiteralString) -> None: 596*cda5da8dSAndroid Build Coastguard Worker run_query("SELECT * FROM students") # ok 597*cda5da8dSAndroid Build Coastguard Worker run_query(literal_string) # ok 598*cda5da8dSAndroid Build Coastguard Worker run_query("SELECT * FROM " + literal_string) # ok 599*cda5da8dSAndroid Build Coastguard Worker run_query(arbitrary_string) # type checker error 600*cda5da8dSAndroid Build Coastguard Worker run_query( # type checker error 601*cda5da8dSAndroid Build Coastguard Worker f"SELECT * FROM students WHERE name = {arbitrary_string}" 602*cda5da8dSAndroid Build Coastguard Worker ) 603*cda5da8dSAndroid Build Coastguard Worker 604*cda5da8dSAndroid Build Coastguard Worker Only string literals and other LiteralStrings are compatible 605*cda5da8dSAndroid Build Coastguard Worker with LiteralString. This provides a tool to help prevent 606*cda5da8dSAndroid Build Coastguard Worker security issues such as SQL injection. 607*cda5da8dSAndroid Build Coastguard Worker """ 608*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{self} is not subscriptable") 609*cda5da8dSAndroid Build Coastguard Worker 610*cda5da8dSAndroid Build Coastguard Worker 611*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 612*cda5da8dSAndroid Build Coastguard Workerdef ClassVar(self, parameters): 613*cda5da8dSAndroid Build Coastguard Worker """Special type construct to mark class variables. 614*cda5da8dSAndroid Build Coastguard Worker 615*cda5da8dSAndroid Build Coastguard Worker An annotation wrapped in ClassVar indicates that a given 616*cda5da8dSAndroid Build Coastguard Worker attribute is intended to be used as a class variable and 617*cda5da8dSAndroid Build Coastguard Worker should not be set on instances of that class. Usage:: 618*cda5da8dSAndroid Build Coastguard Worker 619*cda5da8dSAndroid Build Coastguard Worker class Starship: 620*cda5da8dSAndroid Build Coastguard Worker stats: ClassVar[Dict[str, int]] = {} # class variable 621*cda5da8dSAndroid Build Coastguard Worker damage: int = 10 # instance variable 622*cda5da8dSAndroid Build Coastguard Worker 623*cda5da8dSAndroid Build Coastguard Worker ClassVar accepts only types and cannot be further subscribed. 624*cda5da8dSAndroid Build Coastguard Worker 625*cda5da8dSAndroid Build Coastguard Worker Note that ClassVar is not a class itself, and should not 626*cda5da8dSAndroid Build Coastguard Worker be used with isinstance() or issubclass(). 627*cda5da8dSAndroid Build Coastguard Worker """ 628*cda5da8dSAndroid Build Coastguard Worker item = _type_check(parameters, f'{self} accepts only single type.') 629*cda5da8dSAndroid Build Coastguard Worker return _GenericAlias(self, (item,)) 630*cda5da8dSAndroid Build Coastguard Worker 631*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 632*cda5da8dSAndroid Build Coastguard Workerdef Final(self, parameters): 633*cda5da8dSAndroid Build Coastguard Worker """Special typing construct to indicate final names to type checkers. 634*cda5da8dSAndroid Build Coastguard Worker 635*cda5da8dSAndroid Build Coastguard Worker A final name cannot be re-assigned or overridden in a subclass. 636*cda5da8dSAndroid Build Coastguard Worker 637*cda5da8dSAndroid Build Coastguard Worker For example:: 638*cda5da8dSAndroid Build Coastguard Worker 639*cda5da8dSAndroid Build Coastguard Worker MAX_SIZE: Final = 9000 640*cda5da8dSAndroid Build Coastguard Worker MAX_SIZE += 1 # Error reported by type checker 641*cda5da8dSAndroid Build Coastguard Worker 642*cda5da8dSAndroid Build Coastguard Worker class Connection: 643*cda5da8dSAndroid Build Coastguard Worker TIMEOUT: Final[int] = 10 644*cda5da8dSAndroid Build Coastguard Worker 645*cda5da8dSAndroid Build Coastguard Worker class FastConnector(Connection): 646*cda5da8dSAndroid Build Coastguard Worker TIMEOUT = 1 # Error reported by type checker 647*cda5da8dSAndroid Build Coastguard Worker 648*cda5da8dSAndroid Build Coastguard Worker There is no runtime checking of these properties. 649*cda5da8dSAndroid Build Coastguard Worker """ 650*cda5da8dSAndroid Build Coastguard Worker item = _type_check(parameters, f'{self} accepts only single type.') 651*cda5da8dSAndroid Build Coastguard Worker return _GenericAlias(self, (item,)) 652*cda5da8dSAndroid Build Coastguard Worker 653*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 654*cda5da8dSAndroid Build Coastguard Workerdef Union(self, parameters): 655*cda5da8dSAndroid Build Coastguard Worker """Union type; Union[X, Y] means either X or Y. 656*cda5da8dSAndroid Build Coastguard Worker 657*cda5da8dSAndroid Build Coastguard Worker On Python 3.10 and higher, the | operator 658*cda5da8dSAndroid Build Coastguard Worker can also be used to denote unions; 659*cda5da8dSAndroid Build Coastguard Worker X | Y means the same thing to the type checker as Union[X, Y]. 660*cda5da8dSAndroid Build Coastguard Worker 661*cda5da8dSAndroid Build Coastguard Worker To define a union, use e.g. Union[int, str]. Details: 662*cda5da8dSAndroid Build Coastguard Worker - The arguments must be types and there must be at least one. 663*cda5da8dSAndroid Build Coastguard Worker - None as an argument is a special case and is replaced by 664*cda5da8dSAndroid Build Coastguard Worker type(None). 665*cda5da8dSAndroid Build Coastguard Worker - Unions of unions are flattened, e.g.:: 666*cda5da8dSAndroid Build Coastguard Worker 667*cda5da8dSAndroid Build Coastguard Worker assert Union[Union[int, str], float] == Union[int, str, float] 668*cda5da8dSAndroid Build Coastguard Worker 669*cda5da8dSAndroid Build Coastguard Worker - Unions of a single argument vanish, e.g.:: 670*cda5da8dSAndroid Build Coastguard Worker 671*cda5da8dSAndroid Build Coastguard Worker assert Union[int] == int # The constructor actually returns int 672*cda5da8dSAndroid Build Coastguard Worker 673*cda5da8dSAndroid Build Coastguard Worker - Redundant arguments are skipped, e.g.:: 674*cda5da8dSAndroid Build Coastguard Worker 675*cda5da8dSAndroid Build Coastguard Worker assert Union[int, str, int] == Union[int, str] 676*cda5da8dSAndroid Build Coastguard Worker 677*cda5da8dSAndroid Build Coastguard Worker - When comparing unions, the argument order is ignored, e.g.:: 678*cda5da8dSAndroid Build Coastguard Worker 679*cda5da8dSAndroid Build Coastguard Worker assert Union[int, str] == Union[str, int] 680*cda5da8dSAndroid Build Coastguard Worker 681*cda5da8dSAndroid Build Coastguard Worker - You cannot subclass or instantiate a union. 682*cda5da8dSAndroid Build Coastguard Worker - You can use Optional[X] as a shorthand for Union[X, None]. 683*cda5da8dSAndroid Build Coastguard Worker """ 684*cda5da8dSAndroid Build Coastguard Worker if parameters == (): 685*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Cannot take a Union of no types.") 686*cda5da8dSAndroid Build Coastguard Worker if not isinstance(parameters, tuple): 687*cda5da8dSAndroid Build Coastguard Worker parameters = (parameters,) 688*cda5da8dSAndroid Build Coastguard Worker msg = "Union[arg, ...]: each arg must be a type." 689*cda5da8dSAndroid Build Coastguard Worker parameters = tuple(_type_check(p, msg) for p in parameters) 690*cda5da8dSAndroid Build Coastguard Worker parameters = _remove_dups_flatten(parameters) 691*cda5da8dSAndroid Build Coastguard Worker if len(parameters) == 1: 692*cda5da8dSAndroid Build Coastguard Worker return parameters[0] 693*cda5da8dSAndroid Build Coastguard Worker if len(parameters) == 2 and type(None) in parameters: 694*cda5da8dSAndroid Build Coastguard Worker return _UnionGenericAlias(self, parameters, name="Optional") 695*cda5da8dSAndroid Build Coastguard Worker return _UnionGenericAlias(self, parameters) 696*cda5da8dSAndroid Build Coastguard Worker 697*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 698*cda5da8dSAndroid Build Coastguard Workerdef Optional(self, parameters): 699*cda5da8dSAndroid Build Coastguard Worker """Optional[X] is equivalent to Union[X, None].""" 700*cda5da8dSAndroid Build Coastguard Worker arg = _type_check(parameters, f"{self} requires a single type.") 701*cda5da8dSAndroid Build Coastguard Worker return Union[arg, type(None)] 702*cda5da8dSAndroid Build Coastguard Worker 703*cda5da8dSAndroid Build Coastguard Worker@_LiteralSpecialForm 704*cda5da8dSAndroid Build Coastguard Worker@_tp_cache(typed=True) 705*cda5da8dSAndroid Build Coastguard Workerdef Literal(self, *parameters): 706*cda5da8dSAndroid Build Coastguard Worker """Special typing form to define literal types (a.k.a. value types). 707*cda5da8dSAndroid Build Coastguard Worker 708*cda5da8dSAndroid Build Coastguard Worker This form can be used to indicate to type checkers that the corresponding 709*cda5da8dSAndroid Build Coastguard Worker variable or function parameter has a value equivalent to the provided 710*cda5da8dSAndroid Build Coastguard Worker literal (or one of several literals):: 711*cda5da8dSAndroid Build Coastguard Worker 712*cda5da8dSAndroid Build Coastguard Worker def validate_simple(data: Any) -> Literal[True]: # always returns True 713*cda5da8dSAndroid Build Coastguard Worker ... 714*cda5da8dSAndroid Build Coastguard Worker 715*cda5da8dSAndroid Build Coastguard Worker MODE = Literal['r', 'rb', 'w', 'wb'] 716*cda5da8dSAndroid Build Coastguard Worker def open_helper(file: str, mode: MODE) -> str: 717*cda5da8dSAndroid Build Coastguard Worker ... 718*cda5da8dSAndroid Build Coastguard Worker 719*cda5da8dSAndroid Build Coastguard Worker open_helper('/some/path', 'r') # Passes type check 720*cda5da8dSAndroid Build Coastguard Worker open_helper('/other/path', 'typo') # Error in type checker 721*cda5da8dSAndroid Build Coastguard Worker 722*cda5da8dSAndroid Build Coastguard Worker Literal[...] cannot be subclassed. At runtime, an arbitrary value 723*cda5da8dSAndroid Build Coastguard Worker is allowed as type argument to Literal[...], but type checkers may 724*cda5da8dSAndroid Build Coastguard Worker impose restrictions. 725*cda5da8dSAndroid Build Coastguard Worker """ 726*cda5da8dSAndroid Build Coastguard Worker # There is no '_type_check' call because arguments to Literal[...] are 727*cda5da8dSAndroid Build Coastguard Worker # values, not types. 728*cda5da8dSAndroid Build Coastguard Worker parameters = _flatten_literal_params(parameters) 729*cda5da8dSAndroid Build Coastguard Worker 730*cda5da8dSAndroid Build Coastguard Worker try: 731*cda5da8dSAndroid Build Coastguard Worker parameters = tuple(p for p, _ in _deduplicate(list(_value_and_type_iter(parameters)))) 732*cda5da8dSAndroid Build Coastguard Worker except TypeError: # unhashable parameters 733*cda5da8dSAndroid Build Coastguard Worker pass 734*cda5da8dSAndroid Build Coastguard Worker 735*cda5da8dSAndroid Build Coastguard Worker return _LiteralGenericAlias(self, parameters) 736*cda5da8dSAndroid Build Coastguard Worker 737*cda5da8dSAndroid Build Coastguard Worker 738*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 739*cda5da8dSAndroid Build Coastguard Workerdef TypeAlias(self, parameters): 740*cda5da8dSAndroid Build Coastguard Worker """Special form for marking type aliases. 741*cda5da8dSAndroid Build Coastguard Worker 742*cda5da8dSAndroid Build Coastguard Worker Use TypeAlias to indicate that an assignment should 743*cda5da8dSAndroid Build Coastguard Worker be recognized as a proper type alias definition by type 744*cda5da8dSAndroid Build Coastguard Worker checkers. For example:: 745*cda5da8dSAndroid Build Coastguard Worker 746*cda5da8dSAndroid Build Coastguard Worker Predicate: TypeAlias = Callable[..., bool] 747*cda5da8dSAndroid Build Coastguard Worker 748*cda5da8dSAndroid Build Coastguard Worker It's invalid when used anywhere except as in the example above. 749*cda5da8dSAndroid Build Coastguard Worker """ 750*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{self} is not subscriptable") 751*cda5da8dSAndroid Build Coastguard Worker 752*cda5da8dSAndroid Build Coastguard Worker 753*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 754*cda5da8dSAndroid Build Coastguard Workerdef Concatenate(self, parameters): 755*cda5da8dSAndroid Build Coastguard Worker """Special form for annotating higher-order functions. 756*cda5da8dSAndroid Build Coastguard Worker 757*cda5da8dSAndroid Build Coastguard Worker ``Concatenate`` can be sed in conjunction with ``ParamSpec`` and 758*cda5da8dSAndroid Build Coastguard Worker ``Callable`` to represent a higher order function which adds, removes or 759*cda5da8dSAndroid Build Coastguard Worker transforms the parameters of a callable. 760*cda5da8dSAndroid Build Coastguard Worker 761*cda5da8dSAndroid Build Coastguard Worker For example:: 762*cda5da8dSAndroid Build Coastguard Worker 763*cda5da8dSAndroid Build Coastguard Worker Callable[Concatenate[int, P], int] 764*cda5da8dSAndroid Build Coastguard Worker 765*cda5da8dSAndroid Build Coastguard Worker See PEP 612 for detailed information. 766*cda5da8dSAndroid Build Coastguard Worker """ 767*cda5da8dSAndroid Build Coastguard Worker if parameters == (): 768*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Cannot take a Concatenate of no types.") 769*cda5da8dSAndroid Build Coastguard Worker if not isinstance(parameters, tuple): 770*cda5da8dSAndroid Build Coastguard Worker parameters = (parameters,) 771*cda5da8dSAndroid Build Coastguard Worker if not (parameters[-1] is ... or isinstance(parameters[-1], ParamSpec)): 772*cda5da8dSAndroid Build Coastguard Worker raise TypeError("The last parameter to Concatenate should be a " 773*cda5da8dSAndroid Build Coastguard Worker "ParamSpec variable or ellipsis.") 774*cda5da8dSAndroid Build Coastguard Worker msg = "Concatenate[arg, ...]: each arg must be a type." 775*cda5da8dSAndroid Build Coastguard Worker parameters = (*(_type_check(p, msg) for p in parameters[:-1]), parameters[-1]) 776*cda5da8dSAndroid Build Coastguard Worker return _ConcatenateGenericAlias(self, parameters, 777*cda5da8dSAndroid Build Coastguard Worker _paramspec_tvars=True) 778*cda5da8dSAndroid Build Coastguard Worker 779*cda5da8dSAndroid Build Coastguard Worker 780*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 781*cda5da8dSAndroid Build Coastguard Workerdef TypeGuard(self, parameters): 782*cda5da8dSAndroid Build Coastguard Worker """Special typing construct for marking user-defined type guard functions. 783*cda5da8dSAndroid Build Coastguard Worker 784*cda5da8dSAndroid Build Coastguard Worker ``TypeGuard`` can be used to annotate the return type of a user-defined 785*cda5da8dSAndroid Build Coastguard Worker type guard function. ``TypeGuard`` only accepts a single type argument. 786*cda5da8dSAndroid Build Coastguard Worker At runtime, functions marked this way should return a boolean. 787*cda5da8dSAndroid Build Coastguard Worker 788*cda5da8dSAndroid Build Coastguard Worker ``TypeGuard`` aims to benefit *type narrowing* -- a technique used by static 789*cda5da8dSAndroid Build Coastguard Worker type checkers to determine a more precise type of an expression within a 790*cda5da8dSAndroid Build Coastguard Worker program's code flow. Usually type narrowing is done by analyzing 791*cda5da8dSAndroid Build Coastguard Worker conditional code flow and applying the narrowing to a block of code. The 792*cda5da8dSAndroid Build Coastguard Worker conditional expression here is sometimes referred to as a "type guard". 793*cda5da8dSAndroid Build Coastguard Worker 794*cda5da8dSAndroid Build Coastguard Worker Sometimes it would be convenient to use a user-defined boolean function 795*cda5da8dSAndroid Build Coastguard Worker as a type guard. Such a function should use ``TypeGuard[...]`` as its 796*cda5da8dSAndroid Build Coastguard Worker return type to alert static type checkers to this intention. 797*cda5da8dSAndroid Build Coastguard Worker 798*cda5da8dSAndroid Build Coastguard Worker Using ``-> TypeGuard`` tells the static type checker that for a given 799*cda5da8dSAndroid Build Coastguard Worker function: 800*cda5da8dSAndroid Build Coastguard Worker 801*cda5da8dSAndroid Build Coastguard Worker 1. The return value is a boolean. 802*cda5da8dSAndroid Build Coastguard Worker 2. If the return value is ``True``, the type of its argument 803*cda5da8dSAndroid Build Coastguard Worker is the type inside ``TypeGuard``. 804*cda5da8dSAndroid Build Coastguard Worker 805*cda5da8dSAndroid Build Coastguard Worker For example:: 806*cda5da8dSAndroid Build Coastguard Worker 807*cda5da8dSAndroid Build Coastguard Worker def is_str(val: Union[str, float]): 808*cda5da8dSAndroid Build Coastguard Worker # "isinstance" type guard 809*cda5da8dSAndroid Build Coastguard Worker if isinstance(val, str): 810*cda5da8dSAndroid Build Coastguard Worker # Type of ``val`` is narrowed to ``str`` 811*cda5da8dSAndroid Build Coastguard Worker ... 812*cda5da8dSAndroid Build Coastguard Worker else: 813*cda5da8dSAndroid Build Coastguard Worker # Else, type of ``val`` is narrowed to ``float``. 814*cda5da8dSAndroid Build Coastguard Worker ... 815*cda5da8dSAndroid Build Coastguard Worker 816*cda5da8dSAndroid Build Coastguard Worker Strict type narrowing is not enforced -- ``TypeB`` need not be a narrower 817*cda5da8dSAndroid Build Coastguard Worker form of ``TypeA`` (it can even be a wider form) and this may lead to 818*cda5da8dSAndroid Build Coastguard Worker type-unsafe results. The main reason is to allow for things like 819*cda5da8dSAndroid Build Coastguard Worker narrowing ``List[object]`` to ``List[str]`` even though the latter is not 820*cda5da8dSAndroid Build Coastguard Worker a subtype of the former, since ``List`` is invariant. The responsibility of 821*cda5da8dSAndroid Build Coastguard Worker writing type-safe type guards is left to the user. 822*cda5da8dSAndroid Build Coastguard Worker 823*cda5da8dSAndroid Build Coastguard Worker ``TypeGuard`` also works with type variables. For more information, see 824*cda5da8dSAndroid Build Coastguard Worker PEP 647 (User-Defined Type Guards). 825*cda5da8dSAndroid Build Coastguard Worker """ 826*cda5da8dSAndroid Build Coastguard Worker item = _type_check(parameters, f'{self} accepts only single type.') 827*cda5da8dSAndroid Build Coastguard Worker return _GenericAlias(self, (item,)) 828*cda5da8dSAndroid Build Coastguard Worker 829*cda5da8dSAndroid Build Coastguard Worker 830*cda5da8dSAndroid Build Coastguard Workerclass ForwardRef(_Final, _root=True): 831*cda5da8dSAndroid Build Coastguard Worker """Internal wrapper to hold a forward reference.""" 832*cda5da8dSAndroid Build Coastguard Worker 833*cda5da8dSAndroid Build Coastguard Worker __slots__ = ('__forward_arg__', '__forward_code__', 834*cda5da8dSAndroid Build Coastguard Worker '__forward_evaluated__', '__forward_value__', 835*cda5da8dSAndroid Build Coastguard Worker '__forward_is_argument__', '__forward_is_class__', 836*cda5da8dSAndroid Build Coastguard Worker '__forward_module__') 837*cda5da8dSAndroid Build Coastguard Worker 838*cda5da8dSAndroid Build Coastguard Worker def __init__(self, arg, is_argument=True, module=None, *, is_class=False): 839*cda5da8dSAndroid Build Coastguard Worker if not isinstance(arg, str): 840*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Forward reference must be a string -- got {arg!r}") 841*cda5da8dSAndroid Build Coastguard Worker 842*cda5da8dSAndroid Build Coastguard Worker # If we do `def f(*args: *Ts)`, then we'll have `arg = '*Ts'`. 843*cda5da8dSAndroid Build Coastguard Worker # Unfortunately, this isn't a valid expression on its own, so we 844*cda5da8dSAndroid Build Coastguard Worker # do the unpacking manually. 845*cda5da8dSAndroid Build Coastguard Worker if arg[0] == '*': 846*cda5da8dSAndroid Build Coastguard Worker arg_to_compile = f'({arg},)[0]' # E.g. (*Ts,)[0] or (*tuple[int, int],)[0] 847*cda5da8dSAndroid Build Coastguard Worker else: 848*cda5da8dSAndroid Build Coastguard Worker arg_to_compile = arg 849*cda5da8dSAndroid Build Coastguard Worker try: 850*cda5da8dSAndroid Build Coastguard Worker code = compile(arg_to_compile, '<string>', 'eval') 851*cda5da8dSAndroid Build Coastguard Worker except SyntaxError: 852*cda5da8dSAndroid Build Coastguard Worker raise SyntaxError(f"Forward reference must be an expression -- got {arg!r}") 853*cda5da8dSAndroid Build Coastguard Worker 854*cda5da8dSAndroid Build Coastguard Worker self.__forward_arg__ = arg 855*cda5da8dSAndroid Build Coastguard Worker self.__forward_code__ = code 856*cda5da8dSAndroid Build Coastguard Worker self.__forward_evaluated__ = False 857*cda5da8dSAndroid Build Coastguard Worker self.__forward_value__ = None 858*cda5da8dSAndroid Build Coastguard Worker self.__forward_is_argument__ = is_argument 859*cda5da8dSAndroid Build Coastguard Worker self.__forward_is_class__ = is_class 860*cda5da8dSAndroid Build Coastguard Worker self.__forward_module__ = module 861*cda5da8dSAndroid Build Coastguard Worker 862*cda5da8dSAndroid Build Coastguard Worker def _evaluate(self, globalns, localns, recursive_guard): 863*cda5da8dSAndroid Build Coastguard Worker if self.__forward_arg__ in recursive_guard: 864*cda5da8dSAndroid Build Coastguard Worker return self 865*cda5da8dSAndroid Build Coastguard Worker if not self.__forward_evaluated__ or localns is not globalns: 866*cda5da8dSAndroid Build Coastguard Worker if globalns is None and localns is None: 867*cda5da8dSAndroid Build Coastguard Worker globalns = localns = {} 868*cda5da8dSAndroid Build Coastguard Worker elif globalns is None: 869*cda5da8dSAndroid Build Coastguard Worker globalns = localns 870*cda5da8dSAndroid Build Coastguard Worker elif localns is None: 871*cda5da8dSAndroid Build Coastguard Worker localns = globalns 872*cda5da8dSAndroid Build Coastguard Worker if self.__forward_module__ is not None: 873*cda5da8dSAndroid Build Coastguard Worker globalns = getattr( 874*cda5da8dSAndroid Build Coastguard Worker sys.modules.get(self.__forward_module__, None), '__dict__', globalns 875*cda5da8dSAndroid Build Coastguard Worker ) 876*cda5da8dSAndroid Build Coastguard Worker type_ = _type_check( 877*cda5da8dSAndroid Build Coastguard Worker eval(self.__forward_code__, globalns, localns), 878*cda5da8dSAndroid Build Coastguard Worker "Forward references must evaluate to types.", 879*cda5da8dSAndroid Build Coastguard Worker is_argument=self.__forward_is_argument__, 880*cda5da8dSAndroid Build Coastguard Worker allow_special_forms=self.__forward_is_class__, 881*cda5da8dSAndroid Build Coastguard Worker ) 882*cda5da8dSAndroid Build Coastguard Worker self.__forward_value__ = _eval_type( 883*cda5da8dSAndroid Build Coastguard Worker type_, globalns, localns, recursive_guard | {self.__forward_arg__} 884*cda5da8dSAndroid Build Coastguard Worker ) 885*cda5da8dSAndroid Build Coastguard Worker self.__forward_evaluated__ = True 886*cda5da8dSAndroid Build Coastguard Worker return self.__forward_value__ 887*cda5da8dSAndroid Build Coastguard Worker 888*cda5da8dSAndroid Build Coastguard Worker def __eq__(self, other): 889*cda5da8dSAndroid Build Coastguard Worker if not isinstance(other, ForwardRef): 890*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 891*cda5da8dSAndroid Build Coastguard Worker if self.__forward_evaluated__ and other.__forward_evaluated__: 892*cda5da8dSAndroid Build Coastguard Worker return (self.__forward_arg__ == other.__forward_arg__ and 893*cda5da8dSAndroid Build Coastguard Worker self.__forward_value__ == other.__forward_value__) 894*cda5da8dSAndroid Build Coastguard Worker return (self.__forward_arg__ == other.__forward_arg__ and 895*cda5da8dSAndroid Build Coastguard Worker self.__forward_module__ == other.__forward_module__) 896*cda5da8dSAndroid Build Coastguard Worker 897*cda5da8dSAndroid Build Coastguard Worker def __hash__(self): 898*cda5da8dSAndroid Build Coastguard Worker return hash((self.__forward_arg__, self.__forward_module__)) 899*cda5da8dSAndroid Build Coastguard Worker 900*cda5da8dSAndroid Build Coastguard Worker def __or__(self, other): 901*cda5da8dSAndroid Build Coastguard Worker return Union[self, other] 902*cda5da8dSAndroid Build Coastguard Worker 903*cda5da8dSAndroid Build Coastguard Worker def __ror__(self, other): 904*cda5da8dSAndroid Build Coastguard Worker return Union[other, self] 905*cda5da8dSAndroid Build Coastguard Worker 906*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 907*cda5da8dSAndroid Build Coastguard Worker if self.__forward_module__ is None: 908*cda5da8dSAndroid Build Coastguard Worker module_repr = '' 909*cda5da8dSAndroid Build Coastguard Worker else: 910*cda5da8dSAndroid Build Coastguard Worker module_repr = f', module={self.__forward_module__!r}' 911*cda5da8dSAndroid Build Coastguard Worker return f'ForwardRef({self.__forward_arg__!r}{module_repr})' 912*cda5da8dSAndroid Build Coastguard Worker 913*cda5da8dSAndroid Build Coastguard Worker 914*cda5da8dSAndroid Build Coastguard Workerdef _is_unpacked_typevartuple(x: Any) -> bool: 915*cda5da8dSAndroid Build Coastguard Worker return ((not isinstance(x, type)) and 916*cda5da8dSAndroid Build Coastguard Worker getattr(x, '__typing_is_unpacked_typevartuple__', False)) 917*cda5da8dSAndroid Build Coastguard Worker 918*cda5da8dSAndroid Build Coastguard Worker 919*cda5da8dSAndroid Build Coastguard Workerdef _is_typevar_like(x: Any) -> bool: 920*cda5da8dSAndroid Build Coastguard Worker return isinstance(x, (TypeVar, ParamSpec)) or _is_unpacked_typevartuple(x) 921*cda5da8dSAndroid Build Coastguard Worker 922*cda5da8dSAndroid Build Coastguard Worker 923*cda5da8dSAndroid Build Coastguard Workerclass _PickleUsingNameMixin: 924*cda5da8dSAndroid Build Coastguard Worker """Mixin enabling pickling based on self.__name__.""" 925*cda5da8dSAndroid Build Coastguard Worker 926*cda5da8dSAndroid Build Coastguard Worker def __reduce__(self): 927*cda5da8dSAndroid Build Coastguard Worker return self.__name__ 928*cda5da8dSAndroid Build Coastguard Worker 929*cda5da8dSAndroid Build Coastguard Worker 930*cda5da8dSAndroid Build Coastguard Workerclass _BoundVarianceMixin: 931*cda5da8dSAndroid Build Coastguard Worker """Mixin giving __init__ bound and variance arguments. 932*cda5da8dSAndroid Build Coastguard Worker 933*cda5da8dSAndroid Build Coastguard Worker This is used by TypeVar and ParamSpec, which both employ the notions of 934*cda5da8dSAndroid Build Coastguard Worker a type 'bound' (restricting type arguments to be a subtype of some 935*cda5da8dSAndroid Build Coastguard Worker specified type) and type 'variance' (determining subtype relations between 936*cda5da8dSAndroid Build Coastguard Worker generic types). 937*cda5da8dSAndroid Build Coastguard Worker """ 938*cda5da8dSAndroid Build Coastguard Worker def __init__(self, bound, covariant, contravariant): 939*cda5da8dSAndroid Build Coastguard Worker """Used to setup TypeVars and ParamSpec's bound, covariant and 940*cda5da8dSAndroid Build Coastguard Worker contravariant attributes. 941*cda5da8dSAndroid Build Coastguard Worker """ 942*cda5da8dSAndroid Build Coastguard Worker if covariant and contravariant: 943*cda5da8dSAndroid Build Coastguard Worker raise ValueError("Bivariant types are not supported.") 944*cda5da8dSAndroid Build Coastguard Worker self.__covariant__ = bool(covariant) 945*cda5da8dSAndroid Build Coastguard Worker self.__contravariant__ = bool(contravariant) 946*cda5da8dSAndroid Build Coastguard Worker if bound: 947*cda5da8dSAndroid Build Coastguard Worker self.__bound__ = _type_check(bound, "Bound must be a type.") 948*cda5da8dSAndroid Build Coastguard Worker else: 949*cda5da8dSAndroid Build Coastguard Worker self.__bound__ = None 950*cda5da8dSAndroid Build Coastguard Worker 951*cda5da8dSAndroid Build Coastguard Worker def __or__(self, right): 952*cda5da8dSAndroid Build Coastguard Worker return Union[self, right] 953*cda5da8dSAndroid Build Coastguard Worker 954*cda5da8dSAndroid Build Coastguard Worker def __ror__(self, left): 955*cda5da8dSAndroid Build Coastguard Worker return Union[left, self] 956*cda5da8dSAndroid Build Coastguard Worker 957*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 958*cda5da8dSAndroid Build Coastguard Worker if self.__covariant__: 959*cda5da8dSAndroid Build Coastguard Worker prefix = '+' 960*cda5da8dSAndroid Build Coastguard Worker elif self.__contravariant__: 961*cda5da8dSAndroid Build Coastguard Worker prefix = '-' 962*cda5da8dSAndroid Build Coastguard Worker else: 963*cda5da8dSAndroid Build Coastguard Worker prefix = '~' 964*cda5da8dSAndroid Build Coastguard Worker return prefix + self.__name__ 965*cda5da8dSAndroid Build Coastguard Worker 966*cda5da8dSAndroid Build Coastguard Worker 967*cda5da8dSAndroid Build Coastguard Workerclass TypeVar(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin, 968*cda5da8dSAndroid Build Coastguard Worker _root=True): 969*cda5da8dSAndroid Build Coastguard Worker """Type variable. 970*cda5da8dSAndroid Build Coastguard Worker 971*cda5da8dSAndroid Build Coastguard Worker Usage:: 972*cda5da8dSAndroid Build Coastguard Worker 973*cda5da8dSAndroid Build Coastguard Worker T = TypeVar('T') # Can be anything 974*cda5da8dSAndroid Build Coastguard Worker A = TypeVar('A', str, bytes) # Must be str or bytes 975*cda5da8dSAndroid Build Coastguard Worker 976*cda5da8dSAndroid Build Coastguard Worker Type variables exist primarily for the benefit of static type 977*cda5da8dSAndroid Build Coastguard Worker checkers. They serve as the parameters for generic types as well 978*cda5da8dSAndroid Build Coastguard Worker as for generic function definitions. See class Generic for more 979*cda5da8dSAndroid Build Coastguard Worker information on generic types. Generic functions work as follows: 980*cda5da8dSAndroid Build Coastguard Worker 981*cda5da8dSAndroid Build Coastguard Worker def repeat(x: T, n: int) -> List[T]: 982*cda5da8dSAndroid Build Coastguard Worker '''Return a list containing n references to x.''' 983*cda5da8dSAndroid Build Coastguard Worker return [x]*n 984*cda5da8dSAndroid Build Coastguard Worker 985*cda5da8dSAndroid Build Coastguard Worker def longest(x: A, y: A) -> A: 986*cda5da8dSAndroid Build Coastguard Worker '''Return the longest of two strings.''' 987*cda5da8dSAndroid Build Coastguard Worker return x if len(x) >= len(y) else y 988*cda5da8dSAndroid Build Coastguard Worker 989*cda5da8dSAndroid Build Coastguard Worker The latter example's signature is essentially the overloading 990*cda5da8dSAndroid Build Coastguard Worker of (str, str) -> str and (bytes, bytes) -> bytes. Also note 991*cda5da8dSAndroid Build Coastguard Worker that if the arguments are instances of some subclass of str, 992*cda5da8dSAndroid Build Coastguard Worker the return type is still plain str. 993*cda5da8dSAndroid Build Coastguard Worker 994*cda5da8dSAndroid Build Coastguard Worker At runtime, isinstance(x, T) and issubclass(C, T) will raise TypeError. 995*cda5da8dSAndroid Build Coastguard Worker 996*cda5da8dSAndroid Build Coastguard Worker Type variables defined with covariant=True or contravariant=True 997*cda5da8dSAndroid Build Coastguard Worker can be used to declare covariant or contravariant generic types. 998*cda5da8dSAndroid Build Coastguard Worker See PEP 484 for more details. By default generic types are invariant 999*cda5da8dSAndroid Build Coastguard Worker in all type variables. 1000*cda5da8dSAndroid Build Coastguard Worker 1001*cda5da8dSAndroid Build Coastguard Worker Type variables can be introspected. e.g.: 1002*cda5da8dSAndroid Build Coastguard Worker 1003*cda5da8dSAndroid Build Coastguard Worker T.__name__ == 'T' 1004*cda5da8dSAndroid Build Coastguard Worker T.__constraints__ == () 1005*cda5da8dSAndroid Build Coastguard Worker T.__covariant__ == False 1006*cda5da8dSAndroid Build Coastguard Worker T.__contravariant__ = False 1007*cda5da8dSAndroid Build Coastguard Worker A.__constraints__ == (str, bytes) 1008*cda5da8dSAndroid Build Coastguard Worker 1009*cda5da8dSAndroid Build Coastguard Worker Note that only type variables defined in global scope can be pickled. 1010*cda5da8dSAndroid Build Coastguard Worker """ 1011*cda5da8dSAndroid Build Coastguard Worker 1012*cda5da8dSAndroid Build Coastguard Worker def __init__(self, name, *constraints, bound=None, 1013*cda5da8dSAndroid Build Coastguard Worker covariant=False, contravariant=False): 1014*cda5da8dSAndroid Build Coastguard Worker self.__name__ = name 1015*cda5da8dSAndroid Build Coastguard Worker super().__init__(bound, covariant, contravariant) 1016*cda5da8dSAndroid Build Coastguard Worker if constraints and bound is not None: 1017*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Constraints cannot be combined with bound=...") 1018*cda5da8dSAndroid Build Coastguard Worker if constraints and len(constraints) == 1: 1019*cda5da8dSAndroid Build Coastguard Worker raise TypeError("A single constraint is not allowed") 1020*cda5da8dSAndroid Build Coastguard Worker msg = "TypeVar(name, constraint, ...): constraints must be types." 1021*cda5da8dSAndroid Build Coastguard Worker self.__constraints__ = tuple(_type_check(t, msg) for t in constraints) 1022*cda5da8dSAndroid Build Coastguard Worker def_mod = _caller() 1023*cda5da8dSAndroid Build Coastguard Worker if def_mod != 'typing': 1024*cda5da8dSAndroid Build Coastguard Worker self.__module__ = def_mod 1025*cda5da8dSAndroid Build Coastguard Worker 1026*cda5da8dSAndroid Build Coastguard Worker def __typing_subst__(self, arg): 1027*cda5da8dSAndroid Build Coastguard Worker msg = "Parameters to generic types must be types." 1028*cda5da8dSAndroid Build Coastguard Worker arg = _type_check(arg, msg, is_argument=True) 1029*cda5da8dSAndroid Build Coastguard Worker if ((isinstance(arg, _GenericAlias) and arg.__origin__ is Unpack) or 1030*cda5da8dSAndroid Build Coastguard Worker (isinstance(arg, GenericAlias) and getattr(arg, '__unpacked__', False))): 1031*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{arg} is not valid as type argument") 1032*cda5da8dSAndroid Build Coastguard Worker return arg 1033*cda5da8dSAndroid Build Coastguard Worker 1034*cda5da8dSAndroid Build Coastguard Worker 1035*cda5da8dSAndroid Build Coastguard Workerclass TypeVarTuple(_Final, _Immutable, _PickleUsingNameMixin, _root=True): 1036*cda5da8dSAndroid Build Coastguard Worker """Type variable tuple. 1037*cda5da8dSAndroid Build Coastguard Worker 1038*cda5da8dSAndroid Build Coastguard Worker Usage: 1039*cda5da8dSAndroid Build Coastguard Worker 1040*cda5da8dSAndroid Build Coastguard Worker Ts = TypeVarTuple('Ts') # Can be given any name 1041*cda5da8dSAndroid Build Coastguard Worker 1042*cda5da8dSAndroid Build Coastguard Worker Just as a TypeVar (type variable) is a placeholder for a single type, 1043*cda5da8dSAndroid Build Coastguard Worker a TypeVarTuple is a placeholder for an *arbitrary* number of types. For 1044*cda5da8dSAndroid Build Coastguard Worker example, if we define a generic class using a TypeVarTuple: 1045*cda5da8dSAndroid Build Coastguard Worker 1046*cda5da8dSAndroid Build Coastguard Worker class C(Generic[*Ts]): ... 1047*cda5da8dSAndroid Build Coastguard Worker 1048*cda5da8dSAndroid Build Coastguard Worker Then we can parameterize that class with an arbitrary number of type 1049*cda5da8dSAndroid Build Coastguard Worker arguments: 1050*cda5da8dSAndroid Build Coastguard Worker 1051*cda5da8dSAndroid Build Coastguard Worker C[int] # Fine 1052*cda5da8dSAndroid Build Coastguard Worker C[int, str] # Also fine 1053*cda5da8dSAndroid Build Coastguard Worker C[()] # Even this is fine 1054*cda5da8dSAndroid Build Coastguard Worker 1055*cda5da8dSAndroid Build Coastguard Worker For more details, see PEP 646. 1056*cda5da8dSAndroid Build Coastguard Worker 1057*cda5da8dSAndroid Build Coastguard Worker Note that only TypeVarTuples defined in global scope can be pickled. 1058*cda5da8dSAndroid Build Coastguard Worker """ 1059*cda5da8dSAndroid Build Coastguard Worker 1060*cda5da8dSAndroid Build Coastguard Worker def __init__(self, name): 1061*cda5da8dSAndroid Build Coastguard Worker self.__name__ = name 1062*cda5da8dSAndroid Build Coastguard Worker 1063*cda5da8dSAndroid Build Coastguard Worker # Used for pickling. 1064*cda5da8dSAndroid Build Coastguard Worker def_mod = _caller() 1065*cda5da8dSAndroid Build Coastguard Worker if def_mod != 'typing': 1066*cda5da8dSAndroid Build Coastguard Worker self.__module__ = def_mod 1067*cda5da8dSAndroid Build Coastguard Worker 1068*cda5da8dSAndroid Build Coastguard Worker def __iter__(self): 1069*cda5da8dSAndroid Build Coastguard Worker yield Unpack[self] 1070*cda5da8dSAndroid Build Coastguard Worker 1071*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 1072*cda5da8dSAndroid Build Coastguard Worker return self.__name__ 1073*cda5da8dSAndroid Build Coastguard Worker 1074*cda5da8dSAndroid Build Coastguard Worker def __typing_subst__(self, arg): 1075*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Substitution of bare TypeVarTuple is not supported") 1076*cda5da8dSAndroid Build Coastguard Worker 1077*cda5da8dSAndroid Build Coastguard Worker def __typing_prepare_subst__(self, alias, args): 1078*cda5da8dSAndroid Build Coastguard Worker params = alias.__parameters__ 1079*cda5da8dSAndroid Build Coastguard Worker typevartuple_index = params.index(self) 1080*cda5da8dSAndroid Build Coastguard Worker for param in params[typevartuple_index + 1:]: 1081*cda5da8dSAndroid Build Coastguard Worker if isinstance(param, TypeVarTuple): 1082*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"More than one TypeVarTuple parameter in {alias}") 1083*cda5da8dSAndroid Build Coastguard Worker 1084*cda5da8dSAndroid Build Coastguard Worker alen = len(args) 1085*cda5da8dSAndroid Build Coastguard Worker plen = len(params) 1086*cda5da8dSAndroid Build Coastguard Worker left = typevartuple_index 1087*cda5da8dSAndroid Build Coastguard Worker right = plen - typevartuple_index - 1 1088*cda5da8dSAndroid Build Coastguard Worker var_tuple_index = None 1089*cda5da8dSAndroid Build Coastguard Worker fillarg = None 1090*cda5da8dSAndroid Build Coastguard Worker for k, arg in enumerate(args): 1091*cda5da8dSAndroid Build Coastguard Worker if not isinstance(arg, type): 1092*cda5da8dSAndroid Build Coastguard Worker subargs = getattr(arg, '__typing_unpacked_tuple_args__', None) 1093*cda5da8dSAndroid Build Coastguard Worker if subargs and len(subargs) == 2 and subargs[-1] is ...: 1094*cda5da8dSAndroid Build Coastguard Worker if var_tuple_index is not None: 1095*cda5da8dSAndroid Build Coastguard Worker raise TypeError("More than one unpacked arbitrary-length tuple argument") 1096*cda5da8dSAndroid Build Coastguard Worker var_tuple_index = k 1097*cda5da8dSAndroid Build Coastguard Worker fillarg = subargs[0] 1098*cda5da8dSAndroid Build Coastguard Worker if var_tuple_index is not None: 1099*cda5da8dSAndroid Build Coastguard Worker left = min(left, var_tuple_index) 1100*cda5da8dSAndroid Build Coastguard Worker right = min(right, alen - var_tuple_index - 1) 1101*cda5da8dSAndroid Build Coastguard Worker elif left + right > alen: 1102*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Too few arguments for {alias};" 1103*cda5da8dSAndroid Build Coastguard Worker f" actual {alen}, expected at least {plen-1}") 1104*cda5da8dSAndroid Build Coastguard Worker 1105*cda5da8dSAndroid Build Coastguard Worker return ( 1106*cda5da8dSAndroid Build Coastguard Worker *args[:left], 1107*cda5da8dSAndroid Build Coastguard Worker *([fillarg]*(typevartuple_index - left)), 1108*cda5da8dSAndroid Build Coastguard Worker tuple(args[left: alen - right]), 1109*cda5da8dSAndroid Build Coastguard Worker *([fillarg]*(plen - right - left - typevartuple_index - 1)), 1110*cda5da8dSAndroid Build Coastguard Worker *args[alen - right:], 1111*cda5da8dSAndroid Build Coastguard Worker ) 1112*cda5da8dSAndroid Build Coastguard Worker 1113*cda5da8dSAndroid Build Coastguard Worker 1114*cda5da8dSAndroid Build Coastguard Workerclass ParamSpecArgs(_Final, _Immutable, _root=True): 1115*cda5da8dSAndroid Build Coastguard Worker """The args for a ParamSpec object. 1116*cda5da8dSAndroid Build Coastguard Worker 1117*cda5da8dSAndroid Build Coastguard Worker Given a ParamSpec object P, P.args is an instance of ParamSpecArgs. 1118*cda5da8dSAndroid Build Coastguard Worker 1119*cda5da8dSAndroid Build Coastguard Worker ParamSpecArgs objects have a reference back to their ParamSpec: 1120*cda5da8dSAndroid Build Coastguard Worker 1121*cda5da8dSAndroid Build Coastguard Worker P.args.__origin__ is P 1122*cda5da8dSAndroid Build Coastguard Worker 1123*cda5da8dSAndroid Build Coastguard Worker This type is meant for runtime introspection and has no special meaning to 1124*cda5da8dSAndroid Build Coastguard Worker static type checkers. 1125*cda5da8dSAndroid Build Coastguard Worker """ 1126*cda5da8dSAndroid Build Coastguard Worker def __init__(self, origin): 1127*cda5da8dSAndroid Build Coastguard Worker self.__origin__ = origin 1128*cda5da8dSAndroid Build Coastguard Worker 1129*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 1130*cda5da8dSAndroid Build Coastguard Worker return f"{self.__origin__.__name__}.args" 1131*cda5da8dSAndroid Build Coastguard Worker 1132*cda5da8dSAndroid Build Coastguard Worker def __eq__(self, other): 1133*cda5da8dSAndroid Build Coastguard Worker if not isinstance(other, ParamSpecArgs): 1134*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 1135*cda5da8dSAndroid Build Coastguard Worker return self.__origin__ == other.__origin__ 1136*cda5da8dSAndroid Build Coastguard Worker 1137*cda5da8dSAndroid Build Coastguard Worker 1138*cda5da8dSAndroid Build Coastguard Workerclass ParamSpecKwargs(_Final, _Immutable, _root=True): 1139*cda5da8dSAndroid Build Coastguard Worker """The kwargs for a ParamSpec object. 1140*cda5da8dSAndroid Build Coastguard Worker 1141*cda5da8dSAndroid Build Coastguard Worker Given a ParamSpec object P, P.kwargs is an instance of ParamSpecKwargs. 1142*cda5da8dSAndroid Build Coastguard Worker 1143*cda5da8dSAndroid Build Coastguard Worker ParamSpecKwargs objects have a reference back to their ParamSpec: 1144*cda5da8dSAndroid Build Coastguard Worker 1145*cda5da8dSAndroid Build Coastguard Worker P.kwargs.__origin__ is P 1146*cda5da8dSAndroid Build Coastguard Worker 1147*cda5da8dSAndroid Build Coastguard Worker This type is meant for runtime introspection and has no special meaning to 1148*cda5da8dSAndroid Build Coastguard Worker static type checkers. 1149*cda5da8dSAndroid Build Coastguard Worker """ 1150*cda5da8dSAndroid Build Coastguard Worker def __init__(self, origin): 1151*cda5da8dSAndroid Build Coastguard Worker self.__origin__ = origin 1152*cda5da8dSAndroid Build Coastguard Worker 1153*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 1154*cda5da8dSAndroid Build Coastguard Worker return f"{self.__origin__.__name__}.kwargs" 1155*cda5da8dSAndroid Build Coastguard Worker 1156*cda5da8dSAndroid Build Coastguard Worker def __eq__(self, other): 1157*cda5da8dSAndroid Build Coastguard Worker if not isinstance(other, ParamSpecKwargs): 1158*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 1159*cda5da8dSAndroid Build Coastguard Worker return self.__origin__ == other.__origin__ 1160*cda5da8dSAndroid Build Coastguard Worker 1161*cda5da8dSAndroid Build Coastguard Worker 1162*cda5da8dSAndroid Build Coastguard Workerclass ParamSpec(_Final, _Immutable, _BoundVarianceMixin, _PickleUsingNameMixin, 1163*cda5da8dSAndroid Build Coastguard Worker _root=True): 1164*cda5da8dSAndroid Build Coastguard Worker """Parameter specification variable. 1165*cda5da8dSAndroid Build Coastguard Worker 1166*cda5da8dSAndroid Build Coastguard Worker Usage:: 1167*cda5da8dSAndroid Build Coastguard Worker 1168*cda5da8dSAndroid Build Coastguard Worker P = ParamSpec('P') 1169*cda5da8dSAndroid Build Coastguard Worker 1170*cda5da8dSAndroid Build Coastguard Worker Parameter specification variables exist primarily for the benefit of static 1171*cda5da8dSAndroid Build Coastguard Worker type checkers. They are used to forward the parameter types of one 1172*cda5da8dSAndroid Build Coastguard Worker callable to another callable, a pattern commonly found in higher order 1173*cda5da8dSAndroid Build Coastguard Worker functions and decorators. They are only valid when used in ``Concatenate``, 1174*cda5da8dSAndroid Build Coastguard Worker or as the first argument to ``Callable``, or as parameters for user-defined 1175*cda5da8dSAndroid Build Coastguard Worker Generics. See class Generic for more information on generic types. An 1176*cda5da8dSAndroid Build Coastguard Worker example for annotating a decorator:: 1177*cda5da8dSAndroid Build Coastguard Worker 1178*cda5da8dSAndroid Build Coastguard Worker T = TypeVar('T') 1179*cda5da8dSAndroid Build Coastguard Worker P = ParamSpec('P') 1180*cda5da8dSAndroid Build Coastguard Worker 1181*cda5da8dSAndroid Build Coastguard Worker def add_logging(f: Callable[P, T]) -> Callable[P, T]: 1182*cda5da8dSAndroid Build Coastguard Worker '''A type-safe decorator to add logging to a function.''' 1183*cda5da8dSAndroid Build Coastguard Worker def inner(*args: P.args, **kwargs: P.kwargs) -> T: 1184*cda5da8dSAndroid Build Coastguard Worker logging.info(f'{f.__name__} was called') 1185*cda5da8dSAndroid Build Coastguard Worker return f(*args, **kwargs) 1186*cda5da8dSAndroid Build Coastguard Worker return inner 1187*cda5da8dSAndroid Build Coastguard Worker 1188*cda5da8dSAndroid Build Coastguard Worker @add_logging 1189*cda5da8dSAndroid Build Coastguard Worker def add_two(x: float, y: float) -> float: 1190*cda5da8dSAndroid Build Coastguard Worker '''Add two numbers together.''' 1191*cda5da8dSAndroid Build Coastguard Worker return x + y 1192*cda5da8dSAndroid Build Coastguard Worker 1193*cda5da8dSAndroid Build Coastguard Worker Parameter specification variables can be introspected. e.g.: 1194*cda5da8dSAndroid Build Coastguard Worker 1195*cda5da8dSAndroid Build Coastguard Worker P.__name__ == 'P' 1196*cda5da8dSAndroid Build Coastguard Worker 1197*cda5da8dSAndroid Build Coastguard Worker Note that only parameter specification variables defined in global scope can 1198*cda5da8dSAndroid Build Coastguard Worker be pickled. 1199*cda5da8dSAndroid Build Coastguard Worker """ 1200*cda5da8dSAndroid Build Coastguard Worker 1201*cda5da8dSAndroid Build Coastguard Worker @property 1202*cda5da8dSAndroid Build Coastguard Worker def args(self): 1203*cda5da8dSAndroid Build Coastguard Worker return ParamSpecArgs(self) 1204*cda5da8dSAndroid Build Coastguard Worker 1205*cda5da8dSAndroid Build Coastguard Worker @property 1206*cda5da8dSAndroid Build Coastguard Worker def kwargs(self): 1207*cda5da8dSAndroid Build Coastguard Worker return ParamSpecKwargs(self) 1208*cda5da8dSAndroid Build Coastguard Worker 1209*cda5da8dSAndroid Build Coastguard Worker def __init__(self, name, *, bound=None, covariant=False, contravariant=False): 1210*cda5da8dSAndroid Build Coastguard Worker self.__name__ = name 1211*cda5da8dSAndroid Build Coastguard Worker super().__init__(bound, covariant, contravariant) 1212*cda5da8dSAndroid Build Coastguard Worker def_mod = _caller() 1213*cda5da8dSAndroid Build Coastguard Worker if def_mod != 'typing': 1214*cda5da8dSAndroid Build Coastguard Worker self.__module__ = def_mod 1215*cda5da8dSAndroid Build Coastguard Worker 1216*cda5da8dSAndroid Build Coastguard Worker def __typing_subst__(self, arg): 1217*cda5da8dSAndroid Build Coastguard Worker if isinstance(arg, (list, tuple)): 1218*cda5da8dSAndroid Build Coastguard Worker arg = tuple(_type_check(a, "Expected a type.") for a in arg) 1219*cda5da8dSAndroid Build Coastguard Worker elif not _is_param_expr(arg): 1220*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Expected a list of types, an ellipsis, " 1221*cda5da8dSAndroid Build Coastguard Worker f"ParamSpec, or Concatenate. Got {arg}") 1222*cda5da8dSAndroid Build Coastguard Worker return arg 1223*cda5da8dSAndroid Build Coastguard Worker 1224*cda5da8dSAndroid Build Coastguard Worker def __typing_prepare_subst__(self, alias, args): 1225*cda5da8dSAndroid Build Coastguard Worker params = alias.__parameters__ 1226*cda5da8dSAndroid Build Coastguard Worker i = params.index(self) 1227*cda5da8dSAndroid Build Coastguard Worker if i >= len(args): 1228*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Too few arguments for {alias}") 1229*cda5da8dSAndroid Build Coastguard Worker # Special case where Z[[int, str, bool]] == Z[int, str, bool] in PEP 612. 1230*cda5da8dSAndroid Build Coastguard Worker if len(params) == 1 and not _is_param_expr(args[0]): 1231*cda5da8dSAndroid Build Coastguard Worker assert i == 0 1232*cda5da8dSAndroid Build Coastguard Worker args = (args,) 1233*cda5da8dSAndroid Build Coastguard Worker # Convert lists to tuples to help other libraries cache the results. 1234*cda5da8dSAndroid Build Coastguard Worker elif isinstance(args[i], list): 1235*cda5da8dSAndroid Build Coastguard Worker args = (*args[:i], tuple(args[i]), *args[i+1:]) 1236*cda5da8dSAndroid Build Coastguard Worker return args 1237*cda5da8dSAndroid Build Coastguard Worker 1238*cda5da8dSAndroid Build Coastguard Workerdef _is_dunder(attr): 1239*cda5da8dSAndroid Build Coastguard Worker return attr.startswith('__') and attr.endswith('__') 1240*cda5da8dSAndroid Build Coastguard Worker 1241*cda5da8dSAndroid Build Coastguard Workerclass _BaseGenericAlias(_Final, _root=True): 1242*cda5da8dSAndroid Build Coastguard Worker """The central part of the internal API. 1243*cda5da8dSAndroid Build Coastguard Worker 1244*cda5da8dSAndroid Build Coastguard Worker This represents a generic version of type 'origin' with type arguments 'params'. 1245*cda5da8dSAndroid Build Coastguard Worker There are two kind of these aliases: user defined and special. The special ones 1246*cda5da8dSAndroid Build Coastguard Worker are wrappers around builtin collections and ABCs in collections.abc. These must 1247*cda5da8dSAndroid Build Coastguard Worker have 'name' always set. If 'inst' is False, then the alias can't be instantiated; 1248*cda5da8dSAndroid Build Coastguard Worker this is used by e.g. typing.List and typing.Dict. 1249*cda5da8dSAndroid Build Coastguard Worker """ 1250*cda5da8dSAndroid Build Coastguard Worker 1251*cda5da8dSAndroid Build Coastguard Worker def __init__(self, origin, *, inst=True, name=None): 1252*cda5da8dSAndroid Build Coastguard Worker self._inst = inst 1253*cda5da8dSAndroid Build Coastguard Worker self._name = name 1254*cda5da8dSAndroid Build Coastguard Worker self.__origin__ = origin 1255*cda5da8dSAndroid Build Coastguard Worker self.__slots__ = None # This is not documented. 1256*cda5da8dSAndroid Build Coastguard Worker 1257*cda5da8dSAndroid Build Coastguard Worker def __call__(self, *args, **kwargs): 1258*cda5da8dSAndroid Build Coastguard Worker if not self._inst: 1259*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Type {self._name} cannot be instantiated; " 1260*cda5da8dSAndroid Build Coastguard Worker f"use {self.__origin__.__name__}() instead") 1261*cda5da8dSAndroid Build Coastguard Worker result = self.__origin__(*args, **kwargs) 1262*cda5da8dSAndroid Build Coastguard Worker try: 1263*cda5da8dSAndroid Build Coastguard Worker result.__orig_class__ = self 1264*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 1265*cda5da8dSAndroid Build Coastguard Worker pass 1266*cda5da8dSAndroid Build Coastguard Worker return result 1267*cda5da8dSAndroid Build Coastguard Worker 1268*cda5da8dSAndroid Build Coastguard Worker def __mro_entries__(self, bases): 1269*cda5da8dSAndroid Build Coastguard Worker res = [] 1270*cda5da8dSAndroid Build Coastguard Worker if self.__origin__ not in bases: 1271*cda5da8dSAndroid Build Coastguard Worker res.append(self.__origin__) 1272*cda5da8dSAndroid Build Coastguard Worker i = bases.index(self) 1273*cda5da8dSAndroid Build Coastguard Worker for b in bases[i+1:]: 1274*cda5da8dSAndroid Build Coastguard Worker if isinstance(b, _BaseGenericAlias) or issubclass(b, Generic): 1275*cda5da8dSAndroid Build Coastguard Worker break 1276*cda5da8dSAndroid Build Coastguard Worker else: 1277*cda5da8dSAndroid Build Coastguard Worker res.append(Generic) 1278*cda5da8dSAndroid Build Coastguard Worker return tuple(res) 1279*cda5da8dSAndroid Build Coastguard Worker 1280*cda5da8dSAndroid Build Coastguard Worker def __getattr__(self, attr): 1281*cda5da8dSAndroid Build Coastguard Worker if attr in {'__name__', '__qualname__'}: 1282*cda5da8dSAndroid Build Coastguard Worker return self._name or self.__origin__.__name__ 1283*cda5da8dSAndroid Build Coastguard Worker 1284*cda5da8dSAndroid Build Coastguard Worker # We are careful for copy and pickle. 1285*cda5da8dSAndroid Build Coastguard Worker # Also for simplicity we don't relay any dunder names 1286*cda5da8dSAndroid Build Coastguard Worker if '__origin__' in self.__dict__ and not _is_dunder(attr): 1287*cda5da8dSAndroid Build Coastguard Worker return getattr(self.__origin__, attr) 1288*cda5da8dSAndroid Build Coastguard Worker raise AttributeError(attr) 1289*cda5da8dSAndroid Build Coastguard Worker 1290*cda5da8dSAndroid Build Coastguard Worker def __setattr__(self, attr, val): 1291*cda5da8dSAndroid Build Coastguard Worker if _is_dunder(attr) or attr in {'_name', '_inst', '_nparams', 1292*cda5da8dSAndroid Build Coastguard Worker '_paramspec_tvars'}: 1293*cda5da8dSAndroid Build Coastguard Worker super().__setattr__(attr, val) 1294*cda5da8dSAndroid Build Coastguard Worker else: 1295*cda5da8dSAndroid Build Coastguard Worker setattr(self.__origin__, attr, val) 1296*cda5da8dSAndroid Build Coastguard Worker 1297*cda5da8dSAndroid Build Coastguard Worker def __instancecheck__(self, obj): 1298*cda5da8dSAndroid Build Coastguard Worker return self.__subclasscheck__(type(obj)) 1299*cda5da8dSAndroid Build Coastguard Worker 1300*cda5da8dSAndroid Build Coastguard Worker def __subclasscheck__(self, cls): 1301*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Subscripted generics cannot be used with" 1302*cda5da8dSAndroid Build Coastguard Worker " class and instance checks") 1303*cda5da8dSAndroid Build Coastguard Worker 1304*cda5da8dSAndroid Build Coastguard Worker def __dir__(self): 1305*cda5da8dSAndroid Build Coastguard Worker return list(set(super().__dir__() 1306*cda5da8dSAndroid Build Coastguard Worker + [attr for attr in dir(self.__origin__) if not _is_dunder(attr)])) 1307*cda5da8dSAndroid Build Coastguard Worker 1308*cda5da8dSAndroid Build Coastguard Worker 1309*cda5da8dSAndroid Build Coastguard Worker# Special typing constructs Union, Optional, Generic, Callable and Tuple 1310*cda5da8dSAndroid Build Coastguard Worker# use three special attributes for internal bookkeeping of generic types: 1311*cda5da8dSAndroid Build Coastguard Worker# * __parameters__ is a tuple of unique free type parameters of a generic 1312*cda5da8dSAndroid Build Coastguard Worker# type, for example, Dict[T, T].__parameters__ == (T,); 1313*cda5da8dSAndroid Build Coastguard Worker# * __origin__ keeps a reference to a type that was subscripted, 1314*cda5da8dSAndroid Build Coastguard Worker# e.g., Union[T, int].__origin__ == Union, or the non-generic version of 1315*cda5da8dSAndroid Build Coastguard Worker# the type. 1316*cda5da8dSAndroid Build Coastguard Worker# * __args__ is a tuple of all arguments used in subscripting, 1317*cda5da8dSAndroid Build Coastguard Worker# e.g., Dict[T, int].__args__ == (T, int). 1318*cda5da8dSAndroid Build Coastguard Worker 1319*cda5da8dSAndroid Build Coastguard Worker 1320*cda5da8dSAndroid Build Coastguard Workerclass _GenericAlias(_BaseGenericAlias, _root=True): 1321*cda5da8dSAndroid Build Coastguard Worker # The type of parameterized generics. 1322*cda5da8dSAndroid Build Coastguard Worker # 1323*cda5da8dSAndroid Build Coastguard Worker # That is, for example, `type(List[int])` is `_GenericAlias`. 1324*cda5da8dSAndroid Build Coastguard Worker # 1325*cda5da8dSAndroid Build Coastguard Worker # Objects which are instances of this class include: 1326*cda5da8dSAndroid Build Coastguard Worker # * Parameterized container types, e.g. `Tuple[int]`, `List[int]`. 1327*cda5da8dSAndroid Build Coastguard Worker # * Note that native container types, e.g. `tuple`, `list`, use 1328*cda5da8dSAndroid Build Coastguard Worker # `types.GenericAlias` instead. 1329*cda5da8dSAndroid Build Coastguard Worker # * Parameterized classes: 1330*cda5da8dSAndroid Build Coastguard Worker # T = TypeVar('T') 1331*cda5da8dSAndroid Build Coastguard Worker # class C(Generic[T]): pass 1332*cda5da8dSAndroid Build Coastguard Worker # # C[int] is a _GenericAlias 1333*cda5da8dSAndroid Build Coastguard Worker # * `Callable` aliases, generic `Callable` aliases, and 1334*cda5da8dSAndroid Build Coastguard Worker # parameterized `Callable` aliases: 1335*cda5da8dSAndroid Build Coastguard Worker # T = TypeVar('T') 1336*cda5da8dSAndroid Build Coastguard Worker # # _CallableGenericAlias inherits from _GenericAlias. 1337*cda5da8dSAndroid Build Coastguard Worker # A = Callable[[], None] # _CallableGenericAlias 1338*cda5da8dSAndroid Build Coastguard Worker # B = Callable[[T], None] # _CallableGenericAlias 1339*cda5da8dSAndroid Build Coastguard Worker # C = B[int] # _CallableGenericAlias 1340*cda5da8dSAndroid Build Coastguard Worker # * Parameterized `Final`, `ClassVar` and `TypeGuard`: 1341*cda5da8dSAndroid Build Coastguard Worker # # All _GenericAlias 1342*cda5da8dSAndroid Build Coastguard Worker # Final[int] 1343*cda5da8dSAndroid Build Coastguard Worker # ClassVar[float] 1344*cda5da8dSAndroid Build Coastguard Worker # TypeVar[bool] 1345*cda5da8dSAndroid Build Coastguard Worker 1346*cda5da8dSAndroid Build Coastguard Worker def __init__(self, origin, args, *, inst=True, name=None, 1347*cda5da8dSAndroid Build Coastguard Worker _paramspec_tvars=False): 1348*cda5da8dSAndroid Build Coastguard Worker super().__init__(origin, inst=inst, name=name) 1349*cda5da8dSAndroid Build Coastguard Worker if not isinstance(args, tuple): 1350*cda5da8dSAndroid Build Coastguard Worker args = (args,) 1351*cda5da8dSAndroid Build Coastguard Worker self.__args__ = tuple(... if a is _TypingEllipsis else 1352*cda5da8dSAndroid Build Coastguard Worker a for a in args) 1353*cda5da8dSAndroid Build Coastguard Worker self.__parameters__ = _collect_parameters(args) 1354*cda5da8dSAndroid Build Coastguard Worker self._paramspec_tvars = _paramspec_tvars 1355*cda5da8dSAndroid Build Coastguard Worker if not name: 1356*cda5da8dSAndroid Build Coastguard Worker self.__module__ = origin.__module__ 1357*cda5da8dSAndroid Build Coastguard Worker 1358*cda5da8dSAndroid Build Coastguard Worker def __eq__(self, other): 1359*cda5da8dSAndroid Build Coastguard Worker if not isinstance(other, _GenericAlias): 1360*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 1361*cda5da8dSAndroid Build Coastguard Worker return (self.__origin__ == other.__origin__ 1362*cda5da8dSAndroid Build Coastguard Worker and self.__args__ == other.__args__) 1363*cda5da8dSAndroid Build Coastguard Worker 1364*cda5da8dSAndroid Build Coastguard Worker def __hash__(self): 1365*cda5da8dSAndroid Build Coastguard Worker return hash((self.__origin__, self.__args__)) 1366*cda5da8dSAndroid Build Coastguard Worker 1367*cda5da8dSAndroid Build Coastguard Worker def __or__(self, right): 1368*cda5da8dSAndroid Build Coastguard Worker return Union[self, right] 1369*cda5da8dSAndroid Build Coastguard Worker 1370*cda5da8dSAndroid Build Coastguard Worker def __ror__(self, left): 1371*cda5da8dSAndroid Build Coastguard Worker return Union[left, self] 1372*cda5da8dSAndroid Build Coastguard Worker 1373*cda5da8dSAndroid Build Coastguard Worker @_tp_cache 1374*cda5da8dSAndroid Build Coastguard Worker def __getitem__(self, args): 1375*cda5da8dSAndroid Build Coastguard Worker # Parameterizes an already-parameterized object. 1376*cda5da8dSAndroid Build Coastguard Worker # 1377*cda5da8dSAndroid Build Coastguard Worker # For example, we arrive here doing something like: 1378*cda5da8dSAndroid Build Coastguard Worker # T1 = TypeVar('T1') 1379*cda5da8dSAndroid Build Coastguard Worker # T2 = TypeVar('T2') 1380*cda5da8dSAndroid Build Coastguard Worker # T3 = TypeVar('T3') 1381*cda5da8dSAndroid Build Coastguard Worker # class A(Generic[T1]): pass 1382*cda5da8dSAndroid Build Coastguard Worker # B = A[T2] # B is a _GenericAlias 1383*cda5da8dSAndroid Build Coastguard Worker # C = B[T3] # Invokes _GenericAlias.__getitem__ 1384*cda5da8dSAndroid Build Coastguard Worker # 1385*cda5da8dSAndroid Build Coastguard Worker # We also arrive here when parameterizing a generic `Callable` alias: 1386*cda5da8dSAndroid Build Coastguard Worker # T = TypeVar('T') 1387*cda5da8dSAndroid Build Coastguard Worker # C = Callable[[T], None] 1388*cda5da8dSAndroid Build Coastguard Worker # C[int] # Invokes _GenericAlias.__getitem__ 1389*cda5da8dSAndroid Build Coastguard Worker 1390*cda5da8dSAndroid Build Coastguard Worker if self.__origin__ in (Generic, Protocol): 1391*cda5da8dSAndroid Build Coastguard Worker # Can't subscript Generic[...] or Protocol[...]. 1392*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Cannot subscript already-subscripted {self}") 1393*cda5da8dSAndroid Build Coastguard Worker if not self.__parameters__: 1394*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"{self} is not a generic class") 1395*cda5da8dSAndroid Build Coastguard Worker 1396*cda5da8dSAndroid Build Coastguard Worker # Preprocess `args`. 1397*cda5da8dSAndroid Build Coastguard Worker if not isinstance(args, tuple): 1398*cda5da8dSAndroid Build Coastguard Worker args = (args,) 1399*cda5da8dSAndroid Build Coastguard Worker args = tuple(_type_convert(p) for p in args) 1400*cda5da8dSAndroid Build Coastguard Worker args = _unpack_args(args) 1401*cda5da8dSAndroid Build Coastguard Worker new_args = self._determine_new_args(args) 1402*cda5da8dSAndroid Build Coastguard Worker r = self.copy_with(new_args) 1403*cda5da8dSAndroid Build Coastguard Worker return r 1404*cda5da8dSAndroid Build Coastguard Worker 1405*cda5da8dSAndroid Build Coastguard Worker def _determine_new_args(self, args): 1406*cda5da8dSAndroid Build Coastguard Worker # Determines new __args__ for __getitem__. 1407*cda5da8dSAndroid Build Coastguard Worker # 1408*cda5da8dSAndroid Build Coastguard Worker # For example, suppose we had: 1409*cda5da8dSAndroid Build Coastguard Worker # T1 = TypeVar('T1') 1410*cda5da8dSAndroid Build Coastguard Worker # T2 = TypeVar('T2') 1411*cda5da8dSAndroid Build Coastguard Worker # class A(Generic[T1, T2]): pass 1412*cda5da8dSAndroid Build Coastguard Worker # T3 = TypeVar('T3') 1413*cda5da8dSAndroid Build Coastguard Worker # B = A[int, T3] 1414*cda5da8dSAndroid Build Coastguard Worker # C = B[str] 1415*cda5da8dSAndroid Build Coastguard Worker # `B.__args__` is `(int, T3)`, so `C.__args__` should be `(int, str)`. 1416*cda5da8dSAndroid Build Coastguard Worker # Unfortunately, this is harder than it looks, because if `T3` is 1417*cda5da8dSAndroid Build Coastguard Worker # anything more exotic than a plain `TypeVar`, we need to consider 1418*cda5da8dSAndroid Build Coastguard Worker # edge cases. 1419*cda5da8dSAndroid Build Coastguard Worker 1420*cda5da8dSAndroid Build Coastguard Worker params = self.__parameters__ 1421*cda5da8dSAndroid Build Coastguard Worker # In the example above, this would be {T3: str} 1422*cda5da8dSAndroid Build Coastguard Worker for param in params: 1423*cda5da8dSAndroid Build Coastguard Worker prepare = getattr(param, '__typing_prepare_subst__', None) 1424*cda5da8dSAndroid Build Coastguard Worker if prepare is not None: 1425*cda5da8dSAndroid Build Coastguard Worker args = prepare(self, args) 1426*cda5da8dSAndroid Build Coastguard Worker alen = len(args) 1427*cda5da8dSAndroid Build Coastguard Worker plen = len(params) 1428*cda5da8dSAndroid Build Coastguard Worker if alen != plen: 1429*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Too {'many' if alen > plen else 'few'} arguments for {self};" 1430*cda5da8dSAndroid Build Coastguard Worker f" actual {alen}, expected {plen}") 1431*cda5da8dSAndroid Build Coastguard Worker new_arg_by_param = dict(zip(params, args)) 1432*cda5da8dSAndroid Build Coastguard Worker return tuple(self._make_substitution(self.__args__, new_arg_by_param)) 1433*cda5da8dSAndroid Build Coastguard Worker 1434*cda5da8dSAndroid Build Coastguard Worker def _make_substitution(self, args, new_arg_by_param): 1435*cda5da8dSAndroid Build Coastguard Worker """Create a list of new type arguments.""" 1436*cda5da8dSAndroid Build Coastguard Worker new_args = [] 1437*cda5da8dSAndroid Build Coastguard Worker for old_arg in args: 1438*cda5da8dSAndroid Build Coastguard Worker if isinstance(old_arg, type): 1439*cda5da8dSAndroid Build Coastguard Worker new_args.append(old_arg) 1440*cda5da8dSAndroid Build Coastguard Worker continue 1441*cda5da8dSAndroid Build Coastguard Worker 1442*cda5da8dSAndroid Build Coastguard Worker substfunc = getattr(old_arg, '__typing_subst__', None) 1443*cda5da8dSAndroid Build Coastguard Worker if substfunc: 1444*cda5da8dSAndroid Build Coastguard Worker new_arg = substfunc(new_arg_by_param[old_arg]) 1445*cda5da8dSAndroid Build Coastguard Worker else: 1446*cda5da8dSAndroid Build Coastguard Worker subparams = getattr(old_arg, '__parameters__', ()) 1447*cda5da8dSAndroid Build Coastguard Worker if not subparams: 1448*cda5da8dSAndroid Build Coastguard Worker new_arg = old_arg 1449*cda5da8dSAndroid Build Coastguard Worker else: 1450*cda5da8dSAndroid Build Coastguard Worker subargs = [] 1451*cda5da8dSAndroid Build Coastguard Worker for x in subparams: 1452*cda5da8dSAndroid Build Coastguard Worker if isinstance(x, TypeVarTuple): 1453*cda5da8dSAndroid Build Coastguard Worker subargs.extend(new_arg_by_param[x]) 1454*cda5da8dSAndroid Build Coastguard Worker else: 1455*cda5da8dSAndroid Build Coastguard Worker subargs.append(new_arg_by_param[x]) 1456*cda5da8dSAndroid Build Coastguard Worker new_arg = old_arg[tuple(subargs)] 1457*cda5da8dSAndroid Build Coastguard Worker 1458*cda5da8dSAndroid Build Coastguard Worker if self.__origin__ == collections.abc.Callable and isinstance(new_arg, tuple): 1459*cda5da8dSAndroid Build Coastguard Worker # Consider the following `Callable`. 1460*cda5da8dSAndroid Build Coastguard Worker # C = Callable[[int], str] 1461*cda5da8dSAndroid Build Coastguard Worker # Here, `C.__args__` should be (int, str) - NOT ([int], str). 1462*cda5da8dSAndroid Build Coastguard Worker # That means that if we had something like... 1463*cda5da8dSAndroid Build Coastguard Worker # P = ParamSpec('P') 1464*cda5da8dSAndroid Build Coastguard Worker # T = TypeVar('T') 1465*cda5da8dSAndroid Build Coastguard Worker # C = Callable[P, T] 1466*cda5da8dSAndroid Build Coastguard Worker # D = C[[int, str], float] 1467*cda5da8dSAndroid Build Coastguard Worker # ...we need to be careful; `new_args` should end up as 1468*cda5da8dSAndroid Build Coastguard Worker # `(int, str, float)` rather than `([int, str], float)`. 1469*cda5da8dSAndroid Build Coastguard Worker new_args.extend(new_arg) 1470*cda5da8dSAndroid Build Coastguard Worker elif _is_unpacked_typevartuple(old_arg): 1471*cda5da8dSAndroid Build Coastguard Worker # Consider the following `_GenericAlias`, `B`: 1472*cda5da8dSAndroid Build Coastguard Worker # class A(Generic[*Ts]): ... 1473*cda5da8dSAndroid Build Coastguard Worker # B = A[T, *Ts] 1474*cda5da8dSAndroid Build Coastguard Worker # If we then do: 1475*cda5da8dSAndroid Build Coastguard Worker # B[float, int, str] 1476*cda5da8dSAndroid Build Coastguard Worker # The `new_arg` corresponding to `T` will be `float`, and the 1477*cda5da8dSAndroid Build Coastguard Worker # `new_arg` corresponding to `*Ts` will be `(int, str)`. We 1478*cda5da8dSAndroid Build Coastguard Worker # should join all these types together in a flat list 1479*cda5da8dSAndroid Build Coastguard Worker # `(float, int, str)` - so again, we should `extend`. 1480*cda5da8dSAndroid Build Coastguard Worker new_args.extend(new_arg) 1481*cda5da8dSAndroid Build Coastguard Worker elif isinstance(old_arg, tuple): 1482*cda5da8dSAndroid Build Coastguard Worker # Corner case: 1483*cda5da8dSAndroid Build Coastguard Worker # P = ParamSpec('P') 1484*cda5da8dSAndroid Build Coastguard Worker # T = TypeVar('T') 1485*cda5da8dSAndroid Build Coastguard Worker # class Base(Generic[P]): ... 1486*cda5da8dSAndroid Build Coastguard Worker # Can be substituted like this: 1487*cda5da8dSAndroid Build Coastguard Worker # X = Base[[int, T]] 1488*cda5da8dSAndroid Build Coastguard Worker # In this case, `old_arg` will be a tuple: 1489*cda5da8dSAndroid Build Coastguard Worker new_args.append( 1490*cda5da8dSAndroid Build Coastguard Worker tuple(self._make_substitution(old_arg, new_arg_by_param)), 1491*cda5da8dSAndroid Build Coastguard Worker ) 1492*cda5da8dSAndroid Build Coastguard Worker else: 1493*cda5da8dSAndroid Build Coastguard Worker new_args.append(new_arg) 1494*cda5da8dSAndroid Build Coastguard Worker return new_args 1495*cda5da8dSAndroid Build Coastguard Worker 1496*cda5da8dSAndroid Build Coastguard Worker def copy_with(self, args): 1497*cda5da8dSAndroid Build Coastguard Worker return self.__class__(self.__origin__, args, name=self._name, inst=self._inst, 1498*cda5da8dSAndroid Build Coastguard Worker _paramspec_tvars=self._paramspec_tvars) 1499*cda5da8dSAndroid Build Coastguard Worker 1500*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 1501*cda5da8dSAndroid Build Coastguard Worker if self._name: 1502*cda5da8dSAndroid Build Coastguard Worker name = 'typing.' + self._name 1503*cda5da8dSAndroid Build Coastguard Worker else: 1504*cda5da8dSAndroid Build Coastguard Worker name = _type_repr(self.__origin__) 1505*cda5da8dSAndroid Build Coastguard Worker if self.__args__: 1506*cda5da8dSAndroid Build Coastguard Worker args = ", ".join([_type_repr(a) for a in self.__args__]) 1507*cda5da8dSAndroid Build Coastguard Worker else: 1508*cda5da8dSAndroid Build Coastguard Worker # To ensure the repr is eval-able. 1509*cda5da8dSAndroid Build Coastguard Worker args = "()" 1510*cda5da8dSAndroid Build Coastguard Worker return f'{name}[{args}]' 1511*cda5da8dSAndroid Build Coastguard Worker 1512*cda5da8dSAndroid Build Coastguard Worker def __reduce__(self): 1513*cda5da8dSAndroid Build Coastguard Worker if self._name: 1514*cda5da8dSAndroid Build Coastguard Worker origin = globals()[self._name] 1515*cda5da8dSAndroid Build Coastguard Worker else: 1516*cda5da8dSAndroid Build Coastguard Worker origin = self.__origin__ 1517*cda5da8dSAndroid Build Coastguard Worker args = tuple(self.__args__) 1518*cda5da8dSAndroid Build Coastguard Worker if len(args) == 1 and not isinstance(args[0], tuple): 1519*cda5da8dSAndroid Build Coastguard Worker args, = args 1520*cda5da8dSAndroid Build Coastguard Worker return operator.getitem, (origin, args) 1521*cda5da8dSAndroid Build Coastguard Worker 1522*cda5da8dSAndroid Build Coastguard Worker def __mro_entries__(self, bases): 1523*cda5da8dSAndroid Build Coastguard Worker if isinstance(self.__origin__, _SpecialForm): 1524*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Cannot subclass {self!r}") 1525*cda5da8dSAndroid Build Coastguard Worker 1526*cda5da8dSAndroid Build Coastguard Worker if self._name: # generic version of an ABC or built-in class 1527*cda5da8dSAndroid Build Coastguard Worker return super().__mro_entries__(bases) 1528*cda5da8dSAndroid Build Coastguard Worker if self.__origin__ is Generic: 1529*cda5da8dSAndroid Build Coastguard Worker if Protocol in bases: 1530*cda5da8dSAndroid Build Coastguard Worker return () 1531*cda5da8dSAndroid Build Coastguard Worker i = bases.index(self) 1532*cda5da8dSAndroid Build Coastguard Worker for b in bases[i+1:]: 1533*cda5da8dSAndroid Build Coastguard Worker if isinstance(b, _BaseGenericAlias) and b is not self: 1534*cda5da8dSAndroid Build Coastguard Worker return () 1535*cda5da8dSAndroid Build Coastguard Worker return (self.__origin__,) 1536*cda5da8dSAndroid Build Coastguard Worker 1537*cda5da8dSAndroid Build Coastguard Worker def __iter__(self): 1538*cda5da8dSAndroid Build Coastguard Worker yield Unpack[self] 1539*cda5da8dSAndroid Build Coastguard Worker 1540*cda5da8dSAndroid Build Coastguard Worker 1541*cda5da8dSAndroid Build Coastguard Worker# _nparams is the number of accepted parameters, e.g. 0 for Hashable, 1542*cda5da8dSAndroid Build Coastguard Worker# 1 for List and 2 for Dict. It may be -1 if variable number of 1543*cda5da8dSAndroid Build Coastguard Worker# parameters are accepted (needs custom __getitem__). 1544*cda5da8dSAndroid Build Coastguard Worker 1545*cda5da8dSAndroid Build Coastguard Workerclass _SpecialGenericAlias(_NotIterable, _BaseGenericAlias, _root=True): 1546*cda5da8dSAndroid Build Coastguard Worker def __init__(self, origin, nparams, *, inst=True, name=None): 1547*cda5da8dSAndroid Build Coastguard Worker if name is None: 1548*cda5da8dSAndroid Build Coastguard Worker name = origin.__name__ 1549*cda5da8dSAndroid Build Coastguard Worker super().__init__(origin, inst=inst, name=name) 1550*cda5da8dSAndroid Build Coastguard Worker self._nparams = nparams 1551*cda5da8dSAndroid Build Coastguard Worker if origin.__module__ == 'builtins': 1552*cda5da8dSAndroid Build Coastguard Worker self.__doc__ = f'A generic version of {origin.__qualname__}.' 1553*cda5da8dSAndroid Build Coastguard Worker else: 1554*cda5da8dSAndroid Build Coastguard Worker self.__doc__ = f'A generic version of {origin.__module__}.{origin.__qualname__}.' 1555*cda5da8dSAndroid Build Coastguard Worker 1556*cda5da8dSAndroid Build Coastguard Worker @_tp_cache 1557*cda5da8dSAndroid Build Coastguard Worker def __getitem__(self, params): 1558*cda5da8dSAndroid Build Coastguard Worker if not isinstance(params, tuple): 1559*cda5da8dSAndroid Build Coastguard Worker params = (params,) 1560*cda5da8dSAndroid Build Coastguard Worker msg = "Parameters to generic types must be types." 1561*cda5da8dSAndroid Build Coastguard Worker params = tuple(_type_check(p, msg) for p in params) 1562*cda5da8dSAndroid Build Coastguard Worker _check_generic(self, params, self._nparams) 1563*cda5da8dSAndroid Build Coastguard Worker return self.copy_with(params) 1564*cda5da8dSAndroid Build Coastguard Worker 1565*cda5da8dSAndroid Build Coastguard Worker def copy_with(self, params): 1566*cda5da8dSAndroid Build Coastguard Worker return _GenericAlias(self.__origin__, params, 1567*cda5da8dSAndroid Build Coastguard Worker name=self._name, inst=self._inst) 1568*cda5da8dSAndroid Build Coastguard Worker 1569*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 1570*cda5da8dSAndroid Build Coastguard Worker return 'typing.' + self._name 1571*cda5da8dSAndroid Build Coastguard Worker 1572*cda5da8dSAndroid Build Coastguard Worker def __subclasscheck__(self, cls): 1573*cda5da8dSAndroid Build Coastguard Worker if isinstance(cls, _SpecialGenericAlias): 1574*cda5da8dSAndroid Build Coastguard Worker return issubclass(cls.__origin__, self.__origin__) 1575*cda5da8dSAndroid Build Coastguard Worker if not isinstance(cls, _GenericAlias): 1576*cda5da8dSAndroid Build Coastguard Worker return issubclass(cls, self.__origin__) 1577*cda5da8dSAndroid Build Coastguard Worker return super().__subclasscheck__(cls) 1578*cda5da8dSAndroid Build Coastguard Worker 1579*cda5da8dSAndroid Build Coastguard Worker def __reduce__(self): 1580*cda5da8dSAndroid Build Coastguard Worker return self._name 1581*cda5da8dSAndroid Build Coastguard Worker 1582*cda5da8dSAndroid Build Coastguard Worker def __or__(self, right): 1583*cda5da8dSAndroid Build Coastguard Worker return Union[self, right] 1584*cda5da8dSAndroid Build Coastguard Worker 1585*cda5da8dSAndroid Build Coastguard Worker def __ror__(self, left): 1586*cda5da8dSAndroid Build Coastguard Worker return Union[left, self] 1587*cda5da8dSAndroid Build Coastguard Worker 1588*cda5da8dSAndroid Build Coastguard Workerclass _CallableGenericAlias(_NotIterable, _GenericAlias, _root=True): 1589*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 1590*cda5da8dSAndroid Build Coastguard Worker assert self._name == 'Callable' 1591*cda5da8dSAndroid Build Coastguard Worker args = self.__args__ 1592*cda5da8dSAndroid Build Coastguard Worker if len(args) == 2 and _is_param_expr(args[0]): 1593*cda5da8dSAndroid Build Coastguard Worker return super().__repr__() 1594*cda5da8dSAndroid Build Coastguard Worker return (f'typing.Callable' 1595*cda5da8dSAndroid Build Coastguard Worker f'[[{", ".join([_type_repr(a) for a in args[:-1]])}], ' 1596*cda5da8dSAndroid Build Coastguard Worker f'{_type_repr(args[-1])}]') 1597*cda5da8dSAndroid Build Coastguard Worker 1598*cda5da8dSAndroid Build Coastguard Worker def __reduce__(self): 1599*cda5da8dSAndroid Build Coastguard Worker args = self.__args__ 1600*cda5da8dSAndroid Build Coastguard Worker if not (len(args) == 2 and _is_param_expr(args[0])): 1601*cda5da8dSAndroid Build Coastguard Worker args = list(args[:-1]), args[-1] 1602*cda5da8dSAndroid Build Coastguard Worker return operator.getitem, (Callable, args) 1603*cda5da8dSAndroid Build Coastguard Worker 1604*cda5da8dSAndroid Build Coastguard Worker 1605*cda5da8dSAndroid Build Coastguard Workerclass _CallableType(_SpecialGenericAlias, _root=True): 1606*cda5da8dSAndroid Build Coastguard Worker def copy_with(self, params): 1607*cda5da8dSAndroid Build Coastguard Worker return _CallableGenericAlias(self.__origin__, params, 1608*cda5da8dSAndroid Build Coastguard Worker name=self._name, inst=self._inst, 1609*cda5da8dSAndroid Build Coastguard Worker _paramspec_tvars=True) 1610*cda5da8dSAndroid Build Coastguard Worker 1611*cda5da8dSAndroid Build Coastguard Worker def __getitem__(self, params): 1612*cda5da8dSAndroid Build Coastguard Worker if not isinstance(params, tuple) or len(params) != 2: 1613*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Callable must be used as " 1614*cda5da8dSAndroid Build Coastguard Worker "Callable[[arg, ...], result].") 1615*cda5da8dSAndroid Build Coastguard Worker args, result = params 1616*cda5da8dSAndroid Build Coastguard Worker # This relaxes what args can be on purpose to allow things like 1617*cda5da8dSAndroid Build Coastguard Worker # PEP 612 ParamSpec. Responsibility for whether a user is using 1618*cda5da8dSAndroid Build Coastguard Worker # Callable[...] properly is deferred to static type checkers. 1619*cda5da8dSAndroid Build Coastguard Worker if isinstance(args, list): 1620*cda5da8dSAndroid Build Coastguard Worker params = (tuple(args), result) 1621*cda5da8dSAndroid Build Coastguard Worker else: 1622*cda5da8dSAndroid Build Coastguard Worker params = (args, result) 1623*cda5da8dSAndroid Build Coastguard Worker return self.__getitem_inner__(params) 1624*cda5da8dSAndroid Build Coastguard Worker 1625*cda5da8dSAndroid Build Coastguard Worker @_tp_cache 1626*cda5da8dSAndroid Build Coastguard Worker def __getitem_inner__(self, params): 1627*cda5da8dSAndroid Build Coastguard Worker args, result = params 1628*cda5da8dSAndroid Build Coastguard Worker msg = "Callable[args, result]: result must be a type." 1629*cda5da8dSAndroid Build Coastguard Worker result = _type_check(result, msg) 1630*cda5da8dSAndroid Build Coastguard Worker if args is Ellipsis: 1631*cda5da8dSAndroid Build Coastguard Worker return self.copy_with((_TypingEllipsis, result)) 1632*cda5da8dSAndroid Build Coastguard Worker if not isinstance(args, tuple): 1633*cda5da8dSAndroid Build Coastguard Worker args = (args,) 1634*cda5da8dSAndroid Build Coastguard Worker args = tuple(_type_convert(arg) for arg in args) 1635*cda5da8dSAndroid Build Coastguard Worker params = args + (result,) 1636*cda5da8dSAndroid Build Coastguard Worker return self.copy_with(params) 1637*cda5da8dSAndroid Build Coastguard Worker 1638*cda5da8dSAndroid Build Coastguard Worker 1639*cda5da8dSAndroid Build Coastguard Workerclass _TupleType(_SpecialGenericAlias, _root=True): 1640*cda5da8dSAndroid Build Coastguard Worker @_tp_cache 1641*cda5da8dSAndroid Build Coastguard Worker def __getitem__(self, params): 1642*cda5da8dSAndroid Build Coastguard Worker if not isinstance(params, tuple): 1643*cda5da8dSAndroid Build Coastguard Worker params = (params,) 1644*cda5da8dSAndroid Build Coastguard Worker if len(params) >= 2 and params[-1] is ...: 1645*cda5da8dSAndroid Build Coastguard Worker msg = "Tuple[t, ...]: t must be a type." 1646*cda5da8dSAndroid Build Coastguard Worker params = tuple(_type_check(p, msg) for p in params[:-1]) 1647*cda5da8dSAndroid Build Coastguard Worker return self.copy_with((*params, _TypingEllipsis)) 1648*cda5da8dSAndroid Build Coastguard Worker msg = "Tuple[t0, t1, ...]: each t must be a type." 1649*cda5da8dSAndroid Build Coastguard Worker params = tuple(_type_check(p, msg) for p in params) 1650*cda5da8dSAndroid Build Coastguard Worker return self.copy_with(params) 1651*cda5da8dSAndroid Build Coastguard Worker 1652*cda5da8dSAndroid Build Coastguard Worker 1653*cda5da8dSAndroid Build Coastguard Workerclass _UnionGenericAlias(_NotIterable, _GenericAlias, _root=True): 1654*cda5da8dSAndroid Build Coastguard Worker def copy_with(self, params): 1655*cda5da8dSAndroid Build Coastguard Worker return Union[params] 1656*cda5da8dSAndroid Build Coastguard Worker 1657*cda5da8dSAndroid Build Coastguard Worker def __eq__(self, other): 1658*cda5da8dSAndroid Build Coastguard Worker if not isinstance(other, (_UnionGenericAlias, types.UnionType)): 1659*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 1660*cda5da8dSAndroid Build Coastguard Worker return set(self.__args__) == set(other.__args__) 1661*cda5da8dSAndroid Build Coastguard Worker 1662*cda5da8dSAndroid Build Coastguard Worker def __hash__(self): 1663*cda5da8dSAndroid Build Coastguard Worker return hash(frozenset(self.__args__)) 1664*cda5da8dSAndroid Build Coastguard Worker 1665*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 1666*cda5da8dSAndroid Build Coastguard Worker args = self.__args__ 1667*cda5da8dSAndroid Build Coastguard Worker if len(args) == 2: 1668*cda5da8dSAndroid Build Coastguard Worker if args[0] is type(None): 1669*cda5da8dSAndroid Build Coastguard Worker return f'typing.Optional[{_type_repr(args[1])}]' 1670*cda5da8dSAndroid Build Coastguard Worker elif args[1] is type(None): 1671*cda5da8dSAndroid Build Coastguard Worker return f'typing.Optional[{_type_repr(args[0])}]' 1672*cda5da8dSAndroid Build Coastguard Worker return super().__repr__() 1673*cda5da8dSAndroid Build Coastguard Worker 1674*cda5da8dSAndroid Build Coastguard Worker def __instancecheck__(self, obj): 1675*cda5da8dSAndroid Build Coastguard Worker return self.__subclasscheck__(type(obj)) 1676*cda5da8dSAndroid Build Coastguard Worker 1677*cda5da8dSAndroid Build Coastguard Worker def __subclasscheck__(self, cls): 1678*cda5da8dSAndroid Build Coastguard Worker for arg in self.__args__: 1679*cda5da8dSAndroid Build Coastguard Worker if issubclass(cls, arg): 1680*cda5da8dSAndroid Build Coastguard Worker return True 1681*cda5da8dSAndroid Build Coastguard Worker 1682*cda5da8dSAndroid Build Coastguard Worker def __reduce__(self): 1683*cda5da8dSAndroid Build Coastguard Worker func, (origin, args) = super().__reduce__() 1684*cda5da8dSAndroid Build Coastguard Worker return func, (Union, args) 1685*cda5da8dSAndroid Build Coastguard Worker 1686*cda5da8dSAndroid Build Coastguard Worker 1687*cda5da8dSAndroid Build Coastguard Workerdef _value_and_type_iter(parameters): 1688*cda5da8dSAndroid Build Coastguard Worker return ((p, type(p)) for p in parameters) 1689*cda5da8dSAndroid Build Coastguard Worker 1690*cda5da8dSAndroid Build Coastguard Worker 1691*cda5da8dSAndroid Build Coastguard Workerclass _LiteralGenericAlias(_GenericAlias, _root=True): 1692*cda5da8dSAndroid Build Coastguard Worker def __eq__(self, other): 1693*cda5da8dSAndroid Build Coastguard Worker if not isinstance(other, _LiteralGenericAlias): 1694*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 1695*cda5da8dSAndroid Build Coastguard Worker 1696*cda5da8dSAndroid Build Coastguard Worker return set(_value_and_type_iter(self.__args__)) == set(_value_and_type_iter(other.__args__)) 1697*cda5da8dSAndroid Build Coastguard Worker 1698*cda5da8dSAndroid Build Coastguard Worker def __hash__(self): 1699*cda5da8dSAndroid Build Coastguard Worker return hash(frozenset(_value_and_type_iter(self.__args__))) 1700*cda5da8dSAndroid Build Coastguard Worker 1701*cda5da8dSAndroid Build Coastguard Worker 1702*cda5da8dSAndroid Build Coastguard Workerclass _ConcatenateGenericAlias(_GenericAlias, _root=True): 1703*cda5da8dSAndroid Build Coastguard Worker def copy_with(self, params): 1704*cda5da8dSAndroid Build Coastguard Worker if isinstance(params[-1], (list, tuple)): 1705*cda5da8dSAndroid Build Coastguard Worker return (*params[:-1], *params[-1]) 1706*cda5da8dSAndroid Build Coastguard Worker if isinstance(params[-1], _ConcatenateGenericAlias): 1707*cda5da8dSAndroid Build Coastguard Worker params = (*params[:-1], *params[-1].__args__) 1708*cda5da8dSAndroid Build Coastguard Worker return super().copy_with(params) 1709*cda5da8dSAndroid Build Coastguard Worker 1710*cda5da8dSAndroid Build Coastguard Worker 1711*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 1712*cda5da8dSAndroid Build Coastguard Workerdef Unpack(self, parameters): 1713*cda5da8dSAndroid Build Coastguard Worker """Type unpack operator. 1714*cda5da8dSAndroid Build Coastguard Worker 1715*cda5da8dSAndroid Build Coastguard Worker The type unpack operator takes the child types from some container type, 1716*cda5da8dSAndroid Build Coastguard Worker such as `tuple[int, str]` or a `TypeVarTuple`, and 'pulls them out'. For 1717*cda5da8dSAndroid Build Coastguard Worker example:: 1718*cda5da8dSAndroid Build Coastguard Worker 1719*cda5da8dSAndroid Build Coastguard Worker # For some generic class `Foo`: 1720*cda5da8dSAndroid Build Coastguard Worker Foo[Unpack[tuple[int, str]]] # Equivalent to Foo[int, str] 1721*cda5da8dSAndroid Build Coastguard Worker 1722*cda5da8dSAndroid Build Coastguard Worker Ts = TypeVarTuple('Ts') 1723*cda5da8dSAndroid Build Coastguard Worker # Specifies that `Bar` is generic in an arbitrary number of types. 1724*cda5da8dSAndroid Build Coastguard Worker # (Think of `Ts` as a tuple of an arbitrary number of individual 1725*cda5da8dSAndroid Build Coastguard Worker # `TypeVar`s, which the `Unpack` is 'pulling out' directly into the 1726*cda5da8dSAndroid Build Coastguard Worker # `Generic[]`.) 1727*cda5da8dSAndroid Build Coastguard Worker class Bar(Generic[Unpack[Ts]]): ... 1728*cda5da8dSAndroid Build Coastguard Worker Bar[int] # Valid 1729*cda5da8dSAndroid Build Coastguard Worker Bar[int, str] # Also valid 1730*cda5da8dSAndroid Build Coastguard Worker 1731*cda5da8dSAndroid Build Coastguard Worker From Python 3.11, this can also be done using the `*` operator:: 1732*cda5da8dSAndroid Build Coastguard Worker 1733*cda5da8dSAndroid Build Coastguard Worker Foo[*tuple[int, str]] 1734*cda5da8dSAndroid Build Coastguard Worker class Bar(Generic[*Ts]): ... 1735*cda5da8dSAndroid Build Coastguard Worker 1736*cda5da8dSAndroid Build Coastguard Worker Note that there is only some runtime checking of this operator. Not 1737*cda5da8dSAndroid Build Coastguard Worker everything the runtime allows may be accepted by static type checkers. 1738*cda5da8dSAndroid Build Coastguard Worker 1739*cda5da8dSAndroid Build Coastguard Worker For more information, see PEP 646. 1740*cda5da8dSAndroid Build Coastguard Worker """ 1741*cda5da8dSAndroid Build Coastguard Worker item = _type_check(parameters, f'{self} accepts only single type.') 1742*cda5da8dSAndroid Build Coastguard Worker return _UnpackGenericAlias(origin=self, args=(item,)) 1743*cda5da8dSAndroid Build Coastguard Worker 1744*cda5da8dSAndroid Build Coastguard Worker 1745*cda5da8dSAndroid Build Coastguard Workerclass _UnpackGenericAlias(_GenericAlias, _root=True): 1746*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 1747*cda5da8dSAndroid Build Coastguard Worker # `Unpack` only takes one argument, so __args__ should contain only 1748*cda5da8dSAndroid Build Coastguard Worker # a single item. 1749*cda5da8dSAndroid Build Coastguard Worker return '*' + repr(self.__args__[0]) 1750*cda5da8dSAndroid Build Coastguard Worker 1751*cda5da8dSAndroid Build Coastguard Worker def __getitem__(self, args): 1752*cda5da8dSAndroid Build Coastguard Worker if self.__typing_is_unpacked_typevartuple__: 1753*cda5da8dSAndroid Build Coastguard Worker return args 1754*cda5da8dSAndroid Build Coastguard Worker return super().__getitem__(args) 1755*cda5da8dSAndroid Build Coastguard Worker 1756*cda5da8dSAndroid Build Coastguard Worker @property 1757*cda5da8dSAndroid Build Coastguard Worker def __typing_unpacked_tuple_args__(self): 1758*cda5da8dSAndroid Build Coastguard Worker assert self.__origin__ is Unpack 1759*cda5da8dSAndroid Build Coastguard Worker assert len(self.__args__) == 1 1760*cda5da8dSAndroid Build Coastguard Worker arg, = self.__args__ 1761*cda5da8dSAndroid Build Coastguard Worker if isinstance(arg, _GenericAlias): 1762*cda5da8dSAndroid Build Coastguard Worker assert arg.__origin__ is tuple 1763*cda5da8dSAndroid Build Coastguard Worker return arg.__args__ 1764*cda5da8dSAndroid Build Coastguard Worker return None 1765*cda5da8dSAndroid Build Coastguard Worker 1766*cda5da8dSAndroid Build Coastguard Worker @property 1767*cda5da8dSAndroid Build Coastguard Worker def __typing_is_unpacked_typevartuple__(self): 1768*cda5da8dSAndroid Build Coastguard Worker assert self.__origin__ is Unpack 1769*cda5da8dSAndroid Build Coastguard Worker assert len(self.__args__) == 1 1770*cda5da8dSAndroid Build Coastguard Worker return isinstance(self.__args__[0], TypeVarTuple) 1771*cda5da8dSAndroid Build Coastguard Worker 1772*cda5da8dSAndroid Build Coastguard Worker 1773*cda5da8dSAndroid Build Coastguard Workerclass Generic: 1774*cda5da8dSAndroid Build Coastguard Worker """Abstract base class for generic types. 1775*cda5da8dSAndroid Build Coastguard Worker 1776*cda5da8dSAndroid Build Coastguard Worker A generic type is typically declared by inheriting from 1777*cda5da8dSAndroid Build Coastguard Worker this class parameterized with one or more type variables. 1778*cda5da8dSAndroid Build Coastguard Worker For example, a generic mapping type might be defined as:: 1779*cda5da8dSAndroid Build Coastguard Worker 1780*cda5da8dSAndroid Build Coastguard Worker class Mapping(Generic[KT, VT]): 1781*cda5da8dSAndroid Build Coastguard Worker def __getitem__(self, key: KT) -> VT: 1782*cda5da8dSAndroid Build Coastguard Worker ... 1783*cda5da8dSAndroid Build Coastguard Worker # Etc. 1784*cda5da8dSAndroid Build Coastguard Worker 1785*cda5da8dSAndroid Build Coastguard Worker This class can then be used as follows:: 1786*cda5da8dSAndroid Build Coastguard Worker 1787*cda5da8dSAndroid Build Coastguard Worker def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT: 1788*cda5da8dSAndroid Build Coastguard Worker try: 1789*cda5da8dSAndroid Build Coastguard Worker return mapping[key] 1790*cda5da8dSAndroid Build Coastguard Worker except KeyError: 1791*cda5da8dSAndroid Build Coastguard Worker return default 1792*cda5da8dSAndroid Build Coastguard Worker """ 1793*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 1794*cda5da8dSAndroid Build Coastguard Worker _is_protocol = False 1795*cda5da8dSAndroid Build Coastguard Worker 1796*cda5da8dSAndroid Build Coastguard Worker @_tp_cache 1797*cda5da8dSAndroid Build Coastguard Worker def __class_getitem__(cls, params): 1798*cda5da8dSAndroid Build Coastguard Worker """Parameterizes a generic class. 1799*cda5da8dSAndroid Build Coastguard Worker 1800*cda5da8dSAndroid Build Coastguard Worker At least, parameterizing a generic class is the *main* thing this method 1801*cda5da8dSAndroid Build Coastguard Worker does. For example, for some generic class `Foo`, this is called when we 1802*cda5da8dSAndroid Build Coastguard Worker do `Foo[int]` - there, with `cls=Foo` and `params=int`. 1803*cda5da8dSAndroid Build Coastguard Worker 1804*cda5da8dSAndroid Build Coastguard Worker However, note that this method is also called when defining generic 1805*cda5da8dSAndroid Build Coastguard Worker classes in the first place with `class Foo(Generic[T]): ...`. 1806*cda5da8dSAndroid Build Coastguard Worker """ 1807*cda5da8dSAndroid Build Coastguard Worker if not isinstance(params, tuple): 1808*cda5da8dSAndroid Build Coastguard Worker params = (params,) 1809*cda5da8dSAndroid Build Coastguard Worker 1810*cda5da8dSAndroid Build Coastguard Worker params = tuple(_type_convert(p) for p in params) 1811*cda5da8dSAndroid Build Coastguard Worker if cls in (Generic, Protocol): 1812*cda5da8dSAndroid Build Coastguard Worker # Generic and Protocol can only be subscripted with unique type variables. 1813*cda5da8dSAndroid Build Coastguard Worker if not params: 1814*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 1815*cda5da8dSAndroid Build Coastguard Worker f"Parameter list to {cls.__qualname__}[...] cannot be empty" 1816*cda5da8dSAndroid Build Coastguard Worker ) 1817*cda5da8dSAndroid Build Coastguard Worker if not all(_is_typevar_like(p) for p in params): 1818*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 1819*cda5da8dSAndroid Build Coastguard Worker f"Parameters to {cls.__name__}[...] must all be type variables " 1820*cda5da8dSAndroid Build Coastguard Worker f"or parameter specification variables.") 1821*cda5da8dSAndroid Build Coastguard Worker if len(set(params)) != len(params): 1822*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 1823*cda5da8dSAndroid Build Coastguard Worker f"Parameters to {cls.__name__}[...] must all be unique") 1824*cda5da8dSAndroid Build Coastguard Worker else: 1825*cda5da8dSAndroid Build Coastguard Worker # Subscripting a regular Generic subclass. 1826*cda5da8dSAndroid Build Coastguard Worker for param in cls.__parameters__: 1827*cda5da8dSAndroid Build Coastguard Worker prepare = getattr(param, '__typing_prepare_subst__', None) 1828*cda5da8dSAndroid Build Coastguard Worker if prepare is not None: 1829*cda5da8dSAndroid Build Coastguard Worker params = prepare(cls, params) 1830*cda5da8dSAndroid Build Coastguard Worker _check_generic(cls, params, len(cls.__parameters__)) 1831*cda5da8dSAndroid Build Coastguard Worker 1832*cda5da8dSAndroid Build Coastguard Worker new_args = [] 1833*cda5da8dSAndroid Build Coastguard Worker for param, new_arg in zip(cls.__parameters__, params): 1834*cda5da8dSAndroid Build Coastguard Worker if isinstance(param, TypeVarTuple): 1835*cda5da8dSAndroid Build Coastguard Worker new_args.extend(new_arg) 1836*cda5da8dSAndroid Build Coastguard Worker else: 1837*cda5da8dSAndroid Build Coastguard Worker new_args.append(new_arg) 1838*cda5da8dSAndroid Build Coastguard Worker params = tuple(new_args) 1839*cda5da8dSAndroid Build Coastguard Worker 1840*cda5da8dSAndroid Build Coastguard Worker return _GenericAlias(cls, params, 1841*cda5da8dSAndroid Build Coastguard Worker _paramspec_tvars=True) 1842*cda5da8dSAndroid Build Coastguard Worker 1843*cda5da8dSAndroid Build Coastguard Worker def __init_subclass__(cls, *args, **kwargs): 1844*cda5da8dSAndroid Build Coastguard Worker super().__init_subclass__(*args, **kwargs) 1845*cda5da8dSAndroid Build Coastguard Worker tvars = [] 1846*cda5da8dSAndroid Build Coastguard Worker if '__orig_bases__' in cls.__dict__: 1847*cda5da8dSAndroid Build Coastguard Worker error = Generic in cls.__orig_bases__ 1848*cda5da8dSAndroid Build Coastguard Worker else: 1849*cda5da8dSAndroid Build Coastguard Worker error = (Generic in cls.__bases__ and 1850*cda5da8dSAndroid Build Coastguard Worker cls.__name__ != 'Protocol' and 1851*cda5da8dSAndroid Build Coastguard Worker type(cls) != _TypedDictMeta) 1852*cda5da8dSAndroid Build Coastguard Worker if error: 1853*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Cannot inherit from plain Generic") 1854*cda5da8dSAndroid Build Coastguard Worker if '__orig_bases__' in cls.__dict__: 1855*cda5da8dSAndroid Build Coastguard Worker tvars = _collect_parameters(cls.__orig_bases__) 1856*cda5da8dSAndroid Build Coastguard Worker # Look for Generic[T1, ..., Tn]. 1857*cda5da8dSAndroid Build Coastguard Worker # If found, tvars must be a subset of it. 1858*cda5da8dSAndroid Build Coastguard Worker # If not found, tvars is it. 1859*cda5da8dSAndroid Build Coastguard Worker # Also check for and reject plain Generic, 1860*cda5da8dSAndroid Build Coastguard Worker # and reject multiple Generic[...]. 1861*cda5da8dSAndroid Build Coastguard Worker gvars = None 1862*cda5da8dSAndroid Build Coastguard Worker for base in cls.__orig_bases__: 1863*cda5da8dSAndroid Build Coastguard Worker if (isinstance(base, _GenericAlias) and 1864*cda5da8dSAndroid Build Coastguard Worker base.__origin__ is Generic): 1865*cda5da8dSAndroid Build Coastguard Worker if gvars is not None: 1866*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 1867*cda5da8dSAndroid Build Coastguard Worker "Cannot inherit from Generic[...] multiple times.") 1868*cda5da8dSAndroid Build Coastguard Worker gvars = base.__parameters__ 1869*cda5da8dSAndroid Build Coastguard Worker if gvars is not None: 1870*cda5da8dSAndroid Build Coastguard Worker tvarset = set(tvars) 1871*cda5da8dSAndroid Build Coastguard Worker gvarset = set(gvars) 1872*cda5da8dSAndroid Build Coastguard Worker if not tvarset <= gvarset: 1873*cda5da8dSAndroid Build Coastguard Worker s_vars = ', '.join(str(t) for t in tvars if t not in gvarset) 1874*cda5da8dSAndroid Build Coastguard Worker s_args = ', '.join(str(g) for g in gvars) 1875*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Some type variables ({s_vars}) are" 1876*cda5da8dSAndroid Build Coastguard Worker f" not listed in Generic[{s_args}]") 1877*cda5da8dSAndroid Build Coastguard Worker tvars = gvars 1878*cda5da8dSAndroid Build Coastguard Worker cls.__parameters__ = tuple(tvars) 1879*cda5da8dSAndroid Build Coastguard Worker 1880*cda5da8dSAndroid Build Coastguard Worker 1881*cda5da8dSAndroid Build Coastguard Workerclass _TypingEllipsis: 1882*cda5da8dSAndroid Build Coastguard Worker """Internal placeholder for ... (ellipsis).""" 1883*cda5da8dSAndroid Build Coastguard Worker 1884*cda5da8dSAndroid Build Coastguard Worker 1885*cda5da8dSAndroid Build Coastguard Worker_TYPING_INTERNALS = ['__parameters__', '__orig_bases__', '__orig_class__', 1886*cda5da8dSAndroid Build Coastguard Worker '_is_protocol', '_is_runtime_protocol'] 1887*cda5da8dSAndroid Build Coastguard Worker 1888*cda5da8dSAndroid Build Coastguard Worker_SPECIAL_NAMES = ['__abstractmethods__', '__annotations__', '__dict__', '__doc__', 1889*cda5da8dSAndroid Build Coastguard Worker '__init__', '__module__', '__new__', '__slots__', 1890*cda5da8dSAndroid Build Coastguard Worker '__subclasshook__', '__weakref__', '__class_getitem__'] 1891*cda5da8dSAndroid Build Coastguard Worker 1892*cda5da8dSAndroid Build Coastguard Worker# These special attributes will be not collected as protocol members. 1893*cda5da8dSAndroid Build Coastguard WorkerEXCLUDED_ATTRIBUTES = _TYPING_INTERNALS + _SPECIAL_NAMES + ['_MutableMapping__marker'] 1894*cda5da8dSAndroid Build Coastguard Worker 1895*cda5da8dSAndroid Build Coastguard Worker 1896*cda5da8dSAndroid Build Coastguard Workerdef _get_protocol_attrs(cls): 1897*cda5da8dSAndroid Build Coastguard Worker """Collect protocol members from a protocol class objects. 1898*cda5da8dSAndroid Build Coastguard Worker 1899*cda5da8dSAndroid Build Coastguard Worker This includes names actually defined in the class dictionary, as well 1900*cda5da8dSAndroid Build Coastguard Worker as names that appear in annotations. Special names (above) are skipped. 1901*cda5da8dSAndroid Build Coastguard Worker """ 1902*cda5da8dSAndroid Build Coastguard Worker attrs = set() 1903*cda5da8dSAndroid Build Coastguard Worker for base in cls.__mro__[:-1]: # without object 1904*cda5da8dSAndroid Build Coastguard Worker if base.__name__ in ('Protocol', 'Generic'): 1905*cda5da8dSAndroid Build Coastguard Worker continue 1906*cda5da8dSAndroid Build Coastguard Worker annotations = getattr(base, '__annotations__', {}) 1907*cda5da8dSAndroid Build Coastguard Worker for attr in list(base.__dict__.keys()) + list(annotations.keys()): 1908*cda5da8dSAndroid Build Coastguard Worker if not attr.startswith('_abc_') and attr not in EXCLUDED_ATTRIBUTES: 1909*cda5da8dSAndroid Build Coastguard Worker attrs.add(attr) 1910*cda5da8dSAndroid Build Coastguard Worker return attrs 1911*cda5da8dSAndroid Build Coastguard Worker 1912*cda5da8dSAndroid Build Coastguard Worker 1913*cda5da8dSAndroid Build Coastguard Workerdef _is_callable_members_only(cls): 1914*cda5da8dSAndroid Build Coastguard Worker # PEP 544 prohibits using issubclass() with protocols that have non-method members. 1915*cda5da8dSAndroid Build Coastguard Worker return all(callable(getattr(cls, attr, None)) for attr in _get_protocol_attrs(cls)) 1916*cda5da8dSAndroid Build Coastguard Worker 1917*cda5da8dSAndroid Build Coastguard Worker 1918*cda5da8dSAndroid Build Coastguard Workerdef _no_init_or_replace_init(self, *args, **kwargs): 1919*cda5da8dSAndroid Build Coastguard Worker cls = type(self) 1920*cda5da8dSAndroid Build Coastguard Worker 1921*cda5da8dSAndroid Build Coastguard Worker if cls._is_protocol: 1922*cda5da8dSAndroid Build Coastguard Worker raise TypeError('Protocols cannot be instantiated') 1923*cda5da8dSAndroid Build Coastguard Worker 1924*cda5da8dSAndroid Build Coastguard Worker # Already using a custom `__init__`. No need to calculate correct 1925*cda5da8dSAndroid Build Coastguard Worker # `__init__` to call. This can lead to RecursionError. See bpo-45121. 1926*cda5da8dSAndroid Build Coastguard Worker if cls.__init__ is not _no_init_or_replace_init: 1927*cda5da8dSAndroid Build Coastguard Worker return 1928*cda5da8dSAndroid Build Coastguard Worker 1929*cda5da8dSAndroid Build Coastguard Worker # Initially, `__init__` of a protocol subclass is set to `_no_init_or_replace_init`. 1930*cda5da8dSAndroid Build Coastguard Worker # The first instantiation of the subclass will call `_no_init_or_replace_init` which 1931*cda5da8dSAndroid Build Coastguard Worker # searches for a proper new `__init__` in the MRO. The new `__init__` 1932*cda5da8dSAndroid Build Coastguard Worker # replaces the subclass' old `__init__` (ie `_no_init_or_replace_init`). Subsequent 1933*cda5da8dSAndroid Build Coastguard Worker # instantiation of the protocol subclass will thus use the new 1934*cda5da8dSAndroid Build Coastguard Worker # `__init__` and no longer call `_no_init_or_replace_init`. 1935*cda5da8dSAndroid Build Coastguard Worker for base in cls.__mro__: 1936*cda5da8dSAndroid Build Coastguard Worker init = base.__dict__.get('__init__', _no_init_or_replace_init) 1937*cda5da8dSAndroid Build Coastguard Worker if init is not _no_init_or_replace_init: 1938*cda5da8dSAndroid Build Coastguard Worker cls.__init__ = init 1939*cda5da8dSAndroid Build Coastguard Worker break 1940*cda5da8dSAndroid Build Coastguard Worker else: 1941*cda5da8dSAndroid Build Coastguard Worker # should not happen 1942*cda5da8dSAndroid Build Coastguard Worker cls.__init__ = object.__init__ 1943*cda5da8dSAndroid Build Coastguard Worker 1944*cda5da8dSAndroid Build Coastguard Worker cls.__init__(self, *args, **kwargs) 1945*cda5da8dSAndroid Build Coastguard Worker 1946*cda5da8dSAndroid Build Coastguard Worker 1947*cda5da8dSAndroid Build Coastguard Workerdef _caller(depth=1, default='__main__'): 1948*cda5da8dSAndroid Build Coastguard Worker try: 1949*cda5da8dSAndroid Build Coastguard Worker return sys._getframe(depth + 1).f_globals.get('__name__', default) 1950*cda5da8dSAndroid Build Coastguard Worker except (AttributeError, ValueError): # For platforms without _getframe() 1951*cda5da8dSAndroid Build Coastguard Worker return None 1952*cda5da8dSAndroid Build Coastguard Worker 1953*cda5da8dSAndroid Build Coastguard Worker 1954*cda5da8dSAndroid Build Coastguard Workerdef _allow_reckless_class_checks(depth=3): 1955*cda5da8dSAndroid Build Coastguard Worker """Allow instance and class checks for special stdlib modules. 1956*cda5da8dSAndroid Build Coastguard Worker 1957*cda5da8dSAndroid Build Coastguard Worker The abc and functools modules indiscriminately call isinstance() and 1958*cda5da8dSAndroid Build Coastguard Worker issubclass() on the whole MRO of a user class, which may contain protocols. 1959*cda5da8dSAndroid Build Coastguard Worker """ 1960*cda5da8dSAndroid Build Coastguard Worker return _caller(depth) in {'abc', 'functools', None} 1961*cda5da8dSAndroid Build Coastguard Worker 1962*cda5da8dSAndroid Build Coastguard Worker 1963*cda5da8dSAndroid Build Coastguard Worker_PROTO_ALLOWLIST = { 1964*cda5da8dSAndroid Build Coastguard Worker 'collections.abc': [ 1965*cda5da8dSAndroid Build Coastguard Worker 'Callable', 'Awaitable', 'Iterable', 'Iterator', 'AsyncIterable', 1966*cda5da8dSAndroid Build Coastguard Worker 'Hashable', 'Sized', 'Container', 'Collection', 'Reversible', 1967*cda5da8dSAndroid Build Coastguard Worker ], 1968*cda5da8dSAndroid Build Coastguard Worker 'contextlib': ['AbstractContextManager', 'AbstractAsyncContextManager'], 1969*cda5da8dSAndroid Build Coastguard Worker} 1970*cda5da8dSAndroid Build Coastguard Worker 1971*cda5da8dSAndroid Build Coastguard Worker 1972*cda5da8dSAndroid Build Coastguard Workerclass _ProtocolMeta(ABCMeta): 1973*cda5da8dSAndroid Build Coastguard Worker # This metaclass is really unfortunate and exists only because of 1974*cda5da8dSAndroid Build Coastguard Worker # the lack of __instancehook__. 1975*cda5da8dSAndroid Build Coastguard Worker def __instancecheck__(cls, instance): 1976*cda5da8dSAndroid Build Coastguard Worker # We need this method for situations where attributes are 1977*cda5da8dSAndroid Build Coastguard Worker # assigned in __init__. 1978*cda5da8dSAndroid Build Coastguard Worker if ( 1979*cda5da8dSAndroid Build Coastguard Worker getattr(cls, '_is_protocol', False) and 1980*cda5da8dSAndroid Build Coastguard Worker not getattr(cls, '_is_runtime_protocol', False) and 1981*cda5da8dSAndroid Build Coastguard Worker not _allow_reckless_class_checks(depth=2) 1982*cda5da8dSAndroid Build Coastguard Worker ): 1983*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Instance and class checks can only be used with" 1984*cda5da8dSAndroid Build Coastguard Worker " @runtime_checkable protocols") 1985*cda5da8dSAndroid Build Coastguard Worker 1986*cda5da8dSAndroid Build Coastguard Worker if ((not getattr(cls, '_is_protocol', False) or 1987*cda5da8dSAndroid Build Coastguard Worker _is_callable_members_only(cls)) and 1988*cda5da8dSAndroid Build Coastguard Worker issubclass(instance.__class__, cls)): 1989*cda5da8dSAndroid Build Coastguard Worker return True 1990*cda5da8dSAndroid Build Coastguard Worker if cls._is_protocol: 1991*cda5da8dSAndroid Build Coastguard Worker if all(hasattr(instance, attr) and 1992*cda5da8dSAndroid Build Coastguard Worker # All *methods* can be blocked by setting them to None. 1993*cda5da8dSAndroid Build Coastguard Worker (not callable(getattr(cls, attr, None)) or 1994*cda5da8dSAndroid Build Coastguard Worker getattr(instance, attr) is not None) 1995*cda5da8dSAndroid Build Coastguard Worker for attr in _get_protocol_attrs(cls)): 1996*cda5da8dSAndroid Build Coastguard Worker return True 1997*cda5da8dSAndroid Build Coastguard Worker return super().__instancecheck__(instance) 1998*cda5da8dSAndroid Build Coastguard Worker 1999*cda5da8dSAndroid Build Coastguard Worker 2000*cda5da8dSAndroid Build Coastguard Workerclass Protocol(Generic, metaclass=_ProtocolMeta): 2001*cda5da8dSAndroid Build Coastguard Worker """Base class for protocol classes. 2002*cda5da8dSAndroid Build Coastguard Worker 2003*cda5da8dSAndroid Build Coastguard Worker Protocol classes are defined as:: 2004*cda5da8dSAndroid Build Coastguard Worker 2005*cda5da8dSAndroid Build Coastguard Worker class Proto(Protocol): 2006*cda5da8dSAndroid Build Coastguard Worker def meth(self) -> int: 2007*cda5da8dSAndroid Build Coastguard Worker ... 2008*cda5da8dSAndroid Build Coastguard Worker 2009*cda5da8dSAndroid Build Coastguard Worker Such classes are primarily used with static type checkers that recognize 2010*cda5da8dSAndroid Build Coastguard Worker structural subtyping (static duck-typing), for example:: 2011*cda5da8dSAndroid Build Coastguard Worker 2012*cda5da8dSAndroid Build Coastguard Worker class C: 2013*cda5da8dSAndroid Build Coastguard Worker def meth(self) -> int: 2014*cda5da8dSAndroid Build Coastguard Worker return 0 2015*cda5da8dSAndroid Build Coastguard Worker 2016*cda5da8dSAndroid Build Coastguard Worker def func(x: Proto) -> int: 2017*cda5da8dSAndroid Build Coastguard Worker return x.meth() 2018*cda5da8dSAndroid Build Coastguard Worker 2019*cda5da8dSAndroid Build Coastguard Worker func(C()) # Passes static type check 2020*cda5da8dSAndroid Build Coastguard Worker 2021*cda5da8dSAndroid Build Coastguard Worker See PEP 544 for details. Protocol classes decorated with 2022*cda5da8dSAndroid Build Coastguard Worker @typing.runtime_checkable act as simple-minded runtime protocols that check 2023*cda5da8dSAndroid Build Coastguard Worker only the presence of given attributes, ignoring their type signatures. 2024*cda5da8dSAndroid Build Coastguard Worker Protocol classes can be generic, they are defined as:: 2025*cda5da8dSAndroid Build Coastguard Worker 2026*cda5da8dSAndroid Build Coastguard Worker class GenProto(Protocol[T]): 2027*cda5da8dSAndroid Build Coastguard Worker def meth(self) -> T: 2028*cda5da8dSAndroid Build Coastguard Worker ... 2029*cda5da8dSAndroid Build Coastguard Worker """ 2030*cda5da8dSAndroid Build Coastguard Worker 2031*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 2032*cda5da8dSAndroid Build Coastguard Worker _is_protocol = True 2033*cda5da8dSAndroid Build Coastguard Worker _is_runtime_protocol = False 2034*cda5da8dSAndroid Build Coastguard Worker 2035*cda5da8dSAndroid Build Coastguard Worker def __init_subclass__(cls, *args, **kwargs): 2036*cda5da8dSAndroid Build Coastguard Worker super().__init_subclass__(*args, **kwargs) 2037*cda5da8dSAndroid Build Coastguard Worker 2038*cda5da8dSAndroid Build Coastguard Worker # Determine if this is a protocol or a concrete subclass. 2039*cda5da8dSAndroid Build Coastguard Worker if not cls.__dict__.get('_is_protocol', False): 2040*cda5da8dSAndroid Build Coastguard Worker cls._is_protocol = any(b is Protocol for b in cls.__bases__) 2041*cda5da8dSAndroid Build Coastguard Worker 2042*cda5da8dSAndroid Build Coastguard Worker # Set (or override) the protocol subclass hook. 2043*cda5da8dSAndroid Build Coastguard Worker def _proto_hook(other): 2044*cda5da8dSAndroid Build Coastguard Worker if not cls.__dict__.get('_is_protocol', False): 2045*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 2046*cda5da8dSAndroid Build Coastguard Worker 2047*cda5da8dSAndroid Build Coastguard Worker # First, perform various sanity checks. 2048*cda5da8dSAndroid Build Coastguard Worker if not getattr(cls, '_is_runtime_protocol', False): 2049*cda5da8dSAndroid Build Coastguard Worker if _allow_reckless_class_checks(): 2050*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 2051*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Instance and class checks can only be used with" 2052*cda5da8dSAndroid Build Coastguard Worker " @runtime_checkable protocols") 2053*cda5da8dSAndroid Build Coastguard Worker if not _is_callable_members_only(cls): 2054*cda5da8dSAndroid Build Coastguard Worker if _allow_reckless_class_checks(): 2055*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 2056*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Protocols with non-method members" 2057*cda5da8dSAndroid Build Coastguard Worker " don't support issubclass()") 2058*cda5da8dSAndroid Build Coastguard Worker if not isinstance(other, type): 2059*cda5da8dSAndroid Build Coastguard Worker # Same error message as for issubclass(1, int). 2060*cda5da8dSAndroid Build Coastguard Worker raise TypeError('issubclass() arg 1 must be a class') 2061*cda5da8dSAndroid Build Coastguard Worker 2062*cda5da8dSAndroid Build Coastguard Worker # Second, perform the actual structural compatibility check. 2063*cda5da8dSAndroid Build Coastguard Worker for attr in _get_protocol_attrs(cls): 2064*cda5da8dSAndroid Build Coastguard Worker for base in other.__mro__: 2065*cda5da8dSAndroid Build Coastguard Worker # Check if the members appears in the class dictionary... 2066*cda5da8dSAndroid Build Coastguard Worker if attr in base.__dict__: 2067*cda5da8dSAndroid Build Coastguard Worker if base.__dict__[attr] is None: 2068*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 2069*cda5da8dSAndroid Build Coastguard Worker break 2070*cda5da8dSAndroid Build Coastguard Worker 2071*cda5da8dSAndroid Build Coastguard Worker # ...or in annotations, if it is a sub-protocol. 2072*cda5da8dSAndroid Build Coastguard Worker annotations = getattr(base, '__annotations__', {}) 2073*cda5da8dSAndroid Build Coastguard Worker if (isinstance(annotations, collections.abc.Mapping) and 2074*cda5da8dSAndroid Build Coastguard Worker attr in annotations and 2075*cda5da8dSAndroid Build Coastguard Worker issubclass(other, Generic) and other._is_protocol): 2076*cda5da8dSAndroid Build Coastguard Worker break 2077*cda5da8dSAndroid Build Coastguard Worker else: 2078*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 2079*cda5da8dSAndroid Build Coastguard Worker return True 2080*cda5da8dSAndroid Build Coastguard Worker 2081*cda5da8dSAndroid Build Coastguard Worker if '__subclasshook__' not in cls.__dict__: 2082*cda5da8dSAndroid Build Coastguard Worker cls.__subclasshook__ = _proto_hook 2083*cda5da8dSAndroid Build Coastguard Worker 2084*cda5da8dSAndroid Build Coastguard Worker # We have nothing more to do for non-protocols... 2085*cda5da8dSAndroid Build Coastguard Worker if not cls._is_protocol: 2086*cda5da8dSAndroid Build Coastguard Worker return 2087*cda5da8dSAndroid Build Coastguard Worker 2088*cda5da8dSAndroid Build Coastguard Worker # ... otherwise check consistency of bases, and prohibit instantiation. 2089*cda5da8dSAndroid Build Coastguard Worker for base in cls.__bases__: 2090*cda5da8dSAndroid Build Coastguard Worker if not (base in (object, Generic) or 2091*cda5da8dSAndroid Build Coastguard Worker base.__module__ in _PROTO_ALLOWLIST and 2092*cda5da8dSAndroid Build Coastguard Worker base.__name__ in _PROTO_ALLOWLIST[base.__module__] or 2093*cda5da8dSAndroid Build Coastguard Worker issubclass(base, Generic) and base._is_protocol): 2094*cda5da8dSAndroid Build Coastguard Worker raise TypeError('Protocols can only inherit from other' 2095*cda5da8dSAndroid Build Coastguard Worker ' protocols, got %r' % base) 2096*cda5da8dSAndroid Build Coastguard Worker if cls.__init__ is Protocol.__init__: 2097*cda5da8dSAndroid Build Coastguard Worker cls.__init__ = _no_init_or_replace_init 2098*cda5da8dSAndroid Build Coastguard Worker 2099*cda5da8dSAndroid Build Coastguard Worker 2100*cda5da8dSAndroid Build Coastguard Workerclass _AnnotatedAlias(_NotIterable, _GenericAlias, _root=True): 2101*cda5da8dSAndroid Build Coastguard Worker """Runtime representation of an annotated type. 2102*cda5da8dSAndroid Build Coastguard Worker 2103*cda5da8dSAndroid Build Coastguard Worker At its core 'Annotated[t, dec1, dec2, ...]' is an alias for the type 't' 2104*cda5da8dSAndroid Build Coastguard Worker with extra annotations. The alias behaves like a normal typing alias. 2105*cda5da8dSAndroid Build Coastguard Worker Instantiating is the same as instantiating the underlying type; binding 2106*cda5da8dSAndroid Build Coastguard Worker it to types is also the same. 2107*cda5da8dSAndroid Build Coastguard Worker 2108*cda5da8dSAndroid Build Coastguard Worker The metadata itself is stored in a '__metadata__' attribute as a tuple. 2109*cda5da8dSAndroid Build Coastguard Worker """ 2110*cda5da8dSAndroid Build Coastguard Worker 2111*cda5da8dSAndroid Build Coastguard Worker def __init__(self, origin, metadata): 2112*cda5da8dSAndroid Build Coastguard Worker if isinstance(origin, _AnnotatedAlias): 2113*cda5da8dSAndroid Build Coastguard Worker metadata = origin.__metadata__ + metadata 2114*cda5da8dSAndroid Build Coastguard Worker origin = origin.__origin__ 2115*cda5da8dSAndroid Build Coastguard Worker super().__init__(origin, origin) 2116*cda5da8dSAndroid Build Coastguard Worker self.__metadata__ = metadata 2117*cda5da8dSAndroid Build Coastguard Worker 2118*cda5da8dSAndroid Build Coastguard Worker def copy_with(self, params): 2119*cda5da8dSAndroid Build Coastguard Worker assert len(params) == 1 2120*cda5da8dSAndroid Build Coastguard Worker new_type = params[0] 2121*cda5da8dSAndroid Build Coastguard Worker return _AnnotatedAlias(new_type, self.__metadata__) 2122*cda5da8dSAndroid Build Coastguard Worker 2123*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 2124*cda5da8dSAndroid Build Coastguard Worker return "typing.Annotated[{}, {}]".format( 2125*cda5da8dSAndroid Build Coastguard Worker _type_repr(self.__origin__), 2126*cda5da8dSAndroid Build Coastguard Worker ", ".join(repr(a) for a in self.__metadata__) 2127*cda5da8dSAndroid Build Coastguard Worker ) 2128*cda5da8dSAndroid Build Coastguard Worker 2129*cda5da8dSAndroid Build Coastguard Worker def __reduce__(self): 2130*cda5da8dSAndroid Build Coastguard Worker return operator.getitem, ( 2131*cda5da8dSAndroid Build Coastguard Worker Annotated, (self.__origin__,) + self.__metadata__ 2132*cda5da8dSAndroid Build Coastguard Worker ) 2133*cda5da8dSAndroid Build Coastguard Worker 2134*cda5da8dSAndroid Build Coastguard Worker def __eq__(self, other): 2135*cda5da8dSAndroid Build Coastguard Worker if not isinstance(other, _AnnotatedAlias): 2136*cda5da8dSAndroid Build Coastguard Worker return NotImplemented 2137*cda5da8dSAndroid Build Coastguard Worker return (self.__origin__ == other.__origin__ 2138*cda5da8dSAndroid Build Coastguard Worker and self.__metadata__ == other.__metadata__) 2139*cda5da8dSAndroid Build Coastguard Worker 2140*cda5da8dSAndroid Build Coastguard Worker def __hash__(self): 2141*cda5da8dSAndroid Build Coastguard Worker return hash((self.__origin__, self.__metadata__)) 2142*cda5da8dSAndroid Build Coastguard Worker 2143*cda5da8dSAndroid Build Coastguard Worker def __getattr__(self, attr): 2144*cda5da8dSAndroid Build Coastguard Worker if attr in {'__name__', '__qualname__'}: 2145*cda5da8dSAndroid Build Coastguard Worker return 'Annotated' 2146*cda5da8dSAndroid Build Coastguard Worker return super().__getattr__(attr) 2147*cda5da8dSAndroid Build Coastguard Worker 2148*cda5da8dSAndroid Build Coastguard Worker 2149*cda5da8dSAndroid Build Coastguard Workerclass Annotated: 2150*cda5da8dSAndroid Build Coastguard Worker """Add context-specific metadata to a type. 2151*cda5da8dSAndroid Build Coastguard Worker 2152*cda5da8dSAndroid Build Coastguard Worker Example: Annotated[int, runtime_check.Unsigned] indicates to the 2153*cda5da8dSAndroid Build Coastguard Worker hypothetical runtime_check module that this type is an unsigned int. 2154*cda5da8dSAndroid Build Coastguard Worker Every other consumer of this type can ignore this metadata and treat 2155*cda5da8dSAndroid Build Coastguard Worker this type as int. 2156*cda5da8dSAndroid Build Coastguard Worker 2157*cda5da8dSAndroid Build Coastguard Worker The first argument to Annotated must be a valid type. 2158*cda5da8dSAndroid Build Coastguard Worker 2159*cda5da8dSAndroid Build Coastguard Worker Details: 2160*cda5da8dSAndroid Build Coastguard Worker 2161*cda5da8dSAndroid Build Coastguard Worker - It's an error to call `Annotated` with less than two arguments. 2162*cda5da8dSAndroid Build Coastguard Worker - Access the metadata via the ``__metadata__`` attribute:: 2163*cda5da8dSAndroid Build Coastguard Worker 2164*cda5da8dSAndroid Build Coastguard Worker assert Annotated[int, '$'].__metadata__ == ('$',) 2165*cda5da8dSAndroid Build Coastguard Worker 2166*cda5da8dSAndroid Build Coastguard Worker - Nested Annotated are flattened:: 2167*cda5da8dSAndroid Build Coastguard Worker 2168*cda5da8dSAndroid Build Coastguard Worker assert Annotated[Annotated[T, Ann1, Ann2], Ann3] == Annotated[T, Ann1, Ann2, Ann3] 2169*cda5da8dSAndroid Build Coastguard Worker 2170*cda5da8dSAndroid Build Coastguard Worker - Instantiating an annotated type is equivalent to instantiating the 2171*cda5da8dSAndroid Build Coastguard Worker underlying type:: 2172*cda5da8dSAndroid Build Coastguard Worker 2173*cda5da8dSAndroid Build Coastguard Worker assert Annotated[C, Ann1](5) == C(5) 2174*cda5da8dSAndroid Build Coastguard Worker 2175*cda5da8dSAndroid Build Coastguard Worker - Annotated can be used as a generic type alias:: 2176*cda5da8dSAndroid Build Coastguard Worker 2177*cda5da8dSAndroid Build Coastguard Worker Optimized = Annotated[T, runtime.Optimize()] 2178*cda5da8dSAndroid Build Coastguard Worker assert Optimized[int] == Annotated[int, runtime.Optimize()] 2179*cda5da8dSAndroid Build Coastguard Worker 2180*cda5da8dSAndroid Build Coastguard Worker OptimizedList = Annotated[List[T], runtime.Optimize()] 2181*cda5da8dSAndroid Build Coastguard Worker assert OptimizedList[int] == Annotated[List[int], runtime.Optimize()] 2182*cda5da8dSAndroid Build Coastguard Worker 2183*cda5da8dSAndroid Build Coastguard Worker - Annotated cannot be used with an unpacked TypeVarTuple:: 2184*cda5da8dSAndroid Build Coastguard Worker 2185*cda5da8dSAndroid Build Coastguard Worker Annotated[*Ts, Ann1] # NOT valid 2186*cda5da8dSAndroid Build Coastguard Worker 2187*cda5da8dSAndroid Build Coastguard Worker This would be equivalent to 2188*cda5da8dSAndroid Build Coastguard Worker 2189*cda5da8dSAndroid Build Coastguard Worker Annotated[T1, T2, T3, ..., Ann1] 2190*cda5da8dSAndroid Build Coastguard Worker 2191*cda5da8dSAndroid Build Coastguard Worker where T1, T2 etc. are TypeVars, which would be invalid, because 2192*cda5da8dSAndroid Build Coastguard Worker only one type should be passed to Annotated. 2193*cda5da8dSAndroid Build Coastguard Worker """ 2194*cda5da8dSAndroid Build Coastguard Worker 2195*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 2196*cda5da8dSAndroid Build Coastguard Worker 2197*cda5da8dSAndroid Build Coastguard Worker def __new__(cls, *args, **kwargs): 2198*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Type Annotated cannot be instantiated.") 2199*cda5da8dSAndroid Build Coastguard Worker 2200*cda5da8dSAndroid Build Coastguard Worker @_tp_cache 2201*cda5da8dSAndroid Build Coastguard Worker def __class_getitem__(cls, params): 2202*cda5da8dSAndroid Build Coastguard Worker if not isinstance(params, tuple) or len(params) < 2: 2203*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Annotated[...] should be used " 2204*cda5da8dSAndroid Build Coastguard Worker "with at least two arguments (a type and an " 2205*cda5da8dSAndroid Build Coastguard Worker "annotation).") 2206*cda5da8dSAndroid Build Coastguard Worker if _is_unpacked_typevartuple(params[0]): 2207*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Annotated[...] should not be used with an " 2208*cda5da8dSAndroid Build Coastguard Worker "unpacked TypeVarTuple") 2209*cda5da8dSAndroid Build Coastguard Worker msg = "Annotated[t, ...]: t must be a type." 2210*cda5da8dSAndroid Build Coastguard Worker origin = _type_check(params[0], msg, allow_special_forms=True) 2211*cda5da8dSAndroid Build Coastguard Worker metadata = tuple(params[1:]) 2212*cda5da8dSAndroid Build Coastguard Worker return _AnnotatedAlias(origin, metadata) 2213*cda5da8dSAndroid Build Coastguard Worker 2214*cda5da8dSAndroid Build Coastguard Worker def __init_subclass__(cls, *args, **kwargs): 2215*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 2216*cda5da8dSAndroid Build Coastguard Worker "Cannot subclass {}.Annotated".format(cls.__module__) 2217*cda5da8dSAndroid Build Coastguard Worker ) 2218*cda5da8dSAndroid Build Coastguard Worker 2219*cda5da8dSAndroid Build Coastguard Worker 2220*cda5da8dSAndroid Build Coastguard Workerdef runtime_checkable(cls): 2221*cda5da8dSAndroid Build Coastguard Worker """Mark a protocol class as a runtime protocol. 2222*cda5da8dSAndroid Build Coastguard Worker 2223*cda5da8dSAndroid Build Coastguard Worker Such protocol can be used with isinstance() and issubclass(). 2224*cda5da8dSAndroid Build Coastguard Worker Raise TypeError if applied to a non-protocol class. 2225*cda5da8dSAndroid Build Coastguard Worker This allows a simple-minded structural check very similar to 2226*cda5da8dSAndroid Build Coastguard Worker one trick ponies in collections.abc such as Iterable. 2227*cda5da8dSAndroid Build Coastguard Worker 2228*cda5da8dSAndroid Build Coastguard Worker For example:: 2229*cda5da8dSAndroid Build Coastguard Worker 2230*cda5da8dSAndroid Build Coastguard Worker @runtime_checkable 2231*cda5da8dSAndroid Build Coastguard Worker class Closable(Protocol): 2232*cda5da8dSAndroid Build Coastguard Worker def close(self): ... 2233*cda5da8dSAndroid Build Coastguard Worker 2234*cda5da8dSAndroid Build Coastguard Worker assert isinstance(open('/some/file'), Closable) 2235*cda5da8dSAndroid Build Coastguard Worker 2236*cda5da8dSAndroid Build Coastguard Worker Warning: this will check only the presence of the required methods, 2237*cda5da8dSAndroid Build Coastguard Worker not their type signatures! 2238*cda5da8dSAndroid Build Coastguard Worker """ 2239*cda5da8dSAndroid Build Coastguard Worker if not issubclass(cls, Generic) or not cls._is_protocol: 2240*cda5da8dSAndroid Build Coastguard Worker raise TypeError('@runtime_checkable can be only applied to protocol classes,' 2241*cda5da8dSAndroid Build Coastguard Worker ' got %r' % cls) 2242*cda5da8dSAndroid Build Coastguard Worker cls._is_runtime_protocol = True 2243*cda5da8dSAndroid Build Coastguard Worker return cls 2244*cda5da8dSAndroid Build Coastguard Worker 2245*cda5da8dSAndroid Build Coastguard Worker 2246*cda5da8dSAndroid Build Coastguard Workerdef cast(typ, val): 2247*cda5da8dSAndroid Build Coastguard Worker """Cast a value to a type. 2248*cda5da8dSAndroid Build Coastguard Worker 2249*cda5da8dSAndroid Build Coastguard Worker This returns the value unchanged. To the type checker this 2250*cda5da8dSAndroid Build Coastguard Worker signals that the return value has the designated type, but at 2251*cda5da8dSAndroid Build Coastguard Worker runtime we intentionally don't check anything (we want this 2252*cda5da8dSAndroid Build Coastguard Worker to be as fast as possible). 2253*cda5da8dSAndroid Build Coastguard Worker """ 2254*cda5da8dSAndroid Build Coastguard Worker return val 2255*cda5da8dSAndroid Build Coastguard Worker 2256*cda5da8dSAndroid Build Coastguard Worker 2257*cda5da8dSAndroid Build Coastguard Workerdef assert_type(val, typ, /): 2258*cda5da8dSAndroid Build Coastguard Worker """Ask a static type checker to confirm that the value is of the given type. 2259*cda5da8dSAndroid Build Coastguard Worker 2260*cda5da8dSAndroid Build Coastguard Worker At runtime this does nothing: it returns the first argument unchanged with no 2261*cda5da8dSAndroid Build Coastguard Worker checks or side effects, no matter the actual type of the argument. 2262*cda5da8dSAndroid Build Coastguard Worker 2263*cda5da8dSAndroid Build Coastguard Worker When a static type checker encounters a call to assert_type(), it 2264*cda5da8dSAndroid Build Coastguard Worker emits an error if the value is not of the specified type:: 2265*cda5da8dSAndroid Build Coastguard Worker 2266*cda5da8dSAndroid Build Coastguard Worker def greet(name: str) -> None: 2267*cda5da8dSAndroid Build Coastguard Worker assert_type(name, str) # ok 2268*cda5da8dSAndroid Build Coastguard Worker assert_type(name, int) # type checker error 2269*cda5da8dSAndroid Build Coastguard Worker """ 2270*cda5da8dSAndroid Build Coastguard Worker return val 2271*cda5da8dSAndroid Build Coastguard Worker 2272*cda5da8dSAndroid Build Coastguard Worker 2273*cda5da8dSAndroid Build Coastguard Worker_allowed_types = (types.FunctionType, types.BuiltinFunctionType, 2274*cda5da8dSAndroid Build Coastguard Worker types.MethodType, types.ModuleType, 2275*cda5da8dSAndroid Build Coastguard Worker WrapperDescriptorType, MethodWrapperType, MethodDescriptorType) 2276*cda5da8dSAndroid Build Coastguard Worker 2277*cda5da8dSAndroid Build Coastguard Worker 2278*cda5da8dSAndroid Build Coastguard Workerdef get_type_hints(obj, globalns=None, localns=None, include_extras=False): 2279*cda5da8dSAndroid Build Coastguard Worker """Return type hints for an object. 2280*cda5da8dSAndroid Build Coastguard Worker 2281*cda5da8dSAndroid Build Coastguard Worker This is often the same as obj.__annotations__, but it handles 2282*cda5da8dSAndroid Build Coastguard Worker forward references encoded as string literals and recursively replaces all 2283*cda5da8dSAndroid Build Coastguard Worker 'Annotated[T, ...]' with 'T' (unless 'include_extras=True'). 2284*cda5da8dSAndroid Build Coastguard Worker 2285*cda5da8dSAndroid Build Coastguard Worker The argument may be a module, class, method, or function. The annotations 2286*cda5da8dSAndroid Build Coastguard Worker are returned as a dictionary. For classes, annotations include also 2287*cda5da8dSAndroid Build Coastguard Worker inherited members. 2288*cda5da8dSAndroid Build Coastguard Worker 2289*cda5da8dSAndroid Build Coastguard Worker TypeError is raised if the argument is not of a type that can contain 2290*cda5da8dSAndroid Build Coastguard Worker annotations, and an empty dictionary is returned if no annotations are 2291*cda5da8dSAndroid Build Coastguard Worker present. 2292*cda5da8dSAndroid Build Coastguard Worker 2293*cda5da8dSAndroid Build Coastguard Worker BEWARE -- the behavior of globalns and localns is counterintuitive 2294*cda5da8dSAndroid Build Coastguard Worker (unless you are familiar with how eval() and exec() work). The 2295*cda5da8dSAndroid Build Coastguard Worker search order is locals first, then globals. 2296*cda5da8dSAndroid Build Coastguard Worker 2297*cda5da8dSAndroid Build Coastguard Worker - If no dict arguments are passed, an attempt is made to use the 2298*cda5da8dSAndroid Build Coastguard Worker globals from obj (or the respective module's globals for classes), 2299*cda5da8dSAndroid Build Coastguard Worker and these are also used as the locals. If the object does not appear 2300*cda5da8dSAndroid Build Coastguard Worker to have globals, an empty dictionary is used. For classes, the search 2301*cda5da8dSAndroid Build Coastguard Worker order is globals first then locals. 2302*cda5da8dSAndroid Build Coastguard Worker 2303*cda5da8dSAndroid Build Coastguard Worker - If one dict argument is passed, it is used for both globals and 2304*cda5da8dSAndroid Build Coastguard Worker locals. 2305*cda5da8dSAndroid Build Coastguard Worker 2306*cda5da8dSAndroid Build Coastguard Worker - If two dict arguments are passed, they specify globals and 2307*cda5da8dSAndroid Build Coastguard Worker locals, respectively. 2308*cda5da8dSAndroid Build Coastguard Worker """ 2309*cda5da8dSAndroid Build Coastguard Worker if getattr(obj, '__no_type_check__', None): 2310*cda5da8dSAndroid Build Coastguard Worker return {} 2311*cda5da8dSAndroid Build Coastguard Worker # Classes require a special treatment. 2312*cda5da8dSAndroid Build Coastguard Worker if isinstance(obj, type): 2313*cda5da8dSAndroid Build Coastguard Worker hints = {} 2314*cda5da8dSAndroid Build Coastguard Worker for base in reversed(obj.__mro__): 2315*cda5da8dSAndroid Build Coastguard Worker if globalns is None: 2316*cda5da8dSAndroid Build Coastguard Worker base_globals = getattr(sys.modules.get(base.__module__, None), '__dict__', {}) 2317*cda5da8dSAndroid Build Coastguard Worker else: 2318*cda5da8dSAndroid Build Coastguard Worker base_globals = globalns 2319*cda5da8dSAndroid Build Coastguard Worker ann = base.__dict__.get('__annotations__', {}) 2320*cda5da8dSAndroid Build Coastguard Worker if isinstance(ann, types.GetSetDescriptorType): 2321*cda5da8dSAndroid Build Coastguard Worker ann = {} 2322*cda5da8dSAndroid Build Coastguard Worker base_locals = dict(vars(base)) if localns is None else localns 2323*cda5da8dSAndroid Build Coastguard Worker if localns is None and globalns is None: 2324*cda5da8dSAndroid Build Coastguard Worker # This is surprising, but required. Before Python 3.10, 2325*cda5da8dSAndroid Build Coastguard Worker # get_type_hints only evaluated the globalns of 2326*cda5da8dSAndroid Build Coastguard Worker # a class. To maintain backwards compatibility, we reverse 2327*cda5da8dSAndroid Build Coastguard Worker # the globalns and localns order so that eval() looks into 2328*cda5da8dSAndroid Build Coastguard Worker # *base_globals* first rather than *base_locals*. 2329*cda5da8dSAndroid Build Coastguard Worker # This only affects ForwardRefs. 2330*cda5da8dSAndroid Build Coastguard Worker base_globals, base_locals = base_locals, base_globals 2331*cda5da8dSAndroid Build Coastguard Worker for name, value in ann.items(): 2332*cda5da8dSAndroid Build Coastguard Worker if value is None: 2333*cda5da8dSAndroid Build Coastguard Worker value = type(None) 2334*cda5da8dSAndroid Build Coastguard Worker if isinstance(value, str): 2335*cda5da8dSAndroid Build Coastguard Worker value = ForwardRef(value, is_argument=False, is_class=True) 2336*cda5da8dSAndroid Build Coastguard Worker value = _eval_type(value, base_globals, base_locals) 2337*cda5da8dSAndroid Build Coastguard Worker hints[name] = value 2338*cda5da8dSAndroid Build Coastguard Worker return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} 2339*cda5da8dSAndroid Build Coastguard Worker 2340*cda5da8dSAndroid Build Coastguard Worker if globalns is None: 2341*cda5da8dSAndroid Build Coastguard Worker if isinstance(obj, types.ModuleType): 2342*cda5da8dSAndroid Build Coastguard Worker globalns = obj.__dict__ 2343*cda5da8dSAndroid Build Coastguard Worker else: 2344*cda5da8dSAndroid Build Coastguard Worker nsobj = obj 2345*cda5da8dSAndroid Build Coastguard Worker # Find globalns for the unwrapped object. 2346*cda5da8dSAndroid Build Coastguard Worker while hasattr(nsobj, '__wrapped__'): 2347*cda5da8dSAndroid Build Coastguard Worker nsobj = nsobj.__wrapped__ 2348*cda5da8dSAndroid Build Coastguard Worker globalns = getattr(nsobj, '__globals__', {}) 2349*cda5da8dSAndroid Build Coastguard Worker if localns is None: 2350*cda5da8dSAndroid Build Coastguard Worker localns = globalns 2351*cda5da8dSAndroid Build Coastguard Worker elif localns is None: 2352*cda5da8dSAndroid Build Coastguard Worker localns = globalns 2353*cda5da8dSAndroid Build Coastguard Worker hints = getattr(obj, '__annotations__', None) 2354*cda5da8dSAndroid Build Coastguard Worker if hints is None: 2355*cda5da8dSAndroid Build Coastguard Worker # Return empty annotations for something that _could_ have them. 2356*cda5da8dSAndroid Build Coastguard Worker if isinstance(obj, _allowed_types): 2357*cda5da8dSAndroid Build Coastguard Worker return {} 2358*cda5da8dSAndroid Build Coastguard Worker else: 2359*cda5da8dSAndroid Build Coastguard Worker raise TypeError('{!r} is not a module, class, method, ' 2360*cda5da8dSAndroid Build Coastguard Worker 'or function.'.format(obj)) 2361*cda5da8dSAndroid Build Coastguard Worker hints = dict(hints) 2362*cda5da8dSAndroid Build Coastguard Worker for name, value in hints.items(): 2363*cda5da8dSAndroid Build Coastguard Worker if value is None: 2364*cda5da8dSAndroid Build Coastguard Worker value = type(None) 2365*cda5da8dSAndroid Build Coastguard Worker if isinstance(value, str): 2366*cda5da8dSAndroid Build Coastguard Worker # class-level forward refs were handled above, this must be either 2367*cda5da8dSAndroid Build Coastguard Worker # a module-level annotation or a function argument annotation 2368*cda5da8dSAndroid Build Coastguard Worker value = ForwardRef( 2369*cda5da8dSAndroid Build Coastguard Worker value, 2370*cda5da8dSAndroid Build Coastguard Worker is_argument=not isinstance(obj, types.ModuleType), 2371*cda5da8dSAndroid Build Coastguard Worker is_class=False, 2372*cda5da8dSAndroid Build Coastguard Worker ) 2373*cda5da8dSAndroid Build Coastguard Worker hints[name] = _eval_type(value, globalns, localns) 2374*cda5da8dSAndroid Build Coastguard Worker return hints if include_extras else {k: _strip_annotations(t) for k, t in hints.items()} 2375*cda5da8dSAndroid Build Coastguard Worker 2376*cda5da8dSAndroid Build Coastguard Worker 2377*cda5da8dSAndroid Build Coastguard Workerdef _strip_annotations(t): 2378*cda5da8dSAndroid Build Coastguard Worker """Strip the annotations from a given type.""" 2379*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, _AnnotatedAlias): 2380*cda5da8dSAndroid Build Coastguard Worker return _strip_annotations(t.__origin__) 2381*cda5da8dSAndroid Build Coastguard Worker if hasattr(t, "__origin__") and t.__origin__ in (Required, NotRequired): 2382*cda5da8dSAndroid Build Coastguard Worker return _strip_annotations(t.__args__[0]) 2383*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, _GenericAlias): 2384*cda5da8dSAndroid Build Coastguard Worker stripped_args = tuple(_strip_annotations(a) for a in t.__args__) 2385*cda5da8dSAndroid Build Coastguard Worker if stripped_args == t.__args__: 2386*cda5da8dSAndroid Build Coastguard Worker return t 2387*cda5da8dSAndroid Build Coastguard Worker return t.copy_with(stripped_args) 2388*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, GenericAlias): 2389*cda5da8dSAndroid Build Coastguard Worker stripped_args = tuple(_strip_annotations(a) for a in t.__args__) 2390*cda5da8dSAndroid Build Coastguard Worker if stripped_args == t.__args__: 2391*cda5da8dSAndroid Build Coastguard Worker return t 2392*cda5da8dSAndroid Build Coastguard Worker return GenericAlias(t.__origin__, stripped_args) 2393*cda5da8dSAndroid Build Coastguard Worker if isinstance(t, types.UnionType): 2394*cda5da8dSAndroid Build Coastguard Worker stripped_args = tuple(_strip_annotations(a) for a in t.__args__) 2395*cda5da8dSAndroid Build Coastguard Worker if stripped_args == t.__args__: 2396*cda5da8dSAndroid Build Coastguard Worker return t 2397*cda5da8dSAndroid Build Coastguard Worker return functools.reduce(operator.or_, stripped_args) 2398*cda5da8dSAndroid Build Coastguard Worker 2399*cda5da8dSAndroid Build Coastguard Worker return t 2400*cda5da8dSAndroid Build Coastguard Worker 2401*cda5da8dSAndroid Build Coastguard Worker 2402*cda5da8dSAndroid Build Coastguard Workerdef get_origin(tp): 2403*cda5da8dSAndroid Build Coastguard Worker """Get the unsubscripted version of a type. 2404*cda5da8dSAndroid Build Coastguard Worker 2405*cda5da8dSAndroid Build Coastguard Worker This supports generic types, Callable, Tuple, Union, Literal, Final, ClassVar 2406*cda5da8dSAndroid Build Coastguard Worker Annotated, and others. Return None for unsupported types. Examples:: 2407*cda5da8dSAndroid Build Coastguard Worker 2408*cda5da8dSAndroid Build Coastguard Worker assert get_origin(Literal[42]) is Literal 2409*cda5da8dSAndroid Build Coastguard Worker assert get_origin(int) is None 2410*cda5da8dSAndroid Build Coastguard Worker assert get_origin(ClassVar[int]) is ClassVar 2411*cda5da8dSAndroid Build Coastguard Worker assert get_origin(Generic) is Generic 2412*cda5da8dSAndroid Build Coastguard Worker assert get_origin(Generic[T]) is Generic 2413*cda5da8dSAndroid Build Coastguard Worker assert get_origin(Union[T, int]) is Union 2414*cda5da8dSAndroid Build Coastguard Worker assert get_origin(List[Tuple[T, T]][int]) is list 2415*cda5da8dSAndroid Build Coastguard Worker assert get_origin(P.args) is P 2416*cda5da8dSAndroid Build Coastguard Worker """ 2417*cda5da8dSAndroid Build Coastguard Worker if isinstance(tp, _AnnotatedAlias): 2418*cda5da8dSAndroid Build Coastguard Worker return Annotated 2419*cda5da8dSAndroid Build Coastguard Worker if isinstance(tp, (_BaseGenericAlias, GenericAlias, 2420*cda5da8dSAndroid Build Coastguard Worker ParamSpecArgs, ParamSpecKwargs)): 2421*cda5da8dSAndroid Build Coastguard Worker return tp.__origin__ 2422*cda5da8dSAndroid Build Coastguard Worker if tp is Generic: 2423*cda5da8dSAndroid Build Coastguard Worker return Generic 2424*cda5da8dSAndroid Build Coastguard Worker if isinstance(tp, types.UnionType): 2425*cda5da8dSAndroid Build Coastguard Worker return types.UnionType 2426*cda5da8dSAndroid Build Coastguard Worker return None 2427*cda5da8dSAndroid Build Coastguard Worker 2428*cda5da8dSAndroid Build Coastguard Worker 2429*cda5da8dSAndroid Build Coastguard Workerdef get_args(tp): 2430*cda5da8dSAndroid Build Coastguard Worker """Get type arguments with all substitutions performed. 2431*cda5da8dSAndroid Build Coastguard Worker 2432*cda5da8dSAndroid Build Coastguard Worker For unions, basic simplifications used by Union constructor are performed. 2433*cda5da8dSAndroid Build Coastguard Worker 2434*cda5da8dSAndroid Build Coastguard Worker Examples:: 2435*cda5da8dSAndroid Build Coastguard Worker 2436*cda5da8dSAndroid Build Coastguard Worker assert get_args(Dict[str, int]) == (str, int) 2437*cda5da8dSAndroid Build Coastguard Worker assert get_args(int) == () 2438*cda5da8dSAndroid Build Coastguard Worker assert get_args(Union[int, Union[T, int], str][int]) == (int, str) 2439*cda5da8dSAndroid Build Coastguard Worker assert get_args(Union[int, Tuple[T, int]][str]) == (int, Tuple[str, int]) 2440*cda5da8dSAndroid Build Coastguard Worker assert get_args(Callable[[], T][int]) == ([], int) 2441*cda5da8dSAndroid Build Coastguard Worker """ 2442*cda5da8dSAndroid Build Coastguard Worker if isinstance(tp, _AnnotatedAlias): 2443*cda5da8dSAndroid Build Coastguard Worker return (tp.__origin__,) + tp.__metadata__ 2444*cda5da8dSAndroid Build Coastguard Worker if isinstance(tp, (_GenericAlias, GenericAlias)): 2445*cda5da8dSAndroid Build Coastguard Worker res = tp.__args__ 2446*cda5da8dSAndroid Build Coastguard Worker if _should_unflatten_callable_args(tp, res): 2447*cda5da8dSAndroid Build Coastguard Worker res = (list(res[:-1]), res[-1]) 2448*cda5da8dSAndroid Build Coastguard Worker return res 2449*cda5da8dSAndroid Build Coastguard Worker if isinstance(tp, types.UnionType): 2450*cda5da8dSAndroid Build Coastguard Worker return tp.__args__ 2451*cda5da8dSAndroid Build Coastguard Worker return () 2452*cda5da8dSAndroid Build Coastguard Worker 2453*cda5da8dSAndroid Build Coastguard Worker 2454*cda5da8dSAndroid Build Coastguard Workerdef is_typeddict(tp): 2455*cda5da8dSAndroid Build Coastguard Worker """Check if an annotation is a TypedDict class. 2456*cda5da8dSAndroid Build Coastguard Worker 2457*cda5da8dSAndroid Build Coastguard Worker For example:: 2458*cda5da8dSAndroid Build Coastguard Worker 2459*cda5da8dSAndroid Build Coastguard Worker class Film(TypedDict): 2460*cda5da8dSAndroid Build Coastguard Worker title: str 2461*cda5da8dSAndroid Build Coastguard Worker year: int 2462*cda5da8dSAndroid Build Coastguard Worker 2463*cda5da8dSAndroid Build Coastguard Worker is_typeddict(Film) # => True 2464*cda5da8dSAndroid Build Coastguard Worker is_typeddict(Union[list, str]) # => False 2465*cda5da8dSAndroid Build Coastguard Worker """ 2466*cda5da8dSAndroid Build Coastguard Worker return isinstance(tp, _TypedDictMeta) 2467*cda5da8dSAndroid Build Coastguard Worker 2468*cda5da8dSAndroid Build Coastguard Worker 2469*cda5da8dSAndroid Build Coastguard Worker_ASSERT_NEVER_REPR_MAX_LENGTH = 100 2470*cda5da8dSAndroid Build Coastguard Worker 2471*cda5da8dSAndroid Build Coastguard Worker 2472*cda5da8dSAndroid Build Coastguard Workerdef assert_never(arg: Never, /) -> Never: 2473*cda5da8dSAndroid Build Coastguard Worker """Statically assert that a line of code is unreachable. 2474*cda5da8dSAndroid Build Coastguard Worker 2475*cda5da8dSAndroid Build Coastguard Worker Example:: 2476*cda5da8dSAndroid Build Coastguard Worker 2477*cda5da8dSAndroid Build Coastguard Worker def int_or_str(arg: int | str) -> None: 2478*cda5da8dSAndroid Build Coastguard Worker match arg: 2479*cda5da8dSAndroid Build Coastguard Worker case int(): 2480*cda5da8dSAndroid Build Coastguard Worker print("It's an int") 2481*cda5da8dSAndroid Build Coastguard Worker case str(): 2482*cda5da8dSAndroid Build Coastguard Worker print("It's a str") 2483*cda5da8dSAndroid Build Coastguard Worker case _: 2484*cda5da8dSAndroid Build Coastguard Worker assert_never(arg) 2485*cda5da8dSAndroid Build Coastguard Worker 2486*cda5da8dSAndroid Build Coastguard Worker If a type checker finds that a call to assert_never() is 2487*cda5da8dSAndroid Build Coastguard Worker reachable, it will emit an error. 2488*cda5da8dSAndroid Build Coastguard Worker 2489*cda5da8dSAndroid Build Coastguard Worker At runtime, this throws an exception when called. 2490*cda5da8dSAndroid Build Coastguard Worker """ 2491*cda5da8dSAndroid Build Coastguard Worker value = repr(arg) 2492*cda5da8dSAndroid Build Coastguard Worker if len(value) > _ASSERT_NEVER_REPR_MAX_LENGTH: 2493*cda5da8dSAndroid Build Coastguard Worker value = value[:_ASSERT_NEVER_REPR_MAX_LENGTH] + '...' 2494*cda5da8dSAndroid Build Coastguard Worker raise AssertionError(f"Expected code to be unreachable, but got: {value}") 2495*cda5da8dSAndroid Build Coastguard Worker 2496*cda5da8dSAndroid Build Coastguard Worker 2497*cda5da8dSAndroid Build Coastguard Workerdef no_type_check(arg): 2498*cda5da8dSAndroid Build Coastguard Worker """Decorator to indicate that annotations are not type hints. 2499*cda5da8dSAndroid Build Coastguard Worker 2500*cda5da8dSAndroid Build Coastguard Worker The argument must be a class or function; if it is a class, it 2501*cda5da8dSAndroid Build Coastguard Worker applies recursively to all methods and classes defined in that class 2502*cda5da8dSAndroid Build Coastguard Worker (but not to methods defined in its superclasses or subclasses). 2503*cda5da8dSAndroid Build Coastguard Worker 2504*cda5da8dSAndroid Build Coastguard Worker This mutates the function(s) or class(es) in place. 2505*cda5da8dSAndroid Build Coastguard Worker """ 2506*cda5da8dSAndroid Build Coastguard Worker if isinstance(arg, type): 2507*cda5da8dSAndroid Build Coastguard Worker for key in dir(arg): 2508*cda5da8dSAndroid Build Coastguard Worker obj = getattr(arg, key) 2509*cda5da8dSAndroid Build Coastguard Worker if ( 2510*cda5da8dSAndroid Build Coastguard Worker not hasattr(obj, '__qualname__') 2511*cda5da8dSAndroid Build Coastguard Worker or obj.__qualname__ != f'{arg.__qualname__}.{obj.__name__}' 2512*cda5da8dSAndroid Build Coastguard Worker or getattr(obj, '__module__', None) != arg.__module__ 2513*cda5da8dSAndroid Build Coastguard Worker ): 2514*cda5da8dSAndroid Build Coastguard Worker # We only modify objects that are defined in this type directly. 2515*cda5da8dSAndroid Build Coastguard Worker # If classes / methods are nested in multiple layers, 2516*cda5da8dSAndroid Build Coastguard Worker # we will modify them when processing their direct holders. 2517*cda5da8dSAndroid Build Coastguard Worker continue 2518*cda5da8dSAndroid Build Coastguard Worker # Instance, class, and static methods: 2519*cda5da8dSAndroid Build Coastguard Worker if isinstance(obj, types.FunctionType): 2520*cda5da8dSAndroid Build Coastguard Worker obj.__no_type_check__ = True 2521*cda5da8dSAndroid Build Coastguard Worker if isinstance(obj, types.MethodType): 2522*cda5da8dSAndroid Build Coastguard Worker obj.__func__.__no_type_check__ = True 2523*cda5da8dSAndroid Build Coastguard Worker # Nested types: 2524*cda5da8dSAndroid Build Coastguard Worker if isinstance(obj, type): 2525*cda5da8dSAndroid Build Coastguard Worker no_type_check(obj) 2526*cda5da8dSAndroid Build Coastguard Worker try: 2527*cda5da8dSAndroid Build Coastguard Worker arg.__no_type_check__ = True 2528*cda5da8dSAndroid Build Coastguard Worker except TypeError: # built-in classes 2529*cda5da8dSAndroid Build Coastguard Worker pass 2530*cda5da8dSAndroid Build Coastguard Worker return arg 2531*cda5da8dSAndroid Build Coastguard Worker 2532*cda5da8dSAndroid Build Coastguard Worker 2533*cda5da8dSAndroid Build Coastguard Workerdef no_type_check_decorator(decorator): 2534*cda5da8dSAndroid Build Coastguard Worker """Decorator to give another decorator the @no_type_check effect. 2535*cda5da8dSAndroid Build Coastguard Worker 2536*cda5da8dSAndroid Build Coastguard Worker This wraps the decorator with something that wraps the decorated 2537*cda5da8dSAndroid Build Coastguard Worker function in @no_type_check. 2538*cda5da8dSAndroid Build Coastguard Worker """ 2539*cda5da8dSAndroid Build Coastguard Worker @functools.wraps(decorator) 2540*cda5da8dSAndroid Build Coastguard Worker def wrapped_decorator(*args, **kwds): 2541*cda5da8dSAndroid Build Coastguard Worker func = decorator(*args, **kwds) 2542*cda5da8dSAndroid Build Coastguard Worker func = no_type_check(func) 2543*cda5da8dSAndroid Build Coastguard Worker return func 2544*cda5da8dSAndroid Build Coastguard Worker 2545*cda5da8dSAndroid Build Coastguard Worker return wrapped_decorator 2546*cda5da8dSAndroid Build Coastguard Worker 2547*cda5da8dSAndroid Build Coastguard Worker 2548*cda5da8dSAndroid Build Coastguard Workerdef _overload_dummy(*args, **kwds): 2549*cda5da8dSAndroid Build Coastguard Worker """Helper for @overload to raise when called.""" 2550*cda5da8dSAndroid Build Coastguard Worker raise NotImplementedError( 2551*cda5da8dSAndroid Build Coastguard Worker "You should not call an overloaded function. " 2552*cda5da8dSAndroid Build Coastguard Worker "A series of @overload-decorated functions " 2553*cda5da8dSAndroid Build Coastguard Worker "outside a stub module should always be followed " 2554*cda5da8dSAndroid Build Coastguard Worker "by an implementation that is not @overload-ed.") 2555*cda5da8dSAndroid Build Coastguard Worker 2556*cda5da8dSAndroid Build Coastguard Worker 2557*cda5da8dSAndroid Build Coastguard Worker# {module: {qualname: {firstlineno: func}}} 2558*cda5da8dSAndroid Build Coastguard Worker_overload_registry = defaultdict(functools.partial(defaultdict, dict)) 2559*cda5da8dSAndroid Build Coastguard Worker 2560*cda5da8dSAndroid Build Coastguard Worker 2561*cda5da8dSAndroid Build Coastguard Workerdef overload(func): 2562*cda5da8dSAndroid Build Coastguard Worker """Decorator for overloaded functions/methods. 2563*cda5da8dSAndroid Build Coastguard Worker 2564*cda5da8dSAndroid Build Coastguard Worker In a stub file, place two or more stub definitions for the same 2565*cda5da8dSAndroid Build Coastguard Worker function in a row, each decorated with @overload. For example:: 2566*cda5da8dSAndroid Build Coastguard Worker 2567*cda5da8dSAndroid Build Coastguard Worker @overload 2568*cda5da8dSAndroid Build Coastguard Worker def utf8(value: None) -> None: ... 2569*cda5da8dSAndroid Build Coastguard Worker @overload 2570*cda5da8dSAndroid Build Coastguard Worker def utf8(value: bytes) -> bytes: ... 2571*cda5da8dSAndroid Build Coastguard Worker @overload 2572*cda5da8dSAndroid Build Coastguard Worker def utf8(value: str) -> bytes: ... 2573*cda5da8dSAndroid Build Coastguard Worker 2574*cda5da8dSAndroid Build Coastguard Worker In a non-stub file (i.e. a regular .py file), do the same but 2575*cda5da8dSAndroid Build Coastguard Worker follow it with an implementation. The implementation should *not* 2576*cda5da8dSAndroid Build Coastguard Worker be decorated with @overload. For example:: 2577*cda5da8dSAndroid Build Coastguard Worker 2578*cda5da8dSAndroid Build Coastguard Worker @overload 2579*cda5da8dSAndroid Build Coastguard Worker def utf8(value: None) -> None: ... 2580*cda5da8dSAndroid Build Coastguard Worker @overload 2581*cda5da8dSAndroid Build Coastguard Worker def utf8(value: bytes) -> bytes: ... 2582*cda5da8dSAndroid Build Coastguard Worker @overload 2583*cda5da8dSAndroid Build Coastguard Worker def utf8(value: str) -> bytes: ... 2584*cda5da8dSAndroid Build Coastguard Worker def utf8(value): 2585*cda5da8dSAndroid Build Coastguard Worker ... # implementation goes here 2586*cda5da8dSAndroid Build Coastguard Worker 2587*cda5da8dSAndroid Build Coastguard Worker The overloads for a function can be retrieved at runtime using the 2588*cda5da8dSAndroid Build Coastguard Worker get_overloads() function. 2589*cda5da8dSAndroid Build Coastguard Worker """ 2590*cda5da8dSAndroid Build Coastguard Worker # classmethod and staticmethod 2591*cda5da8dSAndroid Build Coastguard Worker f = getattr(func, "__func__", func) 2592*cda5da8dSAndroid Build Coastguard Worker try: 2593*cda5da8dSAndroid Build Coastguard Worker _overload_registry[f.__module__][f.__qualname__][f.__code__.co_firstlineno] = func 2594*cda5da8dSAndroid Build Coastguard Worker except AttributeError: 2595*cda5da8dSAndroid Build Coastguard Worker # Not a normal function; ignore. 2596*cda5da8dSAndroid Build Coastguard Worker pass 2597*cda5da8dSAndroid Build Coastguard Worker return _overload_dummy 2598*cda5da8dSAndroid Build Coastguard Worker 2599*cda5da8dSAndroid Build Coastguard Worker 2600*cda5da8dSAndroid Build Coastguard Workerdef get_overloads(func): 2601*cda5da8dSAndroid Build Coastguard Worker """Return all defined overloads for *func* as a sequence.""" 2602*cda5da8dSAndroid Build Coastguard Worker # classmethod and staticmethod 2603*cda5da8dSAndroid Build Coastguard Worker f = getattr(func, "__func__", func) 2604*cda5da8dSAndroid Build Coastguard Worker if f.__module__ not in _overload_registry: 2605*cda5da8dSAndroid Build Coastguard Worker return [] 2606*cda5da8dSAndroid Build Coastguard Worker mod_dict = _overload_registry[f.__module__] 2607*cda5da8dSAndroid Build Coastguard Worker if f.__qualname__ not in mod_dict: 2608*cda5da8dSAndroid Build Coastguard Worker return [] 2609*cda5da8dSAndroid Build Coastguard Worker return list(mod_dict[f.__qualname__].values()) 2610*cda5da8dSAndroid Build Coastguard Worker 2611*cda5da8dSAndroid Build Coastguard Worker 2612*cda5da8dSAndroid Build Coastguard Workerdef clear_overloads(): 2613*cda5da8dSAndroid Build Coastguard Worker """Clear all overloads in the registry.""" 2614*cda5da8dSAndroid Build Coastguard Worker _overload_registry.clear() 2615*cda5da8dSAndroid Build Coastguard Worker 2616*cda5da8dSAndroid Build Coastguard Worker 2617*cda5da8dSAndroid Build Coastguard Workerdef final(f): 2618*cda5da8dSAndroid Build Coastguard Worker """Decorator to indicate final methods and final classes. 2619*cda5da8dSAndroid Build Coastguard Worker 2620*cda5da8dSAndroid Build Coastguard Worker Use this decorator to indicate to type checkers that the decorated 2621*cda5da8dSAndroid Build Coastguard Worker method cannot be overridden, and decorated class cannot be subclassed. 2622*cda5da8dSAndroid Build Coastguard Worker 2623*cda5da8dSAndroid Build Coastguard Worker For example:: 2624*cda5da8dSAndroid Build Coastguard Worker 2625*cda5da8dSAndroid Build Coastguard Worker class Base: 2626*cda5da8dSAndroid Build Coastguard Worker @final 2627*cda5da8dSAndroid Build Coastguard Worker def done(self) -> None: 2628*cda5da8dSAndroid Build Coastguard Worker ... 2629*cda5da8dSAndroid Build Coastguard Worker class Sub(Base): 2630*cda5da8dSAndroid Build Coastguard Worker def done(self) -> None: # Error reported by type checker 2631*cda5da8dSAndroid Build Coastguard Worker ... 2632*cda5da8dSAndroid Build Coastguard Worker 2633*cda5da8dSAndroid Build Coastguard Worker @final 2634*cda5da8dSAndroid Build Coastguard Worker class Leaf: 2635*cda5da8dSAndroid Build Coastguard Worker ... 2636*cda5da8dSAndroid Build Coastguard Worker class Other(Leaf): # Error reported by type checker 2637*cda5da8dSAndroid Build Coastguard Worker ... 2638*cda5da8dSAndroid Build Coastguard Worker 2639*cda5da8dSAndroid Build Coastguard Worker There is no runtime checking of these properties. The decorator 2640*cda5da8dSAndroid Build Coastguard Worker attempts to set the ``__final__`` attribute to ``True`` on the decorated 2641*cda5da8dSAndroid Build Coastguard Worker object to allow runtime introspection. 2642*cda5da8dSAndroid Build Coastguard Worker """ 2643*cda5da8dSAndroid Build Coastguard Worker try: 2644*cda5da8dSAndroid Build Coastguard Worker f.__final__ = True 2645*cda5da8dSAndroid Build Coastguard Worker except (AttributeError, TypeError): 2646*cda5da8dSAndroid Build Coastguard Worker # Skip the attribute silently if it is not writable. 2647*cda5da8dSAndroid Build Coastguard Worker # AttributeError happens if the object has __slots__ or a 2648*cda5da8dSAndroid Build Coastguard Worker # read-only property, TypeError if it's a builtin class. 2649*cda5da8dSAndroid Build Coastguard Worker pass 2650*cda5da8dSAndroid Build Coastguard Worker return f 2651*cda5da8dSAndroid Build Coastguard Worker 2652*cda5da8dSAndroid Build Coastguard Worker 2653*cda5da8dSAndroid Build Coastguard Worker# Some unconstrained type variables. These are used by the container types. 2654*cda5da8dSAndroid Build Coastguard Worker# (These are not for export.) 2655*cda5da8dSAndroid Build Coastguard WorkerT = TypeVar('T') # Any type. 2656*cda5da8dSAndroid Build Coastguard WorkerKT = TypeVar('KT') # Key type. 2657*cda5da8dSAndroid Build Coastguard WorkerVT = TypeVar('VT') # Value type. 2658*cda5da8dSAndroid Build Coastguard WorkerT_co = TypeVar('T_co', covariant=True) # Any type covariant containers. 2659*cda5da8dSAndroid Build Coastguard WorkerV_co = TypeVar('V_co', covariant=True) # Any type covariant containers. 2660*cda5da8dSAndroid Build Coastguard WorkerVT_co = TypeVar('VT_co', covariant=True) # Value type covariant containers. 2661*cda5da8dSAndroid Build Coastguard WorkerT_contra = TypeVar('T_contra', contravariant=True) # Ditto contravariant. 2662*cda5da8dSAndroid Build Coastguard Worker# Internal type variable used for Type[]. 2663*cda5da8dSAndroid Build Coastguard WorkerCT_co = TypeVar('CT_co', covariant=True, bound=type) 2664*cda5da8dSAndroid Build Coastguard Worker 2665*cda5da8dSAndroid Build Coastguard Worker# A useful type variable with constraints. This represents string types. 2666*cda5da8dSAndroid Build Coastguard Worker# (This one *is* for export!) 2667*cda5da8dSAndroid Build Coastguard WorkerAnyStr = TypeVar('AnyStr', bytes, str) 2668*cda5da8dSAndroid Build Coastguard Worker 2669*cda5da8dSAndroid Build Coastguard Worker 2670*cda5da8dSAndroid Build Coastguard Worker# Various ABCs mimicking those in collections.abc. 2671*cda5da8dSAndroid Build Coastguard Worker_alias = _SpecialGenericAlias 2672*cda5da8dSAndroid Build Coastguard Worker 2673*cda5da8dSAndroid Build Coastguard WorkerHashable = _alias(collections.abc.Hashable, 0) # Not generic. 2674*cda5da8dSAndroid Build Coastguard WorkerAwaitable = _alias(collections.abc.Awaitable, 1) 2675*cda5da8dSAndroid Build Coastguard WorkerCoroutine = _alias(collections.abc.Coroutine, 3) 2676*cda5da8dSAndroid Build Coastguard WorkerAsyncIterable = _alias(collections.abc.AsyncIterable, 1) 2677*cda5da8dSAndroid Build Coastguard WorkerAsyncIterator = _alias(collections.abc.AsyncIterator, 1) 2678*cda5da8dSAndroid Build Coastguard WorkerIterable = _alias(collections.abc.Iterable, 1) 2679*cda5da8dSAndroid Build Coastguard WorkerIterator = _alias(collections.abc.Iterator, 1) 2680*cda5da8dSAndroid Build Coastguard WorkerReversible = _alias(collections.abc.Reversible, 1) 2681*cda5da8dSAndroid Build Coastguard WorkerSized = _alias(collections.abc.Sized, 0) # Not generic. 2682*cda5da8dSAndroid Build Coastguard WorkerContainer = _alias(collections.abc.Container, 1) 2683*cda5da8dSAndroid Build Coastguard WorkerCollection = _alias(collections.abc.Collection, 1) 2684*cda5da8dSAndroid Build Coastguard WorkerCallable = _CallableType(collections.abc.Callable, 2) 2685*cda5da8dSAndroid Build Coastguard WorkerCallable.__doc__ = \ 2686*cda5da8dSAndroid Build Coastguard Worker """Deprecated alias to collections.abc.Callable. 2687*cda5da8dSAndroid Build Coastguard Worker 2688*cda5da8dSAndroid Build Coastguard Worker Callable[[int], str] signifies a function of (int) -> str. 2689*cda5da8dSAndroid Build Coastguard Worker The subscription syntax must always be used with exactly two 2690*cda5da8dSAndroid Build Coastguard Worker values: the argument list and the return type. 2691*cda5da8dSAndroid Build Coastguard Worker The argument list must be a list of types, a ParamSpec or ellipsis. 2692*cda5da8dSAndroid Build Coastguard Worker The return type must be a single type. 2693*cda5da8dSAndroid Build Coastguard Worker 2694*cda5da8dSAndroid Build Coastguard Worker There is no syntax to indicate optional or keyword arguments; 2695*cda5da8dSAndroid Build Coastguard Worker such function types are rarely used as callback types. 2696*cda5da8dSAndroid Build Coastguard Worker """ 2697*cda5da8dSAndroid Build Coastguard WorkerAbstractSet = _alias(collections.abc.Set, 1, name='AbstractSet') 2698*cda5da8dSAndroid Build Coastguard WorkerMutableSet = _alias(collections.abc.MutableSet, 1) 2699*cda5da8dSAndroid Build Coastguard Worker# NOTE: Mapping is only covariant in the value type. 2700*cda5da8dSAndroid Build Coastguard WorkerMapping = _alias(collections.abc.Mapping, 2) 2701*cda5da8dSAndroid Build Coastguard WorkerMutableMapping = _alias(collections.abc.MutableMapping, 2) 2702*cda5da8dSAndroid Build Coastguard WorkerSequence = _alias(collections.abc.Sequence, 1) 2703*cda5da8dSAndroid Build Coastguard WorkerMutableSequence = _alias(collections.abc.MutableSequence, 1) 2704*cda5da8dSAndroid Build Coastguard WorkerByteString = _alias(collections.abc.ByteString, 0) # Not generic 2705*cda5da8dSAndroid Build Coastguard Worker# Tuple accepts variable number of parameters. 2706*cda5da8dSAndroid Build Coastguard WorkerTuple = _TupleType(tuple, -1, inst=False, name='Tuple') 2707*cda5da8dSAndroid Build Coastguard WorkerTuple.__doc__ = \ 2708*cda5da8dSAndroid Build Coastguard Worker """Deprecated alias to builtins.tuple. 2709*cda5da8dSAndroid Build Coastguard Worker 2710*cda5da8dSAndroid Build Coastguard Worker Tuple[X, Y] is the cross-product type of X and Y. 2711*cda5da8dSAndroid Build Coastguard Worker 2712*cda5da8dSAndroid Build Coastguard Worker Example: Tuple[T1, T2] is a tuple of two elements corresponding 2713*cda5da8dSAndroid Build Coastguard Worker to type variables T1 and T2. Tuple[int, float, str] is a tuple 2714*cda5da8dSAndroid Build Coastguard Worker of an int, a float and a string. 2715*cda5da8dSAndroid Build Coastguard Worker 2716*cda5da8dSAndroid Build Coastguard Worker To specify a variable-length tuple of homogeneous type, use Tuple[T, ...]. 2717*cda5da8dSAndroid Build Coastguard Worker """ 2718*cda5da8dSAndroid Build Coastguard WorkerList = _alias(list, 1, inst=False, name='List') 2719*cda5da8dSAndroid Build Coastguard WorkerDeque = _alias(collections.deque, 1, name='Deque') 2720*cda5da8dSAndroid Build Coastguard WorkerSet = _alias(set, 1, inst=False, name='Set') 2721*cda5da8dSAndroid Build Coastguard WorkerFrozenSet = _alias(frozenset, 1, inst=False, name='FrozenSet') 2722*cda5da8dSAndroid Build Coastguard WorkerMappingView = _alias(collections.abc.MappingView, 1) 2723*cda5da8dSAndroid Build Coastguard WorkerKeysView = _alias(collections.abc.KeysView, 1) 2724*cda5da8dSAndroid Build Coastguard WorkerItemsView = _alias(collections.abc.ItemsView, 2) 2725*cda5da8dSAndroid Build Coastguard WorkerValuesView = _alias(collections.abc.ValuesView, 1) 2726*cda5da8dSAndroid Build Coastguard WorkerContextManager = _alias(contextlib.AbstractContextManager, 1, name='ContextManager') 2727*cda5da8dSAndroid Build Coastguard WorkerAsyncContextManager = _alias(contextlib.AbstractAsyncContextManager, 1, name='AsyncContextManager') 2728*cda5da8dSAndroid Build Coastguard WorkerDict = _alias(dict, 2, inst=False, name='Dict') 2729*cda5da8dSAndroid Build Coastguard WorkerDefaultDict = _alias(collections.defaultdict, 2, name='DefaultDict') 2730*cda5da8dSAndroid Build Coastguard WorkerOrderedDict = _alias(collections.OrderedDict, 2) 2731*cda5da8dSAndroid Build Coastguard WorkerCounter = _alias(collections.Counter, 1) 2732*cda5da8dSAndroid Build Coastguard WorkerChainMap = _alias(collections.ChainMap, 2) 2733*cda5da8dSAndroid Build Coastguard WorkerGenerator = _alias(collections.abc.Generator, 3) 2734*cda5da8dSAndroid Build Coastguard WorkerAsyncGenerator = _alias(collections.abc.AsyncGenerator, 2) 2735*cda5da8dSAndroid Build Coastguard WorkerType = _alias(type, 1, inst=False, name='Type') 2736*cda5da8dSAndroid Build Coastguard WorkerType.__doc__ = \ 2737*cda5da8dSAndroid Build Coastguard Worker """Deprecated alias to builtins.type. 2738*cda5da8dSAndroid Build Coastguard Worker 2739*cda5da8dSAndroid Build Coastguard Worker builtins.type or typing.Type can be used to annotate class objects. 2740*cda5da8dSAndroid Build Coastguard Worker For example, suppose we have the following classes:: 2741*cda5da8dSAndroid Build Coastguard Worker 2742*cda5da8dSAndroid Build Coastguard Worker class User: ... # Abstract base for User classes 2743*cda5da8dSAndroid Build Coastguard Worker class BasicUser(User): ... 2744*cda5da8dSAndroid Build Coastguard Worker class ProUser(User): ... 2745*cda5da8dSAndroid Build Coastguard Worker class TeamUser(User): ... 2746*cda5da8dSAndroid Build Coastguard Worker 2747*cda5da8dSAndroid Build Coastguard Worker And a function that takes a class argument that's a subclass of 2748*cda5da8dSAndroid Build Coastguard Worker User and returns an instance of the corresponding class:: 2749*cda5da8dSAndroid Build Coastguard Worker 2750*cda5da8dSAndroid Build Coastguard Worker U = TypeVar('U', bound=User) 2751*cda5da8dSAndroid Build Coastguard Worker def new_user(user_class: Type[U]) -> U: 2752*cda5da8dSAndroid Build Coastguard Worker user = user_class() 2753*cda5da8dSAndroid Build Coastguard Worker # (Here we could write the user object to a database) 2754*cda5da8dSAndroid Build Coastguard Worker return user 2755*cda5da8dSAndroid Build Coastguard Worker 2756*cda5da8dSAndroid Build Coastguard Worker joe = new_user(BasicUser) 2757*cda5da8dSAndroid Build Coastguard Worker 2758*cda5da8dSAndroid Build Coastguard Worker At this point the type checker knows that joe has type BasicUser. 2759*cda5da8dSAndroid Build Coastguard Worker """ 2760*cda5da8dSAndroid Build Coastguard Worker 2761*cda5da8dSAndroid Build Coastguard Worker 2762*cda5da8dSAndroid Build Coastguard Worker@runtime_checkable 2763*cda5da8dSAndroid Build Coastguard Workerclass SupportsInt(Protocol): 2764*cda5da8dSAndroid Build Coastguard Worker """An ABC with one abstract method __int__.""" 2765*cda5da8dSAndroid Build Coastguard Worker 2766*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 2767*cda5da8dSAndroid Build Coastguard Worker 2768*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 2769*cda5da8dSAndroid Build Coastguard Worker def __int__(self) -> int: 2770*cda5da8dSAndroid Build Coastguard Worker pass 2771*cda5da8dSAndroid Build Coastguard Worker 2772*cda5da8dSAndroid Build Coastguard Worker 2773*cda5da8dSAndroid Build Coastguard Worker@runtime_checkable 2774*cda5da8dSAndroid Build Coastguard Workerclass SupportsFloat(Protocol): 2775*cda5da8dSAndroid Build Coastguard Worker """An ABC with one abstract method __float__.""" 2776*cda5da8dSAndroid Build Coastguard Worker 2777*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 2778*cda5da8dSAndroid Build Coastguard Worker 2779*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 2780*cda5da8dSAndroid Build Coastguard Worker def __float__(self) -> float: 2781*cda5da8dSAndroid Build Coastguard Worker pass 2782*cda5da8dSAndroid Build Coastguard Worker 2783*cda5da8dSAndroid Build Coastguard Worker 2784*cda5da8dSAndroid Build Coastguard Worker@runtime_checkable 2785*cda5da8dSAndroid Build Coastguard Workerclass SupportsComplex(Protocol): 2786*cda5da8dSAndroid Build Coastguard Worker """An ABC with one abstract method __complex__.""" 2787*cda5da8dSAndroid Build Coastguard Worker 2788*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 2789*cda5da8dSAndroid Build Coastguard Worker 2790*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 2791*cda5da8dSAndroid Build Coastguard Worker def __complex__(self) -> complex: 2792*cda5da8dSAndroid Build Coastguard Worker pass 2793*cda5da8dSAndroid Build Coastguard Worker 2794*cda5da8dSAndroid Build Coastguard Worker 2795*cda5da8dSAndroid Build Coastguard Worker@runtime_checkable 2796*cda5da8dSAndroid Build Coastguard Workerclass SupportsBytes(Protocol): 2797*cda5da8dSAndroid Build Coastguard Worker """An ABC with one abstract method __bytes__.""" 2798*cda5da8dSAndroid Build Coastguard Worker 2799*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 2800*cda5da8dSAndroid Build Coastguard Worker 2801*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 2802*cda5da8dSAndroid Build Coastguard Worker def __bytes__(self) -> bytes: 2803*cda5da8dSAndroid Build Coastguard Worker pass 2804*cda5da8dSAndroid Build Coastguard Worker 2805*cda5da8dSAndroid Build Coastguard Worker 2806*cda5da8dSAndroid Build Coastguard Worker@runtime_checkable 2807*cda5da8dSAndroid Build Coastguard Workerclass SupportsIndex(Protocol): 2808*cda5da8dSAndroid Build Coastguard Worker """An ABC with one abstract method __index__.""" 2809*cda5da8dSAndroid Build Coastguard Worker 2810*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 2811*cda5da8dSAndroid Build Coastguard Worker 2812*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 2813*cda5da8dSAndroid Build Coastguard Worker def __index__(self) -> int: 2814*cda5da8dSAndroid Build Coastguard Worker pass 2815*cda5da8dSAndroid Build Coastguard Worker 2816*cda5da8dSAndroid Build Coastguard Worker 2817*cda5da8dSAndroid Build Coastguard Worker@runtime_checkable 2818*cda5da8dSAndroid Build Coastguard Workerclass SupportsAbs(Protocol[T_co]): 2819*cda5da8dSAndroid Build Coastguard Worker """An ABC with one abstract method __abs__ that is covariant in its return type.""" 2820*cda5da8dSAndroid Build Coastguard Worker 2821*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 2822*cda5da8dSAndroid Build Coastguard Worker 2823*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 2824*cda5da8dSAndroid Build Coastguard Worker def __abs__(self) -> T_co: 2825*cda5da8dSAndroid Build Coastguard Worker pass 2826*cda5da8dSAndroid Build Coastguard Worker 2827*cda5da8dSAndroid Build Coastguard Worker 2828*cda5da8dSAndroid Build Coastguard Worker@runtime_checkable 2829*cda5da8dSAndroid Build Coastguard Workerclass SupportsRound(Protocol[T_co]): 2830*cda5da8dSAndroid Build Coastguard Worker """An ABC with one abstract method __round__ that is covariant in its return type.""" 2831*cda5da8dSAndroid Build Coastguard Worker 2832*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 2833*cda5da8dSAndroid Build Coastguard Worker 2834*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 2835*cda5da8dSAndroid Build Coastguard Worker def __round__(self, ndigits: int = 0) -> T_co: 2836*cda5da8dSAndroid Build Coastguard Worker pass 2837*cda5da8dSAndroid Build Coastguard Worker 2838*cda5da8dSAndroid Build Coastguard Worker 2839*cda5da8dSAndroid Build Coastguard Workerdef _make_nmtuple(name, types, module, defaults = ()): 2840*cda5da8dSAndroid Build Coastguard Worker fields = [n for n, t in types] 2841*cda5da8dSAndroid Build Coastguard Worker types = {n: _type_check(t, f"field {n} annotation must be a type") 2842*cda5da8dSAndroid Build Coastguard Worker for n, t in types} 2843*cda5da8dSAndroid Build Coastguard Worker nm_tpl = collections.namedtuple(name, fields, 2844*cda5da8dSAndroid Build Coastguard Worker defaults=defaults, module=module) 2845*cda5da8dSAndroid Build Coastguard Worker nm_tpl.__annotations__ = nm_tpl.__new__.__annotations__ = types 2846*cda5da8dSAndroid Build Coastguard Worker return nm_tpl 2847*cda5da8dSAndroid Build Coastguard Worker 2848*cda5da8dSAndroid Build Coastguard Worker 2849*cda5da8dSAndroid Build Coastguard Worker# attributes prohibited to set in NamedTuple class syntax 2850*cda5da8dSAndroid Build Coastguard Worker_prohibited = frozenset({'__new__', '__init__', '__slots__', '__getnewargs__', 2851*cda5da8dSAndroid Build Coastguard Worker '_fields', '_field_defaults', 2852*cda5da8dSAndroid Build Coastguard Worker '_make', '_replace', '_asdict', '_source'}) 2853*cda5da8dSAndroid Build Coastguard Worker 2854*cda5da8dSAndroid Build Coastguard Worker_special = frozenset({'__module__', '__name__', '__annotations__'}) 2855*cda5da8dSAndroid Build Coastguard Worker 2856*cda5da8dSAndroid Build Coastguard Worker 2857*cda5da8dSAndroid Build Coastguard Workerclass NamedTupleMeta(type): 2858*cda5da8dSAndroid Build Coastguard Worker def __new__(cls, typename, bases, ns): 2859*cda5da8dSAndroid Build Coastguard Worker assert _NamedTuple in bases 2860*cda5da8dSAndroid Build Coastguard Worker for base in bases: 2861*cda5da8dSAndroid Build Coastguard Worker if base is not _NamedTuple and base is not Generic: 2862*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 2863*cda5da8dSAndroid Build Coastguard Worker 'can only inherit from a NamedTuple type and Generic') 2864*cda5da8dSAndroid Build Coastguard Worker bases = tuple(tuple if base is _NamedTuple else base for base in bases) 2865*cda5da8dSAndroid Build Coastguard Worker types = ns.get('__annotations__', {}) 2866*cda5da8dSAndroid Build Coastguard Worker default_names = [] 2867*cda5da8dSAndroid Build Coastguard Worker for field_name in types: 2868*cda5da8dSAndroid Build Coastguard Worker if field_name in ns: 2869*cda5da8dSAndroid Build Coastguard Worker default_names.append(field_name) 2870*cda5da8dSAndroid Build Coastguard Worker elif default_names: 2871*cda5da8dSAndroid Build Coastguard Worker raise TypeError(f"Non-default namedtuple field {field_name} " 2872*cda5da8dSAndroid Build Coastguard Worker f"cannot follow default field" 2873*cda5da8dSAndroid Build Coastguard Worker f"{'s' if len(default_names) > 1 else ''} " 2874*cda5da8dSAndroid Build Coastguard Worker f"{', '.join(default_names)}") 2875*cda5da8dSAndroid Build Coastguard Worker nm_tpl = _make_nmtuple(typename, types.items(), 2876*cda5da8dSAndroid Build Coastguard Worker defaults=[ns[n] for n in default_names], 2877*cda5da8dSAndroid Build Coastguard Worker module=ns['__module__']) 2878*cda5da8dSAndroid Build Coastguard Worker nm_tpl.__bases__ = bases 2879*cda5da8dSAndroid Build Coastguard Worker if Generic in bases: 2880*cda5da8dSAndroid Build Coastguard Worker class_getitem = Generic.__class_getitem__.__func__ 2881*cda5da8dSAndroid Build Coastguard Worker nm_tpl.__class_getitem__ = classmethod(class_getitem) 2882*cda5da8dSAndroid Build Coastguard Worker # update from user namespace without overriding special namedtuple attributes 2883*cda5da8dSAndroid Build Coastguard Worker for key in ns: 2884*cda5da8dSAndroid Build Coastguard Worker if key in _prohibited: 2885*cda5da8dSAndroid Build Coastguard Worker raise AttributeError("Cannot overwrite NamedTuple attribute " + key) 2886*cda5da8dSAndroid Build Coastguard Worker elif key not in _special and key not in nm_tpl._fields: 2887*cda5da8dSAndroid Build Coastguard Worker setattr(nm_tpl, key, ns[key]) 2888*cda5da8dSAndroid Build Coastguard Worker if Generic in bases: 2889*cda5da8dSAndroid Build Coastguard Worker nm_tpl.__init_subclass__() 2890*cda5da8dSAndroid Build Coastguard Worker return nm_tpl 2891*cda5da8dSAndroid Build Coastguard Worker 2892*cda5da8dSAndroid Build Coastguard Worker 2893*cda5da8dSAndroid Build Coastguard Workerdef NamedTuple(typename, fields=None, /, **kwargs): 2894*cda5da8dSAndroid Build Coastguard Worker """Typed version of namedtuple. 2895*cda5da8dSAndroid Build Coastguard Worker 2896*cda5da8dSAndroid Build Coastguard Worker Usage:: 2897*cda5da8dSAndroid Build Coastguard Worker 2898*cda5da8dSAndroid Build Coastguard Worker class Employee(NamedTuple): 2899*cda5da8dSAndroid Build Coastguard Worker name: str 2900*cda5da8dSAndroid Build Coastguard Worker id: int 2901*cda5da8dSAndroid Build Coastguard Worker 2902*cda5da8dSAndroid Build Coastguard Worker This is equivalent to:: 2903*cda5da8dSAndroid Build Coastguard Worker 2904*cda5da8dSAndroid Build Coastguard Worker Employee = collections.namedtuple('Employee', ['name', 'id']) 2905*cda5da8dSAndroid Build Coastguard Worker 2906*cda5da8dSAndroid Build Coastguard Worker The resulting class has an extra __annotations__ attribute, giving a 2907*cda5da8dSAndroid Build Coastguard Worker dict that maps field names to types. (The field names are also in 2908*cda5da8dSAndroid Build Coastguard Worker the _fields attribute, which is part of the namedtuple API.) 2909*cda5da8dSAndroid Build Coastguard Worker An alternative equivalent functional syntax is also accepted:: 2910*cda5da8dSAndroid Build Coastguard Worker 2911*cda5da8dSAndroid Build Coastguard Worker Employee = NamedTuple('Employee', [('name', str), ('id', int)]) 2912*cda5da8dSAndroid Build Coastguard Worker """ 2913*cda5da8dSAndroid Build Coastguard Worker if fields is None: 2914*cda5da8dSAndroid Build Coastguard Worker fields = kwargs.items() 2915*cda5da8dSAndroid Build Coastguard Worker elif kwargs: 2916*cda5da8dSAndroid Build Coastguard Worker raise TypeError("Either list of fields or keywords" 2917*cda5da8dSAndroid Build Coastguard Worker " can be provided to NamedTuple, not both") 2918*cda5da8dSAndroid Build Coastguard Worker return _make_nmtuple(typename, fields, module=_caller()) 2919*cda5da8dSAndroid Build Coastguard Worker 2920*cda5da8dSAndroid Build Coastguard Worker_NamedTuple = type.__new__(NamedTupleMeta, 'NamedTuple', (), {}) 2921*cda5da8dSAndroid Build Coastguard Worker 2922*cda5da8dSAndroid Build Coastguard Workerdef _namedtuple_mro_entries(bases): 2923*cda5da8dSAndroid Build Coastguard Worker assert NamedTuple in bases 2924*cda5da8dSAndroid Build Coastguard Worker return (_NamedTuple,) 2925*cda5da8dSAndroid Build Coastguard Worker 2926*cda5da8dSAndroid Build Coastguard WorkerNamedTuple.__mro_entries__ = _namedtuple_mro_entries 2927*cda5da8dSAndroid Build Coastguard Worker 2928*cda5da8dSAndroid Build Coastguard Worker 2929*cda5da8dSAndroid Build Coastguard Workerclass _TypedDictMeta(type): 2930*cda5da8dSAndroid Build Coastguard Worker def __new__(cls, name, bases, ns, total=True): 2931*cda5da8dSAndroid Build Coastguard Worker """Create a new typed dict class object. 2932*cda5da8dSAndroid Build Coastguard Worker 2933*cda5da8dSAndroid Build Coastguard Worker This method is called when TypedDict is subclassed, 2934*cda5da8dSAndroid Build Coastguard Worker or when TypedDict is instantiated. This way 2935*cda5da8dSAndroid Build Coastguard Worker TypedDict supports all three syntax forms described in its docstring. 2936*cda5da8dSAndroid Build Coastguard Worker Subclasses and instances of TypedDict return actual dictionaries. 2937*cda5da8dSAndroid Build Coastguard Worker """ 2938*cda5da8dSAndroid Build Coastguard Worker for base in bases: 2939*cda5da8dSAndroid Build Coastguard Worker if type(base) is not _TypedDictMeta and base is not Generic: 2940*cda5da8dSAndroid Build Coastguard Worker raise TypeError('cannot inherit from both a TypedDict type ' 2941*cda5da8dSAndroid Build Coastguard Worker 'and a non-TypedDict base class') 2942*cda5da8dSAndroid Build Coastguard Worker 2943*cda5da8dSAndroid Build Coastguard Worker if any(issubclass(b, Generic) for b in bases): 2944*cda5da8dSAndroid Build Coastguard Worker generic_base = (Generic,) 2945*cda5da8dSAndroid Build Coastguard Worker else: 2946*cda5da8dSAndroid Build Coastguard Worker generic_base = () 2947*cda5da8dSAndroid Build Coastguard Worker 2948*cda5da8dSAndroid Build Coastguard Worker tp_dict = type.__new__(_TypedDictMeta, name, (*generic_base, dict), ns) 2949*cda5da8dSAndroid Build Coastguard Worker 2950*cda5da8dSAndroid Build Coastguard Worker annotations = {} 2951*cda5da8dSAndroid Build Coastguard Worker own_annotations = ns.get('__annotations__', {}) 2952*cda5da8dSAndroid Build Coastguard Worker msg = "TypedDict('Name', {f0: t0, f1: t1, ...}); each t must be a type" 2953*cda5da8dSAndroid Build Coastguard Worker own_annotations = { 2954*cda5da8dSAndroid Build Coastguard Worker n: _type_check(tp, msg, module=tp_dict.__module__) 2955*cda5da8dSAndroid Build Coastguard Worker for n, tp in own_annotations.items() 2956*cda5da8dSAndroid Build Coastguard Worker } 2957*cda5da8dSAndroid Build Coastguard Worker required_keys = set() 2958*cda5da8dSAndroid Build Coastguard Worker optional_keys = set() 2959*cda5da8dSAndroid Build Coastguard Worker 2960*cda5da8dSAndroid Build Coastguard Worker for base in bases: 2961*cda5da8dSAndroid Build Coastguard Worker annotations.update(base.__dict__.get('__annotations__', {})) 2962*cda5da8dSAndroid Build Coastguard Worker required_keys.update(base.__dict__.get('__required_keys__', ())) 2963*cda5da8dSAndroid Build Coastguard Worker optional_keys.update(base.__dict__.get('__optional_keys__', ())) 2964*cda5da8dSAndroid Build Coastguard Worker 2965*cda5da8dSAndroid Build Coastguard Worker annotations.update(own_annotations) 2966*cda5da8dSAndroid Build Coastguard Worker for annotation_key, annotation_type in own_annotations.items(): 2967*cda5da8dSAndroid Build Coastguard Worker annotation_origin = get_origin(annotation_type) 2968*cda5da8dSAndroid Build Coastguard Worker if annotation_origin is Annotated: 2969*cda5da8dSAndroid Build Coastguard Worker annotation_args = get_args(annotation_type) 2970*cda5da8dSAndroid Build Coastguard Worker if annotation_args: 2971*cda5da8dSAndroid Build Coastguard Worker annotation_type = annotation_args[0] 2972*cda5da8dSAndroid Build Coastguard Worker annotation_origin = get_origin(annotation_type) 2973*cda5da8dSAndroid Build Coastguard Worker 2974*cda5da8dSAndroid Build Coastguard Worker if annotation_origin is Required: 2975*cda5da8dSAndroid Build Coastguard Worker required_keys.add(annotation_key) 2976*cda5da8dSAndroid Build Coastguard Worker elif annotation_origin is NotRequired: 2977*cda5da8dSAndroid Build Coastguard Worker optional_keys.add(annotation_key) 2978*cda5da8dSAndroid Build Coastguard Worker elif total: 2979*cda5da8dSAndroid Build Coastguard Worker required_keys.add(annotation_key) 2980*cda5da8dSAndroid Build Coastguard Worker else: 2981*cda5da8dSAndroid Build Coastguard Worker optional_keys.add(annotation_key) 2982*cda5da8dSAndroid Build Coastguard Worker 2983*cda5da8dSAndroid Build Coastguard Worker tp_dict.__annotations__ = annotations 2984*cda5da8dSAndroid Build Coastguard Worker tp_dict.__required_keys__ = frozenset(required_keys) 2985*cda5da8dSAndroid Build Coastguard Worker tp_dict.__optional_keys__ = frozenset(optional_keys) 2986*cda5da8dSAndroid Build Coastguard Worker if not hasattr(tp_dict, '__total__'): 2987*cda5da8dSAndroid Build Coastguard Worker tp_dict.__total__ = total 2988*cda5da8dSAndroid Build Coastguard Worker return tp_dict 2989*cda5da8dSAndroid Build Coastguard Worker 2990*cda5da8dSAndroid Build Coastguard Worker __call__ = dict # static method 2991*cda5da8dSAndroid Build Coastguard Worker 2992*cda5da8dSAndroid Build Coastguard Worker def __subclasscheck__(cls, other): 2993*cda5da8dSAndroid Build Coastguard Worker # Typed dicts are only for static structural subtyping. 2994*cda5da8dSAndroid Build Coastguard Worker raise TypeError('TypedDict does not support instance and class checks') 2995*cda5da8dSAndroid Build Coastguard Worker 2996*cda5da8dSAndroid Build Coastguard Worker __instancecheck__ = __subclasscheck__ 2997*cda5da8dSAndroid Build Coastguard Worker 2998*cda5da8dSAndroid Build Coastguard Worker 2999*cda5da8dSAndroid Build Coastguard Workerdef TypedDict(typename, fields=None, /, *, total=True, **kwargs): 3000*cda5da8dSAndroid Build Coastguard Worker """A simple typed namespace. At runtime it is equivalent to a plain dict. 3001*cda5da8dSAndroid Build Coastguard Worker 3002*cda5da8dSAndroid Build Coastguard Worker TypedDict creates a dictionary type such that a type checker will expect all 3003*cda5da8dSAndroid Build Coastguard Worker instances to have a certain set of keys, where each key is 3004*cda5da8dSAndroid Build Coastguard Worker associated with a value of a consistent type. This expectation 3005*cda5da8dSAndroid Build Coastguard Worker is not checked at runtime. 3006*cda5da8dSAndroid Build Coastguard Worker 3007*cda5da8dSAndroid Build Coastguard Worker Usage:: 3008*cda5da8dSAndroid Build Coastguard Worker 3009*cda5da8dSAndroid Build Coastguard Worker class Point2D(TypedDict): 3010*cda5da8dSAndroid Build Coastguard Worker x: int 3011*cda5da8dSAndroid Build Coastguard Worker y: int 3012*cda5da8dSAndroid Build Coastguard Worker label: str 3013*cda5da8dSAndroid Build Coastguard Worker 3014*cda5da8dSAndroid Build Coastguard Worker a: Point2D = {'x': 1, 'y': 2, 'label': 'good'} # OK 3015*cda5da8dSAndroid Build Coastguard Worker b: Point2D = {'z': 3, 'label': 'bad'} # Fails type check 3016*cda5da8dSAndroid Build Coastguard Worker 3017*cda5da8dSAndroid Build Coastguard Worker assert Point2D(x=1, y=2, label='first') == dict(x=1, y=2, label='first') 3018*cda5da8dSAndroid Build Coastguard Worker 3019*cda5da8dSAndroid Build Coastguard Worker The type info can be accessed via the Point2D.__annotations__ dict, and 3020*cda5da8dSAndroid Build Coastguard Worker the Point2D.__required_keys__ and Point2D.__optional_keys__ frozensets. 3021*cda5da8dSAndroid Build Coastguard Worker TypedDict supports an additional equivalent form:: 3022*cda5da8dSAndroid Build Coastguard Worker 3023*cda5da8dSAndroid Build Coastguard Worker Point2D = TypedDict('Point2D', {'x': int, 'y': int, 'label': str}) 3024*cda5da8dSAndroid Build Coastguard Worker 3025*cda5da8dSAndroid Build Coastguard Worker By default, all keys must be present in a TypedDict. It is possible 3026*cda5da8dSAndroid Build Coastguard Worker to override this by specifying totality:: 3027*cda5da8dSAndroid Build Coastguard Worker 3028*cda5da8dSAndroid Build Coastguard Worker class Point2D(TypedDict, total=False): 3029*cda5da8dSAndroid Build Coastguard Worker x: int 3030*cda5da8dSAndroid Build Coastguard Worker y: int 3031*cda5da8dSAndroid Build Coastguard Worker 3032*cda5da8dSAndroid Build Coastguard Worker This means that a Point2D TypedDict can have any of the keys omitted. A type 3033*cda5da8dSAndroid Build Coastguard Worker checker is only expected to support a literal False or True as the value of 3034*cda5da8dSAndroid Build Coastguard Worker the total argument. True is the default, and makes all items defined in the 3035*cda5da8dSAndroid Build Coastguard Worker class body be required. 3036*cda5da8dSAndroid Build Coastguard Worker 3037*cda5da8dSAndroid Build Coastguard Worker The Required and NotRequired special forms can also be used to mark 3038*cda5da8dSAndroid Build Coastguard Worker individual keys as being required or not required:: 3039*cda5da8dSAndroid Build Coastguard Worker 3040*cda5da8dSAndroid Build Coastguard Worker class Point2D(TypedDict): 3041*cda5da8dSAndroid Build Coastguard Worker x: int # the "x" key must always be present (Required is the default) 3042*cda5da8dSAndroid Build Coastguard Worker y: NotRequired[int] # the "y" key can be omitted 3043*cda5da8dSAndroid Build Coastguard Worker 3044*cda5da8dSAndroid Build Coastguard Worker See PEP 655 for more details on Required and NotRequired. 3045*cda5da8dSAndroid Build Coastguard Worker """ 3046*cda5da8dSAndroid Build Coastguard Worker if fields is None: 3047*cda5da8dSAndroid Build Coastguard Worker fields = kwargs 3048*cda5da8dSAndroid Build Coastguard Worker elif kwargs: 3049*cda5da8dSAndroid Build Coastguard Worker raise TypeError("TypedDict takes either a dict or keyword arguments," 3050*cda5da8dSAndroid Build Coastguard Worker " but not both") 3051*cda5da8dSAndroid Build Coastguard Worker if kwargs: 3052*cda5da8dSAndroid Build Coastguard Worker warnings.warn( 3053*cda5da8dSAndroid Build Coastguard Worker "The kwargs-based syntax for TypedDict definitions is deprecated " 3054*cda5da8dSAndroid Build Coastguard Worker "in Python 3.11, will be removed in Python 3.13, and may not be " 3055*cda5da8dSAndroid Build Coastguard Worker "understood by third-party type checkers.", 3056*cda5da8dSAndroid Build Coastguard Worker DeprecationWarning, 3057*cda5da8dSAndroid Build Coastguard Worker stacklevel=2, 3058*cda5da8dSAndroid Build Coastguard Worker ) 3059*cda5da8dSAndroid Build Coastguard Worker 3060*cda5da8dSAndroid Build Coastguard Worker ns = {'__annotations__': dict(fields)} 3061*cda5da8dSAndroid Build Coastguard Worker module = _caller() 3062*cda5da8dSAndroid Build Coastguard Worker if module is not None: 3063*cda5da8dSAndroid Build Coastguard Worker # Setting correct module is necessary to make typed dict classes pickleable. 3064*cda5da8dSAndroid Build Coastguard Worker ns['__module__'] = module 3065*cda5da8dSAndroid Build Coastguard Worker 3066*cda5da8dSAndroid Build Coastguard Worker return _TypedDictMeta(typename, (), ns, total=total) 3067*cda5da8dSAndroid Build Coastguard Worker 3068*cda5da8dSAndroid Build Coastguard Worker_TypedDict = type.__new__(_TypedDictMeta, 'TypedDict', (), {}) 3069*cda5da8dSAndroid Build Coastguard WorkerTypedDict.__mro_entries__ = lambda bases: (_TypedDict,) 3070*cda5da8dSAndroid Build Coastguard Worker 3071*cda5da8dSAndroid Build Coastguard Worker 3072*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 3073*cda5da8dSAndroid Build Coastguard Workerdef Required(self, parameters): 3074*cda5da8dSAndroid Build Coastguard Worker """Special typing construct to mark a TypedDict key as required. 3075*cda5da8dSAndroid Build Coastguard Worker 3076*cda5da8dSAndroid Build Coastguard Worker This is mainly useful for total=False TypedDicts. For example:: 3077*cda5da8dSAndroid Build Coastguard Worker 3078*cda5da8dSAndroid Build Coastguard Worker class Movie(TypedDict, total=False): 3079*cda5da8dSAndroid Build Coastguard Worker title: Required[str] 3080*cda5da8dSAndroid Build Coastguard Worker year: int 3081*cda5da8dSAndroid Build Coastguard Worker 3082*cda5da8dSAndroid Build Coastguard Worker m = Movie( 3083*cda5da8dSAndroid Build Coastguard Worker title='The Matrix', # typechecker error if key is omitted 3084*cda5da8dSAndroid Build Coastguard Worker year=1999, 3085*cda5da8dSAndroid Build Coastguard Worker ) 3086*cda5da8dSAndroid Build Coastguard Worker 3087*cda5da8dSAndroid Build Coastguard Worker There is no runtime checking that a required key is actually provided 3088*cda5da8dSAndroid Build Coastguard Worker when instantiating a related TypedDict. 3089*cda5da8dSAndroid Build Coastguard Worker """ 3090*cda5da8dSAndroid Build Coastguard Worker item = _type_check(parameters, f'{self._name} accepts only a single type.') 3091*cda5da8dSAndroid Build Coastguard Worker return _GenericAlias(self, (item,)) 3092*cda5da8dSAndroid Build Coastguard Worker 3093*cda5da8dSAndroid Build Coastguard Worker 3094*cda5da8dSAndroid Build Coastguard Worker@_SpecialForm 3095*cda5da8dSAndroid Build Coastguard Workerdef NotRequired(self, parameters): 3096*cda5da8dSAndroid Build Coastguard Worker """Special typing construct to mark a TypedDict key as potentially missing. 3097*cda5da8dSAndroid Build Coastguard Worker 3098*cda5da8dSAndroid Build Coastguard Worker For example:: 3099*cda5da8dSAndroid Build Coastguard Worker 3100*cda5da8dSAndroid Build Coastguard Worker class Movie(TypedDict): 3101*cda5da8dSAndroid Build Coastguard Worker title: str 3102*cda5da8dSAndroid Build Coastguard Worker year: NotRequired[int] 3103*cda5da8dSAndroid Build Coastguard Worker 3104*cda5da8dSAndroid Build Coastguard Worker m = Movie( 3105*cda5da8dSAndroid Build Coastguard Worker title='The Matrix', # typechecker error if key is omitted 3106*cda5da8dSAndroid Build Coastguard Worker year=1999, 3107*cda5da8dSAndroid Build Coastguard Worker ) 3108*cda5da8dSAndroid Build Coastguard Worker """ 3109*cda5da8dSAndroid Build Coastguard Worker item = _type_check(parameters, f'{self._name} accepts only a single type.') 3110*cda5da8dSAndroid Build Coastguard Worker return _GenericAlias(self, (item,)) 3111*cda5da8dSAndroid Build Coastguard Worker 3112*cda5da8dSAndroid Build Coastguard Worker 3113*cda5da8dSAndroid Build Coastguard Workerclass NewType: 3114*cda5da8dSAndroid Build Coastguard Worker """NewType creates simple unique types with almost zero runtime overhead. 3115*cda5da8dSAndroid Build Coastguard Worker 3116*cda5da8dSAndroid Build Coastguard Worker NewType(name, tp) is considered a subtype of tp 3117*cda5da8dSAndroid Build Coastguard Worker by static type checkers. At runtime, NewType(name, tp) returns 3118*cda5da8dSAndroid Build Coastguard Worker a dummy callable that simply returns its argument. Usage:: 3119*cda5da8dSAndroid Build Coastguard Worker 3120*cda5da8dSAndroid Build Coastguard Worker UserId = NewType('UserId', int) 3121*cda5da8dSAndroid Build Coastguard Worker 3122*cda5da8dSAndroid Build Coastguard Worker def name_by_id(user_id: UserId) -> str: 3123*cda5da8dSAndroid Build Coastguard Worker ... 3124*cda5da8dSAndroid Build Coastguard Worker 3125*cda5da8dSAndroid Build Coastguard Worker UserId('user') # Fails type check 3126*cda5da8dSAndroid Build Coastguard Worker 3127*cda5da8dSAndroid Build Coastguard Worker name_by_id(42) # Fails type check 3128*cda5da8dSAndroid Build Coastguard Worker name_by_id(UserId(42)) # OK 3129*cda5da8dSAndroid Build Coastguard Worker 3130*cda5da8dSAndroid Build Coastguard Worker num = UserId(5) + 1 # type: int 3131*cda5da8dSAndroid Build Coastguard Worker """ 3132*cda5da8dSAndroid Build Coastguard Worker 3133*cda5da8dSAndroid Build Coastguard Worker __call__ = _idfunc 3134*cda5da8dSAndroid Build Coastguard Worker 3135*cda5da8dSAndroid Build Coastguard Worker def __init__(self, name, tp): 3136*cda5da8dSAndroid Build Coastguard Worker self.__qualname__ = name 3137*cda5da8dSAndroid Build Coastguard Worker if '.' in name: 3138*cda5da8dSAndroid Build Coastguard Worker name = name.rpartition('.')[-1] 3139*cda5da8dSAndroid Build Coastguard Worker self.__name__ = name 3140*cda5da8dSAndroid Build Coastguard Worker self.__supertype__ = tp 3141*cda5da8dSAndroid Build Coastguard Worker def_mod = _caller() 3142*cda5da8dSAndroid Build Coastguard Worker if def_mod != 'typing': 3143*cda5da8dSAndroid Build Coastguard Worker self.__module__ = def_mod 3144*cda5da8dSAndroid Build Coastguard Worker 3145*cda5da8dSAndroid Build Coastguard Worker def __mro_entries__(self, bases): 3146*cda5da8dSAndroid Build Coastguard Worker # We defined __mro_entries__ to get a better error message 3147*cda5da8dSAndroid Build Coastguard Worker # if a user attempts to subclass a NewType instance. bpo-46170 3148*cda5da8dSAndroid Build Coastguard Worker superclass_name = self.__name__ 3149*cda5da8dSAndroid Build Coastguard Worker 3150*cda5da8dSAndroid Build Coastguard Worker class Dummy: 3151*cda5da8dSAndroid Build Coastguard Worker def __init_subclass__(cls): 3152*cda5da8dSAndroid Build Coastguard Worker subclass_name = cls.__name__ 3153*cda5da8dSAndroid Build Coastguard Worker raise TypeError( 3154*cda5da8dSAndroid Build Coastguard Worker f"Cannot subclass an instance of NewType. Perhaps you were looking for: " 3155*cda5da8dSAndroid Build Coastguard Worker f"`{subclass_name} = NewType({subclass_name!r}, {superclass_name})`" 3156*cda5da8dSAndroid Build Coastguard Worker ) 3157*cda5da8dSAndroid Build Coastguard Worker 3158*cda5da8dSAndroid Build Coastguard Worker return (Dummy,) 3159*cda5da8dSAndroid Build Coastguard Worker 3160*cda5da8dSAndroid Build Coastguard Worker def __repr__(self): 3161*cda5da8dSAndroid Build Coastguard Worker return f'{self.__module__}.{self.__qualname__}' 3162*cda5da8dSAndroid Build Coastguard Worker 3163*cda5da8dSAndroid Build Coastguard Worker def __reduce__(self): 3164*cda5da8dSAndroid Build Coastguard Worker return self.__qualname__ 3165*cda5da8dSAndroid Build Coastguard Worker 3166*cda5da8dSAndroid Build Coastguard Worker def __or__(self, other): 3167*cda5da8dSAndroid Build Coastguard Worker return Union[self, other] 3168*cda5da8dSAndroid Build Coastguard Worker 3169*cda5da8dSAndroid Build Coastguard Worker def __ror__(self, other): 3170*cda5da8dSAndroid Build Coastguard Worker return Union[other, self] 3171*cda5da8dSAndroid Build Coastguard Worker 3172*cda5da8dSAndroid Build Coastguard Worker 3173*cda5da8dSAndroid Build Coastguard Worker# Python-version-specific alias (Python 2: unicode; Python 3: str) 3174*cda5da8dSAndroid Build Coastguard WorkerText = str 3175*cda5da8dSAndroid Build Coastguard Worker 3176*cda5da8dSAndroid Build Coastguard Worker 3177*cda5da8dSAndroid Build Coastguard Worker# Constant that's True when type checking, but False here. 3178*cda5da8dSAndroid Build Coastguard WorkerTYPE_CHECKING = False 3179*cda5da8dSAndroid Build Coastguard Worker 3180*cda5da8dSAndroid Build Coastguard Worker 3181*cda5da8dSAndroid Build Coastguard Workerclass IO(Generic[AnyStr]): 3182*cda5da8dSAndroid Build Coastguard Worker """Generic base class for TextIO and BinaryIO. 3183*cda5da8dSAndroid Build Coastguard Worker 3184*cda5da8dSAndroid Build Coastguard Worker This is an abstract, generic version of the return of open(). 3185*cda5da8dSAndroid Build Coastguard Worker 3186*cda5da8dSAndroid Build Coastguard Worker NOTE: This does not distinguish between the different possible 3187*cda5da8dSAndroid Build Coastguard Worker classes (text vs. binary, read vs. write vs. read/write, 3188*cda5da8dSAndroid Build Coastguard Worker append-only, unbuffered). The TextIO and BinaryIO subclasses 3189*cda5da8dSAndroid Build Coastguard Worker below capture the distinctions between text vs. binary, which is 3190*cda5da8dSAndroid Build Coastguard Worker pervasive in the interface; however we currently do not offer a 3191*cda5da8dSAndroid Build Coastguard Worker way to track the other distinctions in the type system. 3192*cda5da8dSAndroid Build Coastguard Worker """ 3193*cda5da8dSAndroid Build Coastguard Worker 3194*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 3195*cda5da8dSAndroid Build Coastguard Worker 3196*cda5da8dSAndroid Build Coastguard Worker @property 3197*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3198*cda5da8dSAndroid Build Coastguard Worker def mode(self) -> str: 3199*cda5da8dSAndroid Build Coastguard Worker pass 3200*cda5da8dSAndroid Build Coastguard Worker 3201*cda5da8dSAndroid Build Coastguard Worker @property 3202*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3203*cda5da8dSAndroid Build Coastguard Worker def name(self) -> str: 3204*cda5da8dSAndroid Build Coastguard Worker pass 3205*cda5da8dSAndroid Build Coastguard Worker 3206*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3207*cda5da8dSAndroid Build Coastguard Worker def close(self) -> None: 3208*cda5da8dSAndroid Build Coastguard Worker pass 3209*cda5da8dSAndroid Build Coastguard Worker 3210*cda5da8dSAndroid Build Coastguard Worker @property 3211*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3212*cda5da8dSAndroid Build Coastguard Worker def closed(self) -> bool: 3213*cda5da8dSAndroid Build Coastguard Worker pass 3214*cda5da8dSAndroid Build Coastguard Worker 3215*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3216*cda5da8dSAndroid Build Coastguard Worker def fileno(self) -> int: 3217*cda5da8dSAndroid Build Coastguard Worker pass 3218*cda5da8dSAndroid Build Coastguard Worker 3219*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3220*cda5da8dSAndroid Build Coastguard Worker def flush(self) -> None: 3221*cda5da8dSAndroid Build Coastguard Worker pass 3222*cda5da8dSAndroid Build Coastguard Worker 3223*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3224*cda5da8dSAndroid Build Coastguard Worker def isatty(self) -> bool: 3225*cda5da8dSAndroid Build Coastguard Worker pass 3226*cda5da8dSAndroid Build Coastguard Worker 3227*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3228*cda5da8dSAndroid Build Coastguard Worker def read(self, n: int = -1) -> AnyStr: 3229*cda5da8dSAndroid Build Coastguard Worker pass 3230*cda5da8dSAndroid Build Coastguard Worker 3231*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3232*cda5da8dSAndroid Build Coastguard Worker def readable(self) -> bool: 3233*cda5da8dSAndroid Build Coastguard Worker pass 3234*cda5da8dSAndroid Build Coastguard Worker 3235*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3236*cda5da8dSAndroid Build Coastguard Worker def readline(self, limit: int = -1) -> AnyStr: 3237*cda5da8dSAndroid Build Coastguard Worker pass 3238*cda5da8dSAndroid Build Coastguard Worker 3239*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3240*cda5da8dSAndroid Build Coastguard Worker def readlines(self, hint: int = -1) -> List[AnyStr]: 3241*cda5da8dSAndroid Build Coastguard Worker pass 3242*cda5da8dSAndroid Build Coastguard Worker 3243*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3244*cda5da8dSAndroid Build Coastguard Worker def seek(self, offset: int, whence: int = 0) -> int: 3245*cda5da8dSAndroid Build Coastguard Worker pass 3246*cda5da8dSAndroid Build Coastguard Worker 3247*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3248*cda5da8dSAndroid Build Coastguard Worker def seekable(self) -> bool: 3249*cda5da8dSAndroid Build Coastguard Worker pass 3250*cda5da8dSAndroid Build Coastguard Worker 3251*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3252*cda5da8dSAndroid Build Coastguard Worker def tell(self) -> int: 3253*cda5da8dSAndroid Build Coastguard Worker pass 3254*cda5da8dSAndroid Build Coastguard Worker 3255*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3256*cda5da8dSAndroid Build Coastguard Worker def truncate(self, size: int = None) -> int: 3257*cda5da8dSAndroid Build Coastguard Worker pass 3258*cda5da8dSAndroid Build Coastguard Worker 3259*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3260*cda5da8dSAndroid Build Coastguard Worker def writable(self) -> bool: 3261*cda5da8dSAndroid Build Coastguard Worker pass 3262*cda5da8dSAndroid Build Coastguard Worker 3263*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3264*cda5da8dSAndroid Build Coastguard Worker def write(self, s: AnyStr) -> int: 3265*cda5da8dSAndroid Build Coastguard Worker pass 3266*cda5da8dSAndroid Build Coastguard Worker 3267*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3268*cda5da8dSAndroid Build Coastguard Worker def writelines(self, lines: List[AnyStr]) -> None: 3269*cda5da8dSAndroid Build Coastguard Worker pass 3270*cda5da8dSAndroid Build Coastguard Worker 3271*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3272*cda5da8dSAndroid Build Coastguard Worker def __enter__(self) -> 'IO[AnyStr]': 3273*cda5da8dSAndroid Build Coastguard Worker pass 3274*cda5da8dSAndroid Build Coastguard Worker 3275*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3276*cda5da8dSAndroid Build Coastguard Worker def __exit__(self, type, value, traceback) -> None: 3277*cda5da8dSAndroid Build Coastguard Worker pass 3278*cda5da8dSAndroid Build Coastguard Worker 3279*cda5da8dSAndroid Build Coastguard Worker 3280*cda5da8dSAndroid Build Coastguard Workerclass BinaryIO(IO[bytes]): 3281*cda5da8dSAndroid Build Coastguard Worker """Typed version of the return of open() in binary mode.""" 3282*cda5da8dSAndroid Build Coastguard Worker 3283*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 3284*cda5da8dSAndroid Build Coastguard Worker 3285*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3286*cda5da8dSAndroid Build Coastguard Worker def write(self, s: Union[bytes, bytearray]) -> int: 3287*cda5da8dSAndroid Build Coastguard Worker pass 3288*cda5da8dSAndroid Build Coastguard Worker 3289*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3290*cda5da8dSAndroid Build Coastguard Worker def __enter__(self) -> 'BinaryIO': 3291*cda5da8dSAndroid Build Coastguard Worker pass 3292*cda5da8dSAndroid Build Coastguard Worker 3293*cda5da8dSAndroid Build Coastguard Worker 3294*cda5da8dSAndroid Build Coastguard Workerclass TextIO(IO[str]): 3295*cda5da8dSAndroid Build Coastguard Worker """Typed version of the return of open() in text mode.""" 3296*cda5da8dSAndroid Build Coastguard Worker 3297*cda5da8dSAndroid Build Coastguard Worker __slots__ = () 3298*cda5da8dSAndroid Build Coastguard Worker 3299*cda5da8dSAndroid Build Coastguard Worker @property 3300*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3301*cda5da8dSAndroid Build Coastguard Worker def buffer(self) -> BinaryIO: 3302*cda5da8dSAndroid Build Coastguard Worker pass 3303*cda5da8dSAndroid Build Coastguard Worker 3304*cda5da8dSAndroid Build Coastguard Worker @property 3305*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3306*cda5da8dSAndroid Build Coastguard Worker def encoding(self) -> str: 3307*cda5da8dSAndroid Build Coastguard Worker pass 3308*cda5da8dSAndroid Build Coastguard Worker 3309*cda5da8dSAndroid Build Coastguard Worker @property 3310*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3311*cda5da8dSAndroid Build Coastguard Worker def errors(self) -> Optional[str]: 3312*cda5da8dSAndroid Build Coastguard Worker pass 3313*cda5da8dSAndroid Build Coastguard Worker 3314*cda5da8dSAndroid Build Coastguard Worker @property 3315*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3316*cda5da8dSAndroid Build Coastguard Worker def line_buffering(self) -> bool: 3317*cda5da8dSAndroid Build Coastguard Worker pass 3318*cda5da8dSAndroid Build Coastguard Worker 3319*cda5da8dSAndroid Build Coastguard Worker @property 3320*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3321*cda5da8dSAndroid Build Coastguard Worker def newlines(self) -> Any: 3322*cda5da8dSAndroid Build Coastguard Worker pass 3323*cda5da8dSAndroid Build Coastguard Worker 3324*cda5da8dSAndroid Build Coastguard Worker @abstractmethod 3325*cda5da8dSAndroid Build Coastguard Worker def __enter__(self) -> 'TextIO': 3326*cda5da8dSAndroid Build Coastguard Worker pass 3327*cda5da8dSAndroid Build Coastguard Worker 3328*cda5da8dSAndroid Build Coastguard Worker 3329*cda5da8dSAndroid Build Coastguard Workerclass _DeprecatedType(type): 3330*cda5da8dSAndroid Build Coastguard Worker def __getattribute__(cls, name): 3331*cda5da8dSAndroid Build Coastguard Worker if name not in ("__dict__", "__module__") and name in cls.__dict__: 3332*cda5da8dSAndroid Build Coastguard Worker warnings.warn( 3333*cda5da8dSAndroid Build Coastguard Worker f"{cls.__name__} is deprecated, import directly " 3334*cda5da8dSAndroid Build Coastguard Worker f"from typing instead. {cls.__name__} will be removed " 3335*cda5da8dSAndroid Build Coastguard Worker "in Python 3.12.", 3336*cda5da8dSAndroid Build Coastguard Worker DeprecationWarning, 3337*cda5da8dSAndroid Build Coastguard Worker stacklevel=2, 3338*cda5da8dSAndroid Build Coastguard Worker ) 3339*cda5da8dSAndroid Build Coastguard Worker return super().__getattribute__(name) 3340*cda5da8dSAndroid Build Coastguard Worker 3341*cda5da8dSAndroid Build Coastguard Worker 3342*cda5da8dSAndroid Build Coastguard Workerclass io(metaclass=_DeprecatedType): 3343*cda5da8dSAndroid Build Coastguard Worker """Wrapper namespace for IO generic classes.""" 3344*cda5da8dSAndroid Build Coastguard Worker 3345*cda5da8dSAndroid Build Coastguard Worker __all__ = ['IO', 'TextIO', 'BinaryIO'] 3346*cda5da8dSAndroid Build Coastguard Worker IO = IO 3347*cda5da8dSAndroid Build Coastguard Worker TextIO = TextIO 3348*cda5da8dSAndroid Build Coastguard Worker BinaryIO = BinaryIO 3349*cda5da8dSAndroid Build Coastguard Worker 3350*cda5da8dSAndroid Build Coastguard Worker 3351*cda5da8dSAndroid Build Coastguard Workerio.__name__ = __name__ + '.io' 3352*cda5da8dSAndroid Build Coastguard Workersys.modules[io.__name__] = io 3353*cda5da8dSAndroid Build Coastguard Worker 3354*cda5da8dSAndroid Build Coastguard WorkerPattern = _alias(stdlib_re.Pattern, 1) 3355*cda5da8dSAndroid Build Coastguard WorkerMatch = _alias(stdlib_re.Match, 1) 3356*cda5da8dSAndroid Build Coastguard Worker 3357*cda5da8dSAndroid Build Coastguard Workerclass re(metaclass=_DeprecatedType): 3358*cda5da8dSAndroid Build Coastguard Worker """Wrapper namespace for re type aliases.""" 3359*cda5da8dSAndroid Build Coastguard Worker 3360*cda5da8dSAndroid Build Coastguard Worker __all__ = ['Pattern', 'Match'] 3361*cda5da8dSAndroid Build Coastguard Worker Pattern = Pattern 3362*cda5da8dSAndroid Build Coastguard Worker Match = Match 3363*cda5da8dSAndroid Build Coastguard Worker 3364*cda5da8dSAndroid Build Coastguard Worker 3365*cda5da8dSAndroid Build Coastguard Workerre.__name__ = __name__ + '.re' 3366*cda5da8dSAndroid Build Coastguard Workersys.modules[re.__name__] = re 3367*cda5da8dSAndroid Build Coastguard Worker 3368*cda5da8dSAndroid Build Coastguard Worker 3369*cda5da8dSAndroid Build Coastguard Workerdef reveal_type(obj: T, /) -> T: 3370*cda5da8dSAndroid Build Coastguard Worker """Reveal the inferred type of a variable. 3371*cda5da8dSAndroid Build Coastguard Worker 3372*cda5da8dSAndroid Build Coastguard Worker When a static type checker encounters a call to ``reveal_type()``, 3373*cda5da8dSAndroid Build Coastguard Worker it will emit the inferred type of the argument:: 3374*cda5da8dSAndroid Build Coastguard Worker 3375*cda5da8dSAndroid Build Coastguard Worker x: int = 1 3376*cda5da8dSAndroid Build Coastguard Worker reveal_type(x) 3377*cda5da8dSAndroid Build Coastguard Worker 3378*cda5da8dSAndroid Build Coastguard Worker Running a static type checker (e.g., mypy) on this example 3379*cda5da8dSAndroid Build Coastguard Worker will produce output similar to 'Revealed type is "builtins.int"'. 3380*cda5da8dSAndroid Build Coastguard Worker 3381*cda5da8dSAndroid Build Coastguard Worker At runtime, the function prints the runtime type of the 3382*cda5da8dSAndroid Build Coastguard Worker argument and returns it unchanged. 3383*cda5da8dSAndroid Build Coastguard Worker """ 3384*cda5da8dSAndroid Build Coastguard Worker print(f"Runtime type is {type(obj).__name__!r}", file=sys.stderr) 3385*cda5da8dSAndroid Build Coastguard Worker return obj 3386*cda5da8dSAndroid Build Coastguard Worker 3387*cda5da8dSAndroid Build Coastguard Worker 3388*cda5da8dSAndroid Build Coastguard Workerdef dataclass_transform( 3389*cda5da8dSAndroid Build Coastguard Worker *, 3390*cda5da8dSAndroid Build Coastguard Worker eq_default: bool = True, 3391*cda5da8dSAndroid Build Coastguard Worker order_default: bool = False, 3392*cda5da8dSAndroid Build Coastguard Worker kw_only_default: bool = False, 3393*cda5da8dSAndroid Build Coastguard Worker field_specifiers: tuple[type[Any] | Callable[..., Any], ...] = (), 3394*cda5da8dSAndroid Build Coastguard Worker **kwargs: Any, 3395*cda5da8dSAndroid Build Coastguard Worker) -> Callable[[T], T]: 3396*cda5da8dSAndroid Build Coastguard Worker """Decorator to mark an object as providing dataclass-like behaviour. 3397*cda5da8dSAndroid Build Coastguard Worker 3398*cda5da8dSAndroid Build Coastguard Worker The decorator can be applied to a function, class, or metaclass. 3399*cda5da8dSAndroid Build Coastguard Worker 3400*cda5da8dSAndroid Build Coastguard Worker Example usage with a decorator function:: 3401*cda5da8dSAndroid Build Coastguard Worker 3402*cda5da8dSAndroid Build Coastguard Worker T = TypeVar("T") 3403*cda5da8dSAndroid Build Coastguard Worker 3404*cda5da8dSAndroid Build Coastguard Worker @dataclass_transform() 3405*cda5da8dSAndroid Build Coastguard Worker def create_model(cls: type[T]) -> type[T]: 3406*cda5da8dSAndroid Build Coastguard Worker ... 3407*cda5da8dSAndroid Build Coastguard Worker return cls 3408*cda5da8dSAndroid Build Coastguard Worker 3409*cda5da8dSAndroid Build Coastguard Worker @create_model 3410*cda5da8dSAndroid Build Coastguard Worker class CustomerModel: 3411*cda5da8dSAndroid Build Coastguard Worker id: int 3412*cda5da8dSAndroid Build Coastguard Worker name: str 3413*cda5da8dSAndroid Build Coastguard Worker 3414*cda5da8dSAndroid Build Coastguard Worker On a base class:: 3415*cda5da8dSAndroid Build Coastguard Worker 3416*cda5da8dSAndroid Build Coastguard Worker @dataclass_transform() 3417*cda5da8dSAndroid Build Coastguard Worker class ModelBase: ... 3418*cda5da8dSAndroid Build Coastguard Worker 3419*cda5da8dSAndroid Build Coastguard Worker class CustomerModel(ModelBase): 3420*cda5da8dSAndroid Build Coastguard Worker id: int 3421*cda5da8dSAndroid Build Coastguard Worker name: str 3422*cda5da8dSAndroid Build Coastguard Worker 3423*cda5da8dSAndroid Build Coastguard Worker On a metaclass:: 3424*cda5da8dSAndroid Build Coastguard Worker 3425*cda5da8dSAndroid Build Coastguard Worker @dataclass_transform() 3426*cda5da8dSAndroid Build Coastguard Worker class ModelMeta(type): ... 3427*cda5da8dSAndroid Build Coastguard Worker 3428*cda5da8dSAndroid Build Coastguard Worker class ModelBase(metaclass=ModelMeta): ... 3429*cda5da8dSAndroid Build Coastguard Worker 3430*cda5da8dSAndroid Build Coastguard Worker class CustomerModel(ModelBase): 3431*cda5da8dSAndroid Build Coastguard Worker id: int 3432*cda5da8dSAndroid Build Coastguard Worker name: str 3433*cda5da8dSAndroid Build Coastguard Worker 3434*cda5da8dSAndroid Build Coastguard Worker The ``CustomerModel`` classes defined above will 3435*cda5da8dSAndroid Build Coastguard Worker be treated by type checkers similarly to classes created with 3436*cda5da8dSAndroid Build Coastguard Worker ``@dataclasses.dataclass``. 3437*cda5da8dSAndroid Build Coastguard Worker For example, type checkers will assume these classes have 3438*cda5da8dSAndroid Build Coastguard Worker ``__init__`` methods that accept ``id`` and ``name``. 3439*cda5da8dSAndroid Build Coastguard Worker 3440*cda5da8dSAndroid Build Coastguard Worker The arguments to this decorator can be used to customize this behavior: 3441*cda5da8dSAndroid Build Coastguard Worker - ``eq_default`` indicates whether the ``eq`` parameter is assumed to be 3442*cda5da8dSAndroid Build Coastguard Worker ``True`` or ``False`` if it is omitted by the caller. 3443*cda5da8dSAndroid Build Coastguard Worker - ``order_default`` indicates whether the ``order`` parameter is 3444*cda5da8dSAndroid Build Coastguard Worker assumed to be True or False if it is omitted by the caller. 3445*cda5da8dSAndroid Build Coastguard Worker - ``kw_only_default`` indicates whether the ``kw_only`` parameter is 3446*cda5da8dSAndroid Build Coastguard Worker assumed to be True or False if it is omitted by the caller. 3447*cda5da8dSAndroid Build Coastguard Worker - ``field_specifiers`` specifies a static list of supported classes 3448*cda5da8dSAndroid Build Coastguard Worker or functions that describe fields, similar to ``dataclasses.field()``. 3449*cda5da8dSAndroid Build Coastguard Worker - Arbitrary other keyword arguments are accepted in order to allow for 3450*cda5da8dSAndroid Build Coastguard Worker possible future extensions. 3451*cda5da8dSAndroid Build Coastguard Worker 3452*cda5da8dSAndroid Build Coastguard Worker At runtime, this decorator records its arguments in the 3453*cda5da8dSAndroid Build Coastguard Worker ``__dataclass_transform__`` attribute on the decorated object. 3454*cda5da8dSAndroid Build Coastguard Worker It has no other runtime effect. 3455*cda5da8dSAndroid Build Coastguard Worker 3456*cda5da8dSAndroid Build Coastguard Worker See PEP 681 for more details. 3457*cda5da8dSAndroid Build Coastguard Worker """ 3458*cda5da8dSAndroid Build Coastguard Worker def decorator(cls_or_fn): 3459*cda5da8dSAndroid Build Coastguard Worker cls_or_fn.__dataclass_transform__ = { 3460*cda5da8dSAndroid Build Coastguard Worker "eq_default": eq_default, 3461*cda5da8dSAndroid Build Coastguard Worker "order_default": order_default, 3462*cda5da8dSAndroid Build Coastguard Worker "kw_only_default": kw_only_default, 3463*cda5da8dSAndroid Build Coastguard Worker "field_specifiers": field_specifiers, 3464*cda5da8dSAndroid Build Coastguard Worker "kwargs": kwargs, 3465*cda5da8dSAndroid Build Coastguard Worker } 3466*cda5da8dSAndroid Build Coastguard Worker return cls_or_fn 3467*cda5da8dSAndroid Build Coastguard Worker return decorator 3468