Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add un-parse function to ast #68190

Closed
larryhastings opened this issue Apr 19, 2015 · 7 comments
Closed

Add un-parse function to ast #68190

larryhastings opened this issue Apr 19, 2015 · 7 comments
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement

Comments

@larryhastings
Copy link
Contributor

BPO 24002
Nosy @birkenfeld, @larryhastings, @benjaminp, @berkerpeksag, @zware, @serhiy-storchaka

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = <Date 2015-04-19.18:17:35.977>
created_at = <Date 2015-04-19.05:39:10.212>
labels = ['type-feature', 'library']
title = 'Add un-parse function to ast'
updated_at = <Date 2015-04-19.18:17:35.976>
user = 'https://github.com/larryhastings'

bugs.python.org fields:

activity = <Date 2015-04-19.18:17:35.976>
actor = 'larry'
assignee = 'none'
closed = True
closed_date = <Date 2015-04-19.18:17:35.977>
closer = 'larry'
components = ['Library (Lib)']
creation = <Date 2015-04-19.05:39:10.212>
creator = 'larry'
dependencies = []
files = []
hgrepos = []
issue_num = 24002
keywords = []
message_count = 7.0
messages = ['241477', '241482', '241483', '241485', '241486', '241487', '241527']
nosy_count = 6.0
nosy_names = ['georg.brandl', 'larry', 'benjamin.peterson', 'berker.peksag', 'zach.ware', 'serhiy.storchaka']
pr_nums = []
priority = 'normal'
resolution = 'later'
stage = 'resolved'
status = 'closed'
superseder = None
type = 'enhancement'
url = 'https://bugs.python.org/issue24002'
versions = ['Python 3.5']

@larryhastings
Copy link
Contributor Author

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.

@larryhastings larryhastings added stdlib Python modules in the Lib dir type-feature A feature request or enhancement labels Apr 19, 2015
@berkerpeksag
Copy link
Member

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.

@larryhastings
Copy link
Contributor Author

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!)

@serhiy-storchaka
Copy link
Member

For bpo-24001 you need rather eval(ast). But a function for stringifying ast would be useful in any case.

@larryhastings
Copy link
Contributor Author

Actually eval(ast) is all I need for bpo-23967 too. But eval is a builtin, so it feels wrong to have it supporting--and therefore dependent on--ast.

@serhiy-storchaka
Copy link
Member

I think there is standard way to transform ast to bytecode and evaluate it.

@larryhastings
Copy link
Contributor Author

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.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
stdlib Python modules in the Lib dir type-feature A feature request or enhancement
Projects
None yet
Development

No branches or pull requests

3 participants