Short version
tuple[int, ...]
is a valid type in python 3.9+ but mypy
rejects a type alias for that. E.g. consider:
Thing = tuple[int, ...]
This results in "error: Unexpected '...'
" (though python itself will load the module just fine).
Is this a bug in mypy
?
What should/can I do? I thought maybe I could just use NewType
instead but that fails in the same way.
Long version
Python 3.9 incorporates PEP 585, meaning we can use built-in types such as list
, set
and tuple
as generics; as such the versions in typing
are now deprecated (e.g. see docs for typing.Tuple).
mypy
0.800 introduced support for this, so now I can write the following and mypy
will type-check it correctly:
def foo(a: tuple[int, str]):
...
Now, tuple
(and typing.Tuple
) of course have a special form for homogenously-typed tuples of unknown length: tuple[int, ...]
; this works fine too:
def foo(a: tuple[int, ...]):
...
Handily, we can create aliases for types, so this works too:
from typing import Tuple
Thing = Tuple[int, ...]
def foo(a: Thing):
...
Unfortunately, the following (which puts together tuple
, the ...
form, and a type alias) does not work:
Thing = tuple[int, ...]
def foo(a: Thing):
...
Rather, this is rejected by mypy
(v0.812) with the message "error: Unexpected '...'
"
Python itself will load and run such a module just fine, however.
I haven't (yet) been able to find anything indicating that this shouldn't be possible. So:
Am I missing something? Is such a type alias in fact forbidden?
If not, is this a bug in
mypy
?Are there any better ways for working around this than just usingNewType
instead of an alias?I thought using
NewType
would work around this (with some extra work) but it seems to fail in exactly the same way. So right now there seems to be no way to write these types and keepmypy
happy.