Skip to content

Commit b4efccd

Browse files
committed
[upgrade] Improve preserving of comments when removing keys
1 parent 718f123 commit b4efccd

File tree

1 file changed

+31
-19
lines changed

1 file changed

+31
-19
lines changed

bin/upgrade.py

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,34 @@
1010
from ruamel.yaml.comments import CommentedMap, CommentedSeq
1111

1212

13-
# this is slow but tries to preserve the correct comments
14-
def _filter(data: Any, remove: str) -> None:
13+
# This tries to preserve the correct comments.
14+
def _filter(data: Any, remove: str) -> Any:
1515
assert isinstance(data, CommentedMap)
16-
prev = None
17-
for key in data:
18-
if key == remove:
19-
break
20-
while prev and isinstance(prev, (list, dict)):
21-
if isinstance(prev, list):
22-
prev = prev[-1]
16+
17+
remove_index = list(data.keys()).index(remove)
18+
if remove_index == 0:
19+
return data.pop(remove)
20+
21+
curr = data
22+
prev_key = list(data.keys())[remove_index - 1]
23+
while isinstance(curr[prev_key], list | dict):
24+
# Try to remove the comment from the last element in the preceding list/dict
25+
curr = curr[prev_key]
26+
if isinstance(curr, list):
27+
prev_key = len(curr) - 1
2328
else:
24-
prev = prev[prev.keys()[-1]]
25-
if prev is not None:
26-
data.ca.items[prev] = data.ca.items.pop(key)
27-
data.pop(key)
29+
prev_key = list(curr.keys())[-1]
30+
31+
if remove in data.ca.items:
32+
# Move the comment that belongs to the removed key (which comes _after_ the removed key)
33+
# to the preceding key
34+
curr.ca.items[prev_key] = data.ca.items.pop(remove)
35+
else:
36+
# If the removed key does not have a comment,
37+
# the comment after the previous key should be removed
38+
curr.ca.items.pop(prev_key)
39+
40+
return data.pop(remove)
2841

2942

3043
def upgrade_data(problem_path: Path, bar: ProgressBar) -> None:
@@ -210,16 +223,15 @@ def upgrade_problem_yaml(problem_path: Path, bar: ProgressBar) -> None:
210223
if "source_url" in data:
211224
if "source" not in data:
212225
data["source"] = data["source_url"]
213-
if data["source"]:
226+
elif data["source"]:
214227
bar.log("change 'source_url' to 'source.url' in problem.yaml")
215-
source = CommentedMap()
216-
source["name"] = data["source"]
217-
source["url"] = data["source_url"]
218-
data["source"] = source
228+
old_source = _filter(data, "source")
229+
old_source_url = _filter(data, "source_url")
230+
data["source"] = CommentedMap({"name": old_source, "url": old_source_url})
219231
else:
220232
bar.log("remove empty 'source(_url)' in problem.yaml")
221233
_filter(data, "source")
222-
_filter(data, "source_url")
234+
_filter(data, "source_url")
223235

224236
if "limits" in data:
225237
limits = data["limits"]

0 commit comments

Comments
 (0)