diff options
author | cpopa <devnull@localhost> | 2014-08-14 18:20:13 +0300 |
---|---|---|
committer | cpopa <devnull@localhost> | 2014-08-14 18:20:13 +0300 |
commit | 2619e069558471d6600cf691f2673e520c087668 (patch) | |
tree | cfda428057f5c543c692b941f7f7a7394e5b0d9f | |
parent | bf056a6814b4245f5769fa16925bd9878a33fb8f (diff) | |
download | pylint-2619e069558471d6600cf691f2673e520c087668.tar.gz |
Don't emit 'protected-access' if the attribute is accessed using a property defined at the class level.
-rw-r--r-- | ChangeLog | 3 | ||||
-rw-r--r-- | checkers/classes.py | 19 | ||||
-rw-r--r-- | test/input/func_noerror_classes_protected_member_access.py | 1 |
3 files changed, 22 insertions, 1 deletions
@@ -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) |