-
Notifications
You must be signed in to change notification settings - Fork 219
Closed
astral-sh/ruff
#23545Milestone
Description
Summary
ty fails to narrow a PEP 695 type alias through an if x in (...) containment check, resulting in @Todo instead of the correctly narrowed type. The same code works with a bare Literal assignment or TypeAlias.
Minimal repro
Playground link: https://play.ty.dev/7b5eee9d-35c1-4f5c-8b04-a570fdd34cf4
from typing import Literal, assert_never
type Foo = Literal["a", "b", "c", "d"]
def f(x: Foo) -> str:
if x in ("a", "b"):
return "AB"
match x:
case "c":
return "C"
case "d":
return "D"
case _ as never:
assert_never(never) # error: Inferred type of argument is `@Todo`error[type-assertion-failure]: Argument does not have asserted type `Never`
--> main.py:15:13
|
13 | return "D"
14 | case _ as never:
15 | assert_never(never)
| ^^^^^^^^^^^^^-----^
| |
| Inferred type of argument is `@Todo`
What works
All of the following pass without errors:
# 1. Bare Literal (no alias) + if-in: OK
Bar = Literal["a", "b", "c", "d"]
def g(x: Bar) -> str:
if x in ("a", "b"):
return "AB"
match x:
case "c":
return "C"
case "d":
return "D"
case _ as never:
assert_never(never) # OK
# 2. PEP 695 + match only (no if-in): OK
def h(x: Foo) -> str:
match x:
case "a":
return "A"
case "b":
return "B"
case "c":
return "C"
case "d":
return "D"
case _ as never:
assert_never(never) # OK
# 3. PEP 695 + if == (not if-in): OK
def i(x: Foo) -> str:
if x == "a":
return "A"
match x:
case "b":
return "B"
case "c":
return "C"
case "d":
return "D"
case _ as never:
assert_never(never) # OKVersion
ty 0.0.18 (7516727 2026-02-20)
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels