summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcpopa <devnull@localhost>2014-08-14 18:20:13 +0300
committercpopa <devnull@localhost>2014-08-14 18:20:13 +0300
commit2619e069558471d6600cf691f2673e520c087668 (patch)
treecfda428057f5c543c692b941f7f7a7394e5b0d9f
parentbf056a6814b4245f5769fa16925bd9878a33fb8f (diff)
downloadpylint-2619e069558471d6600cf691f2673e520c087668.tar.gz
Don't emit 'protected-access' if the attribute is accessed using a property defined at the class level.
-rw-r--r--ChangeLog3
-rw-r--r--checkers/classes.py19
-rw-r--r--test/input/func_noerror_classes_protected_member_access.py1
3 files changed, 22 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index 7b70fa7..f7c3b90 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -63,6 +63,9 @@ ChangeLog for Pylint
* Look in the metaclass, if defined, for members not found in the current
class. Closes issue #306.
+ * Don't emit 'protected-access' if the attribute is accessed using
+ a property defined at the class level.
+
2014-07-26 -- 1.3.0
* Allow hanging continued indentation for implicitly concatenated
diff --git a/checkers/classes.py b/checkers/classes.py
index 90b2fbe..ebca3f2 100644
--- a/checkers/classes.py
+++ b/checkers/classes.py
@@ -27,7 +27,7 @@ from pylint.interfaces import IAstroidChecker
from pylint.checkers import BaseChecker
from pylint.checkers.utils import (
PYMETHODS, overrides_a_method, check_messages, is_attr_private,
- is_attr_protected, node_frame_class, safe_infer)
+ is_attr_protected, node_frame_class, safe_infer, is_builtin_object)
if sys.version_info >= (3, 0):
NEXT_METHOD = '__next__'
@@ -581,6 +581,23 @@ a metaclass class method.'}
# We are in a class, one remaining valid cases, Klass._attr inside
# Klass
if not (callee == klass.name or callee in klass.basenames):
+ # Detect property assignments in the body of the class.
+ # This is acceptable:
+ #
+ # class A:
+ # b = property(lambda: self._b)
+
+ stmt = node.parent.statement()
+ try:
+ if (isinstance(stmt, astroid.Assign) and
+ (stmt in klass.body or klass.parent_of(stmt)) and
+ isinstance(stmt.value, astroid.CallFunc) and
+ isinstance(stmt.value.func, astroid.Name) and
+ stmt.value.func.name == 'property' and
+ is_builtin_object(next(stmt.value.func.infer(), None))):
+ return
+ except astroid.InferenceError:
+ pass
self.add_message('protected-access', node=node, args=attrname)
def visit_name(self, node):
diff --git a/test/input/func_noerror_classes_protected_member_access.py b/test/input/func_noerror_classes_protected_member_access.py
index bef1bff..eeff97d 100644
--- a/test/input/func_noerror_classes_protected_member_access.py
+++ b/test/input/func_noerror_classes_protected_member_access.py
@@ -22,3 +22,4 @@ class A3123(object):
smeth = staticmethod(smeth)
+ prop = property(lambda self: self._protected)