Infer correct metaclass for protocols
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
A subclass of Protocol is also an ABC:
import abc
from typing import Protocol
class P(Protocol):
@abc.abstractmethod
def f(self) -> None: pass
class C(P):
pass
C() # TypeError: Can't instantiate abstract class C with abstract method f
However, mypy doesn't detect a metaclass conflict here:
from typing import Protocol
class Meta(type): pass
# Metaclass conflict at runtime, but no mypy error
class P(Protocol, metaclass=Meta): pass
At runtime this will generate a metaclass conflict:
Traceback (most recent call last):
File "/Users/jukka/src/mypy/t/t5.py", line 6, in <module>
class P(Protocol, metaclass=Meta): pass
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases
The actual metaclass is typing._ProtocolMeta:
>>> type(typing.Protocol)
<class 'typing._ProtocolMeta'>
Mypy should infer typing._ProtocolMeta as the metaclass of protocol classes. Maybe a custom metaclass should also be rejected, at least if it isn't a subclass of typing._ProtocolMeta.
More discussion here: https://github.com/python/typeshed/pull/9058
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by tracing mypy's metaclass inference for classes derived from Protocol, comparing it with Python's typing._ProtocolMeta behavior shown in the examples. The work is done when protocol classes are assigned the correct metaclass and an incompatible custom metaclass produces a metaclass-conflict diagnostic.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100