Skip to content

Commit 2216d59

Browse files
mzuennimpsijm
andauthored
drop bad support (#445)
* drop bad support * fix * Fix log messages when renaming data/bad/* * [stats] Rename "bad" to "inv" and "good" to "v_o" to stay closer to their actual names --------- Co-authored-by: Maarten Sijm <[email protected]>
1 parent 208e7f4 commit 2216d59

File tree

5 files changed

+75
-25
lines changed

5 files changed

+75
-25
lines changed

bin/config.py

-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,6 @@
8686
"invalid_input",
8787
"invalid_answer",
8888
"invalid_output",
89-
"bad",
9089
]
9190

9291

bin/generate.py

-7
Original file line numberDiff line numberDiff line change
@@ -484,12 +484,6 @@ def __init__(
484484

485485
# root in /data
486486
self.root = self.path.parts[0]
487-
if self.root == "bad":
488-
message(
489-
"bad is deprecated. Use {invalid_input,invalid_answer} instead.",
490-
self.path,
491-
color_type=MessageType.WARN,
492-
)
493487

494488
if not config.COMPILED_FILE_NAME_REGEX.fullmatch(name + ".in"):
495489
raise ParseException("Testcase does not have a valid name.")
@@ -1124,7 +1118,6 @@ def add_testdata_to_cache():
11241118

11251119
# consider specific files for the uniqueness of this testcase
11261120
relevant_files = {
1127-
"bad": [".in", ".ans"],
11281121
"invalid_answer": [".in", ".ans"],
11291122
"invalid_output": [".in", ".ans", ".out"],
11301123
"valid_output": [".in", ".ans", ".out"],

bin/stats.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -68,12 +68,12 @@ def problem_stats(problems):
6868
100,
6969
),
7070
(
71-
"bad",
71+
"inv",
7272
[lambda s: {x.stem for x in s if x.parts[2] in config.INVALID_CASE_DIRECTORIES}],
7373
0,
7474
),
7575
(
76-
"good",
76+
"v_o",
7777
[lambda s: {x.stem for x in s if x.parts[2] in ["valid_output"]}],
7878
0,
7979
),

bin/testcase.py

+1-8
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
fatal,
1111
print_name,
1212
shorten_path,
13-
warn,
1413
)
1514
import config
1615
import validate
@@ -97,12 +96,6 @@ def __init__(self, base_problem, path, *, short_path=None, print_warn=False):
9796
# Display name: everything after data/.
9897
self.name = str(self.short_path.with_suffix(""))
9998

100-
# Backwards compatibility support for `data/bad`.
101-
if self.root == "bad":
102-
if print_warn:
103-
warn("data/bad is deprecated. Use data/{invalid_input,invalid_answer} instead.")
104-
self.root = "invalid_answer" if self.ans_path.is_file() else "invalid_input"
105-
10699
def __repr__(self):
107100
return self.name
108101

@@ -204,7 +197,7 @@ def validate_format(
204197
warn_instead_of_error=warn_instead_of_error,
205198
)
206199
case validate.Mode.INVALID:
207-
assert self.root in config.INVALID_CASE_DIRECTORIES[:-1]
200+
assert self.root in config.INVALID_CASE_DIRECTORIES
208201

209202
ok = self.validate_format(
210203
validate.Mode.INPUT,

bin/upgrade.py

+72-7
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from util import *
44
from validate import InputValidator, AnswerValidator, OutputValidator
55

6+
import secrets
67
import shutil
78
from typing import Any
89

@@ -28,6 +29,34 @@ def upgrade_data(problem_path: Path, bar: ProgressBar) -> None:
2829
bar.log(f"renaming '{old_name}' to '{new_name}'")
2930
old_path.rename(new_path)
3031

32+
def rename_testcase(old_base: Path, new_dir: Path) -> None:
33+
new_dir.mkdir(parents=True, exist_ok=True)
34+
new_base = new_dir / old_base.name
35+
for ext in config.KNOWN_TEXT_DATA_EXTENSIONS:
36+
old_path = old_base.with_suffix(ext)
37+
new_path = new_base.with_suffix(ext)
38+
if old_path.is_file():
39+
old_rel_path, new_rel_path = [
40+
p.relative_to(problem_path) for p in (old_path, new_path)
41+
]
42+
if new_path.exists():
43+
bar.error(
44+
f"can't rename '{old_rel_path}', '{new_rel_path}' already exists",
45+
resume=True,
46+
)
47+
continue
48+
bar.log(f"renaming '{old_rel_path}' to '{new_rel_path}'")
49+
old_path.rename(new_path)
50+
51+
bad_dir = problem_path / "data" / "bad"
52+
for file in bad_dir.glob("*.in"):
53+
if file.with_suffix(".ans").is_file():
54+
rename_testcase(file, problem_path / "data" / "invalid_answer")
55+
else:
56+
rename_testcase(file, problem_path / "data" / "invalid_input")
57+
if bad_dir.is_dir() and not any(bad_dir.iterdir()):
58+
bad_dir.rmdir()
59+
3160

3261
def upgrade_testdata_yaml(problem_path: Path, bar: ProgressBar) -> None:
3362
rename = [
@@ -62,14 +91,16 @@ def upgrade_generators_yaml(problem_path: Path, bar: ProgressBar) -> None:
6291

6392
changed = False
6493

65-
rename = [
66-
("invalid_inputs", "invalid_input"),
67-
("invalid_answers", "invalid_answer"),
68-
("invalid_outputs", "invalid_output"),
69-
("valid_outputs", "valid_output"),
70-
]
7194
if "data" in yaml_data and isinstance(yaml_data["data"], dict):
7295
data = yaml_data["data"]
96+
assert isinstance(data, CommentedMap)
97+
98+
rename = [
99+
("invalid_inputs", "invalid_input"),
100+
("invalid_answers", "invalid_answer"),
101+
("invalid_outputs", "invalid_output"),
102+
("valid_outputs", "valid_output"),
103+
]
73104
for old_name, new_name in rename:
74105
if old_name in data:
75106
if new_name in data:
@@ -82,6 +113,40 @@ def upgrade_generators_yaml(problem_path: Path, bar: ProgressBar) -> None:
82113
ryaml_replace(data, old_name, new_name)
83114
changed = True
84115

116+
# this breaks comments... but that is fine
117+
if "bad" in data:
118+
119+
def move_testcase(name: str, value: Any, new_parent: str) -> None:
120+
parent = ryaml_get_or_add(data, new_parent)
121+
if "data" not in parent:
122+
parent[data] = CommentedSeq
123+
parent = parent["data"]
124+
new_name = name
125+
if isinstance(parent, list):
126+
parent.append(CommentedMap())
127+
parent[-1][new_name] = value
128+
else:
129+
if new_name in parent:
130+
new_name = f"bad_{new_name}"
131+
if new_name in parent:
132+
new_name = f"{new_name}_{secrets.token_hex(6)}"
133+
assert new_name not in parent
134+
parent[new_name] = value
135+
bar.log(f"renaming 'bad.{name}' to '{new_parent}.{new_name}' in generators.yaml")
136+
137+
bad = data["bad"]
138+
if "data" in bad and bad["data"]:
139+
children = bad["data"] if isinstance(bad["data"], list) else [bad["data"]]
140+
for dictionary in children:
141+
for child_name, child_data in sorted(dictionary.items()):
142+
if "ans" in child_data:
143+
move_testcase(child_name, child_data, "invalid_answer")
144+
else:
145+
move_testcase(child_name, child_data, "invalid_input")
146+
147+
ryaml_filter(data, "bad")
148+
changed = True
149+
85150
def upgrade_generated_testdata_yaml(data: dict[str, Any], path: str) -> bool:
86151
changed = False
87152
if "testdata.yaml" in data:
@@ -374,7 +439,7 @@ def add_args(new_data: dict[str, Any]) -> bool:
374439
data["limits"] = CommentedMap()
375440
if "time_limit" in data["limits"]:
376441
bar.error(
377-
"can't change '.timelimit' file, 'limits.time_limit' already exists in problem.yaml",
442+
"can't change 'domjudge-problem.ini' file, 'limits.time_limit' already exists in problem.yaml",
378443
resume=True,
379444
)
380445
else:

0 commit comments

Comments
 (0)