|
10 | 10 | from ruamel.yaml.comments import CommentedMap, CommentedSeq
|
11 | 11 |
|
12 | 12 |
|
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: |
15 | 15 | 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 |
23 | 28 | 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) |
28 | 41 |
|
29 | 42 |
|
30 | 43 | def upgrade_data(problem_path: Path, bar: ProgressBar) -> None:
|
@@ -210,16 +223,15 @@ def upgrade_problem_yaml(problem_path: Path, bar: ProgressBar) -> None:
|
210 | 223 | if "source_url" in data:
|
211 | 224 | if "source" not in data:
|
212 | 225 | data["source"] = data["source_url"]
|
213 |
| - if data["source"]: |
| 226 | + elif data["source"]: |
214 | 227 | 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}) |
219 | 231 | else:
|
220 | 232 | bar.log("remove empty 'source(_url)' in problem.yaml")
|
221 | 233 | _filter(data, "source")
|
222 |
| - _filter(data, "source_url") |
| 234 | + _filter(data, "source_url") |
223 | 235 |
|
224 | 236 | if "limits" in data:
|
225 | 237 | limits = data["limits"]
|
|
0 commit comments