Team Ai
Datasetpublic

codekingpro/portable-devtools

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

Showing the first 1,200 of 3855 lines. Download the file for the rest.

codekingpro/portable-devtools · Team Ai