This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

classification
Title: Add un-parse function to ast
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.5
process
Status: closed Resolution: later
Dependencies: Superseder:
Assigned To: Nosy List: benjamin.peterson, berker.peksag, georg.brandl, larry, serhiy.storchaka, zach.ware
Priority: normal Keywords:

Created on 2015-04-19 05:39 by larry, last changed 2022-04-11 14:58 by admin. This issue is now closed.

Messages (7)
msg241477 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-04-19 05:39
Twice recently I've wanted a function that transforms an AST node tree back into text:

* In the hacked-up Tools/clinic/clinic.py for issue #24001
* In the hacked-up Lib/inspect.py for issue #23967

Both times I did a half-assed job just to get the patch working, so we could decide whether or not we want to go this route.

It seems useful and reasonable to do a proper job and add this functionality to ast.
msg241482 - (view) Author: Berker Peksag (berker.peksag) * (Python committer) Date: 2015-04-19 05:51
Perhaps a NodeVisitor subclass (something like Armin Ronacher's codegen module https://github.com/berkerpeksag/astor/blob/master/astor/codegen.py#L54 can be added to the ast module.
msg241483 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-04-19 05:57
Good idea, I'll go ahead and borrow Guido's time machine.

https://docs.python.org/3/library/ast.html#ast.NodeVisitor

However, NodeVisitor does not transform the ast tree back into text.  So in what way is this helpful?


Also, for what it's worth: both my use cases only need to handle expressions ("r-values" if you prefer).  I don't need to generate classes, functions, blocks, or even statements.  If we wanted to weaken the implementation to only handle expressions I'd be happy.  (In fact, I'd be happier this way, because it means the implementation would be much simpler!)
msg241485 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-04-19 06:11
For issue24001 you need rather eval(ast). But a function for stringifying ast would be useful in any case.
msg241486 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-04-19 06:14
Actually eval(ast) is all I need for #23967 too.  But eval is a builtin, so it feels wrong to have it supporting--and therefore dependent on--ast.
msg241487 - (view) Author: Serhiy Storchaka (serhiy.storchaka) * (Python committer) Date: 2015-04-19 06:16
I think there is standard way to transform ast to bytecode and evaluate it.
msg241527 - (view) Author: Larry Hastings (larry) * (Python committer) Date: 2015-04-19 18:17
There is!  compile() will do it, though the docstring doesn't mention it. (The full documentation does.)

The following function meets both my use cases:

    def eval_ast_expr(node, symbols=None, *, filename='-'):
        """
        Takes an ast.Expr node.  Compiles and evaluates it.
        Returns the result of the expression.

        symbols represents the globals dict the expression
        should see.  (There's no equivalent for "locals" here.)
        """

        if not isinstance(node, ast.Expr):
            raise RuntimeError(
                "eval_ast_expr: node must be of type ast.Expr")

        if symbols == None:
            symbols = globals()

        a = ast.Expression(node.value)
        co = compile(a, filename, 'eval')
        fn = types.FunctionType(co, symbols)
        return fn()

I am therefore closing this bug.  It still seems like a nice-to-have but I'll let somebody else do it when *they* have a use case.
History
Date User Action Args
2022-04-11 14:58:15adminsetgithub: 68190
2015-04-19 18:17:35larrysetstatus: open -> closed
resolution: later
messages: + msg241527

stage: needs patch -> resolved
2015-04-19 06:16:16serhiy.storchakasetmessages: + msg241487
2015-04-19 06:14:40larrysetmessages: + msg241486
2015-04-19 06:11:43serhiy.storchakasetmessages: + msg241485
2015-04-19 05:57:06larrysetmessages: + msg241483
2015-04-19 05:51:43berker.peksagsetnosy: + berker.peksag
messages: + msg241482
2015-04-19 05:49:00larrysetnosy: + zach.ware, serhiy.storchaka
2015-04-19 05:39:10larrycreate