Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I replace a variable name with a value in a Python AST?

I want my users to be able to enter arithmetical expressions on the command line in Python syntax and have the variable names replaced by values at runtime. I don't want to just use eval, I want to use Abstract Syntax Trees.

For example, say I want to rewrite every variable in an AST with the value 3.5 and then evaluate it. From reading the documentation, I came up with this.

import ast

class RewriteName(ast.NodeTransformer):

    def visit_Name(self, node):
        return ast.copy_location(ast.Num(n=3.5, ctx=node.ctx), node)

tree = ast.parse('a + b', 'eval')
tree = RewriteName().visit(tree)
ast.fix_missing_locations(tree)
o = compile(tree, '<string>', 'eval')
print(eval(o))

I want this to print 7.0 but instead I get the following error.

o = compile(tree, '<string>', 'eval')
TypeError: expected Expression node, got Module

I understand that AST confusing nomenclature about Expression vs. Expr, but I haven't been able to find an example of how to sort through this. I tried various arguments to compile including running it on various subnodes of tree thinking that one of those might be Expression I need, but so far without success.

What is example code that makes this work?

like image 238
W.P. McNeill Avatar asked Oct 12 '25 19:10

W.P. McNeill


1 Answers

I was calling ast.parse with the wrong arguments. The correct call is

tree = ast.parse('a+b', '', eval)

(See the comment above.)

like image 200
W.P. McNeill Avatar answered Oct 15 '25 12:10

W.P. McNeill