rbx.cp 0.5.40__tar.gz → 0.5.42__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.40 → rbx_cp-0.5.42}/PKG-INFO +2 -1
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/pyproject.toml +3 -1
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/builder.py +6 -6
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/checkers.py +100 -25
- rbx_cp-0.5.40/rbx/box/main.py → rbx_cp-0.5.42/rbx/box/cli.py +53 -62
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/code.py +199 -84
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/contest/statements.py +4 -2
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/generators.py +55 -49
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/generators_test.py +7 -7
- rbx_cp-0.5.42/rbx/box/main.py +6 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/package.py +42 -1
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/packaging/boca/packager.py +2 -1
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/packaging/main.py +17 -9
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/packaging/moj/packager.py +49 -10
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/retries.py +5 -5
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/schema.py +20 -4
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/solutions.py +46 -108
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/solutions_test.py +5 -6
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/statements/build_statements.py +4 -2
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/stresses.py +23 -12
- rbx_cp-0.5.42/rbx/box/tasks.py +258 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/testcase_extractors.py +21 -21
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/testcases/main.py +19 -14
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/unit.py +10 -7
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/validators.py +10 -10
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/validators_test.py +3 -3
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/sandbox.py +8 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/sandboxes/stupid_sandbox.py +12 -7
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/sandboxes/timeit.py +8 -2
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/steps.py +76 -2
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/steps_with_caching.py +45 -3
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/steps_with_caching_run_test.py +51 -49
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/moj/scripts/compare.sh +25 -6
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/test.py +6 -4
- rbx_cp-0.5.42/rbx/testdata/interactive/checker.cpp +21 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/gen.cpp +11 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/interactor.cpp +63 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/problem.rbx.yml +40 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_ac_pe.cpp +75 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_ac_re.cpp +76 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_ac_too_many_iter.cpp +72 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_inf_cout_with_flush.cpp +79 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_inf_cout_without_flush.cpp +78 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_ml.cpp +78 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_tl_after_ans.cpp +74 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/af_wa.cpp +74 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/interactive-binary-search_mm_naive_cin.cpp +17 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/sols/main.cpp +26 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/testplan.txt +6 -0
- rbx_cp-0.5.42/rbx/testdata/interactive/validator.cpp +16 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/LICENSE +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/README.md +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/annotations.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/autoenum.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/cd.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/compile.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/conftest.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/contest/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/contest/build_contest_statements.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/contest/contest_package.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/contest/contest_utils.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/contest/main.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/contest/schema.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/creation.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/deferred.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/download.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/environment.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/extensions.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/formatting.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/lazy_importing_main.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/lazy_importing_test.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/packaging/boca/extension.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/packaging/contest_main.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/packaging/packager.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/packaging/polygon/packager.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/packaging/polygon/test.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/packaging/polygon/xml_schema.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/presets/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/presets/fetch.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/presets/lock_schema.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/presets/schema.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/sanitizers/warning_stack.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/setter_config.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/state.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/statements/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/statements/builders.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/statements/joiners.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/statements/latex.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/statements/latex_jinja.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/statements/schema.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/stressing/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/stressing/finder_parser.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/stressing/generator_parser.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/testcase_utils.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/testcases/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/ui/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/ui/captured_log.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/ui/css/app.tcss +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/ui/main.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/box/ui/run.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/checker.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/clone.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/config.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/conftest.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/console.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/create.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/edit.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/caching.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/conftest.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/cacher.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/digester.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/sandboxes/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/sandboxes/isolate.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/storage.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/test.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading/judge/testiso.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/grading_utils.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/hydration.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/main.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/metadata.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/providers/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/providers/codeforces.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/providers/provider.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/checkers/boilerplate.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/default_config.json +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/default_setter_config.mac.yml +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/default_setter_config.yml +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/envs/default.rbx.yml +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/envs/isolate.rbx.yml +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/checker.sh +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compare +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/c +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/cc +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/java +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/kt +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/pas +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/py2 +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/py3 +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/c +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/cc +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/java +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/kt +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/py2 +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/py3 +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/contest/statement/olymp.sty +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/contest/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/preset.rbx.yml +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/.gitignore +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/gen.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/problem.rbx.yml +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/random.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/random.txt +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/sols/slow.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/sols/wa.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/statement/olymp.sty +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/statement/projecao.png +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/tests/samples/000.in +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/tests/samples/001.in +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/validator.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/resources/templates/template.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/run.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/schema.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/submit.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/submitors/__init__.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/submitors/codeforces.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/submitors/submitor.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testcase.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testcase_rendering.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/gen1.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/gen2.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/genScript.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/hard-tle.sol.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/ole.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/problem.rbx.yml +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/re.sol.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/sol.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/tests/1.in +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/tle-and-incorrect.sol.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/tle.sol.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/validator.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/box1/wa.sol.cpp +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/caching/executable.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testdata/compatible +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/testing_utils.py +0 -0
- {rbx_cp-0.5.40 → rbx_cp-0.5.42}/rbx/utils.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: rbx.cp
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.42
|
4
4
|
Summary:
|
5
5
|
Author: Roberto Sales
|
6
6
|
Requires-Python: >=3.9,<4.0
|
@@ -29,6 +29,7 @@ Requires-Dist: questionary (>=2.1.0,<3.0.0)
|
|
29
29
|
Requires-Dist: requests (>=2.32.3,<3.0.0)
|
30
30
|
Requires-Dist: rich (>=13.9.4,<14.0.0)
|
31
31
|
Requires-Dist: ruyaml (>=0.91.0,<0.92.0)
|
32
|
+
Requires-Dist: syncer (>=2.0.3,<3.0.0)
|
32
33
|
Requires-Dist: textual (>=0.79.1,<0.80.0)
|
33
34
|
Requires-Dist: typer (>=0.15.1,<0.16.0)
|
34
35
|
Description-Content-Type: text/markdown
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "rbx.cp"
|
3
|
-
version = "0.5.
|
3
|
+
version = "0.5.42"
|
4
4
|
description = ""
|
5
5
|
packages = [
|
6
6
|
{include = "rbx"}
|
@@ -31,6 +31,7 @@ questionary = "^2.1.0"
|
|
31
31
|
lark = "^1.2.2"
|
32
32
|
chardet = "^5.2.0"
|
33
33
|
ruyaml = "^0.91.0"
|
34
|
+
syncer = "^2.0.3"
|
34
35
|
|
35
36
|
[tool.poetry.scripts]
|
36
37
|
rbc = "rbx.main:app"
|
@@ -49,6 +50,7 @@ mkdocstrings = {extras = ["python"], version = "^0.25.1"}
|
|
49
50
|
griffe-fieldz = ">=0.1.2, <1.0.0"
|
50
51
|
pytest-cov = "^5.0.0"
|
51
52
|
textual-dev = "^1.6.1"
|
53
|
+
pytest-asyncio = "^0.26.0"
|
52
54
|
|
53
55
|
[build-system]
|
54
56
|
requires = ["poetry-core"]
|
@@ -20,7 +20,7 @@ from rbx.box.validators import (
|
|
20
20
|
)
|
21
21
|
|
22
22
|
|
23
|
-
def build(
|
23
|
+
async def build(
|
24
24
|
verification: environment.VerificationParam,
|
25
25
|
groups: Optional[Set[str]] = None,
|
26
26
|
output: Optional[bool] = True,
|
@@ -35,7 +35,7 @@ def build(
|
|
35
35
|
'Built [item]{processed}[/item] testcases...',
|
36
36
|
keep=True,
|
37
37
|
) as s:
|
38
|
-
generate_testcases(s, groups=groups)
|
38
|
+
await generate_testcases(s, groups=groups)
|
39
39
|
|
40
40
|
if verification > 0:
|
41
41
|
validator = package.get_validator_or_nil()
|
@@ -50,7 +50,7 @@ def build(
|
|
50
50
|
'Validated [item]{processed}[/item] testcases...',
|
51
51
|
keep=True,
|
52
52
|
) as s:
|
53
|
-
infos = validate_testcases(
|
53
|
+
infos = await validate_testcases(
|
54
54
|
s,
|
55
55
|
groups=groups,
|
56
56
|
)
|
@@ -70,9 +70,9 @@ def build(
|
|
70
70
|
if output:
|
71
71
|
entries = [
|
72
72
|
entry.group_entry
|
73
|
-
for entry in extract_generation_testcases_from_groups(groups)
|
73
|
+
for entry in await extract_generation_testcases_from_groups(groups)
|
74
74
|
]
|
75
|
-
generate_outputs_for_testcases(entries, s)
|
75
|
+
await generate_outputs_for_testcases(entries, s)
|
76
76
|
|
77
77
|
console.console.print(
|
78
78
|
'[success]Problem built.[/success] '
|
@@ -88,7 +88,7 @@ def build(
|
|
88
88
|
|
89
89
|
|
90
90
|
async def verify(verification: environment.VerificationParam) -> bool:
|
91
|
-
if not build(verification=verification):
|
91
|
+
if not await build(verification=verification):
|
92
92
|
return False
|
93
93
|
|
94
94
|
if verification < VerificationLevel.FAST_SOLUTIONS.value:
|
@@ -34,6 +34,24 @@ def compile_checker(progress: Optional[StatusProgress] = None) -> str:
|
|
34
34
|
return digest
|
35
35
|
|
36
36
|
|
37
|
+
def compile_interactor(progress: Optional[StatusProgress] = None) -> str:
|
38
|
+
interactor = package.get_interactor()
|
39
|
+
|
40
|
+
if interactor is None:
|
41
|
+
console.console.print('[error]No interactor found for this problem.[/error]')
|
42
|
+
raise typer.Exit(1)
|
43
|
+
|
44
|
+
if progress:
|
45
|
+
progress.update('Compiling interactor...')
|
46
|
+
|
47
|
+
try:
|
48
|
+
digest = compile_item(interactor, sanitized=SanitizationLevel.PREFER)
|
49
|
+
except Exception as e:
|
50
|
+
console.console.print('[error]Failed compiling interactor.[/error]')
|
51
|
+
raise typer.Exit(1) from e
|
52
|
+
return digest
|
53
|
+
|
54
|
+
|
37
55
|
def _check_pre_output(run_log: Optional[RunLog]) -> CheckerResult:
|
38
56
|
pkg = package.find_problem_package_or_die()
|
39
57
|
|
@@ -90,12 +108,39 @@ def _convert_tle(result: CheckerResult, run_log: Optional[RunLog]) -> CheckerRes
|
|
90
108
|
return result
|
91
109
|
|
92
110
|
|
111
|
+
def process_checker_run_log(
|
112
|
+
checker_run_log: Optional[RunLog], message: str
|
113
|
+
) -> Optional[CheckerResult]:
|
114
|
+
if (
|
115
|
+
checker_run_log is not None
|
116
|
+
and checker_run_log.exitcode != 0
|
117
|
+
and (
|
118
|
+
checker_run_log.exitstatus != SandboxBase.EXIT_NONZERO_RETURN
|
119
|
+
or checker_run_log.exitcode not in [0, 1, 2, 3]
|
120
|
+
)
|
121
|
+
):
|
122
|
+
return None
|
123
|
+
|
124
|
+
if checker_run_log is None:
|
125
|
+
return CheckerResult(outcome=Outcome.INTERNAL_ERROR)
|
126
|
+
if checker_run_log.exitcode not in [0, 1, 2, 3]:
|
127
|
+
return None
|
128
|
+
|
129
|
+
result = CheckerResult(outcome=Outcome.ACCEPTED, message=message)
|
130
|
+
|
131
|
+
if checker_run_log.exitcode in [1, 2]:
|
132
|
+
result = CheckerResult(outcome=Outcome.WRONG_ANSWER, message=message)
|
133
|
+
if checker_run_log.exitcode == 3:
|
134
|
+
result = CheckerResult(outcome=Outcome.JUDGE_FAILED, message=message)
|
135
|
+
return result
|
136
|
+
|
137
|
+
|
93
138
|
def check_with_no_output(run_log: Optional[RunLog]) -> CheckerResult:
|
94
139
|
result = _check_pre_output(run_log)
|
95
140
|
return _convert_tle(result, run_log)
|
96
141
|
|
97
142
|
|
98
|
-
def _check(
|
143
|
+
async def _check(
|
99
144
|
checker_digest: str,
|
100
145
|
run_log: Optional[RunLog],
|
101
146
|
testcase: Testcase,
|
@@ -122,7 +167,7 @@ def _check(
|
|
122
167
|
dest=pathlib.PosixPath('input.txt'),
|
123
168
|
),
|
124
169
|
GradingFileInput(
|
125
|
-
src=testcase.outputPath,
|
170
|
+
src=testcase.outputPath or package.get_empty_sentinel_path(),
|
126
171
|
dest=pathlib.PosixPath('expected.txt'),
|
127
172
|
),
|
128
173
|
GradingFileInput(
|
@@ -130,7 +175,7 @@ def _check(
|
|
130
175
|
dest=pathlib.PosixPath('output.txt'),
|
131
176
|
),
|
132
177
|
]
|
133
|
-
checker_run_log = run_item(
|
178
|
+
checker_run_log = await run_item(
|
134
179
|
package.get_checker(),
|
135
180
|
DigestOrSource.create(checker_digest),
|
136
181
|
stderr=DigestOrDest.create(error),
|
@@ -139,20 +184,15 @@ def _check(
|
|
139
184
|
)
|
140
185
|
message = package.get_digest_as_string(error.value or '') or ''
|
141
186
|
|
142
|
-
|
143
|
-
|
144
|
-
and checker_run_log.exitcode != 0
|
145
|
-
and (
|
146
|
-
checker_run_log.exitstatus != SandboxBase.EXIT_NONZERO_RETURN
|
147
|
-
or checker_run_log.exitcode not in [0, 1, 2, 3]
|
148
|
-
)
|
149
|
-
):
|
187
|
+
processed_checker_result = process_checker_run_log(checker_run_log, message)
|
188
|
+
if processed_checker_result is None:
|
150
189
|
console.console.print(
|
151
190
|
f'[error]Checker [item]{package.get_checker().path}[/item] failed unexpectedly.[/error]'
|
152
191
|
)
|
153
|
-
|
154
|
-
|
155
|
-
|
192
|
+
if checker_run_log is not None:
|
193
|
+
console.console.print(
|
194
|
+
f'[error]Summary:[/error] {checker_run_log.get_summary()}'
|
195
|
+
)
|
156
196
|
console.console.print(
|
157
197
|
f'[error]Testcase input:[/error] [item]{testcase.inputPath}[/item]'
|
158
198
|
)
|
@@ -164,15 +204,7 @@ def _check(
|
|
164
204
|
)
|
165
205
|
raise typer.Exit(1)
|
166
206
|
|
167
|
-
|
168
|
-
return CheckerResult(outcome=Outcome.INTERNAL_ERROR)
|
169
|
-
|
170
|
-
result = CheckerResult(outcome=Outcome.ACCEPTED, message=message)
|
171
|
-
|
172
|
-
if checker_run_log.exitcode in [1, 2]:
|
173
|
-
result = CheckerResult(outcome=Outcome.WRONG_ANSWER, message=message)
|
174
|
-
if checker_run_log.exitcode == 3:
|
175
|
-
result = CheckerResult(outcome=Outcome.JUDGE_FAILED, message=message)
|
207
|
+
result = processed_checker_result
|
176
208
|
|
177
209
|
if skip_run_log:
|
178
210
|
return result
|
@@ -185,13 +217,56 @@ def _check_sanitizer_warnings(run_log: Optional[RunLog]) -> bool:
|
|
185
217
|
return run_log.warnings
|
186
218
|
|
187
219
|
|
188
|
-
def check(
|
220
|
+
async def check(
|
189
221
|
checker_digest: str,
|
190
222
|
run_log: Optional[RunLog],
|
191
223
|
testcase: Testcase,
|
192
224
|
program_output: pathlib.Path,
|
193
225
|
skip_run_log: bool = False,
|
194
226
|
) -> CheckerResult:
|
195
|
-
result = _check(
|
227
|
+
result = await _check(
|
228
|
+
checker_digest, run_log, testcase, program_output, skip_run_log
|
229
|
+
)
|
196
230
|
result.sanitizer_warnings = _check_sanitizer_warnings(run_log)
|
197
231
|
return result
|
232
|
+
|
233
|
+
|
234
|
+
async def check_communication(
|
235
|
+
checker_digest: Optional[str],
|
236
|
+
run_log: Optional[RunLog],
|
237
|
+
interactor_run_log: Optional[RunLog],
|
238
|
+
interactor_stderr: pathlib.Path,
|
239
|
+
testcase: Testcase,
|
240
|
+
program_output: pathlib.Path,
|
241
|
+
skip_run_log: bool = False,
|
242
|
+
) -> CheckerResult:
|
243
|
+
sanitizer_warnings = _check_sanitizer_warnings(run_log)
|
244
|
+
|
245
|
+
result = check_with_no_output(run_log)
|
246
|
+
result.sanitizer_warnings = sanitizer_warnings
|
247
|
+
if result.outcome != Outcome.ACCEPTED:
|
248
|
+
return result
|
249
|
+
|
250
|
+
result = process_checker_run_log(
|
251
|
+
interactor_run_log,
|
252
|
+
interactor_stderr.read_text(),
|
253
|
+
)
|
254
|
+
|
255
|
+
if result is None:
|
256
|
+
result = check_with_no_output(interactor_run_log)
|
257
|
+
result.sanitizer_warnings = sanitizer_warnings
|
258
|
+
if result.outcome != Outcome.ACCEPTED:
|
259
|
+
result.outcome = Outcome.JUDGE_FAILED
|
260
|
+
return result
|
261
|
+
|
262
|
+
result.sanitizer_warnings = sanitizer_warnings
|
263
|
+
if result.outcome != Outcome.ACCEPTED:
|
264
|
+
return result
|
265
|
+
|
266
|
+
if checker_digest is not None:
|
267
|
+
result = await check(
|
268
|
+
checker_digest, run_log, testcase, program_output, skip_run_log
|
269
|
+
)
|
270
|
+
result.sanitizer_warnings = sanitizer_warnings
|
271
|
+
|
272
|
+
return result
|
@@ -1,43 +1,34 @@
|
|
1
|
-
# flake8: noqa
|
2
|
-
from gevent import monkey
|
3
|
-
|
4
|
-
monkey.patch_all()
|
5
|
-
|
6
|
-
import asyncio
|
7
|
-
import tempfile
|
8
|
-
import shlex
|
9
|
-
import sys
|
10
|
-
|
11
|
-
from rbx.box.schema import CodeItem, ExpectedOutcome, TestcaseGroup
|
12
|
-
|
13
|
-
|
14
1
|
import pathlib
|
2
|
+
import shlex
|
15
3
|
import shutil
|
16
|
-
|
4
|
+
import sys
|
5
|
+
import tempfile
|
6
|
+
from typing import Annotated, Optional
|
17
7
|
|
18
8
|
import rich
|
19
9
|
import rich.prompt
|
10
|
+
import syncer
|
20
11
|
import typer
|
21
12
|
|
22
13
|
from rbx import annotations, config, console, utils
|
23
14
|
from rbx.box import (
|
24
15
|
cd,
|
25
|
-
|
26
|
-
state,
|
16
|
+
compile,
|
27
17
|
creation,
|
28
18
|
download,
|
29
19
|
environment,
|
30
20
|
generators,
|
31
21
|
package,
|
32
|
-
compile,
|
33
22
|
presets,
|
23
|
+
setter_config,
|
24
|
+
state,
|
34
25
|
validators,
|
35
26
|
)
|
36
27
|
from rbx.box.contest import main as contest
|
37
28
|
from rbx.box.contest.contest_package import find_contest_yaml
|
38
29
|
from rbx.box.environment import VerificationLevel, get_environment_path
|
39
30
|
from rbx.box.packaging import main as packaging
|
40
|
-
from rbx.box.
|
31
|
+
from rbx.box.schema import CodeItem, ExpectedOutcome, TestcaseGroup
|
41
32
|
from rbx.box.solutions import (
|
42
33
|
estimate_time_limit,
|
43
34
|
get_exact_matching_solutions,
|
@@ -49,6 +40,7 @@ from rbx.box.solutions import (
|
|
49
40
|
)
|
50
41
|
from rbx.box.statements import build_statements
|
51
42
|
from rbx.box.testcase_utils import TestcaseEntry
|
43
|
+
from rbx.box.testcases import main as testcases
|
52
44
|
|
53
45
|
app = typer.Typer(no_args_is_help=True, cls=annotations.AliasGroup)
|
54
46
|
app.add_typer(
|
@@ -145,10 +137,11 @@ def edit():
|
|
145
137
|
'build, b', rich_help_panel='Deploying', help='Build all tests for the problem.'
|
146
138
|
)
|
147
139
|
@package.within_problem
|
148
|
-
|
140
|
+
@syncer.sync
|
141
|
+
async def build(verification: environment.VerificationParam):
|
149
142
|
from rbx.box import builder
|
150
143
|
|
151
|
-
builder.build(verification=verification)
|
144
|
+
await builder.build(verification=verification)
|
152
145
|
|
153
146
|
|
154
147
|
@app.command(
|
@@ -157,7 +150,8 @@ def build(verification: environment.VerificationParam):
|
|
157
150
|
help='Build and run solution(s).',
|
158
151
|
)
|
159
152
|
@package.within_problem
|
160
|
-
|
153
|
+
@syncer.sync
|
154
|
+
async def run(
|
161
155
|
verification: environment.VerificationParam,
|
162
156
|
solution: Annotated[
|
163
157
|
Optional[str],
|
@@ -227,7 +221,7 @@ def run(
|
|
227
221
|
|
228
222
|
from rbx.box import builder
|
229
223
|
|
230
|
-
if not builder.build(verification=verification, output=check):
|
224
|
+
if not await builder.build(verification=verification, output=check):
|
231
225
|
return
|
232
226
|
|
233
227
|
if verification <= VerificationLevel.VALIDATE.value:
|
@@ -246,7 +240,7 @@ def run(
|
|
246
240
|
raise typer.Exit(1)
|
247
241
|
|
248
242
|
# Never use sanitizers for time estimation.
|
249
|
-
override_tl = _time_impl(check=check, detailed=False)
|
243
|
+
override_tl = await _time_impl(check=check, detailed=False)
|
250
244
|
if override_tl is None:
|
251
245
|
raise typer.Exit(1)
|
252
246
|
|
@@ -277,18 +271,16 @@ def run(
|
|
277
271
|
|
278
272
|
console.console.print()
|
279
273
|
console.console.rule('[status]Run report[/status]', style='status')
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
skip_printing_limits=sanitized,
|
287
|
-
)
|
274
|
+
await print_run_report(
|
275
|
+
solution_result,
|
276
|
+
console.console,
|
277
|
+
VerificationLevel(verification),
|
278
|
+
detailed=detailed,
|
279
|
+
skip_printing_limits=sanitized,
|
288
280
|
)
|
289
281
|
|
290
282
|
|
291
|
-
def _time_impl(check: bool, detailed: bool) -> Optional[int]:
|
283
|
+
async def _time_impl(check: bool, detailed: bool) -> Optional[int]:
|
292
284
|
if package.get_main_solution() is None:
|
293
285
|
console.console.print(
|
294
286
|
'[warning]No main solution found, so cannot estimate a time limit.[/warning]'
|
@@ -314,14 +306,12 @@ def _time_impl(check: bool, detailed: bool) -> Optional[int]:
|
|
314
306
|
console.console.rule(
|
315
307
|
'[status]Run report (for time estimation)[/status]', style='status'
|
316
308
|
)
|
317
|
-
ok =
|
318
|
-
|
319
|
-
|
320
|
-
|
321
|
-
|
322
|
-
|
323
|
-
skip_printing_limits=True,
|
324
|
-
)
|
309
|
+
ok = await print_run_report(
|
310
|
+
solution_result,
|
311
|
+
console.console,
|
312
|
+
VerificationLevel(verification),
|
313
|
+
detailed=detailed,
|
314
|
+
skip_printing_limits=True,
|
325
315
|
)
|
326
316
|
|
327
317
|
if not ok:
|
@@ -331,7 +321,7 @@ def _time_impl(check: bool, detailed: bool) -> Optional[int]:
|
|
331
321
|
return None
|
332
322
|
|
333
323
|
console.console.print()
|
334
|
-
return
|
324
|
+
return await estimate_time_limit(console.console, solution_result)
|
335
325
|
|
336
326
|
|
337
327
|
@app.command(
|
@@ -340,7 +330,8 @@ def _time_impl(check: bool, detailed: bool) -> Optional[int]:
|
|
340
330
|
help='Estimate a time limit for the problem based on a time limit formula and timings of accepted solutions.',
|
341
331
|
)
|
342
332
|
@package.within_problem
|
343
|
-
|
333
|
+
@syncer.sync
|
334
|
+
async def time(
|
344
335
|
check: bool = typer.Option(
|
345
336
|
True,
|
346
337
|
'--nocheck',
|
@@ -364,10 +355,10 @@ def time(
|
|
364
355
|
from rbx.box import builder
|
365
356
|
|
366
357
|
verification = VerificationLevel.ALL_SOLUTIONS.value
|
367
|
-
if not builder.build(verification=verification, output=check):
|
358
|
+
if not await builder.build(verification=verification, output=check):
|
368
359
|
return None
|
369
360
|
|
370
|
-
_time_impl(check, detailed)
|
361
|
+
await _time_impl(check, detailed)
|
371
362
|
|
372
363
|
|
373
364
|
@app.command(
|
@@ -376,7 +367,8 @@ def time(
|
|
376
367
|
help='Build and run solution(s) by passing testcases in the CLI.',
|
377
368
|
)
|
378
369
|
@package.within_problem
|
379
|
-
|
370
|
+
@syncer.sync
|
371
|
+
async def irun(
|
380
372
|
verification: environment.VerificationParam,
|
381
373
|
solution: Annotated[
|
382
374
|
Optional[str],
|
@@ -468,20 +460,18 @@ def irun(
|
|
468
460
|
}
|
469
461
|
|
470
462
|
with utils.StatusProgress('Running solutions...') as s:
|
471
|
-
|
472
|
-
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
|
479
|
-
|
480
|
-
|
481
|
-
|
482
|
-
|
483
|
-
sanitized=sanitized,
|
484
|
-
)
|
463
|
+
await run_and_print_interactive_solutions(
|
464
|
+
progress=s,
|
465
|
+
tracked_solutions=tracked_solutions,
|
466
|
+
check=check,
|
467
|
+
verification=VerificationLevel(verification),
|
468
|
+
generator=generators.get_call_from_string(generator)
|
469
|
+
if generator is not None
|
470
|
+
else None,
|
471
|
+
testcase_entry=TestcaseEntry.parse(testcase) if testcase else None,
|
472
|
+
custom_output=output,
|
473
|
+
print=print,
|
474
|
+
sanitized=sanitized,
|
485
475
|
)
|
486
476
|
|
487
477
|
|
@@ -710,7 +700,8 @@ def compile_command(
|
|
710
700
|
help='Run the validator in a one-off fashion, interactively.',
|
711
701
|
)
|
712
702
|
@package.within_problem
|
713
|
-
|
703
|
+
@syncer.sync
|
704
|
+
async def validate(
|
714
705
|
path: Annotated[
|
715
706
|
Optional[str],
|
716
707
|
typer.Option('--path', '-p', help='Path to the testcase to validate.'),
|
@@ -730,11 +721,11 @@ def validate(
|
|
730
721
|
tmppath = pathlib.Path(tmpdir) / '000.in'
|
731
722
|
tmppath.write_text(input)
|
732
723
|
|
733
|
-
info = validators.validate_one_off(
|
724
|
+
info = await validators.validate_one_off(
|
734
725
|
pathlib.Path(tmppath), validator, validator_digest
|
735
726
|
)
|
736
727
|
else:
|
737
|
-
info = validators.validate_one_off(
|
728
|
+
info = await validators.validate_one_off(
|
738
729
|
pathlib.Path(path), validator, validator_digest
|
739
730
|
)
|
740
731
|
|