Estoy probando las anotaciones de tipo de Python con clases base abstractas para escribir algunas interfaces. ¿Hay alguna manera de anotar los posibles tipos de *args
y **kwargs
?
Por ejemplo, ¿cómo se podría expresar que los argumentos razonables para una función son una int
o dos int
s? type(args)
da, Tuple
así que mi suposición fue anotar el tipo como Union[Tuple[int, int], Tuple[int]]
, pero esto no funciona.
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))
Mensajes de error de 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]]"
Tiene sentido que a mypy no le guste esto para la llamada a la función porque espera que haya una tuple
en la llamada misma. La adición después de desempacar también da un error de tipeo que no entiendo.
¿Cómo se anotan los tipos sensibles para *args
y **kwargs
?
Optional
? ¿Cambió algo sobre Python o cambiaste de opinión? ¿Todavía no es estrictamente necesario debido alNone
valor predeterminado?