tenacity icon indicating copy to clipboard operation
tenacity copied to clipboard

mypy error: "Callable[..., Any]" has no attribute "retry"

Open OrBin opened this issue 2 years ago • 2 comments

I have this example code (typing_bug_example.py):

from tenacity import retry


@retry
def do_stuff():
    print("doing stuff")


do_stuff()
retry_stats = do_stuff.retry.statistics
print(retry_stats)

Checking it with mypy, I get this error:

$ mypy typing_bug_example.py 
typing_bug_example.py:10: error: "Callable[..., Any]" has no attribute "retry"
Found 1 error in 1 file (checked 1 source file)

The code runs as expected:

$ python typing_bug_example.py 
doing stuff
{'start_time': 176438.277915419, 'attempt_number': 1, 'idle_for': 0}

Adding # type: ignore[attr-defined] bypasses the issue.

I'm using tenacity 8.0.1 and running Python 3.10.1.

OrBin avatar Mar 20 '22 09:03 OrBin

I've had this problem with decorators of my own that add attributes to the decorated function. I noticed that the core Python function functools.wraps adds an attribute __wrapped__ which likewise mypy knows nothing about.

I think it could be worked around by the decorator returning, instead of a function, an instance of a class with __call__ overridden. But to me it feels unnatural to add that runtime mechanism just to satisfy static code checks. In recent Python versions it might be doable with a protocol, but I figure that since typeshed doesn't contain a solution for functools.wraps then likely there is no good solution yet.

steve-mavens avatar May 05 '22 07:05 steve-mavens

Test to check whether there's a solution yet for functools:

from functools import wraps

@wraps(len)
def my_len(val: str) -> int:
    return len(val)

if __name__ == '__main__':
    assert my_len.__wrapped__ is len

Current results:

$ python check_wraps.py

$ mypy check_wraps.py --strict
check_wraps.py:9: error: "Callable[[str], int]" has no attribute "__wrapped__"
Found 1 error in 1 file (checked 1 source file)

$ python --version
Python 3.10.2

$ mypy --version
mypy 0.942

steve-mavens avatar May 05 '22 07:05 steve-mavens