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
commit402d9298ad25d8ddd9f139a2e34b5efc0e72b7a1 (patch)
treee2da6f484aea8065ca3d8f3c0010cf84e6652e59 /astroid/builder.py
parent581195e02bfa9e6c82dbf6f8710709b0f0b2eb07 (diff)
downloadastroid-git-402d9298ad25d8ddd9f139a2e34b5efc0e72b7a1.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 e684eecc..9cfa3dbb 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)