Skip to content

Commit c3d2cd0

Browse files
committed
python ast parsing file
1 parent 269eabc commit c3d2cd0

File tree

1 file changed

+67
-0
lines changed

1 file changed

+67
-0
lines changed

py_to_ast_json.py

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
#!/usr/bin/env python
2+
import argparse
3+
import ast
4+
import json
5+
from _ast import AST
6+
from pathlib import Path
7+
8+
9+
def print_parsed_result(file: Path, out:Path):
10+
node = ast.parse(file.read_text())
11+
12+
json_out = ast2json(node)
13+
14+
# with open(Path(file.stem + "_ast").with_suffix(".json"), "w") as f:
15+
# json.dump(json.loads(json_out), f, indent=2)
16+
17+
with open(Path(out), "w") as f:
18+
json.dump(json.loads(json_out), f, indent=2)
19+
20+
21+
def ast2json(node) -> str:
22+
if not isinstance(node, AST):
23+
raise TypeError('expected AST, got %r' % node.__class__.__name__)
24+
25+
def _format(node) -> str:
26+
if isinstance(node, AST):
27+
name = node.__class__.__name__
28+
fields = [('_PyType', _format(name))]
29+
fields += [(a, _format(b)) for a, b in iter_fields(node)]
30+
return '{ %s }' % ', '.join(('"%s": %s' % field for field in fields))
31+
32+
if isinstance(node, list):
33+
return '[ %s ]' % ', '.join([_format(x) for x in node])
34+
35+
# todo: better handling here?
36+
# this doesn't distinguish between
37+
# some_name: Tuple[a, ...] and some_name: Tuple[a, "..."]
38+
# both are serialized to
39+
# {
40+
# "_PyType": "Constant",
41+
# "value": "...",
42+
# "kind": null
43+
# }
44+
if node is ...:
45+
return json.dumps("...")
46+
47+
return json.dumps(node)
48+
49+
return _format(node)
50+
51+
52+
def iter_fields(node):
53+
for field in node._fields:
54+
try:
55+
yield field, getattr(node, field)
56+
except AttributeError:
57+
pass
58+
59+
60+
if __name__ == '__main__':
61+
parser = argparse.ArgumentParser()
62+
parser.add_argument("py_file")
63+
parser.add_argument("json_dump_file")
64+
65+
args = parser.parse_args()
66+
67+
print_parsed_result(Path(args.py_file), Path(args.json_dump_file))

0 commit comments

Comments
 (0)