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)

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:

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 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: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