'How to annotate function that takes a tuple of variable length? (variadic tuple type annotation)
I have a function that takes a tuple of different lengths as an argument:
from typing import Tuple
def process_tuple(t: Tuple[str]):
# Do nasty tuple stuff
process_tuple(("a",))
process_tuple(("a", "b"))
process_tuple(("a", "b", "c"))
When I annotate function like mentioned above, I get these error messages
fool.py:9: error: Argument 1 to "process_tuple" has incompatible type "Tuple[str, str]"; expected "Tuple[str]"
fool.py:10: error: Argument 1 to "process_tuple" has incompatible type "Tuple[str, str, str]"; expected "Tuple[str]"
process_tuple really works with tuples and I use them as immutable lists of variable length. I haven't found any consensus on this topic on the internet, so I wonder how should I annotate this kind of input.
Solution 1:[1]
We can annotate variable-length homogeneous tuples using the ... literal (aka Ellipsis) like this:
def process_tuple(t: Tuple[str, ...]):
...
or for Python3.9+
def process_tuple(t: tuple[str, ...]):
...
After that, the errors should go away.
From the docs:
To specify a variable-length tuple of homogeneous type, use literal ellipsis, e.g.
Tuple[int, ...]. A plainTupleis equivalent toTuple[Any, ...], and in turn totuple.
Solution 2:[2]
In addition to the Ellipsis answer as posted by Azat you could make it more explicit by using @typing.overload or typing.Union
from typing import Tuple
@overload
def process_tuple(t: Tuple[str]):
# Do nasty tuple stuff
@overload
def process_tuple(t: Tuple[str, str]):
...
Or with the Union:
from typing import Tuple, Union
def process_tuple(t: Union[Tuple[str], Tuple[str, str], Tuple[str, str, str]]):
# Do nasty tuple stuff
Solution 3:[3]
Python 3.9+
Use tuple:
def process_tuple(t: tuple[str, ...]):
pass
Since Python 3.9, typing.Tuple is depreciated. The documentation for typing.Tuple states:
Deprecated since version 3.9: builtins.tuple now supports
[].
Python 3.8 and earlier
If you are on Python 3.8 or earlier, you should still use typing.Tuple:
from typing import Tuple
def process_tuple(t: Tuple[str, ...]):
pass
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | |
| Solution 3 |
