Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions bin/export.py
Original file line number Diff line number Diff line change
Expand Up @@ -330,9 +330,8 @@ def add_testcase(in_file: Path) -> None:
validator_flags = " ".join(
problem.get_test_case_yaml(
problem.path / "data",
OutputValidator.args_key,
PrintBar("Zip", item="Getting validator_flags for legacy export"),
)
).output_validator_args
)
if validator_flags:
yaml_data["validator_flags"] = validator_flags
Expand Down
46 changes: 35 additions & 11 deletions bin/generate.py
Original file line number Diff line number Diff line change
Expand Up @@ -391,10 +391,8 @@ def __init__(
self.random_salt: str = ""
self.retries: int = 1
else:
self.needs_default_solution = parent_config.needs_default_solution
self.solution = parent_config.solution
self.random_salt = parent_config.random_salt
self.retries = parent_config.retries
for key, value in vars(parent_config).items():
setattr(self, key, value)

if yaml is not None:
if "solution" in yaml:
Expand Down Expand Up @@ -489,6 +487,11 @@ def __init__(
# used to handle duplicated testcase rules
self.copy_of = None

# set during generate
self.generate_success = False

self.process = generator_config.process_testcase(parent.path / name)

bar = PrintBar("generators.yaml", item=parent.path / name)

if name.endswith(".in"):
Expand Down Expand Up @@ -685,6 +688,8 @@ def write(self) -> None:
def link(
t, problem: Problem, generator_config: "GeneratorConfig", bar: ProgressBar, dst: Path
) -> None:
assert t.process

src_dir = problem.path / "data" / t.path.parent
src = src_dir / (t.name + ".in")

Expand Down Expand Up @@ -722,6 +727,8 @@ def validate_in(
meta_yaml: "TestcaseRule.MetaYaml",
bar: ProgressBar,
) -> bool:
assert t.process

infile = problem.tmpdir / "data" / t.hash / "testcase.in"
assert infile.is_file()

Expand Down Expand Up @@ -769,6 +776,8 @@ def validate_ans_and_out(
meta_yaml: "TestcaseRule.MetaYaml",
bar: ProgressBar,
) -> bool:
assert t.process

infile = problem.tmpdir / "data" / t.hash / "testcase.in"
assert infile.is_file()

Expand Down Expand Up @@ -820,9 +829,9 @@ def validate_ans_and_out(
def generate(
t, problem: Problem, generator_config: "GeneratorConfig", parent_bar: ProgressBar
) -> None:
bar = parent_bar.start(str(t.path))
assert t.process

t.generate_success = False
bar = parent_bar.start(str(t.path))

if t.copy_of is not None and not t.intended_copy:
bar.warn(
Expand Down Expand Up @@ -1098,10 +1107,12 @@ def use_feedback_image(feedbackdir: Path, source: str) -> None:
visualize.InputVisualizer
)
output_visualizer = problem.visualizer(visualize.OutputVisualizer)
visualizer_args = testcase.get_test_case_yaml(bar).input_visualizer_args
if output_visualizer is not None:
if out_path.is_file() or problem.settings.ans_is_output:
if visualizer is None or out_path.is_file():
visualizer = output_visualizer
visualizer_args = testcase.get_test_case_yaml(bar).output_visualizer_args
if not out_path.is_file():
assert problem.settings.ans_is_output
out_path = ans_path
Expand All @@ -1112,7 +1123,6 @@ def use_feedback_image(feedbackdir: Path, source: str) -> None:
use_feedback_image(feedbackdir, "validator")
return True

visualizer_args = testcase.test_case_yaml_args(visualizer, bar)
visualizer_hash: dict[object, object] = {
"visualizer_hash": visualizer.hash,
"visualizer_args": visualizer_args,
Expand Down Expand Up @@ -1397,6 +1407,8 @@ def __init__(
def walk(
self,
testcase_f: Optional[Callable[["TestcaseRule | Directory"], object]],
*,
skip_restricted: bool = True,
) -> None: ...

# This overload takes one function for test cases and a separate function for directories.
Expand All @@ -1405,6 +1417,8 @@ def walk(
self,
testcase_f: Optional[Callable[[TestcaseRule], object]],
dir_f: Optional[Callable[["Directory"], object]],
*,
skip_restricted: bool = True,
) -> None: ...

# Map a function over all test cases directory tree.
Expand All @@ -1418,6 +1432,8 @@ def walk(
| Optional[
Callable[["TestcaseRule | Directory"], object] | Callable[["Directory"], object]
] = True,
*,
skip_restricted: bool = True,
) -> None:
if dir_f is True:
dir_f = cast(Optional[Callable[["TestcaseRule | Directory"], object]], testcase_f)
Expand All @@ -1428,6 +1444,8 @@ def walk(
if isinstance(d, Directory):
d.walk(testcase_f, dir_f)
elif isinstance(d, TestcaseRule):
if not d.process and skip_restricted:
continue
if testcase_f:
testcase_f(d)
else:
Expand Down Expand Up @@ -1480,11 +1498,20 @@ def generate_includes(
t = d.includes[key]
target = t.path
new_case = d.path / target.name

if not generator_config.process_testcase(new_case):
continue

bar.start(str(new_case))
infile = problem.path / "data" / target.parent / (target.name + ".in")
ansfile = problem.path / "data" / target.parent / (target.name + ".ans")
new_infile = problem.path / "data" / d.path / (target.name + ".in")

if not t.process:
bar.warn(f"Included case {target} was not processed.")
bar.done()
continue

if not t.generate_success:
bar.error(f"Included case {target} has errors.")
bar.done()
Expand Down Expand Up @@ -1713,10 +1740,6 @@ def parse(
if has_count(yaml):
name += f"-{count_index + 1:0{len(str(count))}}"

# If a list of testcases was passed and this one is not in it, skip it.
if not self.process_testcase(parent.path / name):
continue

t = TestcaseRule(self.problem, self, key, name, yaml, parent, count_index)
if t.path in self.known_cases:
PrintBar("generators.yaml", item=t.path).error(
Expand Down Expand Up @@ -1857,6 +1880,7 @@ def add_included_case(t: TestcaseRule) -> None:
obj.walk(
add_included_case,
lambda d: list(map(add_included_case, d.includes.values())),
skip_restricted=False,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What exactly does this mean?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when doing bt generate you can provide a list of testcases and then only those testcases get regenerated. This was implemented by just skipping them during the walk function. But if you now include a testcase which was skipped you would get the error "unknown testcase" which is wrong, the include should walk over all testcases ^^

)
pass
else:
Expand Down
7 changes: 3 additions & 4 deletions bin/interactive.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,10 +67,9 @@ def get_validator_command() -> Sequence[str | Path]:
run.in_path.absolute(),
run.testcase.ans_path.absolute(),
run.feedbackdir.absolute(),
*run.testcase.test_case_yaml_args(
output_validator,
bar or PrintBar("Run interactive test case"),
),
*run.testcase.get_test_case_yaml(
bar or PrintBar("Run interactive test case")
).output_validator_args,
]

assert run.submission.run_command, "Submission must be built"
Expand Down
Loading
Loading