summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTorsten Marek <shlomme@gmail.com>2014-08-22 22:24:36 +0200
committerTorsten Marek <shlomme@gmail.com>2014-08-22 22:24:36 +0200
commit35b6ec7f90018bfafccd5d1918973f640637750f (patch)
tree261f58acd523b3e5422ecf0d88702070710e68f0
parent5b63901107fbba8cb4ca6331fb8382eaaef4c4e9 (diff)
downloadastroid-35b6ec7f90018bfafccd5d1918973f640637750f.tar.gz
Guard against infinite recursion in _is_metaclass.
Unfortunately, I wasn't able to boil this down to a small-enough reproduction case, since the case that I had depended on conditional imports.
-rw-r--r--scoped_nodes.py10
1 files changed, 8 insertions, 2 deletions
diff --git a/scoped_nodes.py b/scoped_nodes.py
index 5f7f39b..eb60298 100644
--- a/scoped_nodes.py
+++ b/scoped_nodes.py
@@ -756,15 +756,21 @@ def _rec_get_names(args, names=None):
# Class ######################################################################
-def _is_metaclass(klass):
+def _is_metaclass(klass, seen=None):
""" Return if the given class can be
used as a metaclass.
"""
if klass.name == 'type':
return True
+ if seen is None:
+ seen = set()
for base in klass.bases:
try:
for baseobj in base.infer():
+ if baseobj in seen:
+ continue
+ else:
+ seen.add(baseobj)
if isinstance(baseobj, Instance):
# not abstract
return False
@@ -776,7 +782,7 @@ def _is_metaclass(klass):
continue
if baseobj._type == 'metaclass':
return True
- if _is_metaclass(baseobj):
+ if _is_metaclass(baseobj, seen):
return True
except InferenceError:
continue