In python3.8.5,I use gast to modify ast_node then convert back into ast bygast_to_ast. But the result is different with original ast.
It works in Python3.5 and Python2.7
The example code:
import ast
import gast
import textwrap
import unittest
def code_gast_ast(source):
"""
Transform source_code into gast.Node and modify it,
then back to ast.Node.
"""
source = textwrap.dedent(source)
root = gast.parse(source)
new_root = GastNodeTransformer(root).apply()
ast_root = gast.gast_to_ast(new_root)
return ast.dump(ast_root)
def code_ast(source):
"""
Transform source_code into ast.Node, then dump it.
"""
source = textwrap.dedent(source)
root = ast.parse(source)
return ast.dump(root)
class GastNodeTransformer(gast.NodeTransformer):
def __init__(self, root):
self.root = root
def apply(self):
return self.generic_visit(self.root)
def visit_Name(self, node):
"""
Param in func is ast.Name in PY2, but ast.arg in PY3.
It will be generally represented by gast.Name in gast.
"""
if isinstance(node.ctx, gast.Param) and node.id != "self":
node.id += '_new'
return node
class TestPythonCompatibility(unittest.TestCase):
def _check_compatibility(self, source, target):
source_dump = code_gast_ast(source)
target_dump = code_ast(target)
self.assertEqual(source_dump, target_dump)
def test_call(self):
source = """
y = foo(*arg)
"""
target = """
y = foo(*arg_new)
"""
self._check_compatibility(source, target)
# source_dump gast-> ast
# Module(body=[Assign(targets=[Name(id='y', ctx=Store())], value=Call(func=Name(id='foo', ctx=Load()), args=[Starred(value=Name(id='arg_new', ctx=Load()), ctx=Load())], keywords=[]))], type_ignores=[])
# target_dump ast
# Module(body=[Assign(targets=[Name(id='y', ctx=Store())], value=Call(func=Name(id='foo', ctx=Load()), args=[Starred(value=Name(id='arg_new', ctx=Load()), ctx=Load())], keywords=[]), type_comment=None)], type_ignores=[])
After I modified the defination in gast.py, it works in python3.8
from
('Assign', (('targets', 'value',),
('lineno', 'col_offset', 'end_lineno', 'end_col_offset',),
(stmt,))),
into
('Assign', (('targets', 'value','type_comment'),
('lineno', 'col_offset', 'end_lineno', 'end_col_offset',),
(stmt,))),
In python3.8.5,I use gast to modify ast_node then convert back into ast by
gast_to_ast. But the result is different with originalast.It works in Python3.5 and Python2.7
The example code:
After I modified the defination in
gast.py, it works in python3.8from
into