Message357400
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? |
|
Date |
User |
Action |
Args |
2019-11-24 17:39:56 | levkivskyi | set | recipients:
+ levkivskyi, gvanrossum |
2019-11-24 17:39:56 | levkivskyi | set | messageid: <1574617196.5.0.297633036854.issue38908@roundup.psfhosted.org> |
2019-11-24 17:39:56 | levkivskyi | link | issue38908 messages |
2019-11-24 17:39:55 | levkivskyi | create | |
|