Skip to content

Commit 3545a71

Browse files
authored
Fix type of forward reference to a decorated class method (#4486)
The case wasn't properly handled before when accessing through a type object -- the type of the forward reference defaulted to `Any`. The fix doesn't work at module top level since module top levels can't be deferred, but the reference would generally fail at runtime anyway. Fixes #4485.
1 parent b0af822 commit 3545a71

File tree

2 files changed

+31
-2
lines changed

2 files changed

+31
-2
lines changed

mypy/checkmember.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -467,8 +467,12 @@ def analyze_class_attribute_access(itype: Instance,
467467
return builtin_type('types.ModuleType')
468468

469469
if is_decorated:
470-
# TODO: Return type of decorated function. This is quick hack to work around #998.
471-
return AnyType(TypeOfAny.special_form)
470+
assert isinstance(node.node, Decorator)
471+
if node.node.type:
472+
return node.node.type
473+
else:
474+
not_ready_callback(name, context)
475+
return AnyType(TypeOfAny.from_error)
472476
else:
473477
return function_type(cast(FuncBase, node.node), builtin_type('builtins.function'))
474478

test-data/unit/check-inference.test

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1786,6 +1786,31 @@ y = 0
17861786
tmp/m.py:2: error: "int" not callable
17871787
main:3: error: "int" not callable
17881788

1789+
[case testForwardReferenceToDecoratedClassMethod]
1790+
from typing import TypeVar, Callable
1791+
1792+
T = TypeVar('T')
1793+
def dec() -> Callable[[T], T]: pass
1794+
1795+
A.g # E: Cannot determine type of 'g'
1796+
1797+
class A:
1798+
@classmethod
1799+
def f(cls) -> None:
1800+
reveal_type(cls.g) # E: Revealed type is 'def (x: builtins.str)'
1801+
1802+
@classmethod
1803+
@dec()
1804+
def g(cls, x: str) -> None:
1805+
pass
1806+
1807+
@classmethod
1808+
def h(cls) -> None:
1809+
reveal_type(cls.g) # E: Revealed type is 'def (x: builtins.str)'
1810+
1811+
reveal_type(A.g) # E: Revealed type is 'def (x: builtins.str)'
1812+
[builtins fixtures/classmethod.pyi]
1813+
17891814

17901815
-- Tests for special cases of unification
17911816
-- --------------------------------------

0 commit comments

Comments
 (0)