summaryrefslogtreecommitdiff
path: root/scoped_nodes.py
diff options
context:
space:
mode:
authorClaudiu Popa <pcmanticore@gmail.com>2014-07-03 18:21:39 +0300
committerClaudiu Popa <pcmanticore@gmail.com>2014-07-03 18:21:39 +0300
commit05df58447680a54ca4f6444edae06783efe312ea (patch)
tree91273d2df3fdaff72a30e7eef3f83c7fc76d2e4c /scoped_nodes.py
parent5e8112ef05dce3ccaac1f3cf3b8d66d6012d091d (diff)
parentbae8340f044ed41e9b7cfde8d5a8880860862f67 (diff)
downloadastroid-git-05df58447680a54ca4f6444edae06783efe312ea.tar.gz
Merge with default.
--HG-- branch : slots
Diffstat (limited to 'scoped_nodes.py')
-rw-r--r--scoped_nodes.py33
1 files changed, 25 insertions, 8 deletions
diff --git a/scoped_nodes.py b/scoped_nodes.py
index ee917fa8..88b86422 100644
--- a/scoped_nodes.py
+++ b/scoped_nodes.py
@@ -807,6 +807,11 @@ class Class(Statement, LocalsDictNodeNG, FilterStmtsMixin):
if base._newstyle_impl(context):
self._newstyle = True
break
+ klass = self._explicit_metaclass()
+ # could be any callable, we'd need to infer the result of klass(name,
+ # bases, dict). punt if it's not a class node.
+ if klass is not None and isinstance(klass, Class):
+ self._newstyle = klass._newstyle_impl(context)
if self._newstyle is None:
self._newstyle = False
return self._newstyle
@@ -1081,8 +1086,9 @@ class Class(Statement, LocalsDictNodeNG, FilterStmtsMixin):
An explicit defined metaclass is defined
either by passing the ``metaclass`` keyword argument
- in the class definition line (Python 3) or by
- having a ``__metaclass__`` class attribute.
+ in the class definition line (Python 3) or (Python 2) by
+ having a ``__metaclass__`` class attribute, or if there are
+ no explicit bases but there is a global ``__metaclass__`` variable.
"""
if self._metaclass:
# Expects this from Py3k TreeRebuilder
@@ -1090,14 +1096,25 @@ class Class(Statement, LocalsDictNodeNG, FilterStmtsMixin):
return next(node for node in self._metaclass.infer()
if node is not YES)
except (InferenceError, StopIteration):
- return
+ return None
+ if sys.version_info >= (3, ):
+ return None
+
+ if '__metaclass__' in self.locals:
+ assignment = self.locals['__metaclass__'][-1]
+ elif self.bases:
+ return None
+ elif '__metaclass__' in self.root().locals:
+ assignments = [ass for ass in self.root().locals['__metaclass__']
+ if ass.lineno < self.lineno]
+ if not assignments:
+ return None
+ assignment = assignments[-1]
+ else:
+ return None
try:
- meta = self.getattr('__metaclass__')[0]
- except NotFoundError:
- return
- try:
- infered = meta.infer().next()
+ infered = assignment.infer().next()
except InferenceError:
return
if infered is YES: # don't expose this