google / pytype

A static type analyzer for Python code
https://google.github.io/pytype
Other
4.77k stars 279 forks source link

False positive for type-vars in nested function with decorator #966

Open Matthias-Thul opened 3 years ago

Matthias-Thul commented 3 years ago

Consider the following example

from typing import TypeVar, Callable

T = TypeVar('T')
U = TypeVar('U')

def decorator(victim: Callable[..., U]) -> Callable[..., U]:
    return victim

def decorator_2(victim: Callable[..., T]) -> Callable[..., T]:
    @decorator
    def wrapper(*args, **kwargs) -> T:
        return victim(*args, **kwargs)

    return wrapper

PyType 2021.07.19 fails with

File "test.py", line 12, in decorator_2: Invalid type annotation 'T'  [invalid-annotation]
  Appears only once in the signature

When removing the decorator applied to the inner wrapper, PyType doesn't complain anymore. mypy 0.910 is happy with either. This seems related to the closed issue https://github.com/google/pytype/issues/379.

rchen152 commented 3 years ago

Hmm, this seems to be happening because pytype doesn't recognize that decorator returns the original function, so it can no longer tell that wrapper is nested inside decorator_2 and therefore allowed to refer to the latter's TypeVars.

I assume that decorator is more complicated in your actual code, but if you're able to annotate it as an identity function ((victim: T) -> T), that would probably work.