python / python/mypy

`match-case` does not work correctly with Literals vs Enums

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

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

bug topic-enum topic-literal-types topic-match-statement
主要言語
Python
スター
20.6k
フォーク
3.3k
PR マージ指標
PR 指標を取得中

説明

from enum import StrEnum
from typing import Literal, assert_never, reveal_type

class Color(StrEnum):
    RED = "r"
    GREEN = "g"
    BLUE = "b"

def test_literal_as_enum(x: Literal["g"] = "g") -> None:
    match x:
        case Color.RED:
            assert_never(x)
        case Color.GREEN:
            reveal_type(x)
        case Color.BLUE:
            assert_never(x)
        case _:
            assert_never(x)

def test_enum_as_litearl(y: Literal[Color.BLUE] = Color.BLUE) -> None:
    match y:
        case "r":
            assert_never(y)
        case "g":
            assert_never(y)
        case "b":
            reveal_type(y)
        case _:
            assert_never(y)

test_literal_as_enum()  # selects green branch at runtim
test_enum_as_litearl()  # selects blue branch at runtime

Expected no errors, but mypy-playground reports

main.py:14: error: Statement is unreachable  [unreachable]
main.py:18: error: Argument 1 to "assert_never" has incompatible type "Literal['g']"; expected "Never"  [arg-type]
main.py:27: error: Statement is unreachable  [unreachable]
main.py:29: error: Argument 1 to "assert_never" has incompatible type "Literal[Color.BLUE]"; expected "Never"  [arg-type]

Related: https://discuss.python.org/t/amend-pep-586-to-make-enum-values-subtypes-of-literal/59456
Also: #16327, #17162, #19616 (but none of these is specifically about match-case)

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

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

はじめの一歩

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

調査の方向性

まず、Python 3.12、master、warn-unreachable を有効にして、リンクされた mypy-playground の例で報告されたエラーを再現します。次に、Literal 文字列と StrEnum メンバーに対する match-case の絞り込みを追跡し、示されている assert_never と reveal_type のチェックを完了条件として使用します。例ではエラーが発生しないようにします。

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

評価

技術スタック
python
領域
compilers
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
明確に書かれている
初心者へのやさしさ
42/100

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

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