Description
Feature
Currently, a function with multiple typed arguments does not match a protocol that defines typed variadic arguments. I think many people have a use for typing these functions with a variadic callback protocol, especially when writing wrappers. I believe this is related to #5876, but extends the use of Any
to other types.
Pitch
Many times it is useful to define a wrapper function with the signature wrapper(*args: T, **kwargs: Any) -> T
, or something similar. This allows you to create a wrapper that is agnostic to the number of positional arguments, as long as they are all of the same type, with optional keyword arguments. This wrapper can then be applied to any number of functions that take in multiple positional arguments of the same type. For example:
from functools import wraps
from typing import Any, Protocol
class IntTransformer(Protocol):
def __call__(self, *args: int, **kwargs: Any) -> int:
...
def incrementer(func: IntTransformer) -> IntTransformer:
@wraps(func)
def wrapper(*args: int, **kwargs: Any) -> int:
for a in args:
a += 1
return func(*args, **kwargs)
return wrapper
# Argument 1 to "incrementer" has incompatible type "Callable[[int, int], int]"; expected "IntTransformer"
@incrementer
def summation(a: int, b: int) -> int:
return a + b
This capability would extend the proposal in #5876 to still check for the argument types of the non-variadic functions, instead of just looking for Any. I think this would help alleviate typing headaches when trying to implement general wrappers and decorators.