diff options
author | Ćukasz Rogalski <rogalski.91@gmail.com> | 2017-02-05 13:43:55 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-05 13:43:55 +0100 |
commit | ecd9d9e7db0d67db0691b1bbc869d82b915bc988 (patch) | |
tree | 4c6247b9929433fd11a7952549af6fcbbcfa77e9 /pylint | |
parent | 854bfe802145355a659e0b1ec068d31d8000988d (diff) | |
download | pylint-git-ecd9d9e7db0d67db0691b1bbc869d82b915bc988.tar.gz |
Do not emit warning on type(self)._private_attribute access (#1288)
Closes #1031
Diffstat (limited to 'pylint')
-rw-r--r-- | pylint/checkers/classes.py | 33 | ||||
-rw-r--r-- | pylint/test/functional/access_to_protected_members.py | 15 | ||||
-rw-r--r-- | pylint/test/functional/access_to_protected_members.txt | 1 |
3 files changed, 42 insertions, 7 deletions
diff --git a/pylint/checkers/classes.py b/pylint/checkers/classes.py index a5155f8c0..9975220b3 100644 --- a/pylint/checkers/classes.py +++ b/pylint/checkers/classes.py @@ -829,7 +829,7 @@ a metaclass class method.'} methods) """ # Check self - if self.is_first_attr(node): + if self._uses_mandatory_method_param(node): self._accessed.set_accessed(node) return if not self.linter.is_message_enabled('protected-access'): @@ -838,7 +838,8 @@ a metaclass class method.'} self._check_protected_attribute_access(node) def visit_assignattr(self, node): - if isinstance(node.assign_type(), astroid.AugAssign) and self.is_first_attr(node): + if (isinstance(node.assign_type(), astroid.AugAssign) and + self._uses_mandatory_method_param(node)): self._accessed.set_accessed(node) self._check_in_slots(node) @@ -885,7 +886,7 @@ a metaclass class method.'} if not isinstance(node, astroid.AssignAttr): return - if self.is_first_attr(node): + if self._uses_mandatory_method_param(node): return self._check_protected_attribute_access(node) @@ -957,6 +958,10 @@ a metaclass class method.'} node.expr.func.name == 'super': return + # If the expression begins with a call to type(self), that's ok. + if self._is_type_self_call(node.expr): + return + # We are in a class, one remaining valid cases, Klass._attr inside # Klass if not (callee == klass.name or callee in klass.basenames): @@ -976,6 +981,12 @@ a metaclass class method.'} self.add_message('protected-access', node=node, args=attrname) + def _is_type_self_call(self, expr): + return (isinstance(expr, astroid.Call) and + isinstance(expr.func, astroid.Name) and + expr.func.name == 'type' and len(expr.args) == 1 and + self._is_mandatory_method_param(expr.args[0])) + def visit_name(self, node): """check if the name handle an access to a class member if so, register it @@ -1217,12 +1228,20 @@ a metaclass class method.'} args=(class_type, method1.name), node=method1) - def is_first_attr(self, node): + def _uses_mandatory_method_param(self, node): """Check that attribute lookup name use first attribute variable name - (self for method, cls for classmethod and mcs for metaclass). + + Name is `self` for method, `cls` for classmethod and `mcs` for metaclass. + """ + return self._is_mandatory_method_param(node.expr) + + def _is_mandatory_method_param(self, node): + """Check if astroid.Name corresponds to first attribute variable name + + Name is `self` for method, `cls` for classmethod and `mcs` for metaclass. """ - return self._first_attrs and isinstance(node.expr, astroid.Name) and \ - node.expr.name == self._first_attrs[-1] + return (self._first_attrs and isinstance(node, astroid.Name) + and node.name == self._first_attrs[-1]) class SpecialMethodsChecker(BaseChecker): diff --git a/pylint/test/functional/access_to_protected_members.py b/pylint/test/functional/access_to_protected_members.py index fd96bafe5..b1dc2e8df 100644 --- a/pylint/test/functional/access_to_protected_members.py +++ b/pylint/test/functional/access_to_protected_members.py @@ -42,3 +42,18 @@ INST._protected = 2 # [protected-access] print(INST._protected) # [protected-access] INST._cls_protected = 3 # [protected-access] print(INST._cls_protected) # [protected-access] + + +class Issue1031(object): + """Test for GitHub issue 1031""" + _attr = 1 + + def correct_access(self): + """Demonstrates correct access""" + return type(self)._attr + + def incorrect_access(self): + """Demonstrates incorrect access""" + if self._attr == 1: + return type(INST)._protected # [protected-access] + return None diff --git a/pylint/test/functional/access_to_protected_members.txt b/pylint/test/functional/access_to_protected_members.txt index 7ba601b74..fb5c152e6 100644 --- a/pylint/test/functional/access_to_protected_members.txt +++ b/pylint/test/functional/access_to_protected_members.txt @@ -3,3 +3,4 @@ protected-access:41::Access to a protected member _protected of a client class protected-access:42::Access to a protected member _protected of a client class protected-access:43::Access to a protected member _cls_protected of a client class protected-access:44::Access to a protected member _cls_protected of a client class +protected-access:58:Issue1031.incorrect_access:Access to a protected member _protected of a client class |