diff options
author | shadchin <shadchin@yandex-team.ru> | 2022-04-18 12:39:32 +0300 |
---|---|---|
committer | shadchin <shadchin@yandex-team.ru> | 2022-04-18 12:39:32 +0300 |
commit | d4be68e361f4258cf0848fc70018dfe37a2acc24 (patch) | |
tree | 153e294cd97ac8b5d7a989612704a0c1f58e8ad4 /contrib/tools/python3/src/Lib/_collections_abc.py | |
parent | 260c02f5ccf242d9d9b8a873afaf6588c00237d6 (diff) | |
download | ydb-d4be68e361f4258cf0848fc70018dfe37a2acc24.tar.gz |
IGNIETFERRO-1816 Update Python 3 from 3.9.12 to 3.10.4
ref:9f96be6d02ee8044fdd6f124b799b270c20ce641
Diffstat (limited to 'contrib/tools/python3/src/Lib/_collections_abc.py')
-rw-r--r-- | contrib/tools/python3/src/Lib/_collections_abc.py | 150 |
1 files changed, 100 insertions, 50 deletions
diff --git a/contrib/tools/python3/src/Lib/_collections_abc.py b/contrib/tools/python3/src/Lib/_collections_abc.py index 023ac7cf03..40417dc1d3 100644 --- a/contrib/tools/python3/src/Lib/_collections_abc.py +++ b/contrib/tools/python3/src/Lib/_collections_abc.py @@ -416,7 +416,7 @@ class Collection(Sized, Iterable, Container): class _CallableGenericAlias(GenericAlias): """ Represent `Callable[argtypes, resulttype]`. - This sets ``__args__`` to a tuple containing the flattened``argtypes`` + This sets ``__args__`` to a tuple containing the flattened ``argtypes`` followed by ``resulttype``. Example: ``Callable[[int, str], float]`` sets ``__args__`` to @@ -426,32 +426,31 @@ class _CallableGenericAlias(GenericAlias): __slots__ = () def __new__(cls, origin, args): - try: - return cls.__create_ga(origin, args) - except TypeError as exc: - import warnings - warnings.warn(f'{str(exc)} ' - f'(This will raise a TypeError in Python 3.10.)', - DeprecationWarning) - return GenericAlias(origin, args) - - @classmethod - def __create_ga(cls, origin, args): - if not isinstance(args, tuple) or len(args) != 2: + if not (isinstance(args, tuple) and len(args) == 2): raise TypeError( "Callable must be used as Callable[[arg, ...], result].") t_args, t_result = args - if isinstance(t_args, (list, tuple)): - ga_args = tuple(t_args) + (t_result,) - # This relaxes what t_args can be on purpose to allow things like - # PEP 612 ParamSpec. Responsibility for whether a user is using - # Callable[...] properly is deferred to static type checkers. - else: - ga_args = args - return super().__new__(cls, origin, ga_args) + if isinstance(t_args, list): + args = (*t_args, t_result) + elif not _is_param_expr(t_args): + raise TypeError(f"Expected a list of types, an ellipsis, " + f"ParamSpec, or Concatenate. Got {t_args}") + return super().__new__(cls, origin, args) + + @property + def __parameters__(self): + params = [] + for arg in self.__args__: + # Looks like a genericalias + if hasattr(arg, "__parameters__") and isinstance(arg.__parameters__, tuple): + params.extend(arg.__parameters__) + else: + if _is_typevarlike(arg): + params.append(arg) + return tuple(dict.fromkeys(params)) def __repr__(self): - if len(self.__args__) == 2 and self.__args__[0] is Ellipsis: + if len(self.__args__) == 2 and _is_param_expr(self.__args__[0]): return super().__repr__() return (f'collections.abc.Callable' f'[[{", ".join([_type_repr(a) for a in self.__args__[:-1]])}], ' @@ -459,20 +458,78 @@ class _CallableGenericAlias(GenericAlias): def __reduce__(self): args = self.__args__ - if not (len(args) == 2 and args[0] is Ellipsis): + if not (len(args) == 2 and _is_param_expr(args[0])): args = list(args[:-1]), args[-1] return _CallableGenericAlias, (Callable, args) def __getitem__(self, item): # Called during TypeVar substitution, returns the custom subclass - # rather than the default types.GenericAlias object. - ga = super().__getitem__(item) - args = ga.__args__ - t_result = args[-1] - t_args = args[:-1] - args = (t_args, t_result) - return _CallableGenericAlias(Callable, args) - + # rather than the default types.GenericAlias object. Most of the + # code is copied from typing's _GenericAlias and the builtin + # types.GenericAlias. + + # A special case in PEP 612 where if X = Callable[P, int], + # then X[int, str] == X[[int, str]]. + param_len = len(self.__parameters__) + if param_len == 0: + raise TypeError(f'{self} is not a generic class') + if not isinstance(item, tuple): + item = (item,) + if (param_len == 1 and _is_param_expr(self.__parameters__[0]) + and item and not _is_param_expr(item[0])): + item = (list(item),) + item_len = len(item) + if item_len != param_len: + raise TypeError(f'Too {"many" if item_len > param_len else "few"}' + f' arguments for {self};' + f' actual {item_len}, expected {param_len}') + subst = dict(zip(self.__parameters__, item)) + new_args = [] + for arg in self.__args__: + if _is_typevarlike(arg): + if _is_param_expr(arg): + arg = subst[arg] + if not _is_param_expr(arg): + raise TypeError(f"Expected a list of types, an ellipsis, " + f"ParamSpec, or Concatenate. Got {arg}") + else: + arg = subst[arg] + # Looks like a GenericAlias + elif hasattr(arg, '__parameters__') and isinstance(arg.__parameters__, tuple): + subparams = arg.__parameters__ + if subparams: + subargs = tuple(subst[x] for x in subparams) + arg = arg[subargs] + if isinstance(arg, tuple): + new_args.extend(arg) + else: + new_args.append(arg) + + # args[0] occurs due to things like Z[[int, str, bool]] from PEP 612 + if not isinstance(new_args[0], list): + t_result = new_args[-1] + t_args = new_args[:-1] + new_args = (t_args, t_result) + return _CallableGenericAlias(Callable, tuple(new_args)) + + +def _is_typevarlike(arg): + obj = type(arg) + # looks like a TypeVar/ParamSpec + return (obj.__module__ == 'typing' + and obj.__name__ in {'ParamSpec', 'TypeVar'}) + +def _is_param_expr(obj): + """Checks if obj matches either a list of types, ``...``, ``ParamSpec`` or + ``_ConcatenateGenericAlias`` from typing.py + """ + if obj is Ellipsis: + return True + if isinstance(obj, list): + return True + obj = type(obj) + names = ('ParamSpec', '_ConcatenateGenericAlias') + return obj.__module__ == 'typing' and any(obj.__name__ == name for name in names) def _type_repr(obj): """Return the repr() of an object, special-casing types (internal helper). @@ -514,7 +571,6 @@ class Callable(metaclass=ABCMeta): class Set(Collection): - """A set is a finite, iterable container. This class provides concrete generic implementations of all @@ -740,19 +796,19 @@ MutableSet.register(set) ### MAPPINGS ### - class Mapping(Collection): - - __slots__ = () - """A Mapping is a generic container for associating key/value pairs. This class provides concrete generic implementations of all methods except for __getitem__, __iter__, and __len__. - """ + __slots__ = () + + # Tell ABCMeta.__new__ that this class should have TPFLAGS_MAPPING set. + __abc_tpflags__ = 1 << 6 # Py_TPFLAGS_MAPPING + @abstractmethod def __getitem__(self, key): raise KeyError @@ -791,7 +847,6 @@ class Mapping(Collection): __reversed__ = None - Mapping.register(mappingproxy) @@ -874,18 +929,16 @@ ValuesView.register(dict_values) class MutableMapping(Mapping): - - __slots__ = () - """A MutableMapping is a generic container for associating key/value pairs. This class provides concrete generic implementations of all methods except for __getitem__, __setitem__, __delitem__, __iter__, and __len__. - """ + __slots__ = () + @abstractmethod def __setitem__(self, key, value): raise KeyError @@ -962,9 +1015,7 @@ MutableMapping.register(dict) ### SEQUENCES ### - class Sequence(Reversible, Collection): - """All the operations on a read-only sequence. Concrete subclasses must override __new__ or __init__, @@ -973,6 +1024,9 @@ class Sequence(Reversible, Collection): __slots__ = () + # Tell ABCMeta.__new__ that this class should have TPFLAGS_SEQUENCE set. + __abc_tpflags__ = 1 << 5 # Py_TPFLAGS_SEQUENCE + @abstractmethod def __getitem__(self, index): raise IndexError @@ -1024,7 +1078,6 @@ class Sequence(Reversible, Collection): 'S.count(value) -> integer -- return number of occurrences of value' return sum(1 for v in self if v is value or v == value) - Sequence.register(tuple) Sequence.register(str) Sequence.register(range) @@ -1032,7 +1085,6 @@ Sequence.register(memoryview) class ByteString(Sequence): - """This unifies bytes and bytearray. XXX Should add all their methods. @@ -1045,16 +1097,14 @@ ByteString.register(bytearray) class MutableSequence(Sequence): - - __slots__ = () - """All the operations on a read-write sequence. Concrete subclasses must provide __new__ or __init__, __getitem__, __setitem__, __delitem__, __len__, and insert(). - """ + __slots__ = () + @abstractmethod def __setitem__(self, index, value): raise IndexError |