-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Description
Bug Report
Considering the following piece of code:
NestedLines = tuple
def print_lines(ls: NestedLines, indent: int = 0) -> None:
for line in ls:
match line:
case NestedLines():
print_lines(line, indent+4)
case _:
print(" "*indent + str(line))
print_lines((1, [2,3,4], (5, [6,7]), 8))
mypy --strict
complains at the case NestedLines()
saying "Class pattern class must not be a type alias with type parameters". However, given that a class pattern has to be a type object (and not a genericalias object), there's no way to resolve this that makes both the runtime and the typechecker happy.
For example, if you define
from typing import TypeAlias
NestedLines: TypeAlias = tuple["NestedLines | object"]
Running this will result in a TypeError: called match pattern must be a class
.
Expected Behavior
Program should both typecheck AND print the following when run:
1
[2, 3, 4]
5
[6, 7]
8
Not sure what's the best solution... pyright is happy about this example, so perhaps some checks need to be removed/relaxed. In the (more complicated real usecase) code where I came accross this, the x = tuple
was not intended as an alias, but there's no way to tell mypy "this is just an assignment", which I think would cmake more explicit that its usage in the match statement is not related to aliases.
The documentation says "Because the distinction between an unannotated variable and a type alias is implicit, ambiguous or incorrect type alias declarations default to defining a normal variable instead of a type alias."; I would say this case is ambiguous/incorrect as a typealias, so it should be considered a regular variable definition. But I even tried NestedLines: type = tuple
, and it is still taken as an alias.
A possible desired behaviour would be: if the value used in a match statement is an "ambiguous" typealias (not defined with a TypeAlias/TypeStatement), and has actually been set to a type object (not a generic alias like tuple[Any]), do not emit an error
Actual Behavior
$ python3.12 -m mypy --strict example.py
example.py:1: error: Missing type parameters for generic type "tuple" [type-arg]
example.py:6: error: Class pattern class must not be a type alias with type parameters [misc]
Found 2 errors in 1 file (checked 1 source file)
If I change it to a typealias
$ python3.12 example.py
Traceback (most recent call last):
File "/home/dmoissetdees/training-materials/unix/labs/whale/template/example.py", line 12, in <module>
print_lines((1, [2,3,4], (5, [6,7]), 8))
File "/home/dmoissetdees/training-materials/unix/labs/whale/template/example.py", line 7, in print_lines
case NestedLines():
^^^^^^^^^^^^^
TypeError: called match pattern must be a class
And mypy still complains (in this case I think correctly):
example.py:7: error: Class pattern class must not be a type alias with type parameters [misc]
Your Environment
- Mypy version used: mypy 1.8.0 (compiled: yes)
- Mypy command-line flags: --strict
- Mypy configuration options from
mypy.ini
(and other config files): none - Python version used: 3.12.2