Description
Please forgive me if this issue is already solved or if it is part of #1317, but I'm not sure this is already covered with the existing issues. I'm trying to find a solution for the following use case:
from collections import Callable
from typing import Any, Tuple
def decorator(func: 'Callable[..., None]') -> 'Callable[..., None]':
def wrapper(*args: Tuple[Any], **kwargs: Tuple[Any]) -> None:
new_args = [arg[0] for arg in args]
new_kwargs = {key: kwargs[key][0] for key in kwargs}
func(*new_args, **new_kwargs)
return wrapper
@decorator
def f1(a: str) -> None:
print('f1')
print(a)
@decorator
def f2(a: str, b: int) -> None:
print('f2')
print(a)
print(b)
@decorator
def f3(a: str, b: int = 3) -> None:
print('f3')
print(a)
print(b)
# This works as expected
f1(('abc',)) # Good 1
f1(a=('keyword_abc',)) # Good 2
f2(('def',), (3,)) # Good 3
f3(('ghi',)) # Good 4
# I would like these to generate an error
f1('abc') # Bad 1
f1(a='abc') # Bad 2
f2('def', 3) # Bad 3
f3('ghi') # Bad 4
I have a decorator, which changes functions to accept all arguments inside a Tuple
. The current solution works and doesn't give any mypy errors, because the type of the decorated functions is
'def (*Any, **Any)'
and basically looses all typing information.
However, after the decorator is applied, the four last lines should give an error, since the decorated function only accepts tuples now.
Is or will there be a way type decorator so that these cases can be solved? I tried different solutions with generics and overloads, but didn't manage to improve upon Callable[..., None]
.
Or, in other words, I would like to add more typing information to decorator
to allow mypy
to convert decorated functions from Callable[[T1, T2, T3], None]
to Callable[[Tuple[T1], Tuple[T2], Tuple[T3]], None]