python / python/mypy

Type is lost after merge with `Union[Any, None]`

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

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

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

説明

Bug Report

from typing import Any

def func(d: dict[int, Any]) -> None:
    x: int | None
    x = d.get(1)
    reveal_type(x)  # typing is lost -> Union[Any, None]

d.get get's correctly inferred as Any | None. However, merging the existing type int | None with Any | None results in Any | None. I.e. mypy looses the original type information. That is unexpected.

Comparing it to a type merge with just Any:

def f(a: Any) -> None:
    x: int | None
    x = a
    reveal_type(x)  # int | None

In this case x retains the type information, as expected.

--
Another example which doesn't rely on dict.get

def g(a: Any | None) -> None:
    x: int | None
    x = a
    reveal_type(x)  # typing is lost -> Union[Any, None]

Expected Behavior

Mypy should retain the original type information even after merging it with Any | None.

Your Environment

  • Mypy version used: 0.971

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

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

はじめの一歩

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

調査の方向性

issue にある 3 つの再現関数から始め、mypy と reveal_type を使って実行し、現在の動作を確認します。既存の int | None 型の値と Any | None を組み合わせる場合の、型のマージと代入のロジックを追跡します。完了条件は、示されているすべての例で推論される型が int | None のままであり、これらのケースに対するリグレッションカバレッジがあることです。

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

評価

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

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

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