8000 Fix type of forward reference to a decorated class method · python/mypy@5a3109c · GitHub
[go: up one dir, main page]

Skip to content

Commit 5a3109c

Browse files
committed
Fix type of forward reference to a decorated class method
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 8082af2 commit 5a3109c

File tree

2 files changed

+29
-2
lines changed

2 files changed

+29
-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.special_form)
472476
else:
473477
return function_type(cast(FuncBase, node.node), builtin_type('builtins.function'))
474478

test-data/unit/check-inference.test

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

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

17891812
-- Tests for special cases of unification
17901813
-- --------------------------------------

0 commit comments

Comments
 (0)
0