TLDR;
I have a decorator that:
- changes the function signature
- the wrapped function uses some generic type arguments
- Other than the signature I would like to use
funtools.wraps
to preserve the rest of the information.
Is there any way to achieve that without mypy
complaining?
More context
A minimal working example would look like this:
from functools import wraps
from typing import Callable, TypeVar
B = TypeVar('B', bound=str)
def str_as_int_wrapper(func: Callable[[int], int]) -> Callable[[B], B]:
WRAPPER_ASSIGNMENTS = ('__module__', '__name__', '__qualname__', '__doc__',)
WRAPPER_UPDATES = ('__dict__', '__annotations__')
@wraps(func, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES)
def _wrapped_func(val: B) -> B:
num = int(val)
result = func(num)
return val.__class__(result)
return _wrapped_func
@str_as_int_wrapper
def add_one(val: int) -> int:
return val + 1
This seems to work alright, but mypy
(version 1.10.0) does not like it. Instead, it complains with
test.py:17: error: Incompatible return value type (got "_Wrapped[[int], int, [Never], Never]", expected "Callable[[B], B]") [return-value]
test.py:17: note: "_Wrapped[[int], int, [Never], Never].__call__" has type "Callable[[Arg(Never, 'val')], Never]"
If I either remove the @wraps
decorator or replace the B
type annotations by str
, the error disappears.
Question
Am I missing something? Is this some already reported bug or limitation from mypy
(couldn’t find anything)? Should it be reported?
Thanks!