@@ -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."""
0 commit comments