False negative when declaring a class with a literal string base, which could refer to a forward-reference type alias
まだ誰も着手していません。
- 主要言語
- Python
- スター
- 20.6k
- フォーク
- 3.3k
- PR マージ指標
- PR 指標を取得中
説明
Bug Report
mypy interprets a literal string, which could refer to a forward-reference type alias, as a valid class base.
To Reproduce
The following example uses both a forward reference (class B1("A")) and a string which doesn't refer to anything (class B2("D")):
class B1("A"):
pass
b1: B1 = B1()
b1.a = "" # mypy: Incompatible types in assignment (expression has type "str", variable has type "int") [assignment]
class B2("D"): # mypy: Class cannot subclass value of type "Any" [misc] \
# mypy: Name "D" is not defined [name-defined]
pass
class A:
a: int
Expected Behavior
I expect the following snippet to show up if we're not under a typing.TYPE_CHECKING block:
class B1("A"): # mypy: Invalid base class "A" [misc] \
# mypy: See https://mypy.readthedocs.io/en/stable/common_issues.html#variables-vs-type-aliases \
# mypy: Variable "A" is not valid as a type [valid-type]
pass
EDIT: this is a more sensible expected error:
class B1("A"): # mypy: Invalid base class [misc]
pass
I can't gauge from PEP 613 whether or not this should should be OK (mypy doesn't show any errors, but FWIW pylance or pyright sees this as an error):
from __future__ import annotations
from typing import TYPE_CHECKING
if TYPE_CHECKING:
class B("A"): # pylance: Expected class type but received "Literal['A']" \
# pylance: Base class type is unknown, obscuring type of derived class
pass
class A:
pass
Your Environment
Tested on mypy-play.net:
- Mypy version used: 0.981 and
master - Mypy command-line flags: None
- Mypy configuration options from
mypy.ini(and other config files):show_error_codes = True - Python version used: 3.10
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず、mypy 0.981 または master を使い、コマンドラインフラグなしで mypy-play.net の 2 つのクラスベースの例を再現します。前方参照と解決できないリテラル文字列ベースについての診断を比較し、その後 TYPE_CHECKING の外側と内側で意図されている動作を判断します。関連するケースが合意された無効なベースのエラーを報告し、妥当な前方参照にリグレッションを起こさなければ完了です。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- compilers
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 35/100