python / python/mypy

False negative when declaring a class with a literal string base, which could refer to a forward-reference type alias

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

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

bug
主要言語
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

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

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

はじめの一歩

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

調査の方向性

まず、mypy 0.981 または master を使い、コマンドラインフラグなしで mypy-play.net の 2 つのクラスベースの例を再現します。前方参照と解決できないリテラル文字列ベースについての診断を比較し、その後 TYPE_CHECKING の外側と内側で意図されている動作を判断します。関連するケースが合意された無効なベースのエラーを報告し、妥当な前方参照にリグレッションを起こさなければ完了です。

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

評価

技術スタック
python
領域
compilers
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

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

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