summaryrefslogtreecommitdiff
path: root/astroid/builder.py
diff options
context:
space:
mode:
authorClaudiu Popa <cpopa@cloudbasesolutions.com>2015-08-02 10:03:45 +0300
committerClaudiu Popa <cpopa@cloudbasesolutions.com>2015-08-02 10:03:45 +0300
commit9d672fc32aa3392157e62ab920524813fcaa373d (patch)
tree5bbafa1f579a5b08d2f67d652e28423172f30613 /astroid/builder.py
parenteba4927bbbe7c71e8b67c26826cc82f4f3281c3c (diff)
downloadastroid-9d672fc32aa3392157e62ab920524813fcaa373d.tar.gz
There's a new separate step for transforms.
Until now, the transforms were applied at the same time the tree was being built. This was problematic if the transform functions were using inference, since the inference was executed on a partially constructed tree, which led to failures when post-building information was needed (such as setting the _from_names for the From imports). Now there's a separate step for transforms, which are applied using transform.TransformVisitor. There's a couple of other related changes: * astroid.parse and AstroidBuilder gained a new parameter `apply_transforms`, which is a boolean flag, which will control if the transforms are applied. We do this because there are uses when the vanilla tree is wanted, without any implicit modification. * the transforms are also applied for builtin modules, as a side effect of the fact that transform visiting was moved in AstroidBuilder._post_build from AstroidBuilder._data_build. Closes issue #116.
Diffstat (limited to 'astroid/builder.py')
-rw-r--r--astroid/builder.py36
1 files changed, 25 insertions, 11 deletions
diff --git a/astroid/builder.py b/astroid/builder.py
index e684eec..9cfa3db 100644
--- a/astroid/builder.py
+++ b/astroid/builder.py
@@ -83,11 +83,19 @@ MANAGER = manager.AstroidManager()
class AstroidBuilder(raw_building.InspectBuilder):
- """Class for building an astroid tree from source code or from a live module."""
+ """Class for building an astroid tree from source code or from a live module.
- def __init__(self, manager=None):
+ The param *manager* specifies the manager class which should be used.
+ If no manager is given, then the default one will be used. The
+ param *apply_transforms* determines if the transforms should be
+ applied after the tree was built from source or from a live object,
+ by default being True.
+ """
+
+ def __init__(self, manager=None, apply_transforms=True):
super(AstroidBuilder, self).__init__()
self._manager = manager or MANAGER
+ self._apply_transforms = apply_transforms
def module_build(self, module, modname=None):
"""Build an astroid from a living module instance."""
@@ -101,12 +109,10 @@ class AstroidBuilder(raw_building.InspectBuilder):
# this is a built-in module
# get a partial representation by introspection
node = self.inspect_build(module, modname=modname, path=path)
- # we have to handle transformation by ourselves since the rebuilder
- # isn't called for builtin nodes
- #
- # XXX it's then only called for Module nodes, not for underlying
- # nodes
- node = self._manager.transform(node)
+ if self._apply_transforms:
+ # We have to handle transformation by ourselves since the
+ # rebuilder isn't called for builtin nodes
+ node = self._manager.visit_transforms(node)
return node
def file_build(self, path, modname=None):
@@ -153,6 +159,10 @@ class AstroidBuilder(raw_building.InspectBuilder):
# handle delayed assattr nodes
for delayed in module._delayed_assattr:
self.delayed_assattr(delayed)
+
+ # Visit the transforms
+ if self._apply_transforms:
+ module = self._manager.visit_transforms(module)
return module
def _data_build(self, data, modname, path):
@@ -236,13 +246,17 @@ class AstroidBuilder(raw_building.InspectBuilder):
pass
-def parse(code, module_name='', path=None):
+def parse(code, module_name='', path=None, apply_transforms=True):
"""Parses a source string in order to obtain an astroid AST from it
:param str code: The code for the module.
:param str module_name: The name for the module, if any
:param str path: The path for the module
+ :param bool apply_transforms:
+ Apply the transforms for the give code. Use it if you
+ don't want the default transforms to be applied.
"""
code = textwrap.dedent(code)
- return AstroidBuilder(MANAGER).string_build(
- code, modname=module_name, path=path)
+ builder = AstroidBuilder(manager=MANAGER,
+ apply_transforms=apply_transforms)
+ return builder.string_build(code, modname=module_name, path=path)