Paul <paul.d...@web.de> added the comment:

Regarding "At runtime, protocol classes will be simple ABCs." (PEP 544):
Unfortunately, this is currently not the case. Actually, there is an extra 
metaclass for protocols, solely to provide an __instancecheck__.
https://github.com/python/cpython/blob/3.9/Lib/typing.py#L1096

```
class _ProtocolMeta(ABCMeta):
    # This metaclass is really unfortunate and exists only because of
    # the lack of __instancehook__.
    def __instancecheck__(cls, instance):
        # We need this method for situations where attributes are
        # assigned in __init__.
        if ((not getattr(cls, '_is_protocol', False) or
                _is_callable_members_only(cls)) and
                issubclass(instance.__class__, cls)):
            return True
        if cls._is_protocol:
            if all(hasattr(instance, attr) and
                    # All *methods* can be blocked by setting them to None.
                    (not callable(getattr(cls, attr, None)) or
                     getattr(instance, attr) is not None)
                    for attr in _get_protocol_attrs(cls)):
                return True
        return super().__instancecheck__(instance)
```


Regarding "There is no intent to provide sophisticated runtime instance and 
class checks against protocol classes." (PEP 544):
I fully understand that. But a runtime instance check that simply checks, if a 
protocol member is there, is not sophisticated. And as you can see in the code 
above, these checks are already implemented, but unfortunately they don't cover 
the case reported by me in the initial message.

I could provide a patch for the _ProtocolMeta to cover the case reported by me. 
It's just a matter of a couple of lines. Even if the runtime isinstance() 
checking is not required to give the right answer, I think the right answer 
would be nice - at least for the most basic checks as "Are the protocol members 
there?"

Regarding "if you inherit from a protocol you are deemed to implement it":
I couldn't find a rule with this meaning in any of the typing PEPs.

But in my point of view, the problem is a different one:
If the instance to check is of a class implemented by another developer (maybe 
the class is from a third-party library - Bob's library), then such a rule does 
not help the first developer (Alice). Alice doesn't know anything about 
such-a-rule-compliance of Bob's classes. She just wants to check if the 
instance returned by one of Bob's functions complies to the protocol.

-------------

The bottom line is:
I'd like to provide a patch if you want me to.

If you think the current implementation must not be touched, then I would 
appreciate if the reported case could be documented. I could deliver a draft 
for this, as well. Currently, the last examples in the sections "Protocol 
members" and "Explicitly declaring implementation" in PEP 544 contain protocol 
members with no default implementation in the protocol, but do not suggest the 
behavior reported above.

----------

_______________________________________
Python tracker <rep...@bugs.python.org>
<https://bugs.python.org/issue43512>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe: 
https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com

Reply via email to