Skip to content

Commit

Permalink
Add support for functools.cached_property (#10408)
Browse files Browse the repository at this point in the history
Add support for functools.cached_property decorator:
https://docs.python.org/3/library/functools.html#functools.cached_property

Closes #8913.
Closes python/typeshed#3963.
  • Loading branch information
cdce8p authored May 5, 2021
1 parent fdeedd6 commit 204c7da
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 1 deletion.
5 changes: 4 additions & 1 deletion mypy/semanal.py
Original file line number Diff line number Diff line change
Expand Up @@ -999,12 +999,15 @@ def visit_decorator(self, dec: Decorator) -> None:
dec.var.is_classmethod = True
self.check_decorated_function_is_method('classmethod', dec)
elif (refers_to_fullname(d, 'builtins.property') or
refers_to_fullname(d, 'abc.abstractproperty')):
refers_to_fullname(d, 'abc.abstractproperty') or
refers_to_fullname(d, 'functools.cached_property')):
removed.append(i)
dec.func.is_property = True
dec.var.is_property = True
if refers_to_fullname(d, 'abc.abstractproperty'):
dec.func.is_abstract = True
elif refers_to_fullname(d, 'functools.cached_property'):
dec.var.is_settable_property = True
self.check_decorated_function_is_method('property', dec)
if len(dec.func.arguments) > 1:
self.fail('Too many arguments', dec.func)
Expand Down
20 changes: 20 additions & 0 deletions test-data/unit/check-functools.test
Original file line number Diff line number Diff line change
Expand Up @@ -107,3 +107,23 @@ Ord() > 1
Ord() >= 1 # E: Unsupported left operand type for >= ("Ord")
[builtins fixtures/ops.pyi]
[builtins fixtures/dict.pyi]

[case testCachedProperty]
# flags: --python-version 3.8
from functools import cached_property
class Parent:
@property
def f(self) -> str: pass
class Child(Parent):
@cached_property
def f(self) -> str: pass
@cached_property
def g(self) -> int: pass
@cached_property
def h(self, arg) -> int: pass # E: Too many arguments
reveal_type(Parent().f) # N: Revealed type is "builtins.str"
reveal_type(Child().f) # N: Revealed type is "builtins.str"
reveal_type(Child().g) # N: Revealed type is "builtins.int"
Child().f = "Hello World"
Child().g = "invalid" # E: Incompatible types in assignment (expression has type "str", variable has type "int")
[builtins fixtures/property.pyi]
1 change: 1 addition & 0 deletions test-data/unit/fixtures/property.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ class function: pass

property = object() # Dummy definition

class dict: pass
class int: pass
class str: pass
class bytes: pass
Expand Down

0 comments on commit 204c7da

Please sign in to comment.