Allow unsafe overrides in sub-subclasses that are compatible with subclass
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Feature
When a subclass is implemented with unsafe method override, error can be suppressed with # type: ignore[override] comment. However, further subclassing requires this comment to be present in subclasses too.
Pitch
Suppose we have the following structure:
class A:
def foo(self) -> int: pass
class B(A):
def foo(self) -> str: pass # type: ignore[override]
class C(B):
def foo(self) -> str: pass
Currently mypy complains:
example.py:8: error: Return type "str" of "foo" incompatible with return type "int" in supertype "A"
But in reality we do expect that all B subclasses should implement foo with signature () -> str. For instance, it is useful when B is replacement for A with slightly different usage (when we don't want to replicate all internal logic - e.g. if it comes from third-party package). It takes care to override all methods that became incompatible after this change, and now B is consistent. Then we want to add some feature to B via subclassing while preserving its interface. All signatures are preserved, but mypy complains that we are incompatible with old base (A). I think that when unsafe override is explicitly ignored once, mypy should check new implementation against definitions in B, not in A, ignoring the fact that B has unsafe overrides. Actually now the checker reports errors that are explicitly ignored: we already took care to ignore that errors inside B.
Real world example: ModelChoiceField in Django inherits from ChoiceField (yeah, that's bad design decision, but I'm working on stubs and can't change the source). Incompatible part:
class ChoiceField(Field):
def to_python(self, data: Optional[Any]) -> str: ...
class ModelChoiceField(ChoiceField):
def to_python(self, data: Optional[Any]) -> Optional[Model]: ... # type: ignore[override]
When end Django user tries to subclass ModelChoiceField and implements to_python with same signature, user receives mypy error. However, this implementation is perfectly valid as long as direct superclass already defines that incompatible change.
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
The issue names no source files or tests. Start by reproducing the A/B/C example and trace mypy's override checking for subclass methods; done means C's compatible override is accepted based on B while B's explicitly ignored incompatibility remains suppressed.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100