summaryrefslogtreecommitdiff
path: root/pylint
diff options
context:
space:
mode:
authorƁukasz Rogalski <rogalski.91@gmail.com>2017-02-05 13:43:55 +0100
committerGitHub <noreply@github.com>2017-02-05 13:43:55 +0100
commitecd9d9e7db0d67db0691b1bbc869d82b915bc988 (patch)
tree4c6247b9929433fd11a7952549af6fcbbcfa77e9 /pylint
parent854bfe802145355a659e0b1ec068d31d8000988d (diff)
downloadpylint-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.py33
-rw-r--r--pylint/test/functional/access_to_protected_members.py15
-rw-r--r--pylint/test/functional/access_to_protected_members.txt1
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