-
-
Notifications
You must be signed in to change notification settings - Fork 3k
Closed
Labels
bugmypy got something wrongmypy got something wrongfalse-positivemypy gave an error on correct codemypy gave an error on correct codepriority-1-normaltopic-overloads
Description
Running mypy --disallow-untyped-decorators with a decorator that defines overloads always seems to report:
Untyped decorator makes function "xxx" untyped
Even though reveal_type(...) calls on the decorated functions seem to indicate type information.
Consider the following code.
Running mypy --disallow-untyped-decorators here yields the following (mypy 0.540):
dec_issue.py:19: error: Overloaded function signatures 1 and 2 overlap with incompatible return types
dec_issue.py:35: error: Untyped decorator makes function "default" untyped
dec_issue.py:41: error: Revealed type is 'def (*Any, **Any) -> builtins.int*'
The first error seems to be covered by other bug reports here (though, for all I know it may be related).
However, the second error seems to be contradicted by the type_reveal, which indicates at least the return type of the decorated "default" function is being picked up.
I may be missing something, but at very least, it seems like a more descriptive error may be warranted?
from typing import *
R = TypeVar("R")
def _make_decorator(arg: str) -> Callable[[Callable[..., R]], Callable[..., R]]:
def dec_(fn: Callable[..., R]) -> Callable[..., R]:
def wrapped(*args: Tuple[Any, ...],
**kwargs: Dict[str, Any]) -> R:
print(f"Prefix {arg}!")
return fn(*args, **kwargs)
return wrapped
return dec_
@overload
def dec(x: Callable[..., R]) -> Callable[..., R]: ...
@overload
def dec(x: str) -> Callable[[Callable[..., R]], Callable[..., R]]: ...
def dec(x: Any) -> Any:
if isinstance(x, str):
return _make_decorator(x)
elif callable(x):
return _make_decorator("default")(x)
else:
raise Exception("unhandled")
@dec
def default(name: str) -> int:
print(f"Hello, {name}!")
return 0
reveal_type(default)
@dec("arg")
def arg(name: str) -> int:
print(f"Hello, {name}!")
return 0
if __name__ == "__main__":
default("Bob")
arg("Bob")
Metadata
Metadata
Assignees
Labels
bugmypy got something wrongmypy got something wrongfalse-positivemypy gave an error on correct codemypy gave an error on correct codepriority-1-normaltopic-overloads