How to annotate function that takes a tuple of variable length? (variadic tuple type annotation)
Solution 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 plainTuple
is equivalent toTuple[Any, ...]
, and in turn totuple
.
Solution 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
![Montreal](https://i.stack.imgur.com/nUMMY.png?s=256&g=1)
Comments
-
Montreal over 2 years
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. -
Montreal over 5 yearsI knew about it, but my tuples can be very lengthy, so it is not an option. Anyway, thank you.
-
Azat Ibrakov over 5 yearsbtw
overload
s should go before implementation -
Montreal over 5 yearsThis actually is a little bit counter-intuitive and counter-logical. If we assume that
List[str]
is okay for variable length lists, then whyTuple[str]
is not okay for variable length tuple? And(type(("a", "a")) == type(("a", "a", "a"))
yieldsTrue
. -
Azat Ibrakov over 5 years@Montreal: that's because
tuple
s andlist
s serve for different purposes:tuple
s are heterogeneous containers (like positional arguments to an arbitrary function or a single table record from RDBMS, or in math world -- elements of cartesian product of different sets (or a union of cartesian products), so each coordinate may have a different type, but their number is usually fixed), whilelist
s are homogeneous (like collection of same table records or a finite sequence of elements of some set) -
Azat Ibrakov over 5 years@Montreal: so
Tuple[str]
is a single-str
-objecttuple
, whileList[str]
is a collection of arbitrary number ofstr
objects