Python: TypeVar for multiple arguments at once

Viewed 281

Is there a way to have a TypeVar (or some other format) capture all the arguments of a function? For example, say I want to wrap a general function, such that all its arguments are given within a tuple:

def invoke(f: Callable[..., T], args: Tuple[...]) -> T:
    return f(*args)

Only that instead of the ellipsis (...), I'll have the static-type inspection enforce the contents of the Tuple to be have the same types as the function's arguments.

Thanks.

1 Answers

You could modify the below to work with your requirements, you'll likely need to add in extra handling.

from typing import Any

class TypeEnforce:
    def __init__(self, func):
        self.func = func
    def __call__(self, *args):
        types = dict(zip(self.func.__annotations__.values(), args))
        for k, v in types.items():
            if k is Any:
                continue
            assert type(v) == k
        self.func(*args)

Example

@TypeEnforce
def my_test(x: str, y: int) -> None:
    print(f"'x' is a {type(x).__name__}")


@TypeEnforce
def my_other_test(x: Any):
    return x

my_test("Test", "eight")
my_other_test("Test2")

Will result in an AssertionError because the function my_test takes (str, int) but is passed (str, str). There would also be edge cases where a hint of TypedDict would always fail because it isn't really a type, rather syntactic sugar for a dict.

Related