diff --git a/pylint/checkers/classes/class_checker.py b/pylint/checkers/classes/class_checker.py index bdfb0968a4..cb6cffcbba 100644 --- a/pylint/checkers/classes/class_checker.py +++ b/pylint/checkers/classes/class_checker.py @@ -49,6 +49,7 @@ _AccessNodes = Union[nodes.Attribute, nodes.AssignAttr] INVALID_BASE_CLASSES = {"bool", "range", "slice", "memoryview"} +ALLOWED_PROPETIES = {"property", "cached_property"} BUILTIN_DECORATORS = {"builtins.property", "builtins.classmethod"} ASTROID_TYPE_COMPARATORS = { nodes.Const: lambda a, b: a.value == b.value, @@ -1252,11 +1253,18 @@ def visit_functiondef(self, node: nodes.FunctionDef) -> None: # attribute affectation will call this method, not hiding it return if isinstance(decorator, nodes.Name): - if decorator.name == "property": + if decorator.name in ALLOWED_PROPETIES: # attribute affectation will either call a setter or raise # an attribute error, anyway not hiding the function return + if ( + isinstance(decorator, nodes.Attribute) + and decorator.expr.name == "functools" + and decorator.attrname == "cached_property" + ): + return + # Infer the decorator and see if it returns something useful inferred = safe_infer(decorator) if not inferred: diff --git a/tests/functional/m/method_hidden.py b/tests/functional/m/method_hidden.py index ea94b3ca26..6adb80b624 100644 --- a/tests/functional/m/method_hidden.py +++ b/tests/functional/m/method_hidden.py @@ -2,6 +2,7 @@ # pylint: disable=unused-private-member """check method hiding ancestor attribute """ +import functools class Abcd: @@ -113,6 +114,12 @@ def _protected(self): # [method-hidden] pass +class CachedChild(Parent): + @functools.cached_property + def _protected(self): + pass + + class ParentTwo: def __init__(self): self.__private = None diff --git a/tests/functional/m/method_hidden.txt b/tests/functional/m/method_hidden.txt index abce3cd407..23651bd4a0 100644 --- a/tests/functional/m/method_hidden.txt +++ b/tests/functional/m/method_hidden.txt @@ -1,3 +1,3 @@ -method-hidden:17:4:17:12:Cdef.abcd:An attribute defined in functional.m.method_hidden line 11 hides this method:UNDEFINED -method-hidden:85:4:85:11:One.one:An attribute defined in functional.m.method_hidden line 83 hides this method:UNDEFINED -method-hidden:112:4:112:18:Child._protected:An attribute defined in functional.m.method_hidden line 108 hides this method:UNDEFINED +method-hidden:18:4:18:12:Cdef.abcd:An attribute defined in functional.m.method_hidden line 12 hides this method:UNDEFINED +method-hidden:86:4:86:11:One.one:An attribute defined in functional.m.method_hidden line 84 hides this method:UNDEFINED +method-hidden:113:4:113:18:Child._protected:An attribute defined in functional.m.method_hidden line 109 hides this method:UNDEFINED