Union of `Never` can't be used
まだ誰も着手していません。
- 主要言語
- Python
- スター
- 20.6k
- フォーク
- 3.3k
- PR マージ指標
- PR 指標を取得中
説明
Bug Report
Functions which optionally take a value of Never type have impossible requirements placed on usages of that optional value.
To Reproduce
https://gist.github.com/mypy-play/a49d72bdacc179ffda5f69d8b66f41ff
from typing import Never
def blah(s: Never | str) -> None:
print(s + "hi")
Expected Behavior
The code type-checks. Since it is impossible for any variable to take a value of type Never, the type signature of blah is equivalent to str -> None. The function's body is valid when s is annotated with type str, so it should be valid when annotated with Never | str.
Actual Behavior
main.py:5: error: Unsupported left operand type for + ("Never") [operator]
main.py:5: note: Left operand is of type "Never | str"
Found 1 error in 1 file (checked 1 source file)
Your Environment
- Python 3.12
- MyPy 1.15.0, invocation as performed in the Playground
Background
Pyright appears to do the right thing here: it accepts this code.
I ran into this when implementing this pattern, which is me placing types around something I found untyped in the wild:
T = TypeVar("T", contravariant=True)
class _MyProtocol(Protocol[T]):
def _foo(self, arg: T | IO[str]) -> None: ...
try:
import foo
class _MyImpl(_MyProtocol[foo.Foo]):
def _foo(self, arg: foo.Foo | IO[str]) -> None:
# do something here
pass
MyType = _MyImpl
except ImportError:
class _MyImplNone(_MyProtocol[Never]):
def _foo(self, arg: Never | IO[str]) -> None:
# correctly assume arg is an IO[str] here
pass
MyType = _MyImplNone
That way, MyType has type _MyProtocol[foo.Foo] | _MyProtocol[Never], allowing a type-level discrimination of whether the foo functionality is present or not.
コントリビューションガイド
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
調査の方向性
Issue またはリンクされた mypy-play の例にある最小限の Python 再現コードから始め、報告された演算子エラーを、期待される str 相当の動作と比較します。型チェック中に Never を含むユニオンがどのように扱われるかを追跡し、その後、示された関数のカバレッジを追加して、Never オペランドエラーなしで mypy が受け入れることを確認します。
索引モデルが issue の本文から書いたものです。
評価
- 技術スタック
- python
- 領域
- devtools
- issue の種類
- バグ
- 難易度
- 4/5
- 見積もり時間
- 3〜5日
- 活発さ
- 停滞
- 明瞭さ
- おおむね明確
- 初心者へのやさしさ
- 42/100