summaryrefslogtreecommitdiff
path: root/astroid/scoped_nodes.py
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2015-08-26 20:39:00 +0300
committerClaudiu Popa <pcmanticore@gmail.com>2015-08-26 20:39:00 +0300
commitd5d10fbbde855dd63b229a611ee0e315f65358dd (patch)
tree3fd11b336cf4b56e7bb6d622cb06cda1bb764828 /astroid/scoped_nodes.py
parentfa094eb579641594b4263577cd151ad8f58e17a8 (diff)
parent993056dcc03874cc77ad951bfbb31f4e3b2e735e (diff)
downloadastroid-git-d5d10fbbde855dd63b229a611ee0e315f65358dd.tar.gz
Merged in renezhang/astroid_metaclass_loop (pull request #85)
Fix infinite loop in metaclass inference
Diffstat (limited to 'astroid/scoped_nodes.py')
-rw-r--r--astroid/scoped_nodes.py22
1 files changed, 15 insertions, 7 deletions
diff --git a/astroid/scoped_nodes.py b/astroid/scoped_nodes.py
index 5f42903e..3fde21ee 100644
--- a/astroid/scoped_nodes.py
+++ b/astroid/scoped_nodes.py
@@ -1550,6 +1550,20 @@ class ClassDef(mixins.FilterStmtsMixin, LocalsDictNodeNG, bases.Statement):
return None
return inferred
+ def _find_metaclass(self, seen):
+ if seen is None:
+ seen = set()
+ seen.add(self)
+
+ klass = self.declared_metaclass()
+ if klass is None:
+ for parent in self.ancestors():
+ if parent not in seen:
+ klass = parent._find_metaclass(seen)
+ if klass is not None:
+ break
+ return klass
+
def metaclass(self):
"""Return the metaclass of this class.
@@ -1557,13 +1571,7 @@ class ClassDef(mixins.FilterStmtsMixin, LocalsDictNodeNG, bases.Statement):
then the first defined metaclass in ancestors will be used
instead.
"""
- klass = self.declared_metaclass()
- if klass is None:
- for parent in self.ancestors():
- klass = parent.metaclass()
- if klass is not None:
- break
- return klass
+ return self._find_metaclass(None)
def has_metaclass_hack(self):
return self._metaclass_hack