Using mypy, why does `tuple[int]` get error?

Using mypy,`list[int]`doesn’t get error as shown below:

x: list[int] = [0, 1, 2, 3, 4]
# No error

But using mypy,`tuple[int]`gets the error as shown below:

x: tuple[int] = (0, 1, 2, 3, 4)
# Error

error: Incompatible types in assignment (expression has type “tuple[int, int, int, int, int]”, variable has type “tuple[int]”)

So, why doestuple[int]get the error?

If you want a variable-length tuple the correct annotation would be tuple[int, ...]. tuple[int] would be a tuple with exactly one int member.

Also see Tuples — typing documentation.

2 Likes

Why doesn’t list[int] need`‘...'`while only tuple[int] needs `‘...'`?

Because tuple[int] means something different. It means exactly (1,), not (1, 2, 3, …).

Tuples and lists are very different structures. Lists are homogenous (all elements are the same type), so the element type only needs to be specified once. Tuples can be heterogenous (elements can be of different types), so all of the element types need to be specified.

1 Like

I would have thought the reason lies in mutability.

A list can change via append and other methods, so the ... would be redundant information. Whereas a tuple does not mutate and ... can be used if you need to type-hint an arbitrary-length tuple. E.g:

def my_function(input: tuple[str|int, ...]):
    ...
1 Like

list is not necessarily homogenous. There is nothing incorrect or invalid with a list of [1, ‘a’, set(), dict()]. The reason is, as @mbyrnepr2 says, mutability. When I define a tuple I know exactly how long it is. If the length of the tuple might change from invocation to invocation I need to declare that. A list is a mutable object with a variable length so the most I can do is declare the data type(s) it will contain for type checking.

2 Likes