rbx.cp 0.5.45__tar.gz → 0.5.46__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/PKG-INFO +1 -1
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/pyproject.toml +1 -1
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/generators.py +77 -40
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/solutions.py +5 -3
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/statements/builders.py +22 -3
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/tasks.py +12 -4
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/testcase_utils.py +66 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/sandboxes/isolate.py +2 -2
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/sandboxes/stupid_sandbox.py +1 -1
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/LICENSE +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/README.md +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/annotations.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/autoenum.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/builder.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/cd.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/checkers.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/cli.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/code.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/compile.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/conftest.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/contest/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/contest/build_contest_statements.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/contest/contest_package.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/contest/contest_utils.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/contest/main.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/contest/schema.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/contest/statements.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/creation.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/deferred.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/download.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/environment.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/extensions.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/formatting.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/generators_test.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/lazy_importing_main.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/lazy_importing_test.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/main.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/package.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/packaging/boca/extension.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/packaging/boca/packager.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/packaging/contest_main.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/packaging/main.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/packaging/moj/packager.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/packaging/packager.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/packaging/polygon/packager.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/packaging/polygon/test.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/packaging/polygon/xml_schema.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/presets/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/presets/fetch.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/presets/lock_schema.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/presets/schema.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/retries.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/sanitizers/warning_stack.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/schema.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/setter_config.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/solutions_test.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/state.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/statements/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/statements/build_statements.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/statements/joiners.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/statements/latex.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/statements/latex_jinja.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/statements/schema.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/stresses.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/stressing/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/stressing/finder_parser.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/stressing/generator_parser.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/testcase_extractors.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/testcases/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/testcases/main.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/ui/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/ui/captured_log.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/ui/css/app.tcss +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/ui/main.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/ui/run.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/unit.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/validators.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/box/validators_test.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/checker.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/clone.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/config.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/conftest.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/console.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/create.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/edit.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/caching.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/conftest.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/cacher.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/digester.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/sandbox.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/sandboxes/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/sandboxes/timeit.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/storage.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/test.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/judge/testiso.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/steps.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/steps_with_caching.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading/steps_with_caching_run_test.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/grading_utils.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/hydration.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/main.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/metadata.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/providers/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/providers/codeforces.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/providers/provider.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/checkers/boilerplate.cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/default_config.json +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/default_setter_config.mac.yml +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/default_setter_config.yml +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/envs/default.rbx.yml +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/envs/isolate.rbx.yml +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/checker.sh +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/compare +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/compile/c +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/compile/cc +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/compile/cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/compile/java +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/compile/kt +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/compile/pas +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/compile/py2 +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/compile/py3 +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/run/c +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/run/cc +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/run/cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/run/java +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/run/kt +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/run/py2 +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/boca/run/py3 +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/packagers/moj/scripts/compare.sh +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/contest/statement/olymp.sty +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/contest/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/preset.rbx.yml +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/.gitignore +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/gen.cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/problem.rbx.yml +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/random.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/random.txt +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/sols/slow.cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/sols/wa.cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/statement/olymp.sty +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/statement/projecao.png +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/tests/samples/000.in +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/tests/samples/001.in +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/validator.cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/templates/template.cpp +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/run.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/schema.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/submit.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/submitors/__init__.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/submitors/codeforces.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/submitors/submitor.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/test.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/testcase.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/testcase_rendering.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/testing_utils.py +0 -0
- {rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/utils.py +0 -0
@@ -1,6 +1,5 @@
|
|
1
1
|
import pathlib
|
2
2
|
import shutil
|
3
|
-
import tempfile
|
4
3
|
from typing import Dict, List, Optional, Set
|
5
4
|
|
6
5
|
import typer
|
@@ -63,6 +62,47 @@ def _copy_testcase_over(
|
|
63
62
|
)
|
64
63
|
|
65
64
|
|
65
|
+
def _copy_testcase_output_over(
|
66
|
+
src_output_path: pathlib.Path, dest_output_path: pathlib.Path, suffix: str
|
67
|
+
) -> bool:
|
68
|
+
dest_output_path.parent.mkdir(parents=True, exist_ok=True)
|
69
|
+
|
70
|
+
src_path = src_output_path.with_suffix(suffix)
|
71
|
+
if not src_path.is_file():
|
72
|
+
return False
|
73
|
+
|
74
|
+
shutil.copy(str(src_path), str(dest_output_path.with_suffix(suffix)))
|
75
|
+
return True
|
76
|
+
|
77
|
+
|
78
|
+
def _copy_testcase_outputs_over(
|
79
|
+
testcase: Testcase, dest: Testcase, pipes: bool = False
|
80
|
+
):
|
81
|
+
assert dest.outputPath is not None
|
82
|
+
dest.outputPath.parent.mkdir(parents=True, exist_ok=True)
|
83
|
+
|
84
|
+
has_copied = False
|
85
|
+
|
86
|
+
if testcase.outputPath is not None and testcase.outputPath.is_file():
|
87
|
+
shutil.copy(str(testcase.outputPath), str(dest.outputPath))
|
88
|
+
has_copied = True
|
89
|
+
|
90
|
+
if not pipes:
|
91
|
+
return has_copied
|
92
|
+
|
93
|
+
reference_path = testcase.outputPath or testcase.inputPath
|
94
|
+
if _copy_testcase_output_over(reference_path, dest.outputPath, '.pin'):
|
95
|
+
has_copied = True
|
96
|
+
|
97
|
+
if _copy_testcase_output_over(reference_path, dest.outputPath, '.pout'):
|
98
|
+
has_copied = True
|
99
|
+
|
100
|
+
if _copy_testcase_output_over(reference_path, dest.outputPath, '.pio'):
|
101
|
+
has_copied = True
|
102
|
+
|
103
|
+
return has_copied
|
104
|
+
|
105
|
+
|
66
106
|
def get_all_built_testcases() -> Dict[str, List[Testcase]]:
|
67
107
|
pkg = package.find_problem_package_or_die()
|
68
108
|
res = {group.name: find_built_testcases(group) for group in pkg.testcases}
|
@@ -256,59 +296,46 @@ async def generate_testcases(
|
|
256
296
|
async def generate_output_for_testcase(
|
257
297
|
main_solution_digest: str,
|
258
298
|
testcase: Testcase,
|
259
|
-
stderr_path: Optional[pathlib.Path] = None,
|
260
299
|
interactor_digest: Optional[str] = None,
|
261
300
|
):
|
262
301
|
assert testcase.outputPath is not None
|
263
302
|
testcase.inputPath.parent.mkdir(parents=True, exist_ok=True)
|
264
303
|
testcase.outputPath.parent.mkdir(parents=True, exist_ok=True)
|
265
304
|
|
266
|
-
if testcase.outputPath.is_file():
|
267
|
-
# Output file was already copied over from manual tests.
|
268
|
-
return
|
269
|
-
|
270
305
|
main_solution = package.get_main_solution()
|
271
306
|
if main_solution is None:
|
272
307
|
return
|
273
308
|
|
274
|
-
|
275
|
-
|
309
|
+
eval: Evaluation = await run_solution_on_testcase(
|
310
|
+
main_solution,
|
311
|
+
main_solution_digest,
|
312
|
+
None,
|
313
|
+
testcase,
|
314
|
+
interactor_digest=interactor_digest,
|
315
|
+
use_retries=False,
|
316
|
+
use_timelimit=False,
|
317
|
+
capture_pipes=True,
|
318
|
+
)
|
276
319
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
None,
|
281
|
-
testcase,
|
282
|
-
output_dir,
|
283
|
-
interactor_digest=interactor_digest,
|
284
|
-
use_retries=False,
|
285
|
-
use_timelimit=False,
|
320
|
+
if eval.result.outcome != Outcome.ACCEPTED:
|
321
|
+
console.console.print(
|
322
|
+
f'[error]Failed generating output for [item]{testcase.inputPath}[/item][/error]',
|
286
323
|
)
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
console.console.print(f'[error]Summary:[/error] {eval.log.get_summary()}')
|
298
|
-
console.console.print(
|
299
|
-
f'[warning]Verdict: [item]{eval.result.outcome.value}[/item][/warning]',
|
300
|
-
)
|
301
|
-
console.console.print(
|
302
|
-
f'[warning]Message: [info]{eval.result.message}[/info][/warning]',
|
303
|
-
)
|
304
|
-
console.console.print(f'Input written at [item]{testcase.inputPath}[/item]')
|
324
|
+
console.console.print(f'[error]Summary:[/error] {eval.log.get_summary()}')
|
325
|
+
console.console.print(
|
326
|
+
f'[warning]Verdict: [item]{eval.result.outcome.value}[/item][/warning]',
|
327
|
+
)
|
328
|
+
console.console.print(
|
329
|
+
f'[warning]Message: [info]{eval.result.message}[/info][/warning]',
|
330
|
+
)
|
331
|
+
console.console.print(f'Input written at [item]{testcase.inputPath}[/item]')
|
332
|
+
console.console.print(f'Output written at [item]{testcase.outputPath}[/item]')
|
333
|
+
if eval.log.stderr_absolute_path is not None:
|
305
334
|
console.console.print(
|
306
|
-
f'
|
335
|
+
f'Stderr written at [item]{eval.log.stderr_absolute_path}[/item]'
|
307
336
|
)
|
308
|
-
if stderr_path is not None:
|
309
|
-
console.console.print(f'Stderr written at [item]{stderr_path}[/item]')
|
310
337
|
|
311
|
-
|
338
|
+
raise typer.Exit(1)
|
312
339
|
|
313
340
|
|
314
341
|
async def generate_outputs_for_testcases(
|
@@ -350,6 +377,14 @@ async def generate_outputs_for_testcases(
|
|
350
377
|
return
|
351
378
|
assert tc.outputPath is not None
|
352
379
|
|
380
|
+
if entry.metadata.copied_from is not None and _copy_testcase_outputs_over(
|
381
|
+
entry.metadata.copied_from, tc
|
382
|
+
):
|
383
|
+
# Copy remaining pipe files.
|
384
|
+
_copy_testcase_outputs_over(entry.metadata.copied_from, tc, pipes=True)
|
385
|
+
step()
|
386
|
+
continue
|
387
|
+
|
353
388
|
if (
|
354
389
|
main_solution is None or solution_digest is None
|
355
390
|
) and not tc.outputPath.is_file():
|
@@ -362,7 +397,9 @@ async def generate_outputs_for_testcases(
|
|
362
397
|
await generate_output_for_testcase(
|
363
398
|
solution_digest,
|
364
399
|
tc,
|
365
|
-
gen_runs_dir / 'main.stderr',
|
366
400
|
interactor_digest=interactor_digest,
|
367
401
|
)
|
402
|
+
if entry.metadata.copied_from is not None:
|
403
|
+
# Copy remaining pipe files.
|
404
|
+
_copy_testcase_outputs_over(entry.metadata.copied_from, tc, pipes=True)
|
368
405
|
step()
|
@@ -185,7 +185,7 @@ def _run_solution(
|
|
185
185
|
compiled_digest,
|
186
186
|
checker_digest,
|
187
187
|
testcase,
|
188
|
-
output_path,
|
188
|
+
output_dir=output_path,
|
189
189
|
interactor_digest=interactor_digest,
|
190
190
|
testcase_index=i,
|
191
191
|
verification=verification,
|
@@ -367,6 +367,7 @@ async def _generate_testcase_interactively(
|
|
367
367
|
)
|
368
368
|
|
369
369
|
is_manual = False
|
370
|
+
is_output_manual = False
|
370
371
|
generation_metadata = None
|
371
372
|
if generator is not None:
|
372
373
|
generation_metadata = GenerationMetadata(
|
@@ -398,6 +399,7 @@ async def _generate_testcase_interactively(
|
|
398
399
|
output = console.multiline_prompt('Testcase output')
|
399
400
|
testcase.outputPath.write_text(output)
|
400
401
|
console.console.print()
|
402
|
+
is_output_manual = True
|
401
403
|
|
402
404
|
generation_metadata = GenerationMetadata(
|
403
405
|
copied_to=testcase,
|
@@ -453,7 +455,7 @@ async def _generate_testcase_interactively(
|
|
453
455
|
)
|
454
456
|
raise
|
455
457
|
|
456
|
-
if main_solution_digest is not None:
|
458
|
+
if main_solution_digest is not None and not is_output_manual:
|
457
459
|
pkg = package.find_problem_package_or_die()
|
458
460
|
if pkg.type == TaskType.COMMUNICATION:
|
459
461
|
interactor_digest = checkers.compile_interactor(progress)
|
@@ -523,7 +525,7 @@ def _run_interactive_solutions(
|
|
523
525
|
compiled_solutions[solution.path],
|
524
526
|
checker_digest,
|
525
527
|
testcase,
|
526
|
-
output_dir,
|
528
|
+
output_dir=output_dir,
|
527
529
|
interactor_digest=interactor_digest,
|
528
530
|
verification=verification,
|
529
531
|
)
|
@@ -25,6 +25,7 @@ from rbx.box.statements.schema import (
|
|
25
25
|
TexToPDF,
|
26
26
|
rbxToTeX,
|
27
27
|
)
|
28
|
+
from rbx.box.testcase_utils import TestcaseInteraction, parse_interaction
|
28
29
|
|
29
30
|
|
30
31
|
@dataclasses.dataclass
|
@@ -63,13 +64,31 @@ class StatementSample(BaseModel):
|
|
63
64
|
inputPath: pathlib.Path
|
64
65
|
outputPath: pathlib.Path
|
65
66
|
hasOutput: bool = True
|
67
|
+
interaction: Optional[TestcaseInteraction] = None
|
66
68
|
|
67
69
|
@staticmethod
|
68
70
|
def from_testcase(testcase: Testcase) -> 'StatementSample':
|
71
|
+
input_path = testcase.inputPath
|
72
|
+
output_path = testcase.outputPath
|
73
|
+
|
74
|
+
pin_path = input_path.with_suffix('.pin')
|
75
|
+
pout_path = input_path.with_suffix('.pout')
|
76
|
+
pio_path = input_path.with_suffix('.pio')
|
77
|
+
|
78
|
+
if pin_path.is_file():
|
79
|
+
input_path = pin_path
|
80
|
+
if pout_path.is_file():
|
81
|
+
output_path = pout_path
|
82
|
+
|
83
|
+
interaction = None
|
84
|
+
if pio_path.is_file():
|
85
|
+
interaction = parse_interaction(pio_path)
|
86
|
+
|
69
87
|
return StatementSample(
|
70
|
-
inputPath=
|
71
|
-
outputPath=
|
72
|
-
hasOutput=
|
88
|
+
inputPath=input_path,
|
89
|
+
outputPath=output_path or utils.get_empty_sentinel_path(),
|
90
|
+
hasOutput=output_path is not None,
|
91
|
+
interaction=interaction,
|
73
92
|
)
|
74
93
|
|
75
94
|
@staticmethod
|
@@ -42,7 +42,7 @@ async def run_solution_on_testcase(
|
|
42
42
|
compiled_digest: str,
|
43
43
|
checker_digest: Optional[str],
|
44
44
|
testcase: Testcase,
|
45
|
-
output_dir: pathlib.Path,
|
45
|
+
output_dir: Optional[pathlib.Path] = None,
|
46
46
|
interactor_digest: Optional[str] = None,
|
47
47
|
testcase_index: int = 0,
|
48
48
|
verification: VerificationLevel = VerificationLevel.NONE,
|
@@ -78,7 +78,11 @@ async def run_solution_on_testcase(
|
|
78
78
|
)
|
79
79
|
extra_config = _get_execution_config(limits, actual_sandbox)
|
80
80
|
|
81
|
-
|
81
|
+
if output_dir is None:
|
82
|
+
assert testcase.outputPath is not None
|
83
|
+
output_path = testcase.outputPath
|
84
|
+
else:
|
85
|
+
output_path = output_dir / testcase.inputPath.with_suffix('.out').name
|
82
86
|
error_path = output_path.with_suffix('.err')
|
83
87
|
log_path = output_path.with_suffix('.log')
|
84
88
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
@@ -151,7 +155,7 @@ async def _run_communication_solution_on_testcase(
|
|
151
155
|
interactor_digest: str,
|
152
156
|
checker_digest: Optional[str],
|
153
157
|
testcase: Testcase,
|
154
|
-
output_dir: pathlib.Path,
|
158
|
+
output_dir: Optional[pathlib.Path] = None,
|
155
159
|
testcase_index: int = 0,
|
156
160
|
verification: VerificationLevel = VerificationLevel.NONE,
|
157
161
|
timelimit_override: Optional[int] = None,
|
@@ -185,7 +189,11 @@ async def _run_communication_solution_on_testcase(
|
|
185
189
|
)
|
186
190
|
# TODO: maybe combine wall time limits?
|
187
191
|
|
188
|
-
|
192
|
+
if output_dir is None:
|
193
|
+
assert testcase.outputPath is not None
|
194
|
+
output_path = testcase.outputPath
|
195
|
+
else:
|
196
|
+
output_path = output_dir / testcase.inputPath.with_suffix('.out').name
|
189
197
|
error_path = output_path.with_suffix('.err')
|
190
198
|
log_path = output_path.with_suffix('.log')
|
191
199
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
@@ -97,6 +97,16 @@ class TestcaseData(BaseModel):
|
|
97
97
|
output: str
|
98
98
|
|
99
99
|
|
100
|
+
class TestcaseInteractionEntry(BaseModel):
|
101
|
+
data: str
|
102
|
+
pipe: int
|
103
|
+
|
104
|
+
|
105
|
+
class TestcaseInteraction(BaseModel):
|
106
|
+
entries: List[TestcaseInteractionEntry]
|
107
|
+
prefixes: Tuple[str, str]
|
108
|
+
|
109
|
+
|
100
110
|
def find_built_testcases(group: TestcaseGroup) -> List[Testcase]:
|
101
111
|
inputs = find_built_testcase_inputs(group)
|
102
112
|
|
@@ -143,3 +153,59 @@ def fill_output_for_defined_testcase(testcase: Testcase) -> Testcase:
|
|
143
153
|
if output_path.is_file():
|
144
154
|
res.outputPath = output_path
|
145
155
|
return res
|
156
|
+
|
157
|
+
|
158
|
+
def parse_interaction(file: pathlib.Path) -> TestcaseInteraction:
|
159
|
+
entries = []
|
160
|
+
with file.open('r') as f:
|
161
|
+
try:
|
162
|
+
interactor_prefix = f.readline().strip()
|
163
|
+
solution_prefix = f.readline().strip()
|
164
|
+
except Exception:
|
165
|
+
console.console.print(
|
166
|
+
f'[error]Failed to read interaction file [item]{file}[/item]. Expected the first two lines to be the interactor and solution prefixes.[/error]'
|
167
|
+
)
|
168
|
+
raise typer.Exit(1) from None
|
169
|
+
|
170
|
+
rest = f.read()
|
171
|
+
start = 0
|
172
|
+
|
173
|
+
def _find_next_prefix(start: int) -> Optional[Tuple[int, int]]:
|
174
|
+
interactor_idx = rest.find(interactor_prefix, start)
|
175
|
+
solution_idx = rest.find(solution_prefix, start)
|
176
|
+
if interactor_idx == -1 and solution_idx == -1:
|
177
|
+
return None
|
178
|
+
if interactor_idx == -1:
|
179
|
+
return (solution_idx, solution_idx + len(solution_prefix))
|
180
|
+
if solution_idx == -1:
|
181
|
+
return (interactor_idx, interactor_idx + len(interactor_prefix))
|
182
|
+
if interactor_idx < solution_idx:
|
183
|
+
return (interactor_idx, interactor_idx + len(interactor_prefix))
|
184
|
+
return (solution_idx, solution_idx + len(solution_prefix))
|
185
|
+
|
186
|
+
def _find_next_block() -> Optional[Tuple[int, Tuple[int, int]]]:
|
187
|
+
prefix = _find_next_prefix(start)
|
188
|
+
if prefix is None:
|
189
|
+
return None
|
190
|
+
prefix_start, prefix_end = prefix
|
191
|
+
prefix = rest[prefix_start:prefix_end]
|
192
|
+
pipe = 1 if prefix == solution_prefix else 0
|
193
|
+
|
194
|
+
nxt = _find_next_prefix(prefix_end)
|
195
|
+
if nxt is None:
|
196
|
+
return (pipe, (prefix_end, len(rest)))
|
197
|
+
nxt_start, _ = nxt
|
198
|
+
return (pipe, (prefix_end, nxt_start))
|
199
|
+
|
200
|
+
while True:
|
201
|
+
block = _find_next_block()
|
202
|
+
if block is None:
|
203
|
+
break
|
204
|
+
pipe, (st, nd) = block
|
205
|
+
entries.append(TestcaseInteractionEntry(data=rest[st:nd], pipe=pipe))
|
206
|
+
start = nd
|
207
|
+
|
208
|
+
return TestcaseInteraction(
|
209
|
+
prefixes=(interactor_prefix, solution_prefix),
|
210
|
+
entries=entries,
|
211
|
+
)
|
@@ -556,7 +556,7 @@ class IsolateSandbox(SandboxBase):
|
|
556
556
|
)
|
557
557
|
except OSError:
|
558
558
|
logger.critical(
|
559
|
-
'Failed to execute program in sandbox
|
559
|
+
'Failed to execute program in sandbox with command: %s',
|
560
560
|
str(args),
|
561
561
|
exc_info=True,
|
562
562
|
)
|
@@ -680,4 +680,4 @@ class IsolateSandbox(SandboxBase):
|
|
680
680
|
if delete:
|
681
681
|
logger.debug('Deleting sandbox in %s.', self._outer_dir)
|
682
682
|
# Delete the working directory.
|
683
|
-
shutil.rmtree(str(self._outer_dir))
|
683
|
+
shutil.rmtree(str(self._outer_dir), ignore_errors=True)
|
@@ -321,4 +321,4 @@ class StupidSandbox(SandboxBase):
|
|
321
321
|
# This sandbox doesn't have any cleanup, but we might want to delete.
|
322
322
|
if delete:
|
323
323
|
logger.debug('Deleting sandbox in %s.', self._path)
|
324
|
-
shutil.rmtree(str(self._path))
|
324
|
+
shutil.rmtree(str(self._path), ignore_errors=True)
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/contest/statement/contest.rbx.tex
RENAMED
File without changes
|
File without changes
|
{rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/contest/statement/template.rbx.tex
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/statement/projecao.png
RENAMED
File without changes
|
{rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/statement/statement.rbx.tex
RENAMED
File without changes
|
{rbx_cp-0.5.45 → rbx_cp-0.5.46}/rbx/resources/presets/default/problem/statement/template.rbx.tex
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|