Skip to content

Commit 392b4d4

Browse files
committed
Remove all usages of PyYAML, exclusively use ruamel.yaml
1 parent 3a2ee83 commit 392b4d4

File tree

13 files changed

+154
-284
lines changed

13 files changed

+154
-284
lines changed

bapctools/cli.py

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@
5555
error,
5656
fatal,
5757
glob,
58-
has_ryaml,
5958
inc_label,
6059
is_problem_directory,
6160
is_relative_to,
@@ -228,17 +227,14 @@ def key(self) -> tuple[int, int]:
228227
verbose(f"order: {', '.join(map(lambda p: str(p.label), problems))}")
229228

230229
if ask_variable_bool("Update order in contest.yaml"):
231-
if has_ryaml:
232-
contest_yaml_path = Path("contest.yaml")
233-
data = read_yaml(contest_yaml_path) or {}
234-
if not isinstance(data, dict):
235-
error("could not parse contest.yaml.")
236-
else:
237-
data["order"] = "".join(p.label or p.name for p in problems)
238-
write_yaml(data, contest_yaml_path)
239-
log("Updated order")
230+
contest_yaml_path = Path("contest.yaml")
231+
data = read_yaml(contest_yaml_path) or {}
232+
if not isinstance(data, dict):
233+
error("could not parse contest.yaml.")
240234
else:
241-
error("ruamel.yaml library not found. Update the order manually.")
235+
data["order"] = "".join(p.label or p.name for p in problems)
236+
write_yaml(data, contest_yaml_path)
237+
log("Updated order")
242238

243239
# Filter problems by submissions/testcases, if given.
244240
if config.level == "problemset" and (config.args.submissions or config.args.testcases):

