Match exhaustiveness with class inheriting from tuple #17139
Description
Bug Report
If I run:
# Run the type checking with "mypy --strict foo.py"
class Add(tuple[int,int]):
pass
class Const(int):
pass
Expr = Add | Const
def my_eval(e : Expr) -> int:
match e:
case Add((a,b)):
return a + b
case Const(x):
return x
print(my_eval(Const(42)))
print(my_eval(Add((42,45))))
with python 11, it runs just fine. But if I run mypy
on this file (with or without strict), I get an error:
$ mypy --strict foo.py
foo.py:11: error: Missing return statement [return]
Found 1 error in 1 file (checked 1 source file)
Usually I get this error when a branch in a match is forgotten… but here I have covered all cases.
Note that the following code does work, but I would prefer the above code that is less verbose and error prone:
# Run the type checking with "mypy --strict foo.py"
class Add:
left: int
right: int
def __init__(self, left:int, right:int):
self.left = left
self.right = right
class Const:
val: int
def __init__(self, val:int):
self.val = val
Expr = Add | Const
def my_eval(e : Expr) -> int:
match e:
case Add():
return e.left + e.right
case Const():
return e.val
print(my_eval(Const(42)))
print(my_eval(Add(42,45)))
To Reproduce
Gist URL: https://gist.github.com/mypy-play/5e61f50c5c61bf4c90b5e1403f2b6be1
Playground URL: https://mypy-play.net/?mypy=latest&python=3.12&gist=5e61f50c5c61bf4c90b5e1403f2b6be1
Expected Behavior
I would expect this to type fine. I need this for instance in this context https://stackoverflow.com/questions/78345055/python-static-type-checking-for-union-type-and-pattern-maching/78345797#78345797
I would also expect this to work when using forward reference:
# Run the type checking with "mypy --strict foo.py"
class Add(tuple['Expr','Expr']):
pass
class Const(int):
pass
Expr = Add | Const
def my_eval(e : Expr) -> int:
match e:
case Add((a,b)):
return my_eval(a) + my_eval(b)
case Const(x):
return x
print(my_eval(Const(42)))
print(my_eval(Add((Const(42),Const(45)))))
Actual Behavior
I get an error.
Your Environment
- Mypy version used: 1.5.1
- Mypy command-line flags: None or
strict
- Mypy configuration options from
mypy.ini
(and other config files): none - Python version used: 3.11.8