[Python-projects] pylint: Rewriting a little bit of the ast ?
Sylvain Thénault
sylvain.thenault at logilab.fr
Thu Feb 7 09:12:35 CET 2008
On Tue, Feb 05, 2008 at 01:56:27PM +0100, Monty Taylor wrote:
> Hi!
Hi,
> I'm trying to write a plugin to handle the bzr.lazy_import function.
> Specifically, it's a function that causes modules to be imported. In
> use, it looks like this:
>
> from bzrlib.lazy_import import lazy_import
>
> lazy_import(globals(), """
> import collapse
> import parent
> import hooks
> """)
>
>
> So obviously, since they aren't part of the tree, pylint isn't going to
> know anything about collapse, parent or hooks.
>
> I got as far as the following :
>
> def visit_callfunc(self, node):
> """called when a CallFunc node is encountered. See compiler.ast
> documentation for a description of available nodes:
> http://www.python.org/doc/current/lib/module-compiler.ast.html
> )
> """
> if self.already_done:
> return
> if isinstance(node.node, astng.Name):
> if node.node.name == "lazy_import":
> theImports = node.args[1].value
>
> newList=list()
> for f in theImports.split('\n'):
>
> foo=compiler.parse(f,"exec")
> newList.extend(foo.node.nodes)
>
>
>
> in_class = node.frame()
> theNodes = in_class.node.nodes
>
> newList.extend(theNodes)
> in_class.node.nodes = newList
> self.already_done = True
>
> self.walk(in_class.node)
>
> So I can detect that we're doing a lazy_import, and I can parse that
> string out... but I can't figure out how to inject it back into the tree
> that we're walking at the moment...
>
> Anything I'm missing here? (other than the fact that I'm on crack...)
I guess your final goal is to avoid error such as "collapse isn't
defined", isn't it ? To reinject the information into the tree, you
should update module's locals dictionary, like:
node.parent = module
node.locals[node.name] = [node]
You can take a look at the logilab.astng.builder module which is doing
that for the original ast. There is still a problem though: doing that
in a pylint plugin isn't the right way, since you've only litllle
control on the order of plugins execution, and so you're not sure that
the checker which will check name error (or any other which should
benefit from the added information) won't be executed before your's. I'm
think the right solution is to have a fake plugin which will monkey
patch the ASTNGBuilder (in the module cited above) to deal with the
lazy_import function at astng building time.
--
Sylvain Thénault LOGILAB, Paris (France)
Formations Python, Zope, Plone, Debian: http://www.logilab.fr/formations
Développement logiciel sur mesure: http://www.logilab.fr/services
Python et calcul scientifique: http://www.logilab.fr/science
More information about the Python-Projects
mailing list