summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCeridwen <ceridwenv@gmail.com>2015-07-13 21:47:10 -0400
committerCeridwen <ceridwenv@gmail.com>2015-07-13 21:47:10 -0400
commit94520560b047a12b5e277fd73400491e8dc1172d (patch)
tree040858d60d4ff44c5778c64ddab0c4deb3410b31
parentd5be6c1926d6fa02b49b320faee5edb1e04f9fae (diff)
downloadastroid-git-94520560b047a12b5e277fd73400491e8dc1172d.tar.gz
Fix code review comments.
Added aliases for inferred() and assign_type(), refactor some uses of ternary if, remove some now-unused internal functions in rebuilder, replaced the mutating docstring function with one that returns values as well as side-effects, change back to lazy-object-proxy, and add keyword args to the Module call in rebuilder.
-rw-r--r--astroid/as_string.py1
-rw-r--r--astroid/bases.py10
-rw-r--r--astroid/builder.py4
-rw-r--r--astroid/mixins.py21
-rw-r--r--astroid/node_classes.py3
-rw-r--r--astroid/nodes.py6
-rw-r--r--astroid/rebuilder.py400
-rw-r--r--astroid/scoped_nodes.py8
-rw-r--r--astroid/tests/unittest_nodes.py1
-rw-r--r--tox.ini6
10 files changed, 244 insertions, 216 deletions
diff --git a/astroid/as_string.py b/astroid/as_string.py
index 53552080..ecada1e1 100644
--- a/astroid/as_string.py
+++ b/astroid/as_string.py
@@ -22,7 +22,6 @@
* :func:`dump` function return an internal representation of nodes found
in the tree, useful for debugging or understanding the tree structure
"""
-
import sys
import six
diff --git a/astroid/bases.py b/astroid/bases.py
index 3aeb340c..9b4c2fe1 100644
--- a/astroid/bases.py
+++ b/astroid/bases.py
@@ -21,6 +21,7 @@ inference utils.
__docformat__ = "restructuredtext en"
import sys
+import warnings
from contextlib import contextmanager
from logilab.common.decorators import cachedproperty
@@ -405,7 +406,6 @@ def path_wrapper(func):
"""return the given infer function wrapped to handle the path"""
def wrapped(node, context=None, _func=func, **kwargs):
"""wrapper function handling context"""
- # print(dump(node), file=sys.stderr)
if context is None:
context = InferenceContext()
context.push(node)
@@ -688,7 +688,7 @@ class NodeNG(object):
yield matching
def _infer_name(self, frame, name):
- # overridden for From, Import, Global, TryExcept and Arguments
+ # overridden for ImportFrom, Import, Global, TryExcept and Arguments
return None
def _infer(self, context=None):
@@ -700,6 +700,12 @@ class NodeNG(object):
'''return list of inferred values for a more simple inference usage'''
return list(self.infer())
+ def infered(self):
+ warnings.warn('%s.infered() is deprecated, use %s.inferred() instead.'
+ % (type(self).__name__, type(self).__name__),
+ PendingDeprecationWarning)
+ return self.inferred()
+
def instanciate_class(self):
"""instanciate a node if it is a Class node, else return self"""
return self
diff --git a/astroid/builder.py b/astroid/builder.py
index 39bec211..8756fa42 100644
--- a/astroid/builder.py
+++ b/astroid/builder.py
@@ -145,7 +145,7 @@ class AstroidBuilder(raw_building.InspectBuilder):
module.file_encoding = encoding
self._manager.cache_module(module)
# post tree building steps after we stored the module in the cache:
- for from_node in module._from_nodes:
+ for from_node in module._import_from_nodes:
if from_node.modname == '__future__':
for symbol, _ in from_node.names:
module.future_imports.add(symbol)
@@ -172,7 +172,7 @@ class AstroidBuilder(raw_building.InspectBuilder):
package = path and path.find('__init__.py') > -1 or False
builder = rebuilder.TreeRebuilder(self._manager)
module = builder.visit_module(node, modname, node_file, package)
- module._from_nodes = builder._from_nodes
+ module._import_from_nodes = builder._import_from_nodes
module._delayed_assattr = builder._delayed_assattr
return module
diff --git a/astroid/mixins.py b/astroid/mixins.py
index bd63700f..6edccfbe 100644
--- a/astroid/mixins.py
+++ b/astroid/mixins.py
@@ -58,12 +58,26 @@ class FilterStmtsMixin(object):
def assign_type(self):
return self
+ def ass_type(self):
+ warnings.warn('%s.ass_type() is deprecated, '
+ 'use %s.assign_type() instead.'
+ % (type(self).__name__, type(self).__name__),
+ PendingDeprecationWarning)
+ return self.assign_type()
+
class AssignTypeMixin(object):
def assign_type(self):
return self
+ def ass_type(self):
+ warnings.warn('%s.ass_type() is deprecated, '
+ 'use %s.assign_type() instead.'
+ % (type(self).__name__, type(self).__name__),
+ PendingDeprecationWarning)
+ return self.assign_type()
+
def _get_filtered_stmts(self, lookup_node, node, _stmts, mystmt):
"""method used in filter_stmts"""
if self is mystmt:
@@ -80,6 +94,13 @@ class ParentAssignTypeMixin(AssignTypeMixin):
def assign_type(self):
return self.parent.assign_type()
+ def ass_type(self):
+ warnings.warn('%s.ass_type() is deprecated, '
+ 'use %s.assign_type() instead.'
+ % (type(self).__name__, type(self).__name__),
+ PendingDeprecationWarning)
+ return self.assign_type()
+
class ImportFromMixin(FilterStmtsMixin):
"""MixIn for From and Import Nodes"""
diff --git a/astroid/node_classes.py b/astroid/node_classes.py
index e8fdffcd..e341b38e 100644
--- a/astroid/node_classes.py
+++ b/astroid/node_classes.py
@@ -674,7 +674,7 @@ class Decorators(NodeNG):
_astroid_fields = ('nodes',)
nodes = None
- def postinit(self, nodes=None):
+ def postinit(self, nodes):
self.nodes = nodes
def scope(self):
@@ -961,7 +961,6 @@ class Keyword(NodeNG):
self.value = value
-# TODO: List, Set, and Tuple duplicate code
class List(NodeNG, Instance, ParentAssignTypeMixin):
"""class representing a List node"""
_astroid_fields = ('elts',)
diff --git a/astroid/nodes.py b/astroid/nodes.py
index d74effd0..07fe8594 100644
--- a/astroid/nodes.py
+++ b/astroid/nodes.py
@@ -38,7 +38,7 @@ on ImportFrom and Import :
__docformat__ = "restructuredtext en"
-import wrapt
+import lazy_object_proxy
from astroid.node_classes import (
Arguments, AssignAttr, Assert, Assign,
@@ -82,9 +82,9 @@ ALL_NODE_CLASSES = (
# Backward-compatibility aliases
def proxy_alias(alias_name, node_type):
- proxy = type(alias_name, (wrapt.ObjectProxy,),
+ proxy = type(alias_name, (lazy_object_proxy.Proxy,),
{'__class__': object.__dict__['__class__']})
- return proxy(node_type)
+ return proxy(lambda: node_type)
Backquote = proxy_alias('Backquote', Repr)
Discard = proxy_alias('Discard', Expr)
diff --git a/astroid/rebuilder.py b/astroid/rebuilder.py
index bc1b0e78..8b2ef48f 100644
--- a/astroid/rebuilder.py
+++ b/astroid/rebuilder.py
@@ -18,6 +18,8 @@
"""this module contains utilities for rebuilding a _ast tree in
order to get a single Astroid representation
"""
+from astroid.as_string import dump
+
import sys
from _ast import (
Expr, Str,
@@ -32,7 +34,7 @@ from _ast import (
Eq, Gt, GtE, In, Is, IsNot, Lt, LtE, NotEq, NotIn,
)
-from astroid import nodes as new
+from astroid import nodes
from astroid import astpeephole
_BIN_OP_CLASSES = {Add: '+',
@@ -89,36 +91,15 @@ REDIRECT = {'arguments': 'Arguments',
PY3 = sys.version_info >= (3, 0)
PY34 = sys.version_info >= (3, 4)
-def _init_set_doc(node, newnode):
- newnode.doc = None
+def _get_doc(node):
try:
if isinstance(node.body[0], Expr) and isinstance(node.body[0].value, Str):
- newnode.doc = node.body[0].value.s
+ doc = node.body[0].value.s
node.body = node.body[1:]
-
+ return node, doc
except IndexError:
pass # ast built from scratch
-
-
-def _create_yield_node(node, parent, rebuilder, factory, assign_ctx):
- newnode = factory()
- _lineno_parent(node, newnode, parent)
- if node.value is not None:
- newnode.value = rebuilder.visit(node.value, newnode, assign_ctx)
- return newnode
-
-
-def _lineno_parent(oldnode, newnode, parent):
- newnode.parent = parent
- newnode.lineno = oldnode.lineno
- newnode.col_offset = oldnode.col_offset
-
-def _set_infos(oldnode, newnode, parent):
- newnode.parent = parent
- if hasattr(oldnode, 'lineno'):
- newnode.lineno = oldnode.lineno
- if hasattr(oldnode, 'col_offset'):
- newnode.col_offset = oldnode.col_offset
+ return node, None
class TreeRebuilder(object):
@@ -127,7 +108,7 @@ class TreeRebuilder(object):
def __init__(self, manager):
self._manager = manager
self._global_names = []
- self._from_nodes = []
+ self._import_from_nodes = []
self._delayed_assattr = []
self._visit_meths = {}
self._transform = manager.transform
@@ -135,9 +116,9 @@ class TreeRebuilder(object):
def visit_module(self, node, modname, modpath, package):
"""visit a Module node by returning a fresh instance of it"""
- newnode = new.Module(modname, None, modpath, modpath,
- package=package, parent=None)
- _init_set_doc(node, newnode)
+ node, doc = _get_doc(node)
+ newnode = nodes.Module(name=modname, doc=doc, file=modpath, path=modpath,
+ package=package, parent=None)
newnode.postinit([self.visit(child, newnode) for child in node.body])
return self._transform(newnode)
@@ -159,17 +140,15 @@ class TreeRebuilder(object):
else:
node.parent.set_local(node.name, node)
-
- def visit_arguments(self, node, parent, assign_ctx=None,
- kwonlyargs=None, kw_defaults=None, annotations=None):
+ def visit_arguments(self, node, parent, assign_ctx=None):
"""visit a Arguments node by returning a fresh instance of it"""
vararg, kwarg = node.vararg, node.kwarg
if PY34:
- newnode = new.Arguments(vararg.arg if vararg else None,
- kwarg.arg if kwarg else None,
- parent)
+ newnode = nodes.Arguments(vararg.arg if vararg else None,
+ kwarg.arg if kwarg else None,
+ parent)
else:
- newnode = new.Arguments(vararg, kwarg, parent)
+ newnode = nodes.Arguments(vararg, kwarg, parent)
args = [self.visit(child, newnode, "Assign") for child in node.args]
defaults = [self.visit(child, newnode, assign_ctx)
for child in node.defaults]
@@ -196,15 +175,19 @@ class TreeRebuilder(object):
if node.kwargannotation:
kwargannotation = self.visit(node.kwarg.annotation,
newnode, assign_ctx)
- newnode.postinit(args, defaults,
- [self.visit(child, newnode, "Assign") for child
- in node.kwonlyargs] if PY3 else [],
- [self.visit(child, newnode, None) if child else
- None for child in node.kw_defaults] if PY3 else [],
- [self.visit(arg.annotation, newnode, None) if
- arg.annotation else None for arg in node.args]
- if PY3 else [],
- varargannotation, kwargannotation)
+ if PY3:
+ kwonlyargs = [self.visit(child, newnode, "Assign") for child
+ in node.kwonlyargs]
+ kw_defaults = [self.visit(child, newnode, None) if child else
+ None for child in node.kw_defaults]
+ annotations = [self.visit(arg.annotation, newnode, None) if
+ arg.annotation else None for arg in node.args]
+ else:
+ kwonlyargs = []
+ kw_defaults = []
+ annotations = []
+ newnode.postinit(args, defaults, kwonlyargs, kw_defaults,
+ annotations, varargannotation, kwargannotation)
# save argument names in locals:
if vararg:
newnode.parent.set_local(vararg, newnode)
@@ -214,34 +197,36 @@ class TreeRebuilder(object):
def visit_assignattr(self, node, parent, assign_ctx=None):
"""visit a AssignAttr node by returning a fresh instance of it"""
- newnode = new.AssignAttr(node.lineno, node.col_offset, parent)
+ newnode = nodes.AssignAttr(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.expr, newnode, None))
self._delayed_assattr.append(newnode)
return newnode
def visit_assert(self, node, parent, assign_ctx=None):
"""visit a Assert node by returning a fresh instance of it"""
- newnode = new.Assert(node.lineno, node.col_offset, parent)
- newnode.postinit(self.visit(node.test, newnode, assign_ctx),
- None if node.msg is None else
- self.visit(node.msg, newnode, assign_ctx))
+ newnode = nodes.Assert(node.lineno, node.col_offset, parent)
+ if node.msg:
+ msg = self.visit(node.msg, newnode, assign_ctx)
+ else:
+ msg = None
+ newnode.postinit(self.visit(node.test, newnode, assign_ctx), msg)
return newnode
def visit_assign(self, node, parent, assign_ctx=None):
"""visit a Assign node by returning a fresh instance of it"""
- newnode = new.Assign(node.lineno, node.col_offset, parent)
+ newnode = nodes.Assign(node.lineno, node.col_offset, parent)
newnode.postinit([self.visit(child, newnode, "Assign")
for child in node.targets],
self.visit(node.value, newnode, None))
klass = newnode.parent.frame()
- if (isinstance(klass, new.ClassDef)
- and isinstance(newnode.value, new.Call)
- and isinstance(newnode.value.func, new.Name)):
+ if (isinstance(klass, nodes.ClassDef)
+ and isinstance(newnode.value, nodes.Call)
+ and isinstance(newnode.value.func, nodes.Name)):
func_name = newnode.value.func.name
for assign_node in newnode.targets:
try:
meth = klass[assign_node.name]
- if isinstance(meth, new.FunctionDef):
+ if isinstance(meth, nodes.FunctionDef):
if func_name in ('classmethod', 'staticmethod'):
meth.type = func_name
elif func_name == 'classproperty': # see lgc.decorators
@@ -253,22 +238,22 @@ class TreeRebuilder(object):
def visit_assignname(self, node, parent, node_name=None):
'''visit a node and return a AssignName node'''
- newnode = new.AssignName(node_name, getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ newnode = nodes.AssignName(node_name, getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
self._save_assignment(newnode)
return newnode
def visit_augassign(self, node, parent, assign_ctx=None):
"""visit a AugAssign node by returning a fresh instance of it"""
- newnode = new.AugAssign(_BIN_OP_CLASSES[type(node.op)] + "=",
- node.lineno, node.col_offset, parent)
+ newnode = nodes.AugAssign(_BIN_OP_CLASSES[type(node.op)] + "=",
+ node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.target, newnode, "Assign"),
self.visit(node.value, newnode, None))
return newnode
def visit_repr(self, node, parent, assign_ctx=None):
"""visit a Backquote node by returning a fresh instance of it"""
- newnode = new.Repr(node.lineno, node.col_offset, parent)
+ newnode = nodes.Repr(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.value, newnode, assign_ctx))
return newnode
@@ -291,74 +276,81 @@ class TreeRebuilder(object):
if newnode:
return newnode
- newnode = new.BinOp(_BIN_OP_CLASSES[type(node.op)],
- node.lineno, node.col_offset, parent)
+ newnode = nodes.BinOp(_BIN_OP_CLASSES[type(node.op)],
+ node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.left, newnode, assign_ctx),
self.visit(node.right, newnode, assign_ctx))
return newnode
def visit_boolop(self, node, parent, assign_ctx=None):
"""visit a BoolOp node by returning a fresh instance of it"""
- newnode = new.BoolOp(_BOOL_OP_CLASSES[type(node.op)],
- node.lineno, node.col_offset, parent)
+ newnode = nodes.BoolOp(_BOOL_OP_CLASSES[type(node.op)],
+ node.lineno, node.col_offset, parent)
newnode.postinit([self.visit(child, newnode, assign_ctx)
for child in node.values])
return newnode
def visit_break(self, node, parent, assign_ctx=None):
"""visit a Break node by returning a fresh instance of it"""
- return new.Break(getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None),
- parent)
+ return nodes.Break(getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None),
+ parent)
def visit_call(self, node, parent, assign_ctx=None):
"""visit a CallFunc node by returning a fresh instance of it"""
- newnode = new.Call(node.lineno, node.col_offset, parent)
+ newnode = nodes.Call(node.lineno, node.col_offset, parent)
+ if node.starargs:
+ starargs = self.visit(node.starargs, newnode, assign_ctx)
+ else:
+ starargs = None
+ if node.kwargs:
+ kwargs = self.visit(node.kwargs, newnode, assign_ctx)
+ else:
+ kwargs = None
newnode.postinit(self.visit(node.func, newnode, assign_ctx),
[self.visit(child, newnode, assign_ctx)
for child in node.args + node.keywords],
- None if node.starargs is None else
- self.visit(node.starargs, newnode, assign_ctx),
- None if node.kwargs is None else
- self.visit(node.kwargs, newnode, assign_ctx))
+ starargs, kwargs)
return newnode
def visit_classdef(self, node, parent, assign_ctx=None, newstyle=None):
"""visit a Class node to become astroid"""
- newnode = new.ClassDef(node.name, None, node.lineno,
- node.col_offset, parent)
- _init_set_doc(node, newnode)
+ node, doc = _get_doc(node)
+ newnode = nodes.ClassDef(node.name, doc, node.lineno,
+ node.col_offset, parent)
metaclass = None
if PY3:
for keyword in node.keywords:
if keyword.arg == 'metaclass':
metaclass = self.visit(keyword, newnode, assign_ctx).value
break
+ # py >= 2.6
+ if 'decorator_list' in node._fields and node.decorator_list:
+ decorators = self.visit_decorators(node, newnode,
+ node.decorator_list, assign_ctx)
+ else:
+ decorators = None
newnode.postinit([self.visit(child, newnode, assign_ctx)
for child in node.bases],
[self.visit(child, newnode, assign_ctx)
for child in node.body],
- # py >= 2.6
- self.visit_decorators(node, newnode, assign_ctx)
- if 'decorator_list' in node._fields
- and node.decorator_list else None,
- newstyle, metaclass)
+ decorators, newstyle, metaclass)
return newnode
def visit_const(self, node, parent, assign_ctx=None):
"""visit a Const node by returning a fresh instance of it"""
- return new.Const(node.value, getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ return nodes.Const(node.value, getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
def visit_continue(self, node, parent, assign_ctx=None):
"""visit a Continue node by returning a fresh instance of it"""
- return new.Continue(getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None),
- parent)
+ return nodes.Continue(getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None),
+ parent)
def visit_compare(self, node, parent, assign_ctx=None):
"""visit a Compare node by returning a fresh instance of it"""
- newnode = new.Compare(node.lineno, node.col_offset, parent)
+ newnode = nodes.Compare(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.left, newnode, assign_ctx),
[(_CMP_OP_CLASSES[op.__class__],
self.visit(expr, newnode, assign_ctx))
@@ -367,36 +359,32 @@ class TreeRebuilder(object):
def visit_comprehension(self, node, parent, assign_ctx=None):
"""visit a Comprehension node by returning a fresh instance of it"""
- newnode = new.Comprehension(parent)
+ newnode = nodes.Comprehension(parent)
newnode.postinit(self.visit(node.target, newnode, "Assign"),
self.visit(node.iter, newnode, None),
[self.visit(child, newnode, None)
for child in node.ifs])
return newnode
- def visit_decorators(self, node, parent, assign_ctx=None):
+ def visit_decorators(self, node, parent, decorators, assign_ctx=None):
"""visit a Decorators node by returning a fresh instance of it"""
# /!\ node is actually a _ast.Function node while
- # parent is a astroid.nodes.Function node
- newnode = new.Decorators(node.lineno, node.col_offset, parent)
- if 'decorators' in node._fields: # py < 2.6, i.e. 2.5
- decorators = node.decorators
- else:
- decorators = node.decorator_list
+ # parent is a astroid.nodes.FunctionDef node
+ newnode = nodes.Decorators(node.lineno, node.col_offset, parent)
newnode.postinit([self.visit(child, newnode, assign_ctx)
for child in decorators])
return newnode
def visit_delete(self, node, parent, assign_ctx=None):
"""visit a Delete node by returning a fresh instance of it"""
- newnode = new.Delete(node.lineno, node.col_offset, parent)
+ newnode = nodes.Delete(node.lineno, node.col_offset, parent)
newnode.postinit([self.visit(child, newnode, "Del")
for child in node.targets])
return newnode
def visit_dict(self, node, parent, assign_ctx=None):
"""visit a Dict node by returning a fresh instance of it"""
- newnode = new.Dict(node.lineno, node.col_offset, parent)
+ newnode = nodes.Dict(node.lineno, node.col_offset, parent)
newnode.postinit([(self.visit(key, newnode, assign_ctx),
self.visit(value, newnode, assign_ctx))
for key, value in zip(node.keys, node.values)])
@@ -404,7 +392,7 @@ class TreeRebuilder(object):
def visit_dictcomp(self, node, parent, assign_ctx=None):
"""visit a DictComp node by returning a fresh instance of it"""
- newnode = new.DictComp(node.lineno, node.col_offset, parent)
+ newnode = nodes.DictComp(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.key, newnode, assign_ctx),
self.visit(node.value, newnode, assign_ctx),
[self.visit(child, newnode, assign_ctx)
@@ -413,54 +401,64 @@ class TreeRebuilder(object):
def visit_expr(self, node, parent, assign_ctx=None):
"""visit a Expr node by returning a fresh instance of it"""
- newnode = new.Expr(node.lineno, node.col_offset, parent)
+ newnode = nodes.Expr(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.value, newnode, assign_ctx))
return newnode
def visit_ellipsis(self, node, parent, assign_ctx=None):
"""visit an Ellipsis node by returning a fresh instance of it"""
- return new.Ellipsis(getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ return nodes.Ellipsis(getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
def visit_emptynode(self, node, parent, assign_ctx=None):
"""visit an EmptyNode node by returning a fresh instance of it"""
- return new.EmptyNode(getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ return nodes.EmptyNode(getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
def visit_excepthandler(self, node, parent, assign_ctx=None):
"""visit an ExceptHandler node by returning a fresh instance of it"""
- newnode = new.ExceptHandler(node.lineno, node.col_offset, parent)
- newnode.postinit(None if node.type is None else
- self.visit(node.type, newnode, assign_ctx),
- # /!\ node.name can be a tuple
- None if node.name is None else
- self.visit(node.name, newnode, "Assign"),
+ newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent)
+ if node.type is None:
+ node_type = None
+ else:
+ node_type = self.visit(node.type, newnode, assign_ctx)
+ if node.name is None:
+ name = None
+ else:
+ # /!\ node.name can be a tuple
+ name = self.visit(node.name, newnode, "Assign")
+ newnode.postinit(node_type, name,
[self.visit(child, newnode, None)
for child in node.body])
return newnode
def visit_exec(self, node, parent, assign_ctx=None):
"""visit an Exec node by returning a fresh instance of it"""
- newnode = new.Exec(node.lineno, node.col_offset, parent)
+ newnode = nodes.Exec(node.lineno, node.col_offset, parent)
+ if node.globals is None:
+ node_globals = None
+ else:
+ node_globals = self.visit(node.globals, newnode, assign_ctx)
+ if node.locals is None:
+ node_locals = None
+ else:
+ node_locals = self.visit(node.locals, newnode, assign_ctx)
newnode.postinit(self.visit(node.body, newnode, assign_ctx),
- None if node.globals is None else
- self.visit(node.globals, newnode, assign_ctx),
- None if node.locals is None else
- self.visit(node.locals, newnode, assign_ctx))
+ node_globals, node_locals)
return newnode
def visit_extslice(self, node, parent, assign_ctx=None):
"""visit an ExtSlice node by returning a fresh instance of it"""
- newnode = new.ExtSlice(parent=parent)
+ newnode = nodes.ExtSlice(parent=parent)
newnode.postinit([self.visit(dim, newnode, assign_ctx)
for dim in node.dims])
return newnode
def visit_for(self, node, parent, assign_ctx=None):
"""visit a For node by returning a fresh instance of it"""
- newnode = new.For(node.lineno, node.col_offset, parent)
+ newnode = nodes.For(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.target, newnode, "Assign"),
self.visit(node.iter, newnode, None),
[self.visit(child, newnode, None)
@@ -472,37 +470,43 @@ class TreeRebuilder(object):
def visit_importfrom(self, node, parent, assign_ctx=None):
"""visit a From node by returning a fresh instance of it"""
names = [(alias.name, alias.asname) for alias in node.names]
- newnode = new.ImportFrom(node.module or '', names, node.level or None,
- getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ newnode = nodes.ImportFrom(node.module or '', names, node.level or None,
+ getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
# store From names to add them to locals after building
- self._from_nodes.append(newnode)
+ self._import_from_nodes.append(newnode)
return newnode
def visit_functiondef(self, node, parent, assign_ctx=None):
"""visit an Function node to become astroid"""
self._global_names.append({})
- newnode = new.FunctionDef(node.name, None, node.lineno,
- node.col_offset, parent)
- _init_set_doc(node, newnode)
- if 'decorators' in node._fields: # py < 2.6
- attr = 'decorators'
+ node, doc = _get_doc(node)
+ newnode = nodes.FunctionDef(node.name, doc, node.lineno,
+ node.col_offset, parent)
+ # py < 2.6
+ if 'decorators' in node._fields and node.decorators:
+ decorators = self.visit_decorators(node, newnode,
+ node.decorators, assign_ctx)
+ elif ('decorator_list' in node._fields and
+ node.decorator_list):
+ decorators = self.visit_decorators(node, newnode,
+ node.decorator_list, assign_ctx)
else:
- attr = 'decorator_list'
- decorators = getattr(node, attr)
+ decorators = None
+ if PY3 and node.returns:
+ returns = self.visit(node.returns, newnode, assign_ctx)
+ else:
+ returns = None
newnode.postinit(self.visit(node.args, newnode, assign_ctx),
[self.visit(child, newnode, assign_ctx)
for child in node.body],
- self.visit_decorators(node, newnode, assign_ctx)
- if decorators else None,
- self.visit(node.returns, newnode, assign_ctx)
- if PY3 and node.returns else None)
+ decorators, returns)
self._global_names.pop()
return newnode
def visit_generatorexp(self, node, parent, assign_ctx=None):
"""visit a GenExpr node by returning a fresh instance of it"""
- newnode = new.GeneratorExp(node.lineno, node.col_offset, parent)
+ newnode = nodes.GeneratorExp(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.elt, newnode, assign_ctx),
[self.visit(child, newnode, assign_ctx)
for child in node.generators])
@@ -513,23 +517,23 @@ class TreeRebuilder(object):
if assign_ctx == "Del":
# FIXME : maybe we should reintroduce and visit_delattr ?
# for instance, deactivating assign_ctx
- newnode = new.DelAttr(node.attr, node.lineno, node.col_offset,
- parent)
+ newnode = nodes.DelAttr(node.attr, node.lineno, node.col_offset,
+ parent)
elif assign_ctx == "Assign":
# FIXME : maybe we should call visit_assignattr ?
- newnode = new.AssignAttr(node.attr, node.lineno, node.col_offset,
- parent)
+ newnode = nodes.AssignAttr(node.attr, node.lineno, node.col_offset,
+ parent)
self._delayed_assattr.append(newnode)
else:
- newnode = new.Attribute(node.attr, node.lineno, node.col_offset,
- parent)
+ newnode = nodes.Attribute(node.attr, node.lineno, node.col_offset,
+ parent)
newnode.postinit(self.visit(node.value, newnode, None))
return newnode
def visit_global(self, node, parent, assign_ctx=None):
"""visit a Global node to become astroid"""
- newnode = new.Global(node.names, getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ newnode = nodes.Global(node.names, getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
if self._global_names: # global at the module level, no effect
for name in node.names:
self._global_names[-1].setdefault(name, []).append(newnode)
@@ -537,7 +541,7 @@ class TreeRebuilder(object):
def visit_if(self, node, parent, assign_ctx=None):
"""visit an If node by returning a fresh instance of it"""
- newnode = new.If(node.lineno, node.col_offset, parent)
+ newnode = nodes.If(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.test, newnode, assign_ctx),
[self.visit(child, newnode, assign_ctx)
for child in node.body],
@@ -547,7 +551,7 @@ class TreeRebuilder(object):
def visit_ifexp(self, node, parent, assign_ctx=None):
"""visit a IfExp node by returning a fresh instance of it"""
- newnode = new.IfExp(node.lineno, node.col_offset, parent)
+ newnode = nodes.IfExp(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.test, newnode, assign_ctx),
self.visit(node.body, newnode, assign_ctx),
self.visit(node.orelse, newnode, assign_ctx))
@@ -556,11 +560,8 @@ class TreeRebuilder(object):
def visit_import(self, node, parent, assign_ctx=None):
"""visit a Import node by returning a fresh instance of it"""
names = [(alias.name, alias.asname) for alias in node.names]
- # print(names)
- newnode = new.Import(names, getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
- # print(as_string.dump(newnode))
- # print(newnode.names)
+ newnode = nodes.Import(names, getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
# save import names in parent's locals:
for (name, asname) in newnode.names:
name = asname or name
@@ -569,33 +570,33 @@ class TreeRebuilder(object):
def visit_index(self, node, parent, assign_ctx=None):
"""visit a Index node by returning a fresh instance of it"""
- newnode = new.Index(parent=parent)
+ newnode = nodes.Index(parent=parent)
newnode.postinit(self.visit(node.value, newnode, assign_ctx))
return newnode
def visit_keyword(self, node, parent, assign_ctx=None):
"""visit a Keyword node by returning a fresh instance of it"""
- newnode = new.Keyword(node.arg, parent=parent)
+ newnode = nodes.Keyword(node.arg, parent=parent)
newnode.postinit(self.visit(node.value, newnode, assign_ctx))
return newnode
def visit_lambda(self, node, parent, assign_ctx=None):
"""visit a Lambda node by returning a fresh instance of it"""
- newnode = new.Lambda(node.lineno, node.col_offset, parent)
+ newnode = nodes.Lambda(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.args, newnode, assign_ctx),
self.visit(node.body, newnode, assign_ctx))
return newnode
def visit_list(self, node, parent, assign_ctx=None):
"""visit a List node by returning a fresh instance of it"""
- newnode = new.List(node.lineno, node.col_offset, parent)
+ newnode = nodes.List(node.lineno, node.col_offset, parent)
newnode.postinit([self.visit(child, newnode, assign_ctx)
for child in node.elts])
return newnode
def visit_listcomp(self, node, parent, assign_ctx=None):
"""visit a ListComp node by returning a fresh instance of it"""
- newnode = new.ListComp(node.lineno, node.col_offset, parent)
+ newnode = nodes.ListComp(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.elt, newnode, assign_ctx),
[self.visit(child, newnode, assign_ctx)
for child in node.generators])
@@ -606,18 +607,19 @@ class TreeRebuilder(object):
# True and False can be assigned to something in py2x, so we have to
# check first the assign_ctx
if assign_ctx == "Del":
- newnode = new.DelName(node.id, node.lineno, node.col_offset, parent)
- elif assign_ctx is not None: # Ass
+ newnode = nodes.DelName(node.id, node.lineno, node.col_offset,
+ parent)
+ elif assign_ctx is not None: # Assign
assert assign_ctx == "Assign"
- newnode = new.AssignName(node.id, node.lineno, node.col_offset,
- parent)
+ newnode = nodes.AssignName(node.id, node.lineno, node.col_offset,
+ parent)
elif node.id in CONST_NAME_TRANSFORMS:
- newnode = new.Const(CONST_NAME_TRANSFORMS[node.id],
- getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ newnode = nodes.Const(CONST_NAME_TRANSFORMS[node.id],
+ getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
return newnode
else:
- newnode = new.Name(node.id, node.lineno, node.col_offset, parent)
+ newnode = nodes.Name(node.id, node.lineno, node.col_offset, parent)
# XXX REMOVE me :
if assign_ctx in ('Del', 'Assign'): # 'Aug' ??
self._save_assignment(newnode)
@@ -625,22 +627,22 @@ class TreeRebuilder(object):
def visit_str(self, node, parent, assign_ctx=None):
"""visit a String/Bytes node by returning a fresh instance of Const"""
- return new.Const(node.s, getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ return nodes.Const(node.s, getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
visit_bytes = visit_str
def visit_num(self, node, parent, assign_ctx=None):
"""visit a Num node by returning a fresh instance of Const"""
- return new.Const(node.n, getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ return nodes.Const(node.n, getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
def visit_pass(self, node, parent, assign_ctx=None):
"""visit a Pass node by returning a fresh instance of it"""
- return new.Pass(node.lineno, node.col_offset, parent)
+ return nodes.Pass(node.lineno, node.col_offset, parent)
def visit_print(self, node, parent, assign_ctx=None):
"""visit a Print node by returning a fresh instance of it"""
- newnode = new.Print(node.nl, node.lineno, node.col_offset, parent)
+ newnode = nodes.Print(node.nl, node.lineno, node.col_offset, parent)
newnode.postinit(None if node.dest is None else
self.visit(node.dest, newnode, assign_ctx),
[self.visit(child, newnode, assign_ctx)
@@ -649,7 +651,7 @@ class TreeRebuilder(object):
def visit_raise(self, node, parent, assign_ctx=None):
"""visit a Raise node by returning a fresh instance of it"""
- newnode = new.Raise(node.lineno, node.col_offset, parent)
+ newnode = nodes.Raise(node.lineno, node.col_offset, parent)
newnode.postinit(None if node.type is None else
self.visit(node.type, newnode, assign_ctx),
None if node.inst is None else
@@ -660,21 +662,21 @@ class TreeRebuilder(object):
def visit_return(self, node, parent, assign_ctx=None):
"""visit a Return node by returning a fresh instance of it"""
- newnode = new.Return(node.lineno, node.col_offset, parent)
+ newnode = nodes.Return(node.lineno, node.col_offset, parent)
if node.value is not None:
newnode.postinit(self.visit(node.value, newnode, assign_ctx))
return newnode
def visit_set(self, node, parent, assign_ctx=None):
"""visit a Set node by returning a fresh instance of it"""
- newnode = new.Set(node.lineno, node.col_offset, parent)
+ newnode = nodes.Set(node.lineno, node.col_offset, parent)
newnode.postinit([self.visit(child, newnode, assign_ctx)
for child in node.elts])
return newnode
def visit_setcomp(self, node, parent, assign_ctx=None):
"""visit a SetComp node by returning a fresh instance of it"""
- newnode = new.SetComp(node.lineno, node.col_offset, parent)
+ newnode = nodes.SetComp(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.elt, newnode, assign_ctx),
[self.visit(child, newnode, assign_ctx)
for child in node.generators])
@@ -682,7 +684,7 @@ class TreeRebuilder(object):
def visit_slice(self, node, parent, assign_ctx=None):
"""visit a Slice node by returning a fresh instance of it"""
- newnode = new.Slice(parent=parent)
+ newnode = nodes.Slice(parent=parent)
newnode.postinit(None if node.lower is None else
self.visit(node.lower, newnode, assign_ctx),
None if node.upper is None else
@@ -693,14 +695,14 @@ class TreeRebuilder(object):
def visit_subscript(self, node, parent, assign_ctx=None):
"""visit a Subscript node by returning a fresh instance of it"""
- newnode = new.Subscript(node.lineno, node.col_offset, parent)
+ newnode = nodes.Subscript(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.value, newnode, None),
self.visit(node.slice, newnode, None))
return newnode
def visit_tryexcept(self, node, parent, assign_ctx=None):
"""visit a TryExcept node by returning a fresh instance of it"""
- newnode = new.TryExcept(node.lineno, node.col_offset, parent)
+ newnode = nodes.TryExcept(node.lineno, node.col_offset, parent)
newnode.postinit([self.visit(child, newnode, assign_ctx)
for child in node.body],
[self.visit(child, newnode, assign_ctx)
@@ -711,7 +713,7 @@ class TreeRebuilder(object):
def visit_tryfinally(self, node, parent, assign_ctx=None):
"""visit a TryFinally node by returning a fresh instance of it"""
- newnode = new.TryFinally(node.lineno, node.col_offset, parent)
+ newnode = nodes.TryFinally(node.lineno, node.col_offset, parent)
newnode.postinit([self.visit(child, newnode, assign_ctx)
for child in node.body],
[self.visit(n, newnode, assign_ctx)
@@ -720,21 +722,21 @@ class TreeRebuilder(object):
def visit_tuple(self, node, parent, assign_ctx=None):
"""visit a Tuple node by returning a fresh instance of it"""
- newnode = new.Tuple(node.lineno, node.col_offset, parent)
+ newnode = nodes.Tuple(node.lineno, node.col_offset, parent)
newnode.postinit([self.visit(child, newnode, assign_ctx)
for child in node.elts])
return newnode
def visit_unaryop(self, node, parent, assign_ctx=None):
"""visit a UnaryOp node by returning a fresh instance of it"""
- newnode = new.UnaryOp(_UNARY_OP_CLASSES[node.op.__class__],
- node.lineno, node.col_offset, parent)
+ newnode = nodes.UnaryOp(_UNARY_OP_CLASSES[node.op.__class__],
+ node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.operand, newnode, assign_ctx))
return newnode
def visit_while(self, node, parent, assign_ctx=None):
"""visit a While node by returning a fresh instance of it"""
- newnode = new.While(node.lineno, node.col_offset, parent)
+ newnode = nodes.While(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.test, newnode, assign_ctx),
[self.visit(child, newnode, assign_ctx)
for child in node.body],
@@ -743,7 +745,7 @@ class TreeRebuilder(object):
return newnode
def visit_with(self, node, parent, assign_ctx=None):
- newnode = new.With(node.lineno, node.col_offset, parent)
+ newnode = nodes.With(node.lineno, node.col_offset, parent)
expr = self.visit(node.context_expr, newnode, assign_ctx)
if node.optional_vars is not None:
optional_vars = self.visit(node.optional_vars, newnode, "Assign")
@@ -756,7 +758,7 @@ class TreeRebuilder(object):
def visit_yield(self, node, parent, assign_ctx=None):
"""visit a Yield node by returning a fresh instance of it"""
- newnode = new.Yield(node.lineno, node.col_offset, parent)
+ newnode = nodes.Yield(node.lineno, node.col_offset, parent)
if node.value is not None:
newnode.postinit(self.visit(node.value, newnode, assign_ctx))
return newnode
@@ -772,34 +774,34 @@ class TreeRebuilder3(TreeRebuilder):
def visit_nameconstant(self, node, parent, assign_ctx=None):
# in Python 3.4 we have NameConstant for True / False / None
- return new.Const(node.value, getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
-
- # def visit_arguments(self, node, parent, assign_ctx=None):
- # return super(TreeRebuilder3, self).visit_arguments(
- # node, parent, assign_ctx, kwonlyargs, kw_defaults,
- # annotations)
+ return nodes.Const(node.value, getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
def visit_excepthandler(self, node, parent, assign_ctx=None):
"""visit an ExceptHandler node by returning a fresh instance of it"""
- newnode = new.ExceptHandler(node.lineno, node.col_offset, parent)
- newnode.postinit(None if node.type is None else
- self.visit(node.type, newnode, assign_ctx),
- None if node.name is None else
- self.visit_assignname(node, newnode, node.name),
+ newnode = nodes.ExceptHandler(node.lineno, node.col_offset, parent)
+ if node.type is None:
+ node_type = None
+ else:
+ node_type = self.visit(node.type, newnode, assign_ctx)
+ if node.name is None:
+ name = None
+ else:
+ name = self.visit_assignname(node, newnode, node.name)
+ newnode.postinit(node_type, name,
[self.visit(child, newnode, assign_ctx)
for child in node.body])
return newnode
def visit_nonlocal(self, node, parent, assign_ctx=None):
"""visit a Nonlocal node and return a new instance of it"""
- return new.Nonlocal(node.names, getattr(node, 'lineno', None),
- getattr(node, 'col_offset', None), parent)
+ return nodes.Nonlocal(node.names, getattr(node, 'lineno', None),
+ getattr(node, 'col_offset', None), parent)
def visit_raise(self, node, parent, assign_ctx=None):
"""visit a Raise node by returning a fresh instance of it"""
- newnode = new.Raise(node.lineno, node.col_offset, parent)
+ newnode = nodes.Raise(node.lineno, node.col_offset, parent)
# no traceback; anyway it is not used in Pylint
newnode.postinit(None if node.exc is None else
self.visit(node.exc, newnode, assign_ctx),
@@ -809,7 +811,7 @@ class TreeRebuilder3(TreeRebuilder):
def visit_starred(self, node, parent, assign_ctx=None):
"""visit a Starred node and return a new instance of it"""
- newnode = new.Starred(node.lineno, node.col_offset, parent)
+ newnode = nodes.Starred(node.lineno, node.col_offset, parent)
newnode.postinit(self.visit(node.value, newnode, assign_ctx))
return newnode
@@ -817,7 +819,7 @@ class TreeRebuilder3(TreeRebuilder):
# python 3.3 introduce a new Try node replacing
# TryFinally/TryExcept nodes
if node.finalbody:
- newnode = new.TryFinally(node.lineno, node.col_offset, parent)
+ newnode = nodes.TryFinally(node.lineno, node.col_offset, parent)
newnode.postinit([self.visit_tryexcept(node, newnode, assign_ctx)]
if node.handlers else
[self.visit(child, newnode, assign_ctx)
@@ -834,7 +836,7 @@ class TreeRebuilder3(TreeRebuilder):
return super(TreeRebuilder3, self).visit_with(node, parent,
assign_ctx)
- newnode = new.With(node.lineno, node.col_offset, parent)
+ newnode = nodes.With(node.lineno, node.col_offset, parent)
def visit_child(child):
expr = self.visit(child.context_expr, newnode, assign_ctx)
if child.optional_vars:
@@ -848,7 +850,7 @@ class TreeRebuilder3(TreeRebuilder):
return newnode
def visit_yieldfrom(self, node, parent, assign_ctx=None):
- newnode = new.YieldFrom(node.lineno, node.col_offset, parent)
+ newnode = nodes.YieldFrom(node.lineno, node.col_offset, parent)
if node.value is not None:
newnode.postinit(self.visit(node.value, newnode, assign_ctx))
return newnode
diff --git a/astroid/scoped_nodes.py b/astroid/scoped_nodes.py
index 592c984c..2e9d389a 100644
--- a/astroid/scoped_nodes.py
+++ b/astroid/scoped_nodes.py
@@ -251,6 +251,7 @@ class Module(LocalsDictNodeNG):
_astroid_fields = ('body',)
fromlineno = 0
+ lineno = 0
# attributes below are set by the builder module or by raw factories
@@ -524,7 +525,6 @@ class ComprehensionScope(LocalsDictNodeNG):
scope_lookup = LocalsDictNodeNG._scope_lookup
-# TODO: lots of code duplication in the comprehensions too.
class GeneratorExp(ComprehensionScope):
_astroid_fields = ('elt', 'generators')
_other_fields = ('locals',)
@@ -1622,9 +1622,9 @@ class ClassDef(bases.Statement, LocalsDictNodeNG, mixins.FilterStmtsMixin):
# Hack to get Pylint working without changing code.
-import wrapt
+import lazy_object_proxy
def proxy_alias(alias_name, node_type):
- proxy = type(alias_name, (wrapt.ObjectProxy,),
+ proxy = type(alias_name, (lazy_object_proxy.Proxy,),
{'__class__': object.__dict__['__class__']})
- return proxy(node_type)
+ return proxy(lambda: node_type)
GenExpr = proxy_alias('GenExpr', GeneratorExp)
diff --git a/astroid/tests/unittest_nodes.py b/astroid/tests/unittest_nodes.py
index 4aaa968e..9c873e17 100644
--- a/astroid/tests/unittest_nodes.py
+++ b/astroid/tests/unittest_nodes.py
@@ -80,6 +80,7 @@ class AsStringTest(resources.SysPathSetup, unittest.TestCase):
def test_module2_as_string(self):
"""check as_string on a whole module prepared to be returned identically
"""
+ self.maxDiff = None
module2 = resources.build_file('data/module2.py', 'data.module2')
with open(resources.find('data/module2.py'), 'r') as fobj:
self.assertMultiLineEqual(module2.as_string(), fobj.read())
diff --git a/tox.ini b/tox.ini
index c7867047..d7156ca8 100644
--- a/tox.ini
+++ b/tox.ini
@@ -4,18 +4,18 @@
envlist = py27, py34, pylint
[testenv:pylint]
-deps =
+deps =
+ lazy-object-proxy
logilab-common
six
- wrapt
hg+https://bitbucket.org/logilab/astroid
hg+https://bitbucket.org/logilab/pylint
commands = pylint -rn --rcfile={toxinidir}/pylintrc {envsitepackagesdir}/astroid
[testenv]
deps =
+ lazy-object-proxy
logilab-common
six
- wrapt
commands = python -m unittest discover -s {envsitepackagesdir}/astroid/tests -p "unittest*.py"