@@ -376,7 +376,7 @@ def _type_check(arg, msg):
376376 if (
377377 type (arg ).__name__ in ('_Union' , '_Optional' ) and
378378 not getattr (arg , '__origin__' , None ) or
379- isinstance (arg , TypingMeta ) and _gorg ( arg ) in (Generic , _Protocol )
379+ isinstance (arg , TypingMeta ) and arg . _gorg in (Generic , _Protocol )
380380 ):
381381 raise TypeError ("Plain %s is not valid as type argument" % arg )
382382 return arg
@@ -849,29 +849,6 @@ def __getitem__(self, arg):
849849Optional = _Optional (_root = True )
850850
851851
852- def _gorg (a ):
853- """Return the farthest origin of a generic class (internal helper)."""
854- assert isinstance (a , GenericMeta )
855- while a .__origin__ is not None :
856- a = a .__origin__
857- return a
858-
859-
860- def _geqv (a , b ):
861- """Return whether two generic classes are equivalent (internal helper).
862-
863- The intention is to consider generic class X and any of its
864- parameterized forms (X[T], X[int], etc.) as equivalent.
865-
866- However, X is not equivalent to a subclass of X.
867-
868- The relation is reflexive, symmetric and transitive.
869- """
870- assert isinstance (a , GenericMeta ) and isinstance (b , GenericMeta )
871- # Reduce each to its origin.
872- return _gorg (a ) is _gorg (b )
873-
874-
875852def _next_in_mro (cls ):
876853 """Helper for Generic.__new__.
877854
@@ -881,7 +858,7 @@ def _next_in_mro(cls):
881858 next_in_mro = object
882859 # Look for the last occurrence of Generic or Generic[...].
883860 for i , c in enumerate (cls .__mro__ [:- 1 ]):
884- if isinstance (c , GenericMeta ) and _gorg ( c ) is Generic :
861+ if isinstance (c , GenericMeta ) and c . _gorg is Generic :
885862 next_in_mro = cls .__mro__ [i + 1 ]
886863 return next_in_mro
887864
@@ -991,14 +968,15 @@ def __new__(cls, name, bases, namespace,
991968 initial_bases = bases
992969 if extra is not None and type (extra ) is abc .ABCMeta and extra not in bases :
993970 bases = (extra ,) + bases
994- bases = tuple (_gorg ( b ) if isinstance (b , GenericMeta ) else b for b in bases )
971+ bases = tuple (b . _gorg if isinstance (b , GenericMeta ) else b for b in bases )
995972
996973 # remove bare Generic from bases if there are other generic bases
997974 if any (isinstance (b , GenericMeta ) and b is not Generic for b in bases ):
998975 bases = tuple (b for b in bases if b is not Generic )
999976 namespace .update ({'__origin__' : origin , '__extra__' : extra })
1000977 self = super ().__new__ (cls , name , bases , namespace , _root = True )
1001-
978+ super (GenericMeta , self ).__setattr__ ('_gorg' ,
979+ self if not origin else origin ._gorg )
1002980 self .__parameters__ = tvars
1003981 # Be prepared that GenericMeta will be subclassed by TupleMeta
1004982 # and CallableMeta, those two allow ..., (), or [] in __args___.
@@ -1041,7 +1019,7 @@ def __new__(cls, name, bases, namespace,
10411019 def _abc_negative_cache (self ):
10421020 if isinstance (self .__extra__ , abc .ABCMeta ):
10431021 return self .__extra__ ._abc_negative_cache
1044- return _gorg ( self ) ._abc_generic_negative_cache
1022+ return self . _gorg ._abc_generic_negative_cache
10451023
10461024 @_abc_negative_cache .setter
10471025 def _abc_negative_cache (self , value ):
@@ -1055,7 +1033,7 @@ def _abc_negative_cache(self, value):
10551033 def _abc_negative_cache_version (self ):
10561034 if isinstance (self .__extra__ , abc .ABCMeta ):
10571035 return self .__extra__ ._abc_negative_cache_version
1058- return _gorg ( self ) ._abc_generic_negative_cache_version
1036+ return self . _gorg ._abc_generic_negative_cache_version
10591037
10601038 @_abc_negative_cache_version .setter
10611039 def _abc_negative_cache_version (self , value ):
@@ -1105,7 +1083,7 @@ def _subs_tree(self, tvars=None, args=None):
11051083 if self .__origin__ is None :
11061084 return self
11071085 tree_args = _subs_tree (self , tvars , args )
1108- return (_gorg ( self ) ,) + tuple (tree_args )
1086+ return (self . _gorg ,) + tuple (tree_args )
11091087
11101088 def __eq__ (self , other ):
11111089 if not isinstance (other , GenericMeta ):
@@ -1121,7 +1099,7 @@ def __hash__(self):
11211099 def __getitem__ (self , params ):
11221100 if not isinstance (params , tuple ):
11231101 params = (params ,)
1124- if not params and not _gorg ( self ) is Tuple :
1102+ if not params and self . _gorg is not Tuple :
11251103 raise TypeError (
11261104 "Parameter list to %s[...] cannot be empty" % _qualname (self ))
11271105 msg = "Parameters to generic types must be types."
@@ -1189,14 +1167,14 @@ def __copy__(self):
11891167 self .__extra__ , self .__orig_bases__ )
11901168
11911169 def __setattr__ (self , attr , value ):
1192- # We consider all the subscripted genrics as proxies for original class
1170+ # We consider all the subscripted generics as proxies for original class
11931171 if (
11941172 attr .startswith ('__' ) and attr .endswith ('__' ) or
11951173 attr .startswith ('_abc_' )
11961174 ):
11971175 super (GenericMeta , self ).__setattr__ (attr , value )
11981176 else :
1199- super (GenericMeta , _gorg ( self ) ).__setattr__ (attr , value )
1177+ super (GenericMeta , self . _gorg ).__setattr__ (attr , value )
12001178
12011179
12021180# Prevent checks for Generic to crash when defining Generic.
@@ -1209,7 +1187,7 @@ def _generic_new(base_cls, cls, *args, **kwds):
12091187 if cls .__origin__ is None :
12101188 return base_cls .__new__ (cls )
12111189 else :
1212- origin = _gorg ( cls )
1190+ origin = cls . _gorg
12131191 obj = base_cls .__new__ (origin )
12141192 try :
12151193 obj .__orig_class__ = cls
@@ -1243,7 +1221,7 @@ def lookup_name(mapping: Mapping[KT, VT], key: KT, default: VT) -> VT:
12431221 __slots__ = ()
12441222
12451223 def __new__ (cls , * args , ** kwds ):
1246- if _geqv ( cls , Generic ) :
1224+ if cls . _gorg is Generic :
12471225 raise TypeError ("Type Generic cannot be instantiated; "
12481226 "it can be used only as a base class" )
12491227 return _generic_new (cls .__next_in_mro__ , cls , * args , ** kwds )
@@ -1265,7 +1243,7 @@ class TupleMeta(GenericMeta):
12651243
12661244 @_tp_cache
12671245 def __getitem__ (self , parameters ):
1268- if self .__origin__ is not None or not _geqv ( self , Tuple ) :
1246+ if self .__origin__ is not None or self . _gorg is not Tuple :
12691247 # Normal generic rules apply if this is not the first subscription
12701248 # or a subscription of a subclass.
12711249 return super ().__getitem__ (parameters )
@@ -1307,7 +1285,7 @@ class Tuple(tuple, extra=tuple, metaclass=TupleMeta):
13071285 __slots__ = ()
13081286
13091287 def __new__ (cls , * args , ** kwds ):
1310- if _geqv ( cls , Tuple ) :
1288+ if cls . _gorg is Tuple :
13111289 raise TypeError ("Type Tuple cannot be instantiated; "
13121290 "use tuple() instead" )
13131291 return _generic_new (tuple , cls , * args , ** kwds )
@@ -1322,7 +1300,7 @@ def __repr__(self):
13221300 return self ._tree_repr (self ._subs_tree ())
13231301
13241302 def _tree_repr (self , tree ):
1325- if _gorg ( self ) is not Callable :
1303+ if self . _gorg is not Callable :
13261304 return super ()._tree_repr (tree )
13271305 # For actual Callable (not its subclass) we override
13281306 # super()._tree_repr() for nice formatting.
@@ -1342,7 +1320,7 @@ def __getitem__(self, parameters):
13421320 with hashable arguments to improve speed.
13431321 """
13441322
1345- if self .__origin__ is not None or not _geqv ( self , Callable ) :
1323+ if self .__origin__ is not None or self . _gorg is not Callable :
13461324 return super ().__getitem__ (parameters )
13471325 if not isinstance (parameters , tuple ) or len (parameters ) != 2 :
13481326 raise TypeError ("Callable must be used as "
@@ -1384,7 +1362,7 @@ class Callable(extra=collections_abc.Callable, metaclass=CallableMeta):
13841362 __slots__ = ()
13851363
13861364 def __new__ (cls , * args , ** kwds ):
1387- if _geqv ( cls , Callable ) :
1365+ if cls . _gorg is Callable :
13881366 raise TypeError ("Type Callable cannot be instantiated; "
13891367 "use a non-abstract subclass instead" )
13901368 return _generic_new (cls .__next_in_mro__ , cls , * args , ** kwds )
@@ -1568,7 +1546,7 @@ def no_type_check(arg):
15681546 if isinstance (arg , type ):
15691547 arg_attrs = arg .__dict__ .copy ()
15701548 for attr , val in arg .__dict__ .items ():
1571- if val in arg .__bases__ :
1549+ if val in arg .__bases__ + ( arg ,) :
15721550 arg_attrs .pop (attr )
15731551 for obj in arg_attrs .values ():
15741552 if isinstance (obj , types .FunctionType ):
@@ -1687,6 +1665,7 @@ def _get_protocol_attrs(self):
16871665 attr != '__annotations__' and
16881666 attr != '__weakref__' and
16891667 attr != '_is_protocol' and
1668+ attr != '_gorg' and
16901669 attr != '__dict__' and
16911670 attr != '__args__' and
16921671 attr != '__slots__' and
@@ -1892,7 +1871,7 @@ class List(list, MutableSequence[T], extra=list):
18921871 __slots__ = ()
18931872
18941873 def __new__ (cls , * args , ** kwds ):
1895- if _geqv ( cls , List ) :
1874+ if cls . _gorg is List :
18961875 raise TypeError ("Type List cannot be instantiated; "
18971876 "use list() instead" )
18981877 return _generic_new (list , cls , * args , ** kwds )
@@ -1903,7 +1882,7 @@ class Deque(collections.deque, MutableSequence[T], extra=collections.deque):
19031882 __slots__ = ()
19041883
19051884 def __new__ (cls , * args , ** kwds ):
1906- if _geqv ( cls , Deque ) :
1885+ if cls . _gorg is Deque :
19071886 return collections .deque (* args , ** kwds )
19081887 return _generic_new (collections .deque , cls , * args , ** kwds )
19091888
@@ -1913,7 +1892,7 @@ class Set(set, MutableSet[T], extra=set):
19131892 __slots__ = ()
19141893
19151894 def __new__ (cls , * args , ** kwds ):
1916- if _geqv ( cls , Set ) :
1895+ if cls . _gorg is Set :
19171896 raise TypeError ("Type Set cannot be instantiated; "
19181897 "use set() instead" )
19191898 return _generic_new (set , cls , * args , ** kwds )
@@ -1923,7 +1902,7 @@ class FrozenSet(frozenset, AbstractSet[T_co], extra=frozenset):
19231902 __slots__ = ()
19241903
19251904 def __new__ (cls , * args , ** kwds ):
1926- if _geqv ( cls , FrozenSet ) :
1905+ if cls . _gorg is FrozenSet :
19271906 raise TypeError ("Type FrozenSet cannot be instantiated; "
19281907 "use frozenset() instead" )
19291908 return _generic_new (frozenset , cls , * args , ** kwds )
@@ -2014,7 +1993,7 @@ class Dict(dict, MutableMapping[KT, VT], extra=dict):
20141993 __slots__ = ()
20151994
20161995 def __new__ (cls , * args , ** kwds ):
2017- if _geqv ( cls , Dict ) :
1996+ if cls . _gorg is Dict :
20181997 raise TypeError ("Type Dict cannot be instantiated; "
20191998 "use dict() instead" )
20201999 return _generic_new (dict , cls , * args , ** kwds )
@@ -2026,7 +2005,7 @@ class DefaultDict(collections.defaultdict, MutableMapping[KT, VT],
20262005 __slots__ = ()
20272006
20282007 def __new__ (cls , * args , ** kwds ):
2029- if _geqv ( cls , DefaultDict ) :
2008+ if cls . _gorg is DefaultDict :
20302009 return collections .defaultdict (* args , ** kwds )
20312010 return _generic_new (collections .defaultdict , cls , * args , ** kwds )
20322011
@@ -2036,7 +2015,7 @@ class Counter(collections.Counter, Dict[T, int], extra=collections.Counter):
20362015 __slots__ = ()
20372016
20382017 def __new__ (cls , * args , ** kwds ):
2039- if _geqv ( cls , Counter ) :
2018+ if cls . _gorg is Counter :
20402019 return collections .Counter (* args , ** kwds )
20412020 return _generic_new (collections .Counter , cls , * args , ** kwds )
20422021
@@ -2051,7 +2030,7 @@ class ChainMap(collections.ChainMap, MutableMapping[KT, VT],
20512030 __slots__ = ()
20522031
20532032 def __new__ (cls , * args , ** kwds ):
2054- if _geqv ( cls , ChainMap ) :
2033+ if cls . _gorg is ChainMap :
20552034 return collections .ChainMap (* args , ** kwds )
20562035 return _generic_new (collections .ChainMap , cls , * args , ** kwds )
20572036
@@ -2070,7 +2049,7 @@ class Generator(Iterator[T_co], Generic[T_co, T_contra, V_co],
20702049 __slots__ = ()
20712050
20722051 def __new__ (cls , * args , ** kwds ):
2073- if _geqv ( cls , Generator ) :
2052+ if cls . _gorg is Generator :
20742053 raise TypeError ("Type Generator cannot be instantiated; "
20752054 "create a subclass instead" )
20762055 return _generic_new (_G_base , cls , * args , ** kwds )
0 commit comments