diff options
author | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2015-08-02 10:03:45 +0300 |
---|---|---|
committer | Claudiu Popa <cpopa@cloudbasesolutions.com> | 2015-08-02 10:03:45 +0300 |
commit | 402d9298ad25d8ddd9f139a2e34b5efc0e72b7a1 (patch) | |
tree | e2da6f484aea8065ca3d8f3c0010cf84e6652e59 /astroid/builder.py | |
parent | 581195e02bfa9e6c82dbf6f8710709b0f0b2eb07 (diff) | |
download | astroid-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.py | 36 |
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) |