Bartłomiej Bartnicki
Bartłomiej Bartnicki

Reputation: 1175

How can I annotate f(*params)?

I cannot work out how to correctly annotate this code:

from typing import Iterable

def f(*params: Iterable) -> str:
    return ":".join(params)

I know that Iterable is incorrect, because mypy tells me:

error: Argument 1 to "join" of "str" has incompatible type Tuple[Iterable[Any], ...]; expected Iterable[str]

… but I don't understand why.

Upvotes: 3

Views: 206

Answers (1)

schesis
schesis

Reputation: 59198

When annotations are combined with *args-style argument lists, the annotation specifies the type of each argument expected. As stated in 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].

In your example, since params is expected to be a tuple of strings, the correct annotation is str:

def f(*params: str) -> str:
    return ":".join(params)

Upvotes: 6

Related Questions