python / python/mypy

Allow unsafe overrides in sub-subclasses that are compatible with subclass

オープン
#12,372 コメント 3 件 リアクション 6 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

feature topic-inheritance
主要言語
Python
スター
20.6k
フォーク
3.3k
PR マージ指標
PR 指標を取得中

説明

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.

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

この issue にはソースファイルもテストも記載されていません。まず A/B/C の例を再現し、サブクラスのメソッドに対する mypy の override チェックを追跡してください。完了条件は、B に基づいて C の互換性のある override が受け入れられ、B の明示的に無視された非互換性が引き続き抑制されることです。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
python
領域
devtools
issue の種類
機能追加
難易度
5/5
見積もり時間
1週間以上
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。