This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author levkivskyi
Recipients gvanrossum, levkivskyi
Date 2019-11-24.17:39:55
SpamBayes Score -1.0
Marked as misclassified Yes
Message-id <1574617196.5.0.297633036854.issue38908@roundup.psfhosted.org>
In-reply-to
Content
The PEP 544 specifies that:

A protocol can be used as a second argument in isinstance() and issubclass() only if it is explicitly opt-in by @runtime_checkable decorator.

It is not specified exactly whether this should be enforced by static type checkers or at runtime. Currently it is enforced in both cases: mypy flags this as error, and a TypeError is raised at runtime.

There is however a problem with current runtime implementation: abc and functools modules may call issubclass() on non-runtime checkable protocols if they appear as explicit superclasses. This is currently solved by a sys._getframe() hack in  typing module.

The problem is that current solution is incomplete. For example, the TypeError is not raised in the case of non-method protocols:

>>> class P(Protocol):
...     x: int
... 
>>> 
>>> class C: ...
... 
>>> isinstance(C(), P)
False  # should be TypeError

I tried to fix it this morning but after an hour of attempts to tweak the existing hack I gave up. It looks like there are only two reasonable solutions:

* Don't enforce @typing.runtime_checkable at runtime, make it a type-checker-only feature (like @typing.final).
* Add a little helper to abc module that would skip classes in MRO for which C._is_protocol is True but C._is_runtime_protocol is False.

Any thoughts/preferences?
History
Date User Action Args
2019-11-24 17:39:56levkivskyisetrecipients: + levkivskyi, gvanrossum
2019-11-24 17:39:56levkivskyisetmessageid: <1574617196.5.0.297633036854.issue38908@roundup.psfhosted.org>
2019-11-24 17:39:56levkivskyilinkissue38908 messages
2019-11-24 17:39:55levkivskyicreate