summaryrefslogtreecommitdiff
path: root/checkers/classes.py
diff options
context:
space:
mode:
Diffstat (limited to 'checkers/classes.py')
-rw-r--r--checkers/classes.py30
1 files changed, 29 insertions, 1 deletions
diff --git a/checkers/classes.py b/checkers/classes.py
index 90b2fbe..d9ebd8d 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):
@@ -801,6 +818,17 @@ a metaclass class method.'}
klass = expr.expr.infer().next()
if klass is YES:
continue
+ # The infered klass can be super(), which was
+ # assigned to a variable and the `__init__` was called later.
+ #
+ # base = super()
+ # base.__init__(...)
+
+ if (isinstance(klass, astroid.Instance) and
+ isinstance(klass._proxied, astroid.Class) and
+ is_builtin_object(klass._proxied) and
+ klass._proxied.name == 'super'):
+ return
try:
del not_called_yet[klass]
except KeyError: