@@ -186,14 +186,13 @@ def _collect_type_vars(types):
186186 return tuple (tvars )
187187
188188
189- def _check_generic (cls , parameters ):
189+ def _check_generic (cls , parameters , elen ):
190190 """Check correct count for parameters of a generic cls (internal helper).
191191 This gives a nice error message in case of count mismatch.
192192 """
193- if not cls . __parameters__ :
193+ if not elen :
194194 raise TypeError (f"{ cls } is not a generic class" )
195195 alen = len (parameters )
196- elen = len (cls .__parameters__ )
197196 if alen != elen :
198197 raise TypeError (f"Too { 'many' if alen > elen else 'few' } parameters for { cls } ;"
199198 f" actual { alen } , expected { elen } " )
@@ -592,17 +591,6 @@ def __reduce__(self):
592591 return self .__name__
593592
594593
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-
606594def _is_dunder (attr ):
607595 return attr .startswith ('__' ) and attr .endswith ('__' )
608596
@@ -615,28 +603,11 @@ class _BaseGenericAlias(_Final, _root=True):
615603 have 'name' always set. If 'inst' is False, then the alias can't be instantiated,
616604 this is used by e.g. typing.List and typing.Dict.
617605 """
618- def __init__ (self , origin , params , * , inst = True , name = None ):
606+ def __init__ (self , origin , * , inst = True , name = None ):
619607 self ._inst = inst
620608 self ._name = name
621- if not isinstance (params , tuple ):
622- params = (params ,)
623609 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 )
628610 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__ ))
640611
641612 def __call__ (self , * args , ** kwargs ):
642613 if not self ._inst :
@@ -669,7 +640,7 @@ def __getattr__(self, attr):
669640 raise AttributeError (attr )
670641
671642 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' ):
673644 super ().__setattr__ (attr , val )
674645 else :
675646 setattr (self .__origin__ , attr , val )
@@ -682,7 +653,38 @@ def __subclasscheck__(self, cls):
682653 " class and instance checks" )
683654
684655
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+
685667class _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+
686688 @_tp_cache
687689 def __getitem__ (self , params ):
688690 if self .__origin__ in (Generic , Protocol ):
@@ -692,14 +694,14 @@ def __getitem__(self, params):
692694 params = (params ,)
693695 msg = "Parameters to generic types must be types."
694696 params = tuple (_type_check (p , msg ) for p in params )
695- _check_generic (self , params )
697+ _check_generic (self , params , len ( self . __parameters__ ) )
696698
697699 subst = dict (zip (self .__parameters__ , params ))
698700 new_args = []
699701 for arg in self .__args__ :
700702 if isinstance (arg , TypeVar ):
701703 arg = subst [arg ]
702- elif isinstance (arg , (_BaseGenericAlias , GenericAlias )):
704+ elif isinstance (arg , (_GenericAlias , GenericAlias )):
703705 subargs = tuple (subst [x ] for x in arg .__parameters__ )
704706 arg = arg [subargs ]
705707 new_args .append (arg )
@@ -739,11 +741,16 @@ def __mro_entries__(self, bases):
739741 return (self .__origin__ ,)
740742
741743
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+
742748class _SpecialGenericAlias (_BaseGenericAlias , _root = True ):
743- def __init__ (self , origin , params , * , inst = True , name = None ):
749+ def __init__ (self , origin , nparams , * , inst = True , name = None ):
744750 if name is None :
745751 name = origin .__name__
746- super ().__init__ (origin , params , inst = inst , name = name )
752+ super ().__init__ (origin , inst = inst , name = name )
753+ self ._nparams = nparams
747754 self .__doc__ = f'A generic version of { origin .__module__ } .{ origin .__qualname__ } '
748755
749756 @_tp_cache
@@ -752,8 +759,7 @@ def __getitem__(self, params):
752759 params = (params ,)
753760 msg = "Parameters to generic types must be types."
754761 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 )
757763 return self .copy_with (params )
758764
759765 def copy_with (self , params ):
@@ -912,7 +918,7 @@ def __class_getitem__(cls, params):
912918 f"Parameters to { cls .__name__ } [...] must all be unique" )
913919 else :
914920 # Subscripting a regular Generic subclass.
915- _check_generic (cls , params )
921+ _check_generic (cls , params , len ( cls . __parameters__ ) )
916922 return _GenericAlias (cls , params )
917923
918924 def __init_subclass__ (cls , * args , ** kwargs ):
@@ -1571,18 +1577,18 @@ class Other(Leaf): # Error reported by type checker
15711577# Various ABCs mimicking those in collections.abc.
15721578_alias = _SpecialGenericAlias
15731579
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 )
15861592Callable .__doc__ = \
15871593 """Callable type; Callable[[int], str] is a function of (int) -> str.
15881594
@@ -1593,15 +1599,16 @@ class Other(Leaf): # Error reported by type checker
15931599 There is no syntax to indicate optional or keyword arguments,
15941600 such function types are rarely used as callback types.
15951601 """
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 )
15981604# 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' )
16051612Tuple .__doc__ = \
16061613 """Tuple type; Tuple[X, Y] is the cross-product type of X and Y.
16071614
@@ -1611,24 +1618,24 @@ class Other(Leaf): # Error reported by type checker
16111618
16121619 To specify a variable-length tuple of homogeneous type, use Tuple[T, ...].
16131620 """
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' )
16321639Type .__doc__ = \
16331640 """A special construct usable to annotate class objects.
16341641
@@ -2122,8 +2129,8 @@ class io:
21222129io .__name__ = __name__ + '.io'
21232130sys .modules [io .__name__ ] = io
21242131
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 )
21272134
21282135class re :
21292136 """Wrapper namespace for re type aliases."""
0 commit comments