@@ -1079,14 +1079,14 @@ def _no_init(self, *args, **kwargs):
1079
1079
raise TypeError ('Protocols cannot be instantiated' )
1080
1080
1081
1081
1082
- def _allow_reckless_class_cheks ( ):
1082
+ def _allow_reckless_class_checks ( depth = 3 ):
1083
1083
"""Allow instance and class checks for special stdlib modules.
1084
1084
1085
1085
The abc and functools modules indiscriminately call isinstance() and
1086
1086
issubclass() on the whole MRO of a user class, which may contain protocols.
1087
1087
"""
1088
1088
try :
1089
- return sys ._getframe (3 ).f_globals ['__name__' ] in ['abc' , 'functools' ]
1089
+ return sys ._getframe (depth ).f_globals ['__name__' ] in ['abc' , 'functools' ]
1090
1090
except (AttributeError , ValueError ): # For platforms without _getframe().
1091
1091
return True
1092
1092
@@ -1106,6 +1106,14 @@ class _ProtocolMeta(ABCMeta):
1106
1106
def __instancecheck__ (cls , instance ):
1107
1107
# We need this method for situations where attributes are
1108
1108
# assigned in __init__.
1109
+ if (
1110
+ getattr (cls , '_is_protocol' , False ) and
1111
+ not getattr (cls , '_is_runtime_protocol' , False ) and
1112
+ not _allow_reckless_class_checks (depth = 2 )
1113
+ ):
1114
+ raise TypeError ("Instance and class checks can only be used with"
1115
+ " @runtime_checkable protocols" )
1116
+
1109
1117
if ((not getattr (cls , '_is_protocol' , False ) or
1110
1118
_is_callable_members_only (cls )) and
1111
1119
issubclass (instance .__class__ , cls )):
@@ -1168,12 +1176,12 @@ def _proto_hook(other):
1168
1176
1169
1177
# First, perform various sanity checks.
1170
1178
if not getattr (cls , '_is_runtime_protocol' , False ):
1171
- if _allow_reckless_class_cheks ():
1179
+ if _allow_reckless_class_checks ():
1172
1180
return NotImplemented
1173
1181
raise TypeError ("Instance and class checks can only be used with"
1174
1182
" @runtime_checkable protocols" )
1175
1183
if not _is_callable_members_only (cls ):
1176
- if _allow_reckless_class_cheks ():
1184
+ if _allow_reckless_class_checks ():
1177
1185
return NotImplemented
1178
1186
raise TypeError ("Protocols with non-method members"
1179
1187
" don't support issubclass()" )
0 commit comments