| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -186,14 +186,13 @@ def _collect_type_vars(types): | |||
| 186 | 186 | return tuple(tvars) | |
| 187 | 187 | ||
| 188 | 188 | ||
| 189 | - def _check_generic(cls, parameters): | ||
| 189 | + def _check_generic(cls, parameters, elen): | ||
| 190 | 190 | """Check correct count for parameters of a generic cls (internal helper). | |
| 191 | 191 | This gives a nice error message in case of count mismatch. | |
| 192 | 192 | """ | |
| 193 | - if not cls.__parameters__: | ||
| 193 | + if not elen: | ||
| 194 | 194 | raise TypeError(f"{cls} is not a generic class") | |
| 195 | 195 | alen = len(parameters) | |
| 196 | - elen = len(cls.__parameters__) | ||
| 197 | 196 | if alen != elen: | |
| 198 | 197 | raise TypeError(f"Too {'many' if alen > elen else 'few'} parameters for {cls};" | |
| 199 | 198 | f" actual {alen}, expected {elen}") | |
@@ -592,17 +591,6 @@ def __reduce__(self): | |||
| 592 | 591 | return self.__name__ | |
| 593 | 592 | ||
| 594 | 593 | ||
| 595 | - # Special typing constructs Union, Optional, Generic, Callable and Tuple | ||
| 596 | - # use three special attributes for internal bookkeeping of generic types: | ||
| 597 | - # * __parameters__ is a tuple of unique free type parameters of a generic | ||
| 598 | - # type, for example, Dict[T, T].__parameters__ == (T,); | ||
| 599 | - # * __origin__ keeps a reference to a type that was subscripted, | ||
| 600 | - # e.g., Union[T, int].__origin__ == Union, or the non-generic version of | ||
| 601 | - # the type. | ||
| 602 | - # * __args__ is a tuple of all arguments used in subscripting, | ||
| 603 | - # e.g., Dict[T, int].__args__ == (T, int). | ||
| 604 | - | ||
| 605 | - | ||
| 606 | 594 | def _is_dunder(attr): | |
| 607 | 595 | return attr.startswith('__') and attr.endswith('__') | |
| 608 | 596 | ||
@@ -615,28 +603,11 @@ class _BaseGenericAlias(_Final, _root=True): | |||
| 615 | 603 | have 'name' always set. If 'inst' is False, then the alias can't be instantiated, | |
| 616 | 604 | this is used by e.g. typing.List and typing.Dict. | |
| 617 | 605 | """ | |
| 618 | - def __init__(self, origin, params, *, inst=True, name=None): | ||
| 606 | + def __init__(self, origin, *, inst=True, name=None): | ||
| 619 | 607 | self._inst = inst | |
| 620 | 608 | self._name = name | |
| 621 | - if not isinstance(params, tuple): | ||
| 622 | - params = (params,) | ||
| 623 | 609 | self.__origin__ = origin | |
| 624 | - self.__args__ = tuple(... if a is _TypingEllipsis else | ||
| 625 | - () if a is _TypingEmpty else | ||
| 626 | - a for a in params) | ||
| 627 | - self.__parameters__ = _collect_type_vars(params) | ||
| 628 | 610 | self.__slots__ = None # This is not documented. | |
| 629 | - if not name: | ||
| 630 | - self.__module__ = origin.__module__ | ||
| 631 | - | ||
| 632 | - def __eq__(self, other): | ||
| 633 | - if not isinstance(other, _BaseGenericAlias): | ||
| 634 | - return NotImplemented | ||
| 635 | - return (self.__origin__ == other.__origin__ | ||
| 636 | - and self.__args__ == other.__args__) | ||
| 637 | - | ||
| 638 | - def __hash__(self): | ||
| 639 | - return hash((self.__origin__, self.__args__)) | ||
| 640 | 611 | ||
| 641 | 612 | def __call__(self, *args, **kwargs): | |
| 642 | 613 | if not self._inst: | |
@@ -669,7 +640,7 @@ def __getattr__(self, attr): | |||
| 669 | 640 | raise AttributeError(attr) | |
| 670 | 641 | ||
| 671 | 642 | def __setattr__(self, attr, val): | |
| 672 | - if _is_dunder(attr) or attr in ('_name', '_inst'): | ||
| 643 | + if _is_dunder(attr) or attr in ('_name', '_inst', '_nparams'): | ||
| 673 | 644 | super().__setattr__(attr, val) | |
| 674 | 645 | else: | |
| 675 | 646 | setattr(self.__origin__, attr, val) | |
@@ -682,7 +653,38 @@ def __subclasscheck__(self, cls): | |||
| 682 | 653 | " class and instance checks") | |
| 683 | 654 | ||
| 684 | 655 | ||
| 656 | + # Special typing constructs Union, Optional, Generic, Callable and Tuple | ||
| 657 | + # use three special attributes for internal bookkeeping of generic types: | ||
| 658 | + # * __parameters__ is a tuple of unique free type parameters of a generic | ||
| 659 | + # type, for example, Dict[T, T].__parameters__ == (T,); | ||
| 660 | + # * __origin__ keeps a reference to a type that was subscripted, | ||
| 661 | + # e.g., Union[T, int].__origin__ == Union, or the non-generic version of | ||
| 662 | + # the type. | ||
| 663 | + # * __args__ is a tuple of all arguments used in subscripting, | ||
| 664 | + # e.g., Dict[T, int].__args__ == (T, int). | ||
| 665 | + | ||
| 666 | + | ||
| 685 | 667 | class _GenericAlias(_BaseGenericAlias, _root=True): | |
| 668 | + def __init__(self, origin, params, *, inst=True, name=None): | ||
| 669 | + super().__init__(origin, inst=inst, name=name) | ||
| 670 | + if not isinstance(params, tuple): | ||
| 671 | + params = (params,) | ||
| 672 | + self.__args__ = tuple(... if a is _TypingEllipsis else | ||
| 673 | + () if a is _TypingEmpty else | ||
| 674 | + a for a in params) | ||
| 675 | + self.__parameters__ = _collect_type_vars(params) | ||
| 676 | + if not name: | ||
| 677 | + self.__module__ = origin.__module__ | ||
| 678 | + | ||
| 679 | + def __eq__(self, other): | ||
| 680 | + if not isinstance(other, _GenericAlias): | ||
| 681 | + return NotImplemented | ||
| 682 | + return (self.__origin__ == other.__origin__ | ||
| 683 | + and self.__args__ == other.__args__) | ||
| 684 | + | ||
| 685 | + def __hash__(self): | ||
| 686 | + return hash((self.__origin__, self.__args__)) | ||
| 687 | + | ||
| 686 | 688 | @_tp_cache | |
| 687 | 689 | def __getitem__(self, params): | |
| 688 | 690 | if self.__origin__ in (Generic, Protocol): | |
@@ -692,14 +694,14 @@ def __getitem__(self, params): | |||
| 692 | 694 | params = (params,) | |
| 693 | 695 | msg = "Parameters to generic types must be types." | |
| 694 | 696 | params = tuple(_type_check(p, msg) for p in params) | |
| 695 | - _check_generic(self, params) | ||
| 697 | + _check_generic(self, params, len(self.__parameters__)) | ||
| 696 | 698 | ||
| 697 | 699 | subst = dict(zip(self.__parameters__, params)) | |
| 698 | 700 | new_args = [] | |
| 699 | 701 | for arg in self.__args__: | |
| 700 | 702 | if isinstance(arg, TypeVar): | |
| 701 | 703 | arg = subst[arg] | |
| 702 | - elif isinstance(arg, (_BaseGenericAlias, GenericAlias)): | ||
| 704 | + elif isinstance(arg, (_GenericAlias, GenericAlias)): | ||
| 703 | 705 | subargs = tuple(subst[x] for x in arg.__parameters__) | |
| 704 | 706 | arg = arg[subargs] | |
| 705 | 707 | new_args.append(arg) | |
@@ -739,11 +741,16 @@ def __mro_entries__(self, bases): | |||
| 739 | 741 | return (self.__origin__,) | |
| 740 | 742 | ||
| 741 | 743 | ||
| 744 | + # _nparams is the number of accepted parameters, e.g. 0 for Hashable, | ||
| 745 | + # 1 for List and 2 for Dict. It may be -1 if variable number of | ||
| 746 | + # parameters are accepted (needs custom __getitem__). | ||
| 747 | + | ||
| 742 | 748 | class _SpecialGenericAlias(_BaseGenericAlias, _root=True): | |
| 743 | - def __init__(self, origin, params, *, inst=True, name=None): | ||
| 749 | + def __init__(self, origin, nparams, *, inst=True, name=None): | ||
| 744 | 750 | if name is None: | |
| 745 | 751 | name = origin.__name__ | |
| 746 | - super().__init__(origin, params, inst=inst, name=name) | ||
| 752 | + super().__init__(origin, inst=inst, name=name) | ||
| 753 | + self._nparams = nparams | ||
| 747 | 754 | self.__doc__ = f'A generic version of {origin.__module__}.{origin.__qualname__}' | |
| 748 | 755 | ||
| 749 | 756 | @_tp_cache | |
@@ -752,8 +759,7 @@ def __getitem__(self, params): | |||
| 752 | 759 | params = (params,) | |
| 753 | 760 | msg = "Parameters to generic types must be types." | |
| 754 | 761 | params = tuple(_type_check(p, msg) for p in params) | |
| 755 | - _check_generic(self, params) | ||
| 756 | - assert self.__args__ == self.__parameters__ | ||
| 762 | + _check_generic(self, params, self._nparams) | ||
| 757 | 763 | return self.copy_with(params) | |
| 758 | 764 | ||
| 759 | 765 | def copy_with(self, params): | |
@@ -912,7 +918,7 @@ def __class_getitem__(cls, params): | |||
| 912 | 918 | f"Parameters to {cls.__name__}[...] must all be unique") | |
| 913 | 919 | else: | |
| 914 | 920 | # Subscripting a regular Generic subclass. | |
| 915 | - _check_generic(cls, params) | ||
| 921 | + _check_generic(cls, params, len(cls.__parameters__)) | ||
| 916 | 922 | return _GenericAlias(cls, params) | |
| 917 | 923 | ||
| 918 | 924 | def __init_subclass__(cls, *args, **kwargs): | |
@@ -1571,18 +1577,18 @@ class Other(Leaf): # Error reported by type checker | |||
| 1571 | 1577 | # Various ABCs mimicking those in collections.abc. | |
| 1572 | 1578 | _alias = _SpecialGenericAlias | |
| 1573 | 1579 | ||
| 1574 | - Hashable = _alias(collections.abc.Hashable, ()) # Not generic. | ||
| 1575 | - Awaitable = _alias(collections.abc.Awaitable, T_co) | ||
| 1576 | - Coroutine = _alias(collections.abc.Coroutine, (T_co, T_contra, V_co)) | ||
| 1577 | - AsyncIterable = _alias(collections.abc.AsyncIterable, T_co) | ||
| 1578 | - AsyncIterator = _alias(collections.abc.AsyncIterator, T_co) | ||
| 1579 | - Iterable = _alias(collections.abc.Iterable, T_co) | ||
| 1580 | - Iterator = _alias(collections.abc.Iterator, T_co) | ||
| 1581 | - Reversible = _alias(collections.abc.Reversible, T_co) | ||
| 1582 | - Sized = _alias(collections.abc.Sized, ()) # Not generic. | ||
| 1583 | - Container = _alias(collections.abc.Container, T_co) | ||
| 1584 | - Collection = _alias(collections.abc.Collection, T_co) | ||
| 1585 | - Callable = _CallableType(collections.abc.Callable, ()) | ||
| 1580 | + Hashable = _alias(collections.abc.Hashable, 0) # Not generic. | ||
| 1581 | + Awaitable = _alias(collections.abc.Awaitable, 1) | ||
| 1582 | + Coroutine = _alias(collections.abc.Coroutine, 3) | ||
| 1583 | + AsyncIterable = _alias(collections.abc.AsyncIterable, 1) | ||
| 1584 | + AsyncIterator = _alias(collections.abc.AsyncIterator, 1) | ||
| 1585 | + Iterable = _alias(collections.abc.Iterable, 1) | ||
| 1586 | + Iterator = _alias(collections.abc.Iterator, 1) | ||
| 1587 | + Reversible = _alias(collections.abc.Reversible, 1) | ||
| 1588 | + Sized = _alias(collections.abc.Sized, 0) # Not generic. | ||
| 1589 | + Container = _alias(collections.abc.Container, 1) | ||
| 1590 | + Collection = _alias(collections.abc.Collection, 1) | ||
| 1591 | + Callable = _CallableType(collections.abc.Callable, 2) | ||
| 1586 | 1592 | Callable.__doc__ = \ | |
| 1587 | 1593 | """Callable type; Callable[[int], str] is a function of (int) -> str. | |
| 1588 | 1594 | ||
@@ -1593,15 +1599,16 @@ class Other(Leaf): # Error reported by type checker | |||
| 1593 | 1599 | There is no syntax to indicate optional or keyword arguments, | |
| 1594 | 1600 | such function types are rarely used as callback types. | |
| 1595 | 1601 | """ | |
| 1596 | - AbstractSet = _alias(collections.abc.Set, T_co, name='AbstractSet') | ||
| 1597 | - MutableSet = _alias(collections.abc.MutableSet, T) | ||
| 1602 | + AbstractSet = _alias(collections.abc.Set, 1, name='AbstractSet') | ||
| 1603 | + MutableSet = _alias(collections.abc.MutableSet, 1) | ||
| 1598 | 1604 | # NOTE: Mapping is only covariant in the value type. | |
| 1599 | - Mapping = _alias(collections.abc.Mapping, (KT, VT_co)) | ||
| 1600 | - MutableMapping = _alias(collections.abc.MutableMapping, (KT, VT)) | ||
| 1601 | - Sequence = _alias(collections.abc.Sequence, T_co) | ||
| 1602 | - MutableSequence = _alias(collections.abc.MutableSequence, T) | ||
| 1603 | - ByteString = _alias(collections.abc.ByteString, ()) # Not generic | ||
| 1604 | - Tuple = _TupleType(tuple, (), inst=False, name='Tuple') | ||
| 1605 | + Mapping = _alias(collections.abc.Mapping, 2) | ||
| 1606 | + MutableMapping = _alias(collections.abc.MutableMapping, 2) | ||
| 1607 | + Sequence = _alias(collections.abc.Sequence, 1) | ||
| 1608 | + MutableSequence = _alias(collections.abc.MutableSequence, 1) | ||
| 1609 | + ByteString = _alias(collections.abc.ByteString, 0) # Not generic | ||
| 1610 | + # Tuple accepts variable number of parameters. | ||
| 1611 | + Tuple = _TupleType(tuple, -1, inst=False, name='Tuple') | ||
| 1605 | 1612 | Tuple.__doc__ = \ | |
| 1606 | 1613 | """Tuple type; Tuple[X, Y] is the cross-product type of X and Y. | |
| 1607 | 1614 | ||
@@ -1611,24 +1618,24 @@ class Other(Leaf): # Error reported by type checker | |||
| 1611 | 1618 | ||
| 1612 | 1619 | To specify a variable-length tuple of homogeneous type, use Tuple[T, ...]. | |
| 1613 | 1620 | """ | |
| 1614 | - List = _alias(list, T, inst=False, name='List') | ||
| 1615 | - Deque = _alias(collections.deque, T, name='Deque') | ||
| 1616 | - Set = _alias(set, T, inst=False, name='Set') | ||
| 1617 | - FrozenSet = _alias(frozenset, T_co, inst=False, name='FrozenSet') | ||
| 1618 | - MappingView = _alias(collections.abc.MappingView, T_co) | ||
| 1619 | - KeysView = _alias(collections.abc.KeysView, KT) | ||
| 1620 | - ItemsView = _alias(collections.abc.ItemsView, (KT, VT_co)) | ||
| 1621 | - ValuesView = _alias(collections.abc.ValuesView, VT_co) | ||
| 1622 | - ContextManager = _alias(contextlib.AbstractContextManager, T_co, name='ContextManager') | ||
| 1623 | - AsyncContextManager = _alias(contextlib.AbstractAsyncContextManager, T_co, name='AsyncContextManager') | ||
| 1624 | - Dict = _alias(dict, (KT, VT), inst=False, name='Dict') | ||
| 1625 | - DefaultDict = _alias(collections.defaultdict, (KT, VT), name='DefaultDict') | ||
| 1626 | - OrderedDict = _alias(collections.OrderedDict, (KT, VT)) | ||
| 1627 | - Counter = _alias(collections.Counter, T) | ||
| 1628 | - ChainMap = _alias(collections.ChainMap, (KT, VT)) | ||
| 1629 | - Generator = _alias(collections.abc.Generator, (T_co, T_contra, V_co)) | ||
| 1630 | - AsyncGenerator = _alias(collections.abc.AsyncGenerator, (T_co, T_contra)) | ||
| 1631 | - Type = _alias(type, CT_co, inst=False, name='Type') | ||
| 1621 | + List = _alias(list, 1, inst=False, name='List') | ||
| 1622 | + Deque = _alias(collections.deque, 1, name='Deque') | ||
| 1623 | + Set = _alias(set, 1, inst=False, name='Set') | ||
| 1624 | + FrozenSet = _alias(frozenset, 1, inst=False, name='FrozenSet') | ||
| 1625 | + MappingView = _alias(collections.abc.MappingView, 1) | ||
| 1626 | + KeysView = _alias(collections.abc.KeysView, 1) | ||
| 1627 | + ItemsView = _alias(collections.abc.ItemsView, 2) | ||
| 1628 | + ValuesView = _alias(collections.abc.ValuesView, 1) | ||
| 1629 | + ContextManager = _alias(contextlib.AbstractContextManager, 1, name='ContextManager') | ||
| 1630 | + AsyncContextManager = _alias(contextlib.AbstractAsyncContextManager, 1, name='AsyncContextManager') | ||
| 1631 | + Dict = _alias(dict, 2, inst=False, name='Dict') | ||
| 1632 | + DefaultDict = _alias(collections.defaultdict, 2, name='DefaultDict') | ||
| 1633 | + OrderedDict = _alias(collections.OrderedDict, 2) | ||
| 1634 | + Counter = _alias(collections.Counter, 1) | ||
| 1635 | + ChainMap = _alias(collections.ChainMap, 2) | ||
| 1636 | + Generator = _alias(collections.abc.Generator, 3) | ||
| 1637 | + AsyncGenerator = _alias(collections.abc.AsyncGenerator, 2) | ||
| 1638 | + Type = _alias(type, 1, inst=False, name='Type') | ||
| 1632 | 1639 | Type.__doc__ = \ | |
| 1633 | 1640 | """A special construct usable to annotate class objects. | |
| 1634 | 1641 | ||
@@ -2122,8 +2129,8 @@ class io: | |||
| 2122 | 2129 | io.__name__ = __name__ + '.io' | |
| 2123 | 2130 | sys.modules[io.__name__] = io | |
| 2124 | 2131 | ||
| 2125 | - Pattern = _alias(stdlib_re.Pattern, AnyStr) | ||
| 2126 | - Match = _alias(stdlib_re.Match, AnyStr) | ||
| 2132 | + Pattern = _alias(stdlib_re.Pattern, 1) | ||
| 2133 | + Match = _alias(stdlib_re.Match, 1) | ||
| 2127 | 2134 | ||
| 2128 | 2135 | class re: | |
| 2129 | 2136 | """Wrapper namespace for re type aliases.""" | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -0,0 +1,2 @@ | |||
| 1 | + Removed attributes ``__args__`` and ``__parameters__`` from special generic | ||
| 2 | + aliases like ``typing.List`` (not subscripted). | ||
| Back | FazBrowse Home | New Git URL |
0 commit comments