Search code examples
pythonpycharmpython-typing

Python type hints and `*args`


Assume I have a function like this:

def foo(*args):
    for x in args:
        print(x)

and let's say I want to say that all the elements of args are int; what is the right way to express it as of PEP 0484? Should I do something like

from typing import Tuple


def foo(*args: Tuple[int, ...]) -> None:
    for x in args:
        print(x)

or something like

def foo(*args: int) -> None:
    for x in args:
        print(x)

or something else entirely?

In particular, I'm trying to use type hints effectively in PyCharm, and none of the solutions I've thought of seems to help PyCharm understand that x should be an int.


Solution

  • According to PEP-484:

    Arbitrary argument lists can as well be type annotated, so that the definition:

    def foo(*args: str, **kwds: int): ...
    

    is acceptable and it means that, e.g., all of the following represent function calls with valid types of arguments:

    foo('a', 'b', 'c')
    foo(x=1, y=2)
    foo('', z=0)
    

    In the body of function foo, the type of variable args is deduced as Tuple[str, ...] and the type of variable kwds is Dict[str, int].

    The correct way to annotate the foo function from your example is:

    def foo(*args: int) -> None:
        for x in args:
            print(x)
    

    In Python 2:

    def foo(*args):
        # type: (*int) -> None
        for x in args:
            print(x)