Issue 24002: Add un-parse function to ast (original) (raw)
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)
Author: Larry Hastings (larry) *
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.
Author: Berker Peksag (berker.peksag) *
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.
Author: Larry Hastings (larry) *
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!)
Author: Serhiy Storchaka (serhiy.storchaka) *
Date: 2015-04-19 06:11
For you need rather eval(ast). But a function for stringifying ast would be useful in any case.
Author: Larry Hastings (larry) *
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.
Author: Serhiy Storchaka (serhiy.storchaka) *
Date: 2015-04-19 06:16
I think there is standard way to transform ast to bytecode and evaluate it.
Author: Larry Hastings (larry) *
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:15
admin
set
github: 68190
2015-04-19 18:17:35
larry
set
status: open -> closed
resolution: later
messages: +
stage: needs patch -> resolved
2015-04-19 06:16:16
serhiy.storchaka
set
messages: +
2015-04-19 06:14:40
larry
set
messages: +
2015-04-19 06:11:43
serhiy.storchaka
set
messages: +
2015-04-19 05:57:06
larry
set
messages: +
2015-04-19 05:51:43
berker.peksag
set
nosy: + berker.peksag
messages: +
2015-04-19 05:49:00
larry
set
nosy: + zach.ware, serhiy.storchaka
2015-04-19 05:39:10
larry
create