Skip to content

Commit a6a19a9

Browse files
committed
feature: new error message for decorator incompatible type
1 parent 42e2178 commit a6a19a9

2 files changed

Lines changed: 31 additions & 5 deletions

File tree

mypy/messages.py

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
ClassDef,
4646
Context,
4747
Expression,
48+
Decorator,
4849
FuncDef,
4950
IndexExpr,
5051
MypyFile,
@@ -772,13 +773,27 @@ def incompatible_argument(
772773
actual_type_str, expected_type_str
773774
)
774775
else:
775-
if self.prefer_simple_messages():
776+
try:
777+
expected_type = callee.arg_types[m - 1]
778+
except IndexError: # Varargs callees
779+
expected_type = callee.arg_types[-1]
780+
781+
decorator_context = callee_name is None and isinstance(outer_context, Decorator)
782+
simple_message = self.prefer_simple_messages() and not decorator_context
783+
784+
if decorator_context:
785+
arg_type_str, expected_type_str = format_type_distinctly(
786+
arg_type, expected_type, bare=True, options=self.options
787+
)
788+
func_name = outer_context.func.name
789+
msg = (
790+
f'Decorated function "{func_name}" has incompatible type '
791+
f'{quote_type_string(arg_type_str)}; expected '
792+
f'{quote_type_string(expected_type_str)}'
793+
)
794+
elif simple_message:
776795
msg = "Argument has incompatible type"
777796
else:
778-
try:
779-
expected_type = callee.arg_types[m - 1]
780-
except IndexError: # Varargs callees
781-
expected_type = callee.arg_types[-1]
782797
arg_type_str, expected_type_str = format_type_distinctly(
783798
arg_type, expected_type, bare=True, options=self.options
784799
)
@@ -822,6 +837,7 @@ def incompatible_argument(
822837
quote_type_string(arg_type_str),
823838
quote_type_string(expected_type_str),
824839
)
840+
if not simple_message:
825841
expected_type = get_proper_type(expected_type)
826842
if isinstance(expected_type, UnionType):
827843
expected_types = list(expected_type.items)

test-data/unit/check-functions.test

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -959,6 +959,16 @@ def dec2(f: Callable[[Any, Any], None]) -> Callable[[Any], None]: pass
959959
@dec2
960960
def f(x, y): pass
961961

962+
[case testDecoratorFactoryApplicationErrorMessage]
963+
from typing import Callable
964+
965+
def decorator(f: object) -> Callable[[Callable[[int], object]], None]: ...
966+
def f(a: int) -> None: ...
967+
968+
@decorator(f) # E: Decorated function "something" has incompatible type "Callable[[], None]"; expected "Callable[[int], object]"
969+
def something() -> None:
970+
pass
971+
962972
[case testNoTypeCheckDecoratorOnMethod1]
963973
from typing import no_type_check
964974

0 commit comments

Comments
 (0)