Sto provando le annotazioni di tipo Python con classi base astratte per scrivere alcune interfacce. C'è un modo per annotare i possibili tipi di *args
e **kwargs
?
Ad esempio, come si potrebbe esprimere che gli argomenti sensibili di una funzione sono uno int
o due int
s? type(args)
dà Tuple
quindi la mia ipotesi era di annotare il tipo come Union[Tuple[int, int], Tuple[int]]
, ma questo non funziona.
from typing import Union, Tuple
def foo(*args: Union[Tuple[int, int], Tuple[int]]):
try:
i, j = args
return i + j
except ValueError:
assert len(args) == 1
i = args[0]
return i
# ok
print(foo((1,)))
print(foo((1, 2)))
# mypy does not like this
print(foo(1))
print(foo(1, 2))
Messaggi di errore da mypy:
t.py: note: In function "foo":
t.py:6: error: Unsupported operand types for + ("tuple" and "Union[Tuple[int, int], Tuple[int]]")
t.py: note: At top level:
t.py:12: error: Argument 1 to "foo" has incompatible type "int"; expected "Union[Tuple[int, int], Tuple[int]]"
t.py:14: error: Argument 1 to "foo" has incompatible type "int"; expected "Union[Tuple[int, int], Tuple[int]]"
t.py:15: error: Argument 1 to "foo" has incompatible type "int"; expected "Union[Tuple[int, int], Tuple[int]]"
t.py:15: error: Argument 2 to "foo" has incompatible type "int"; expected "Union[Tuple[int, int], Tuple[int]]"
Ha senso che a Mypy non piaccia questo per la chiamata di funzione perché si aspetta che ci sia un tuple
nella chiamata stessa. L'aggiunta dopo il disimballaggio dà anche un errore di battitura che non capisco.
Come si annotano i tipi sensibili per *args
e **kwargs
?
Optional
? Qualcosa è cambiato su Python o hai cambiato idea? Non è ancora strettamente necessario a causa delNone
default?