Suppose I have the following string:
code = """
if 1 == 1 and 2 == 2 and 3 == 3:
test = 1
"""
The following code converts that string in a AST.
ast.parse(code)
Then I have a tree like:
Module(body=[<_ast.If object at 0x100747358>])
If(test=BoolOp(op=And(), values=[<_ast.Compare object at 0x100747438>, <_ast.Compare object at 0x100747a90>, <_ast.Compare object at 0x100747d68>]), body=[<_ast.Assign object at 0x100747e48>], orelse=[])
I want to know if there is a way to convert the object at.If into the string if 1 == 1 and 2 == 2 and 3 == 3:
I know it can be done traversing the children node, but it's getting too complicated that way.
3 Answers 3
Python 3.9 introduced ast.unparse which does exactly this, i.e. it reverses ast.parse. Using your example:
import ast
code = """
if 1 == 1 and 2 == 2 and 3 == 3:
test = 1
"""
tree = ast.parse(code)
print(ast.unparse(tree))
This will print out:
if 1 == 1 and 2 == 2 and (3 == 3):
test = 1
Note that there may be slight differences to the original input.
Comments
ast.get_source_segment was added in python 3.8:
>>> import ast
>>> code = """
>>> if 1 == 1 and 2 == 2 and 3 == 3:
>>> test = 1
>>> """
>>> node = ast.parse(code)
>>> ast.get_source_segment(code, node.body[0])
'if 1 == 1 and 2 == 2 and 3 == 3:\n test = 1'
Comments
You can use the astunparse library which was basically just code from the core, repackaged individually.
First, install the library:
pip install astunparse
Then, run your AST module through it to get the source right back. So running:
import ast
import astunparse
code = """
if 1 == 1 and 2 == 2 and 3 == 3:
test = 1
"""
node = ast.parse(code)
astunparse.unparse(node)
Will output:
'\nif ((1 == 1) and (2 == 2) and (3 == 3)):\n test = 1\n'
traversing the children node,<- that's the only way I know how to do itastor