@@ -856,19 +856,6 @@ def _next_in_mro(cls):
856
856
return next_in_mro
857
857
858
858
859
- def _valid_for_check (cls ):
860
- """An internal helper to prohibit isinstance([1], List[str]) etc."""
861
- if cls is Generic :
862
- raise TypeError ("Class %r cannot be used with class "
863
- "or instance checks" % cls )
864
- if (
865
- cls .__origin__ is not None and
866
- sys ._getframe (3 ).f_globals ['__name__' ] not in ['abc' , 'functools' ]
867
- ):
868
- raise TypeError ("Parameterized generics cannot be used with class "
869
- "or instance checks" )
870
-
871
-
872
859
def _make_subclasshook (cls ):
873
860
"""Construct a __subclasshook__ callable that incorporates
874
861
the associated __extra__ class in subclass checks performed
@@ -879,7 +866,6 @@ def _make_subclasshook(cls):
879
866
# Registered classes need not be checked here because
880
867
# cls and its extra share the same _abc_registry.
881
868
def __extrahook__ (subclass ):
882
- _valid_for_check (cls )
883
869
res = cls .__extra__ .__subclasshook__ (subclass )
884
870
if res is not NotImplemented :
885
871
return res
@@ -894,7 +880,6 @@ def __extrahook__(subclass):
894
880
else :
895
881
# For non-ABC extras we'll just call issubclass().
896
882
def __extrahook__ (subclass ):
897
- _valid_for_check (cls )
898
883
if cls .__extra__ and issubclass (subclass , cls .__extra__ ):
899
884
return True
900
885
return NotImplemented
@@ -981,6 +966,7 @@ def __new__(cls, name, bases, namespace,
981
966
# remove bare Generic from bases if there are other generic bases
982
967
if any (isinstance (b , GenericMeta ) and b is not Generic for b in bases ):
983
968
bases = tuple (b for b in bases if b is not Generic )
969
+ namespace .update ({'__origin__' : origin , '__extra__' : extra })
984
970
self = super ().__new__ (cls , name , bases , namespace , _root = True )
985
971
986
972
self .__parameters__ = tvars
@@ -989,8 +975,6 @@ def __new__(cls, name, bases, namespace,
989
975
self .__args__ = tuple (... if a is _TypingEllipsis else
990
976
() if a is _TypingEmpty else
991
977
a for a in args ) if args else None
992
- self .__origin__ = origin
993
- self .__extra__ = extra
994
978
# Speed hack (https://github.com/python/typing/issues/196).
995
979
self .__next_in_mro__ = _next_in_mro (self )
996
980
# Preserve base classes on subclassing (__bases__ are type erased now).
@@ -1009,13 +993,49 @@ def __new__(cls, name, bases, namespace,
1009
993
self .__subclasshook__ = _make_subclasshook (self )
1010
994
if isinstance (extra , abc .ABCMeta ):
1011
995
self ._abc_registry = extra ._abc_registry
996
+ self ._abc_cache = extra ._abc_cache
997
+ elif origin is not None :
998
+ self ._abc_registry = origin ._abc_registry
999
+ self ._abc_cache = origin ._abc_cache
1012
1000
1013
1001
if origin and hasattr (origin , '__qualname__' ): # Fix for Python 3.2.
1014
1002
self .__qualname__ = origin .__qualname__
1015
1003
self .__tree_hash__ = (hash (self ._subs_tree ()) if origin else
1016
1004
super (GenericMeta , self ).__hash__ ())
1017
1005
return self
1018
1006
1007
+ # _abc_negative_cache and _abc_negative_cache_version
1008
+ # realised as descriptors, since GenClass[t1, t2, ...] always
1009
+ # share subclass info with GenClass.
1010
+ # This is an important memory optimization.
1011
+ @property
1012
+ def _abc_negative_cache (self ):
1013
+ if isinstance (self .__extra__ , abc .ABCMeta ):
1014
+ return self .__extra__ ._abc_negative_cache
1015
+ return _gorg (self )._abc_generic_negative_cache
1016
+
1017
+ @_abc_negative_cache .setter
1018
+ def _abc_negative_cache (self , value ):
1019
+ if self .__origin__ is None :
1020
+ if isinstance (self .__extra__ , abc .ABCMeta ):
1021
+ self .__extra__ ._abc_negative_cache = value
1022
+ else :
1023
+ self ._abc_generic_negative_cache = value
1024
+
1025
+ @property
1026
+ def _abc_negative_cache_version (self ):
1027
+ if isinstance (self .__extra__ , abc .ABCMeta ):
1028
+ return self .__extra__ ._abc_negative_cache_version
1029
+ return _gorg (self )._abc_generic_negative_cache_version
1030
+
1031
+ @_abc_negative_cache_version .setter
1032
+ def _abc_negative_cache_version (self , value ):
1033
+ if self .__origin__ is None :
1034
+ if isinstance (self .__extra__ , abc .ABCMeta ):
1035
+ self .__extra__ ._abc_negative_cache_version = value
1036
+ else :
1037
+ self ._abc_generic_negative_cache_version = value
1038
+
1019
1039
def _get_type_vars (self , tvars ):
1020
1040
if self .__origin__ and self .__parameters__ :
1021
1041
_get_type_vars (self .__parameters__ , tvars )
@@ -1114,6 +1134,17 @@ def __getitem__(self, params):
1114
1134
extra = self .__extra__ ,
1115
1135
orig_bases = self .__orig_bases__ )
1116
1136
1137
+ def __subclasscheck__ (self , cls ):
1138
+ if self .__origin__ is not None :
1139
+ if sys ._getframe (1 ).f_globals ['__name__' ] not in ['abc' , 'functools' ]:
1140
+ raise TypeError ("Parameterized generics cannot be used with class "
1141
+ "or instance checks" )
1142
+ return False
1143
+ if self is Generic :
1144
+ raise TypeError ("Class %r cannot be used with class "
1145
+ "or instance checks" % self )
1146
+ return super ().__subclasscheck__ (cls )
1147
+
1117
1148
def __instancecheck__ (self , instance ):
1118
1149
# Since we extend ABC.__subclasscheck__ and
1119
1150
# ABC.__instancecheck__ inlines the cache checking done by the
0 commit comments