Skip to content

Commit 7bb4dd0

Browse files
committed
[upgrade] Improve replacing of keys at their original position
1 parent b4efccd commit 7bb4dd0

File tree

1 file changed

+27
-18
lines changed

1 file changed

+27
-18
lines changed

bin/upgrade.py

Lines changed: 27 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,15 @@ def _filter(data: Any, remove: str) -> Any:
4040
return data.pop(remove)
4141

4242

43+
# Insert a new key before an old key, then remove the old key.
44+
# If new_value is not given, the default is to simply rename the old key to the new key.
45+
def _replace(data: Any, old_key: str, new_key: str, new_value: Any = None) -> None:
46+
if new_value is None:
47+
new_value = data[old_key]
48+
data.insert(list(data.keys()).index(old_key), new_key, new_value)
49+
_filter(data, old_key)
50+
51+
4352
def upgrade_data(problem_path: Path, bar: ProgressBar) -> None:
4453
rename = [
4554
("data/invalid_inputs", "data/invalid_input"),
@@ -61,7 +70,7 @@ def upgrade_data(problem_path: Path, bar: ProgressBar) -> None:
6170
def upgrade_testdata_yaml(problem_path: Path, bar: ProgressBar) -> None:
6271
rename = [
6372
("output_validator_flags", "output_validator_args"),
64-
("inut_validator_flags", "inut_validator_args"),
73+
("input_validator_flags", "input_validator_args"),
6574
]
6675

6776
for f in (problem_path / "data").rglob("testdata.yaml"):
@@ -76,8 +85,7 @@ def upgrade_testdata_yaml(problem_path: Path, bar: ProgressBar) -> None:
7685
resume=True,
7786
)
7887
continue
79-
data[new] = data[old]
80-
data.pop(old)
88+
_replace(data, old, new)
8189

8290
write_yaml(data, f)
8391

@@ -105,8 +113,7 @@ def upgrade_generators_yaml(problem_path: Path, bar: ProgressBar) -> None:
105113
)
106114
continue
107115
bar.log(f"renaming 'data.{old_name}' to 'data.{new_name}' in generators.yaml")
108-
data[new_name] = data[old_name]
109-
data.pop(old_name)
116+
_replace(data, old_name, new_name)
110117

111118
def upgrade_generated_testdata_yaml(data: dict[str, Any], path: str) -> None:
112119
if "testdata.yaml" in data:
@@ -130,8 +137,7 @@ def upgrade_generated_testdata_yaml(data: dict[str, Any], path: str) -> None:
130137
f"change '{old}' to '{new}' in generators.yaml{print_path}",
131138
resume=True,
132139
)
133-
testdata[new] = testdata[old]
134-
testdata.pop(old)
140+
_replace(testdata, old, new)
135141
if "data" in data and data["data"]:
136142
children = data["data"] if isinstance(data["data"], list) else [data["data"]]
137143
for dictionary in children:
@@ -149,18 +155,18 @@ def upgrade_statement(problem_path: Path, bar: ProgressBar) -> None:
149155
if (problem_path / "statement").exists():
150156
bar.error("can't rename 'problem_statement/', 'statement/' already exists", resume=True)
151157
return
152-
bar.log("renaming 'problem_statement/' to 'statement/' in generators.yaml")
158+
bar.log("renaming 'problem_statement/' to 'statement/'")
153159
(problem_path / "problem_statement").rename(problem_path / "statement")
154160

155161
origin = problem_path / "statement"
156162
move = [
157163
("solution*", "solution"),
158-
("problem-slide*", "problem_slid"),
164+
("problem-slide*", "problem_slide"),
159165
]
160166
for glob, dest_name in move:
161167
dest_path = problem_path / dest_name
162168
if dest_path.exists() and not dest_path.is_dir():
163-
bar.error("'dest_name/' is not an directory", resume=True)
169+
bar.error(f"'{dest_name}' is not a directory", resume=True)
164170
continue
165171

166172
for f in origin.glob(glob):
@@ -187,7 +193,7 @@ def upgrade_problem_yaml(problem_path: Path, bar: ProgressBar) -> None:
187193
or data["problem_format_version"] != config.SPEC_VERSION
188194
):
189195
bar.log("set 'problem_format_version' in problem.yaml")
190-
data["problem_format_version"] = config.SPEC_VERSION
196+
data.insert(0, "problem_format_version", config.SPEC_VERSION)
191197

192198
if "validation" in data:
193199
if "type" in data:
@@ -203,7 +209,8 @@ def upgrade_problem_yaml(problem_path: Path, bar: ProgressBar) -> None:
203209
type.append("multi-pass")
204210
if not type:
205211
type.append("pass-fail")
206-
data["type"] = type if len(type) > 1 else type[0]
212+
# "type" comes before "name" in the spec
213+
data.insert(list(data.keys()).index("name"), "type", type if len(type) > 1 else type[0])
207214
_filter(data, "validation")
208215

209216
if "author" in data:
@@ -216,18 +223,20 @@ def upgrade_problem_yaml(problem_path: Path, bar: ProgressBar) -> None:
216223
authors = CommentedSeq(
217224
name.strip() for name in data["author"].replace("and", ",").split(",")
218225
)
219-
data["credits"] = CommentedMap()
220-
data["credits"]["authors"] = authors if len(authors) > 1 else authors[0]
221-
_filter(data, "author")
226+
credits = CommentedMap({"authors": authors if len(authors) > 1 else authors[0]})
227+
_replace(data, "author", "credits", credits)
222228

223229
if "source_url" in data:
224230
if "source" not in data:
225-
data["source"] = data["source_url"]
231+
_replace(data, "source_url", "source")
226232
elif data["source"]:
227233
bar.log("change 'source_url' to 'source.url' in problem.yaml")
234+
old_pos = list(data.keys()).index("source")
228235
old_source = _filter(data, "source")
229236
old_source_url = _filter(data, "source_url")
230-
data["source"] = CommentedMap({"name": old_source, "url": old_source_url})
237+
data.insert(
238+
old_pos, "source", CommentedMap({"name": old_source, "url": old_source_url})
239+
)
231240
else:
232241
bar.log("remove empty 'source(_url)' in problem.yaml")
233242
_filter(data, "source")
@@ -286,7 +295,7 @@ def add_args(new_data: dict[str, Any]) -> bool:
286295
if "testdata.yaml" not in generators_data:
287296
if "data" in generators_data:
288297
# insert before data
289-
pos = [*generators_data.keys()].index("data")
298+
pos = list(generators_data.keys()).index("data")
290299
generators_data.insert(pos, "testdata.yaml", CommentedMap())
291300
else:
292301
# insert at end

0 commit comments

Comments
 (0)