-
-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy path__init__.py
More file actions
130 lines (100 loc) · 3.79 KB
/
__init__.py
File metadata and controls
130 lines (100 loc) · 3.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
"""
Representer for Python.
"""
import json
from typing import Dict
from . import utils
from .normalizer import Normalizer
class Representer:
"""
Represent Python code in normalized form.
"""
def __init__(self, source: str) -> None:
self._tree = utils.parse(source)
self._normalizer = Normalizer()
self.metadata = {"version" : 2}
def normalize(self) -> None:
"""
Normalize the tree.
"""
self._tree = self._normalizer.visit(self._tree)
def clean_up_normalization(self) -> None:
"""
Clean up the tree normalization, replacing empty ClassDef
and Function Def bodies with pass, so that black is happy
formatting them.
"""
self._tree = self._normalizer.fix_empty_bodies(self._tree)
def dump_tree(self) -> str:
"""
Dump the current state of the tree for printing.
"""
return utils.dump_tree(self._tree)
def dump_ast(self) -> str:
"""
Dump the current stat of the tree without indents.
"""
return utils.dump_ast(self._tree)
def dump_code(self, reformat=True) -> str:
"""
Dump the current tree as generate code.
"""
code = utils.to_source(self._tree)
if reformat:
return utils.reformat(code)
return code
@property
def mapping(self) -> Dict[str, str]:
"""
Get the placeholder assignments after normalize.
"""
return self._normalizer.get_placeholders()
def dump_map(self) -> str:
"""
Dump the tree's mapping of placeholders.
"""
return utils.to_json(self.mapping)
def dump_metadata(self) -> Dict[str, int]:
"""
Dump the representer metadata.
"""
return utils.to_json(self.metadata)
def represent(slug: utils.Slug, input: utils.Directory, output: utils.Directory) -> None:
"""
Normalize the `directory/slug.py` file representation.
"""
# get exercise name from config file or compose it from the passed-in slug
config_file = input.joinpath(".meta").joinpath("config.json")
src = None
if config_file.is_file():
config_data = json.loads(config_file.read_text()).get("files", {}).get("solution", [])
if config_data:
src = input.joinpath(config_data[0])
else:
raise FileNotFoundError("No exercise file was found in config.json.")
else:
src = f'{input.joinpath(slug.replace("-", "_"))}.py'
if not src.is_file():
print('No exercise file was found in the input directory.', err)
return
out_dst = output.joinpath("representation.out")
txt_dst = output.joinpath("representation.txt")
map_dst = output.joinpath("mapping.json")
metadata_dst = output.joinpath("representation.json")
# parse the tree from the file contents
representation = Representer(src.read_text())
# save dump of the initial tree for debug
out = ['## BEGIN TREE BEFORE ##', representation.dump_tree(), '## END TREE BEFORE ##', '']
# normalize the tree
representation.normalize()
# clean up missing function and class bodies with pass
representation.clean_up_normalization()
# save dump of normalized code for debug (from un-parsing the normalized AST).
out[0:0] = ['## BEGIN NORMALIZED CODE ##', representation.dump_code(), "## END NORMALIZED CODE ##", '']
# save dump of the normalized tree for debug
out.extend(['## BEGIN NORMALIZED TREE ##', representation.dump_tree(), '## END NORMALIZED TREE ##'])
# dump the representation files
out_dst.write_text("\n".join(out))
txt_dst.write_text(representation.dump_ast())
map_dst.write_text(representation.dump_map())
metadata_dst.write_text(representation.dump_metadata())