@@ -1343,14 +1343,14 @@ def _no_init(self, *args, **kwargs):
13431343 raise TypeError ('Protocols cannot be instantiated' )
13441344
13451345
1346- def _allow_reckless_class_checks ():
1346+ def _allow_reckless_class_checks (depth = 3 ):
13471347 """Allow instance and class checks for special stdlib modules.
13481348
13491349 The abc and functools modules indiscriminately call isinstance() and
13501350 issubclass() on the whole MRO of a user class, which may contain protocols.
13511351 """
13521352 try :
1353- return sys ._getframe (3 ).f_globals ['__name__' ] in ['abc' , 'functools' ]
1353+ return sys ._getframe (depth ).f_globals ['__name__' ] in ['abc' , 'functools' ]
13541354 except (AttributeError , ValueError ): # For platforms without _getframe().
13551355 return True
13561356
@@ -1370,6 +1370,14 @@ class _ProtocolMeta(ABCMeta):
13701370 def __instancecheck__ (cls , instance ):
13711371 # We need this method for situations where attributes are
13721372 # assigned in __init__.
1373+ if (
1374+ getattr (cls , '_is_protocol' , False ) and
1375+ not getattr (cls , '_is_runtime_protocol' , False ) and
1376+ not _allow_reckless_class_checks (depth = 2 )
1377+ ):
1378+ raise TypeError ("Instance and class checks can only be used with"
1379+ " @runtime_checkable protocols" )
1380+
13731381 if ((not getattr (cls , '_is_protocol' , False ) or
13741382 _is_callable_members_only (cls )) and
13751383 issubclass (instance .__class__ , cls )):
0 commit comments