rbx.cp 0.5.39__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.39 → rbx_cp-0.5.42}/PKG-INFO +2 -1
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/pyproject.toml +3 -1
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/builder.py +6 -6
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/checkers.py +105 -26
- rbx_cp-0.5.39/rbx/box/main.py → rbx_cp-0.5.42/rbx/box/cli.py +65 -62
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/code.py +199 -84
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/contest/statements.py +4 -2
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/generators.py +55 -49
- {rbx_cp-0.5.39 → 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.39 → rbx_cp-0.5.42}/rbx/box/package.py +42 -1
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/packaging/boca/packager.py +2 -1
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/packaging/main.py +24 -7
- rbx_cp-0.5.42/rbx/box/packaging/moj/packager.py +164 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/retries.py +5 -5
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/schema.py +86 -4
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/solutions.py +46 -108
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/solutions_test.py +5 -6
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/statements/build_statements.py +4 -2
- {rbx_cp-0.5.39 → 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.39 → rbx_cp-0.5.42}/rbx/box/testcase_extractors.py +21 -21
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/testcases/main.py +19 -14
- rbx_cp-0.5.42/rbx/box/unit.py +116 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/validators.py +27 -18
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/validators_test.py +3 -3
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/sandbox.py +8 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/sandboxes/stupid_sandbox.py +12 -7
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/sandboxes/timeit.py +8 -2
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/steps.py +76 -2
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/steps_with_caching.py +45 -3
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/steps_with_caching_run_test.py +51 -49
- rbx_cp-0.5.42/rbx/resources/packagers/moj/scripts/compare.sh +101 -0
- {rbx_cp-0.5.39 → 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.39 → rbx_cp-0.5.42}/LICENSE +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/README.md +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/annotations.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/autoenum.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/cd.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/compile.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/conftest.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/contest/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/contest/build_contest_statements.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/contest/contest_package.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/contest/contest_utils.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/contest/main.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/contest/schema.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/creation.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/deferred.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/download.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/environment.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/extensions.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/formatting.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/lazy_importing_main.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/lazy_importing_test.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/packaging/boca/extension.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/packaging/contest_main.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/packaging/packager.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/packaging/polygon/packager.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/packaging/polygon/test.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/packaging/polygon/xml_schema.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/presets/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/presets/fetch.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/presets/lock_schema.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/presets/schema.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/sanitizers/warning_stack.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/setter_config.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/state.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/statements/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/statements/builders.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/statements/joiners.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/statements/latex.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/statements/latex_jinja.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/statements/schema.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/stressing/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/stressing/finder_parser.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/stressing/generator_parser.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/testcase_utils.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/testcases/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/ui/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/ui/captured_log.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/ui/css/app.tcss +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/ui/main.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/box/ui/run.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/checker.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/clone.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/config.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/conftest.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/console.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/create.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/edit.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/caching.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/conftest.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/cacher.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/digester.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/sandboxes/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/sandboxes/isolate.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/storage.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/test.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading/judge/testiso.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/grading_utils.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/hydration.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/main.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/metadata.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/providers/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/providers/codeforces.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/providers/provider.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/checkers/boilerplate.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/default_config.json +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/default_setter_config.mac.yml +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/default_setter_config.yml +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/envs/default.rbx.yml +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/envs/isolate.rbx.yml +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/checker.sh +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compare +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/c +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/cc +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/java +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/kt +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/pas +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/py2 +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/compile/py3 +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/c +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/cc +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/java +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/kt +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/py2 +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/packagers/boca/run/py3 +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/contest/statement/olymp.sty +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/contest/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/preset.rbx.yml +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/.gitignore +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/gen.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/problem.rbx.yml +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/random.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/random.txt +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/sols/slow.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/sols/wa.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/statement/olymp.sty +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/statement/projecao.png +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/tests/samples/000.in +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/tests/samples/001.in +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/validator.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/resources/templates/template.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/run.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/schema.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/submit.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/submitors/__init__.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/submitors/codeforces.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/submitors/submitor.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testcase.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testcase_rendering.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/gen1.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/gen2.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/genScript.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/hard-tle.sol.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/ole.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/problem.rbx.yml +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/re.sol.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/sol.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/tests/1.in +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/tle-and-incorrect.sol.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/tle.sol.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/validator.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/box1/wa.sol.cpp +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/caching/executable.py +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testdata/compatible +0 -0
- {rbx_cp-0.5.39 → rbx_cp-0.5.42}/rbx/testing_utils.py +0 -0
- {rbx_cp-0.5.39 → 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:
|
@@ -17,11 +17,15 @@ from rbx.grading.steps import (
|
|
17
17
|
Outcome,
|
18
18
|
RunLog,
|
19
19
|
)
|
20
|
+
from rbx.utils import StatusProgress
|
20
21
|
|
21
22
|
|
22
|
-
def compile_checker() -> str:
|
23
|
+
def compile_checker(progress: Optional[StatusProgress] = None) -> str:
|
23
24
|
checker = package.get_checker()
|
24
25
|
|
26
|
+
if progress:
|
27
|
+
progress.update('Compiling checker...')
|
28
|
+
|
25
29
|
try:
|
26
30
|
digest = compile_item(checker, sanitized=SanitizationLevel.PREFER)
|
27
31
|
except Exception as e:
|
@@ -30,6 +34,24 @@ def compile_checker() -> str:
|
|
30
34
|
return digest
|
31
35
|
|
32
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
|
+
|
33
55
|
def _check_pre_output(run_log: Optional[RunLog]) -> CheckerResult:
|
34
56
|
pkg = package.find_problem_package_or_die()
|
35
57
|
|
@@ -86,12 +108,39 @@ def _convert_tle(result: CheckerResult, run_log: Optional[RunLog]) -> CheckerRes
|
|
86
108
|
return result
|
87
109
|
|
88
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
|
+
|
89
138
|
def check_with_no_output(run_log: Optional[RunLog]) -> CheckerResult:
|
90
139
|
result = _check_pre_output(run_log)
|
91
140
|
return _convert_tle(result, run_log)
|
92
141
|
|
93
142
|
|
94
|
-
def _check(
|
143
|
+
async def _check(
|
95
144
|
checker_digest: str,
|
96
145
|
run_log: Optional[RunLog],
|
97
146
|
testcase: Testcase,
|
@@ -118,7 +167,7 @@ def _check(
|
|
118
167
|
dest=pathlib.PosixPath('input.txt'),
|
119
168
|
),
|
120
169
|
GradingFileInput(
|
121
|
-
src=testcase.outputPath,
|
170
|
+
src=testcase.outputPath or package.get_empty_sentinel_path(),
|
122
171
|
dest=pathlib.PosixPath('expected.txt'),
|
123
172
|
),
|
124
173
|
GradingFileInput(
|
@@ -126,7 +175,7 @@ def _check(
|
|
126
175
|
dest=pathlib.PosixPath('output.txt'),
|
127
176
|
),
|
128
177
|
]
|
129
|
-
checker_run_log = run_item(
|
178
|
+
checker_run_log = await run_item(
|
130
179
|
package.get_checker(),
|
131
180
|
DigestOrSource.create(checker_digest),
|
132
181
|
stderr=DigestOrDest.create(error),
|
@@ -135,20 +184,15 @@ def _check(
|
|
135
184
|
)
|
136
185
|
message = package.get_digest_as_string(error.value or '') or ''
|
137
186
|
|
138
|
-
|
139
|
-
|
140
|
-
and checker_run_log.exitcode != 0
|
141
|
-
and (
|
142
|
-
checker_run_log.exitstatus != SandboxBase.EXIT_NONZERO_RETURN
|
143
|
-
or checker_run_log.exitcode not in [0, 1, 2, 3]
|
144
|
-
)
|
145
|
-
):
|
187
|
+
processed_checker_result = process_checker_run_log(checker_run_log, message)
|
188
|
+
if processed_checker_result is None:
|
146
189
|
console.console.print(
|
147
190
|
f'[error]Checker [item]{package.get_checker().path}[/item] failed unexpectedly.[/error]'
|
148
191
|
)
|
149
|
-
|
150
|
-
|
151
|
-
|
192
|
+
if checker_run_log is not None:
|
193
|
+
console.console.print(
|
194
|
+
f'[error]Summary:[/error] {checker_run_log.get_summary()}'
|
195
|
+
)
|
152
196
|
console.console.print(
|
153
197
|
f'[error]Testcase input:[/error] [item]{testcase.inputPath}[/item]'
|
154
198
|
)
|
@@ -160,15 +204,7 @@ def _check(
|
|
160
204
|
)
|
161
205
|
raise typer.Exit(1)
|
162
206
|
|
163
|
-
|
164
|
-
return CheckerResult(outcome=Outcome.INTERNAL_ERROR)
|
165
|
-
|
166
|
-
result = CheckerResult(outcome=Outcome.ACCEPTED, message=message)
|
167
|
-
|
168
|
-
if checker_run_log.exitcode in [1, 2]:
|
169
|
-
result = CheckerResult(outcome=Outcome.WRONG_ANSWER, message=message)
|
170
|
-
if checker_run_log.exitcode == 3:
|
171
|
-
result = CheckerResult(outcome=Outcome.JUDGE_FAILED, message=message)
|
207
|
+
result = processed_checker_result
|
172
208
|
|
173
209
|
if skip_run_log:
|
174
210
|
return result
|
@@ -181,13 +217,56 @@ def _check_sanitizer_warnings(run_log: Optional[RunLog]) -> bool:
|
|
181
217
|
return run_log.warnings
|
182
218
|
|
183
219
|
|
184
|
-
def check(
|
220
|
+
async def check(
|
185
221
|
checker_digest: str,
|
186
222
|
run_log: Optional[RunLog],
|
187
223
|
testcase: Testcase,
|
188
224
|
program_output: pathlib.Path,
|
189
225
|
skip_run_log: bool = False,
|
190
226
|
) -> CheckerResult:
|
191
|
-
result = _check(
|
227
|
+
result = await _check(
|
228
|
+
checker_digest, run_log, testcase, program_output, skip_run_log
|
229
|
+
)
|
192
230
|
result.sanitizer_warnings = _check_sanitizer_warnings(run_log)
|
193
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,17 +721,29 @@ 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
|
|
741
732
|
validators.print_validation_report([info])
|
742
733
|
|
743
734
|
|
735
|
+
@app.command(
|
736
|
+
'unit',
|
737
|
+
rich_help_panel='Testing',
|
738
|
+
help='Run unit tests for the validator and checker.',
|
739
|
+
)
|
740
|
+
def unit_tests():
|
741
|
+
from rbx.box import unit
|
742
|
+
|
743
|
+
with utils.StatusProgress('Running unit tests...') as s:
|
744
|
+
unit.run_unit_tests(s)
|
745
|
+
|
746
|
+
|
744
747
|
@app.command(
|
745
748
|
'environment, env',
|
746
749
|
rich_help_panel='Configuration',
|