Closed
Description
openedon Dec 15, 2023
Describe the bug
See also: python/mypy#16286
Narrowing a type of a tagged union that consists of classes does not work with match
statement, but does work with if
s.
Code or Screenshots
from typing import Literal
class A:
tag: Literal["a"]
name: str
class B:
tag: Literal["b"]
num: int
def f(d: A | B) -> None:
if d.tag == "a":
reveal_type(d) # Type of "d" is "A"
elif d.tag == "b":
reveal_type(d) # Type of "d" is "B"
def g(d: A | B) -> None:
match d.tag:
case "a":
reveal_type(d) # Type of "d" is "A | B"
case "b":
reveal_type(d) # Type of "d" is "A | B"
(example taken from python/mypy#16286 (comment).)
VS Code extension or command-line
$ pyright --version
pyright 1.1.341
Little off-topic
Unlike mypy, pyright does correctly handle the TypedDict
version:
from typing import Literal, TypedDict
class A(TypedDict):
tag: Literal["a"]
name: str
class B(TypedDict):
tag: Literal["b"]
num: int
def f(d: A | B) -> None:
if d["tag"] == "a":
reveal_type(d) # Type of "d" is "A"
elif d["tag"] == "b":
reveal_type(d) # Type of "d" is "B"
def g(d: A | B) -> None:
match d["tag"]:
case "a":
reveal_type(d) # Type of "d" is "A"
case "b":
reveal_type(d) # Type of "d" is "B"
(example taken from python/mypy#16286 (comment).)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment