False positive for Union[type, ...] and inspect.isclass()
オープン
まだ誰も着手していません。
bug
topic-type-narrowing
- 主要言語
- Python
- スター
- 20.6k
- フォーク
- 3.3k
- PR マージ指標
- PR 指標を取得中
説明
Bug Report
When a variable's type is declared as a union that includes type (or typing.Type[...]), mypy does not take into account whether usage of that variable occurs inside of an if inspect.isclass(...) conditional block, leading to false positives.
To Reproduce
Python code
from inspect import isclass
registry: dict[str, type] = {}
def decorator_factory(arg: str | type):
if isclass(arg):
registry[arg.__name__.lower()] = arg
return arg
else:
def decorator(cls: type):
registry[arg] = cls
return cls
return decorator
@decorator_factory
class Foo:
pass
@decorator_factory("alt")
class Bar:
pass
Expected Behavior**
mypy reports no errors
Actual Behavior
main.py:11: error: Invalid index type "str | type" for "dict[str, type]"; expected type "str" [index]
Found 1 error in 1 file (checked 1 source file)
Workaround
Using typing.cast to narrow the union explicitly.
Python code
from inspect import isclass
from typing import cast, TYPE_CHECKING
registry: dict[str, type] = {}
def decorator_factory(arg: str | type):
if isclass(arg):
registry[arg.__name__.lower()] = arg
return arg
else:
if TYPE_CHECKING:
arg = cast(str, arg)
def decorator(cls: type):
registry[arg] = cls
return cls
return decorator
@decorator_factory
class Foo:
pass
@decorator_factory("alt")
class Bar:
pass
Your Environment
- Mypy version used: 1.7.1
- Mypy command-line flags: (mypy-play defaults)
- Mypy configuration options from
mypy.ini(and other config files): (mypy-play defaults) - Python version used: 3.12
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
まず、リンクされた reproducer を mypy で実行し、報告されたエラーを inspect.isclass() と Union[type, ...] に関する期待される動作と比較します。次に、inspect.isclass の型絞り込みの経路を追跡し、reproducer の回帰テストカバレッジを追加します。cast による回避策なしで mypy がエラーを報告しないことを確認します。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- devtools
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 38/100