summaryrefslogtreecommitdiff
path: root/astroid/objects.py
diff options
context:
space:
mode:
authorClaudiu Popa <cpopa@cloudbasesolutions.com>2015-05-28 21:57:14 +0300
committerClaudiu Popa <cpopa@cloudbasesolutions.com>2015-05-28 21:57:14 +0300
commitadbf48b73e97905dc38583480fa663870c4ea1e2 (patch)
tree1edf5c09ffa81695c2a8800152e7e7644787849d /astroid/objects.py
parent237b6c4662cc0a14b1912748776e5effe92e2611 (diff)
downloadastroid-adbf48b73e97905dc38583480fa663870c4ea1e2.tar.gz
Update the rules for what descriptor is returned from a super(), depending on the accessed object.
Diffstat (limited to 'astroid/objects.py')
-rw-r--r--astroid/objects.py31
1 files changed, 21 insertions, 10 deletions
diff --git a/astroid/objects.py b/astroid/objects.py
index 1599159..89a0229 100644
--- a/astroid/objects.py
+++ b/astroid/objects.py
@@ -69,13 +69,20 @@ class Super(NodeNG):
This class offers almost the same behaviour as Python's super,
which is MRO lookups for retrieving attributes from the parents.
+
+ The *mro_pointer* is the place in the MRO from where we should
+ start looking, not counting it. *mro_type* is the object which
+ provides the MRO, it can be both a type or an instance.
+ *self_class* is the class where the super call is, while
+ *scope* is the function where the super call is.
"""
- def __init__(self, mro_pointer, mro_type, self_class):
+ def __init__(self, mro_pointer, mro_type, self_class, scope):
self.type = mro_type
self.mro_pointer = mro_pointer
self._class_based = False
self._self_class = self_class
+ self._scope = scope
self._model = {
'__thisclass__': self.mro_pointer,
'__self_class__': self._self_class,
@@ -147,16 +154,20 @@ class Super(NodeNG):
found = True
for infered in _infer_stmts([cls[name]], context, frame=self):
- if isinstance(infered, Function):
- if self._class_based:
- # The second argument to super is class, which
- # means that we are returning unbound methods
- # when accessing attributes.
- yield UnboundMethod(infered)
- else:
- yield BoundMethod(infered, cls)
- else:
+ if not isinstance(infered, Function):
+ yield infered
+ continue
+
+ # We can obtain different descriptors from a super depending
+ # on what we are accessing and where the super call is.
+ if infered.type == 'classmethod':
+ yield BoundMethod(infered, cls)
+ elif self._scope.type == 'classmethod' and infered.type == 'method':
+ yield infered
+ elif self._class_based:
yield infered
+ else:
+ yield BoundMethod(infered, cls)
if not found:
raise NotFoundError(name)