bapctools/contest.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from bapctools.util import (
99
error,
1010
fatal,
11-
has_ryaml,
1211
log,
1312
read_yaml,
1413
verbose,
@@ -48,13 +47,6 @@ def __init__(self, yaml_data: Optional[dict[object, object]]) -> None:
4847
def dict(self) -> dict[str, object]:
4948
data = {k: v for k, v in vars(self).items() if not k.startswith("_") and v is not None}
5049
data.update(self._yaml)
51-
if not has_ryaml:
52-
for key in ("duration", "scoreboard_freeze_duration"):
53-
if key in data:
54-
# YAML 1.1 parses 1:00:00 as 3600. Convert it back to a string if so.
55-
# (YAML 1.2 and ruamel.yaml parse it as a string.)
56-
if isinstance(data[key], int):
57-
data[key] = str(datetime.timedelta(seconds=data[key]))
5850
return data
5951

6052

bapctools/export.py

Lines changed: 10 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,12 @@
2323
error,
2424
fatal,
2525
glob,
26-
has_ryaml,
2726
has_substitute,
2827
inc_label,
2928
log,
3029
normalize_yaml_value,
3130
PrintBar,
3231
read_yaml,
33-
require_ruamel,
3432
ryaml_filter,
3533
substitute,
3634
verbose,
@@ -136,7 +134,6 @@ def build_samples_zip(problems: list[Problem], output: Path, languages: list[str
136134
bar.log("done")
137135

138136

139-
@require_ruamel("zip", False)
140137
def build_problem_zip(problem: Problem, output: Path) -> bool:
141138
"""Make DOMjudge/Kattis ZIP file for specified problem."""
142139

@@ -430,7 +427,6 @@ def add_testcase(in_file: Path) -> None:
430427
# solutions*.{lang}.pdf
431428
# problem-slides*.{lang}.pdf
432429
# Output is <outfile>
433-
@require_ruamel("zip", None)
434430
def build_contest_zip(
435431
problems: list[Problem], zipfiles: list[Path], outfile: str, languages: list[str]
436432
) -> None:
@@ -481,15 +477,12 @@ def add_file(file: Path) -> None:
481477

482478

483479
def update_contest_id(cid: str) -> None:
484-
if has_ryaml:
485-
contest_yaml_path = Path("contest.yaml")
486-
data = read_yaml(contest_yaml_path)
487-
assert isinstance(data, dict)
488-
data["contest_id"] = cid
489-
write_yaml(data, contest_yaml_path)
490-
log(f"Updated contest_id to {cid}")
491-
else:
492-
error(f"ruamel.yaml library not found. Update the id manually to {cid}.")
480+
contest_yaml_path = Path("contest.yaml")
481+
data = read_yaml(contest_yaml_path)
482+
assert isinstance(data, dict)
483+
data["contest_id"] = cid
484+
write_yaml(data, contest_yaml_path)
485+
log(f"Updated contest_id to {cid}")
493486

494487

495488
def export_contest(cid: Optional[str]) -> str:
@@ -531,14 +524,11 @@ def export_contest(cid: Optional[str]) -> str:
531524
return new_cid
532525

533526

527+
# Update name and time limit values.
534528
def update_problems_yaml(problems: list[Problem], colors: Optional[list[str]] = None) -> None:
535-
# Update name and time limit values.
536-
if not has_ryaml:
537-
log(
538-
"ruamel.yaml library not found. Make sure to update the name and time limit fields manually."
539-
)
540-
return
541-
529+
# Make sure problems.yaml is formatted correctly.
530+
# We cannot use the resulting `list[ProblemsYamlEntry]`, because we need to edit them.
531+
# TODO #102 Perhaps there's a way that ProblemsYamlEntry can also be a ruamel.yaml CommentedMap?
542532
problems_yaml()
543533

544534
log("Updating problems.yaml")

bapctools/fuzz.py

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from typing import Any, Optional
88

99
from colorama import Style
10+
from ruamel.yaml.comments import CommentedMap, CommentedSeq
1011

1112
from bapctools import config, generate, parallel, problem
1213
from bapctools.run import Run, Submission
@@ -15,20 +16,15 @@
1516
eprint,
1617
error,
1718
fatal,
18-
has_ryaml,
1919
PrintBar,
2020
ProgressBar,
2121
read_yaml,
22-
require_ruamel,
2322
ryaml_get_or_add,
2423
write_yaml,
2524
)
2625
from bapctools.validate import Mode, OutputValidator
2726
from bapctools.verdicts import Verdict
2827

29-
if has_ryaml:
30-
from ruamel.yaml.comments import CommentedMap, CommentedSeq
31-
3228
# STEPS:
3329
# 1. Find generator invocations depending on {seed}.
3430
# 2. Generate a testcase + .ans using the rule using a random seed.
@@ -247,7 +243,6 @@ def add_testcase(t: generate.TestcaseRule) -> None:
247243
# SUBMISSIONS
248244
self.submissions = self.problem.selected_or_accepted_submissions()
249245

250-
@require_ruamel("Fuzz", False)
251246
def run(self) -> bool:
252247
if len(self.testcase_rules) == 0:
253248
error("No invocations depending on {seed} found.")

bapctools/generate.py

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from typing import cast, Final, Literal, Optional, overload, TypeVar
1212

1313
from colorama import Fore, Style
14+
from ruamel.yaml.comments import CommentedMap, CommentedSeq
1415

1516
from bapctools import config, parallel, program, run, validate, visualize
1617
from bapctools.problem import Problem
@@ -26,7 +27,6 @@
2627
fatal,
2728
get_basedirs,
2829
glob,
29-
has_ryaml,
3030
hash_file_content,
3131
hash_string,
3232
is_relative_to,
@@ -35,7 +35,6 @@
3535
PrintBar,
3636
ProgressBar,
3737
read_yaml,
38-
require_ruamel,
3938
ryaml_get_or_add,
4039
shorten_path,
4140
substitute,
@@ -44,10 +43,6 @@
4443
)
4544
from bapctools.verdicts import Verdict
4645

47-
if has_ryaml:
48-
import ruamel.yaml
49-
50-
5146
YAML_TYPE = Optional[str | dict[object, object]]
5247

5348
INCLUSIVE_RANGE_REGEX = re.compile(r"^(-?\d+)\.\.=(-?\d+)$")
@@ -721,7 +716,7 @@ def get(key: str, default: T) -> T:
721716

722717
def write(self) -> None:
723718
data = {k: v for k, v in vars(self).items() if not k.startswith("_")}
724-
write_yaml(data, self._path, allow_yamllib=True)
719+
write_yaml(data, self._path)
725720

726721
def link(
727722
t,
@@ -2244,7 +2239,6 @@ def update_gitignore_file(self) -> None:
22442239

22452240
# add all testcases specified as copy keys in the generators.yaml
22462241
# can handle files and complete directories
2247-
@require_ruamel("generate --upgrade", False)
22482242
def add(self, to_add: Sequence[Path]) -> bool:
22492243
if self.n_parse_error > 0:
22502244
return False
@@ -2268,12 +2262,12 @@ def add(self, to_add: Sequence[Path]) -> bool:
22682262
generators_yaml = self.problem.path / "generators" / "generators.yaml"
22692263
data = read_yaml(generators_yaml)
22702264
if data is None:
2271-
data = ruamel.yaml.comments.CommentedMap()
2272-
assert isinstance(data, ruamel.yaml.comments.CommentedMap)
2265+
data = CommentedMap()
2266+
assert isinstance(data, CommentedMap)
22732267

22742268
parent = ryaml_get_or_add(data, "data")
22752269
parent = ryaml_get_or_add(parent, "secret")
2276-
entry = ryaml_get_or_add(parent, "data", ruamel.yaml.comments.CommentedSeq)
2270+
entry = ryaml_get_or_add(parent, "data", CommentedSeq)
22772271

22782272
bar = ProgressBar("Adding", items=in_files)
22792273
for in_file in sorted(in_files, key=lambda x: x.name):
@@ -2283,12 +2277,10 @@ def add(self, to_add: Sequence[Path]) -> bool:
22832277
elif in_file in known:
22842278
bar.log("already found in generators.yaml. Skipping.")
22852279
else:
2286-
entry.append(ruamel.yaml.comments.CommentedMap())
2280+
entry.append(CommentedMap())
22872281
path_in_gen = in_file.relative_to("generators")
22882282
name = path_in_gen.with_suffix("").as_posix().replace("/", "_")
2289-
new = ruamel.yaml.comments.CommentedMap(
2290-
{"copy": path_in_gen.with_suffix("").as_posix()}
2291-
)
2283+
new = CommentedMap({"copy": path_in_gen.with_suffix("").as_posix()})
22922284
new.fa.set_flow_style()
22932285
entry[-1][str(name)] = new
22942286
bar.log("added to generators.yaml.")
@@ -2302,7 +2294,6 @@ def add(self, to_add: Sequence[Path]) -> bool:
23022294
return True
23032295

23042296
# reorder all testcases in the given directories
2305-
@require_ruamel("generate --reorder", False)
23062297
def reorder(self) -> bool:
23072298
if self.n_parse_error > 0:
23082299
return False

bapctools/problem.py

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
from typing import Final, Literal, Optional, overload, TYPE_CHECKING
99

1010
from colorama import Fore, Style
11+
from ruamel.yaml.comments import CommentedMap
12+
from ruamel.yaml.scanner import ScannerError
1113

1214
from bapctools import (
1315
check_testing_tool,
@@ -30,7 +32,6 @@
3032
fatal,
3133
generate_problem_uuid,
3234
glob,
33-
has_ryaml,
3435
hash_file_content,
3536
is_relative_to,
3637
is_uuid,
@@ -50,9 +51,6 @@
5051
if TYPE_CHECKING: # Prevent circular import: https://stackoverflow.com/a/39757388
5152
from bapctools.program import Program
5253

53-
if has_ryaml:
54-
import ruamel.yaml
55-
5654

5755
class Person:
5856
def __init__(self, yaml_data: str | dict[object, object], parent_path: str):
@@ -517,14 +515,10 @@ def _determine_statement_languages(self) -> list[str]:
517515
def _read_settings(self) -> None:
518516
# parse problem.yaml
519517
yaml_path = self.path / "problem.yaml"
520-
if has_ryaml:
521-
try:
522-
yaml_data = read_yaml(yaml_path)
523-
except ruamel.yaml.scanner.ScannerError:
524-
fatal(f"Make sure {self.name}/problem.yaml does not contain any more {{% ... %}}.")
525-
else:
526-
yaml_data = read_yaml(yaml_path)
527-
yaml_data = yaml_data or {}
518+
try:
519+
yaml_data = read_yaml(yaml_path) or {}
520+
except ScannerError:
521+
fatal(f"Make sure {self.name}/problem.yaml does not contain any more {{% ... %}}.")
528522

529523
if not isinstance(yaml_data, dict):
530524
fatal(f"{self.name}/problem.yaml is illformed.")
@@ -1599,19 +1593,16 @@ def get_slowest(result: verdicts.Verdicts) -> tuple[str, float]:
15991593
eprint()
16001594

16011595
if config.args.write:
1602-
if not has_ryaml:
1603-
warn("ruamel.yaml library not found. Please update the time limit fields manually.")
1596+
yaml_path = problem.path / "problem.yaml"
1597+
problem_yaml = read_yaml(yaml_path)
1598+
if problem_yaml is None:
1599+
problem_yaml = CommentedMap()
1600+
if not isinstance(problem_yaml, CommentedMap):
1601+
warn("could not parse problem.yaml")
16041602
else:
1605-
yaml_path = problem.path / "problem.yaml"
1606-
problem_yaml = read_yaml(yaml_path)
1607-
if problem_yaml is None:
1608-
problem_yaml = ruamel.yaml.comments.CommentedMap()
1609-
if not isinstance(problem_yaml, ruamel.yaml.comments.CommentedMap):
1610-
warn("could not parse problem.yaml")
1611-
else:
1612-
limits = ryaml_get_or_add(problem_yaml, "limits")
1613-
limits["time_limit"] = problem.limits.time_limit
1614-
write_yaml(problem_yaml, problem.path / "problem.yaml")
1603+
limits = ryaml_get_or_add(problem_yaml, "limits")
1604+
limits["time_limit"] = problem.limits.time_limit
1605+
write_yaml(problem_yaml, problem.path / "problem.yaml")
16151606

16161607
submission, testcase, duration = run_all(
16171608
lambda vs: vs == [verdicts.Verdict.TIME_LIMIT_EXCEEDED], min

bapctools/program.py

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -480,11 +480,7 @@ def _compile(self, bar: ProgressBar) -> bool:
480480
bar.error("Failed", data)
481481
return False
482482

483-
write_yaml(
484-
{"hash": self.hash, "command": self.compile_command},
485-
meta_path,
486-
allow_yamllib=True,
487-
)
483+
write_yaml({"hash": self.hash, "command": self.compile_command}, meta_path)
488484
return True
489485

490486
# Return True on success, False on failure.

0 commit comments

Comments
 (0)