[New-bugs-announce] [issue38908] Troubles with @runtime_checkable protocols

Ivan Levkivskyi report at bugs.python.org
Sun Nov 24 12:39:56 EST 2019


New submission from Ivan Levkivskyi <levkivskyi at gmail.com>:

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?

----------
components: Library (Lib)
messages: 357400
nosy: gvanrossum, levkivskyi
priority: normal
severity: normal
status: open
title: Troubles with @runtime_checkable protocols
type: behavior
versions: Python 3.8, Python 3.9

_______________________________________
Python tracker <report at bugs.python.org>
<https://bugs.python.org/issue38908>
_______________________________________


More information about the New-bugs-announce mailing list