mirror of
https://github.com/python/cpython.git
synced 2025-10-09 16:34:44 +00:00
gh-104555: Runtime-checkable protocols: Don't let previous calls to isinstance()
influence whether issubclass()
raises an exception (#104559)
Co-authored-by: Carl Meyer <carl@oddbird.net>
This commit is contained in:
parent
2f369cafee
commit
b27fe67f3c
3 changed files with 96 additions and 7 deletions
|
@ -1775,8 +1775,8 @@ del _pickle_psargs, _pickle_pskwargs
|
|||
|
||||
|
||||
class _ProtocolMeta(ABCMeta):
|
||||
# This metaclass is really unfortunate and exists only because of
|
||||
# the lack of __instancehook__.
|
||||
# This metaclass is somewhat unfortunate,
|
||||
# but is necessary for several reasons...
|
||||
def __init__(cls, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
cls.__protocol_attrs__ = _get_protocol_attrs(cls)
|
||||
|
@ -1786,6 +1786,17 @@ class _ProtocolMeta(ABCMeta):
|
|||
callable(getattr(cls, attr, None)) for attr in cls.__protocol_attrs__
|
||||
)
|
||||
|
||||
def __subclasscheck__(cls, other):
|
||||
if (
|
||||
getattr(cls, '_is_protocol', False)
|
||||
and not cls.__callable_proto_members_only__
|
||||
and not _allow_reckless_class_checks(depth=2)
|
||||
):
|
||||
raise TypeError(
|
||||
"Protocols with non-method members don't support issubclass()"
|
||||
)
|
||||
return super().__subclasscheck__(other)
|
||||
|
||||
def __instancecheck__(cls, instance):
|
||||
# We need this method for situations where attributes are
|
||||
# assigned in __init__.
|
||||
|
@ -1869,11 +1880,6 @@ class Protocol(Generic, metaclass=_ProtocolMeta):
|
|||
raise TypeError("Instance and class checks can only be used with"
|
||||
" @runtime_checkable protocols")
|
||||
|
||||
if not cls.__callable_proto_members_only__ :
|
||||
if _allow_reckless_class_checks():
|
||||
return NotImplemented
|
||||
raise TypeError("Protocols with non-method members"
|
||||
" don't support issubclass()")
|
||||
if not isinstance(other, type):
|
||||
# Same error message as for issubclass(1, int).
|
||||
raise TypeError('issubclass() arg 1 must be a class')
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue