Search code examples
pythonpycharmtype-hinting

Typehint tuple of ints gives IDE warning. List of ints does not. Why?


Why does the typehint tuple[int] behave differently from list[int]?

This gives me a visual warning:

def func_with_tuple(x: tuple[int]):
    pass
    
    
func_with_tuple((1, 2, 3))

#                  ^
# warning _________|

Expected type 'tuple[int]', got 'tuple[int, int, int]' instead

while this does not:

def func_with_list(x: list[int]):
        pass
    
    
func_with_list([1, 2, 3])

How should I typehint a tuple of ints then?


Solution

  • So, looking at PEP 484 where the Python type annotation system was defined, it states:

    Tuple, used by listing the element types, for example Tuple[int, int, str]. The empty tuple can be typed as Tuple[()]. Arbitrary-length homogeneous tuples can be expressed using one type and ellipsis, for example Tuple[int, ...]. (The ... here are part of the syntax, a literal ellipsis.)

    Note, that PEP uses typing.Tuple, which is currently deprecated in favor of tuple, but it still documents this same thing. So,

    tuple[int]
    

    Means *a length 1 tuple with an int.

    tuple objects and list objects are used differently. A list should be thought of as an arbitrary-sized, homogenous sequence. tuple objects are more like record types, fixed-size, with possibly heterogenous types. Hence, their type annotation has different semantics.

    So you either want:

    tuple[int, ...]
    

    Or

    tuple[int, int, int]