rbx.cp 0.5.29__tar.gz → 0.5.31__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.29 → rbx_cp-0.5.31}/PKG-INFO +1 -1
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/pyproject.toml +1 -1
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/code.py +58 -1
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/contest/schema.py +5 -5
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/creation.py +10 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/extensions.py +2 -2
- rbx_cp-0.5.31/rbx/box/formatting.py +10 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/generators.py +12 -10
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/generators_test.py +1 -1
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/main.py +14 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/schema.py +36 -28
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/setter_config.py +7 -7
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/solutions.py +34 -24
- rbx_cp-0.5.31/rbx/box/state.py +9 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/statements/schema.py +6 -4
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/sandboxes/stupid_sandbox.py +0 -1
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/LICENSE +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/README.md +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/annotations.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/autoenum.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/builder.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/cd.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/checkers.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/compile.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/conftest.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/contest/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/contest/build_contest_statements.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/contest/contest_package.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/contest/contest_utils.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/contest/main.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/contest/statements.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/deferred.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/download.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/environment.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/package.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/packaging/boca/extension.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/packaging/boca/packager.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/packaging/contest_main.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/packaging/main.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/packaging/packager.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/packaging/polygon/packager.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/packaging/polygon/test.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/packaging/polygon/xml_schema.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/presets/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/presets/fetch.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/presets/lock_schema.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/presets/schema.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/retries.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/sanitizers/warning_stack.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/solutions_test.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/statements/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/statements/build_statements.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/statements/builders.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/statements/joiners.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/statements/latex.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/statements/latex_jinja.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/stresses.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/stressing/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/stressing/finder_parser.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/stressing/generator_parser.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/testcases.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/ui/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/ui/captured_log.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/ui/css/app.tcss +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/ui/main.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/ui/run.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/validators.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/box/validators_test.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/checker.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/clone.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/config.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/conftest.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/console.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/create.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/edit.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/caching.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/conftest.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/cacher.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/digester.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/sandbox.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/sandboxes/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/sandboxes/isolate.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/sandboxes/timeit.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/storage.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/test.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/judge/testiso.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/steps.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/steps_with_caching.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading/steps_with_caching_run_test.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/grading_utils.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/hydration.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/main.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/metadata.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/providers/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/providers/codeforces.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/providers/provider.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/checkers/boilerplate.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/default_config.json +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/default_setter_config.mac.yml +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/default_setter_config.yml +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/envs/default.rbx.yml +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/envs/isolate.rbx.yml +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/checker.sh +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/compare +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/compile/c +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/compile/cc +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/compile/cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/compile/java +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/compile/kt +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/compile/pas +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/compile/py2 +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/compile/py3 +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/run/c +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/run/cc +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/run/cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/run/java +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/run/kt +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/run/py2 +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/packagers/boca/run/py3 +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/contest/statement/olymp.sty +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/contest/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/preset.rbx.yml +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/.gitignore +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/gen.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/problem.rbx.yml +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/random.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/random.txt +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/sols/slow.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/sols/wa.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/statement/olymp.sty +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/statement/projecao.png +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/statement/template.rbx.tex +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/tests/samples/000.in +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/tests/samples/001.in +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/validator.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/resources/templates/template.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/run.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/schema.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/submit.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/submitors/__init__.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/submitors/codeforces.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/submitors/submitor.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/test.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testcase.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testcase_rendering.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/gen1.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/gen2.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/genScript.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/hard-tle.sol.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/ole.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/problem.rbx.yml +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/re.sol.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/sol.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/tests/1.in +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/tle-and-incorrect.sol.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/tle.sol.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/validator.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/box1/wa.sol.cpp +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/caching/executable.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testdata/compatible +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/testing_utils.py +0 -0
- {rbx_cp-0.5.29 → rbx_cp-0.5.31}/rbx/utils.py +0 -0
@@ -1,5 +1,6 @@
|
|
1
1
|
import pathlib
|
2
2
|
import re
|
3
|
+
import resource
|
3
4
|
import shlex
|
4
5
|
from enum import Enum
|
5
6
|
from pathlib import PosixPath
|
@@ -10,7 +11,7 @@ import rich.text
|
|
10
11
|
import typer
|
11
12
|
|
12
13
|
from rbx import console
|
13
|
-
from rbx.box import download, package, setter_config
|
14
|
+
from rbx.box import download, package, setter_config, state
|
14
15
|
from rbx.box.environment import (
|
15
16
|
ExecutionConfig,
|
16
17
|
get_compilation_config,
|
@@ -22,6 +23,7 @@ from rbx.box.environment import (
|
|
22
23
|
get_sandbox_params_from_config,
|
23
24
|
merge_execution_configs,
|
24
25
|
)
|
26
|
+
from rbx.box.formatting import get_formatted_memory
|
25
27
|
from rbx.box.sanitizers import warning_stack
|
26
28
|
from rbx.box.schema import CodeItem
|
27
29
|
from rbx.grading import steps_with_caching
|
@@ -150,6 +152,57 @@ def _ignore_warning_in_cxx_input(input: GradingFileInput):
|
|
150
152
|
input.src = preprocessed_path
|
151
153
|
|
152
154
|
|
155
|
+
def _format_stack_limit(limit: int) -> str:
|
156
|
+
if limit == resource.RLIM_INFINITY:
|
157
|
+
return 'unlimited'
|
158
|
+
return get_formatted_memory(limit)
|
159
|
+
|
160
|
+
|
161
|
+
def _check_stack_limit():
|
162
|
+
if not state.STATE.run_through_cli:
|
163
|
+
return
|
164
|
+
soft, hard = resource.RLIM_INFINITY, resource.RLIM_INFINITY
|
165
|
+
|
166
|
+
TARGET = 256 * 1024 * 1024 # 256 MiB
|
167
|
+
try:
|
168
|
+
soft, hard = resource.getrlimit(resource.RLIMIT_STACK)
|
169
|
+
except Exception:
|
170
|
+
pass
|
171
|
+
|
172
|
+
if soft != hard or (soft != resource.RLIM_INFINITY and soft < TARGET):
|
173
|
+
soft_fmt = _format_stack_limit(soft)
|
174
|
+
hard_fmt = _format_stack_limit(hard)
|
175
|
+
console.console.print(
|
176
|
+
f'[error]Stack limit is too low (limit is set as [item]{soft_fmt}[/item], but configured user capacity is [item]{hard_fmt}[/item]).[/error]'
|
177
|
+
)
|
178
|
+
console.console.print(
|
179
|
+
'[error]It is not safe to develop problems in [item]rbx[/item] with this configuration.[/error]'
|
180
|
+
)
|
181
|
+
console.console.print(
|
182
|
+
'To solve this, add the following lines to the end of your [item]~/.bashrc[/item] or [item]~/.zshrc[/item] file (or equivalent shell configuration file):'
|
183
|
+
)
|
184
|
+
|
185
|
+
target_text = TARGET
|
186
|
+
if hard != resource.RLIM_INFINITY:
|
187
|
+
target_text = min(hard, TARGET)
|
188
|
+
console.console.print(
|
189
|
+
"""
|
190
|
+
```
|
191
|
+
export RBX_BIN_PATH=`which rbx`
|
192
|
+
function rbx() {
|
193
|
+
ulimit -s %s && $RBX_BIN_PATH $@
|
194
|
+
}
|
195
|
+
```
|
196
|
+
"""
|
197
|
+
% target_text
|
198
|
+
)
|
199
|
+
console.console.print()
|
200
|
+
console.console.print(
|
201
|
+
'You can read more about this in [item]https://rsalesc.github.io/rbx/stack-limit/[/item].'
|
202
|
+
)
|
203
|
+
raise typer.Exit(1)
|
204
|
+
|
205
|
+
|
153
206
|
# Compile code item and return its digest in the storage.
|
154
207
|
def compile_item(
|
155
208
|
code: CodeItem,
|
@@ -157,6 +210,8 @@ def compile_item(
|
|
157
210
|
force_warnings: bool = False,
|
158
211
|
verbose: bool = False,
|
159
212
|
) -> str:
|
213
|
+
_check_stack_limit()
|
214
|
+
|
160
215
|
generator_path = PosixPath(code.path)
|
161
216
|
|
162
217
|
if not generator_path.is_file():
|
@@ -268,6 +323,8 @@ def run_item(
|
|
268
323
|
extra_config: Optional[ExecutionConfig] = None,
|
269
324
|
retry_index: Optional[int] = None,
|
270
325
|
) -> Optional[RunLog]:
|
326
|
+
_check_stack_limit()
|
327
|
+
|
271
328
|
language = find_language_name(code)
|
272
329
|
execution_options = get_execution_config(language)
|
273
330
|
if extra_config is not None:
|
@@ -19,7 +19,7 @@ class ProblemStatementOverride(BaseModel):
|
|
19
19
|
model_config = ConfigDict(extra='forbid')
|
20
20
|
|
21
21
|
configure: List[ConversionStep] = Field(
|
22
|
-
[],
|
22
|
+
default=[],
|
23
23
|
discriminator='type',
|
24
24
|
description="""
|
25
25
|
Configure how certain conversion steps should happen when applied to the statement file.
|
@@ -33,7 +33,7 @@ configure them in case they are applied.
|
|
33
33
|
class ContestStatement(BaseModel):
|
34
34
|
model_config = ConfigDict(extra='forbid')
|
35
35
|
|
36
|
-
language: str = Field('en', description='Language code for this statement.')
|
36
|
+
language: str = Field(default='en', description='Language code for this statement.')
|
37
37
|
|
38
38
|
title: str = Field(description='Title of the contest in this language.')
|
39
39
|
|
@@ -50,7 +50,7 @@ class ContestStatement(BaseModel):
|
|
50
50
|
type: StatementType = Field(description='Type of the input statement file.')
|
51
51
|
|
52
52
|
joiner: Optional[Joiner] = Field(
|
53
|
-
None,
|
53
|
+
default=None,
|
54
54
|
description="""
|
55
55
|
Joiner to be used to build the statement.
|
56
56
|
|
@@ -98,7 +98,7 @@ Can be glob pattern as well, such as `imgs/*.png`.
|
|
98
98
|
# Vars to be re-used in the statement.
|
99
99
|
# - It will be available as \VAR{vars} variable in the contest-level box statement.
|
100
100
|
vars: Dict[str, Primitive] = Field(
|
101
|
-
{}, description='Variables to be re-used across the package.'
|
101
|
+
default={}, description='Variables to be re-used across the package.'
|
102
102
|
)
|
103
103
|
|
104
104
|
@property
|
@@ -147,7 +147,7 @@ class Contest(BaseModel):
|
|
147
147
|
# Vars to be re-used in the statements.
|
148
148
|
# - It will be available as \VAR{vars} variable in the contest-level box statement.
|
149
149
|
vars: Dict[str, Primitive] = Field(
|
150
|
-
{}, description='Variables to be re-used across the package.'
|
150
|
+
default={}, description='Variables to be re-used across the package.'
|
151
151
|
)
|
152
152
|
|
153
153
|
@property
|
@@ -6,6 +6,7 @@ import typer
|
|
6
6
|
|
7
7
|
from rbx import console
|
8
8
|
from rbx.box import presets
|
9
|
+
from rbx.box.contest.contest_package import find_contest_yaml
|
9
10
|
from rbx.box.presets.fetch import get_preset_fetch_info
|
10
11
|
|
11
12
|
|
@@ -26,6 +27,15 @@ def create(
|
|
26
27
|
] = None,
|
27
28
|
path: Optional[pathlib.Path] = None,
|
28
29
|
):
|
30
|
+
if find_contest_yaml() is not None:
|
31
|
+
console.console.print(
|
32
|
+
'[error]Cannot [item]rbx create[/item] a problem inside a contest.[/error]'
|
33
|
+
)
|
34
|
+
console.console.print(
|
35
|
+
'[error]Instead, use [item]rbx contest add[/item] to add a problem to a contest.[/error]'
|
36
|
+
)
|
37
|
+
raise typer.Exit(1)
|
38
|
+
|
29
39
|
preset = preset or 'default'
|
30
40
|
console.console.print(f'Creating new problem [item]{name}[/item]...')
|
31
41
|
|
@@ -8,11 +8,11 @@ from rbx.box.packaging.boca.extension import BocaExtension, BocaLanguageExtensio
|
|
8
8
|
# Extension abstractions.
|
9
9
|
class Extensions(BaseModel):
|
10
10
|
boca: Optional[BocaExtension] = Field(
|
11
|
-
None, description='Environment-level extensions for BOCA packaging.'
|
11
|
+
default=None, description='Environment-level extensions for BOCA packaging.'
|
12
12
|
)
|
13
13
|
|
14
14
|
|
15
15
|
class LanguageExtensions(BaseModel):
|
16
16
|
boca: Optional[BocaLanguageExtension] = Field(
|
17
|
-
None, description='Language-level extensions for BOCA packaging.'
|
17
|
+
default=None, description='Language-level extensions for BOCA packaging.'
|
18
18
|
)
|
@@ -0,0 +1,10 @@
|
|
1
|
+
def get_formatted_memory(memory_in_bytes: int, mib_decimal_places: int = 0) -> str:
|
2
|
+
if memory_in_bytes < 1024 * 1024:
|
3
|
+
if memory_in_bytes < 1024:
|
4
|
+
return f'{memory_in_bytes} B'
|
5
|
+
return f'{memory_in_bytes / 1024:.0f} KiB'
|
6
|
+
return f'{memory_in_bytes / (1024 * 1024):.{mib_decimal_places}f} MiB'
|
7
|
+
|
8
|
+
|
9
|
+
def get_formatted_time(time_in_ms: int) -> str:
|
10
|
+
return f'{time_in_ms} ms'
|
@@ -47,11 +47,11 @@ def _get_group_output(
|
|
47
47
|
return group_path / f'{subgroup_prefix}{i:03d}.out'
|
48
48
|
|
49
49
|
|
50
|
-
def
|
50
|
+
def _fill_output_for_defined_testcase(testcase: Testcase) -> Testcase:
|
51
51
|
res = testcase.model_copy()
|
52
52
|
if res.outputPath is not None:
|
53
53
|
return res
|
54
|
-
output_path = res.inputPath.with_suffix('.
|
54
|
+
output_path = res.inputPath.with_suffix('.ans')
|
55
55
|
if output_path.is_file():
|
56
56
|
res.outputPath = output_path
|
57
57
|
return res
|
@@ -61,7 +61,7 @@ def _copy_testcase_over(
|
|
61
61
|
testcase: Testcase,
|
62
62
|
dest: Testcase,
|
63
63
|
):
|
64
|
-
testcase =
|
64
|
+
testcase = _fill_output_for_defined_testcase(testcase)
|
65
65
|
dest.inputPath.parent.mkdir(parents=True, exist_ok=True)
|
66
66
|
shutil.copy(
|
67
67
|
str(testcase.inputPath),
|
@@ -195,7 +195,7 @@ def run_testcase_visitor(visitor: TestcaseVisitor):
|
|
195
195
|
pkg = package.find_problem_package_or_die()
|
196
196
|
|
197
197
|
def _explore_subgroup(
|
198
|
-
subgroup: TestcaseSubgroup, subgroup_index: int, prefix: List[str]
|
198
|
+
subgroup: TestcaseSubgroup, subgroup_index: Optional[int], prefix: List[str]
|
199
199
|
):
|
200
200
|
assert prefix and len(prefix) >= 1 and len(prefix) <= 2
|
201
201
|
group_path = prefix[0]
|
@@ -212,8 +212,10 @@ def run_testcase_visitor(visitor: TestcaseVisitor):
|
|
212
212
|
def _copied_to(i: int) -> Testcase:
|
213
213
|
group_fs_path = package.get_build_testgroup_path(group_path)
|
214
214
|
group_prefix = ''
|
215
|
+
if subgroup_index is not None:
|
216
|
+
group_prefix = f'{subgroup_index}-'
|
215
217
|
if len(prefix) == 2:
|
216
|
-
group_prefix
|
218
|
+
group_prefix += f'{prefix[1]}-'
|
217
219
|
return Testcase(
|
218
220
|
inputPath=_get_group_input(group_fs_path, group_prefix, i),
|
219
221
|
outputPath=_get_group_output(group_fs_path, group_prefix, i),
|
@@ -228,7 +230,7 @@ def run_testcase_visitor(visitor: TestcaseVisitor):
|
|
228
230
|
group_entry=_entry(i),
|
229
231
|
subgroup_entry=_sub_entry(i),
|
230
232
|
metadata=GenerationMetadata(
|
231
|
-
copied_from=
|
233
|
+
copied_from=_fill_output_for_defined_testcase(tc),
|
232
234
|
copied_to=_copied_to(i),
|
233
235
|
),
|
234
236
|
)
|
@@ -249,7 +251,7 @@ def run_testcase_visitor(visitor: TestcaseVisitor):
|
|
249
251
|
group_entry=_entry(i),
|
250
252
|
subgroup_entry=_sub_entry(i),
|
251
253
|
metadata=GenerationMetadata(
|
252
|
-
copied_from=
|
254
|
+
copied_from=_fill_output_for_defined_testcase(tc),
|
253
255
|
copied_to=_copied_to(i),
|
254
256
|
),
|
255
257
|
)
|
@@ -296,10 +298,10 @@ def run_testcase_visitor(visitor: TestcaseVisitor):
|
|
296
298
|
if not visitor.should_visit_group(group.name):
|
297
299
|
continue
|
298
300
|
|
299
|
-
_explore_subgroup(group, 0, [group.name])
|
301
|
+
_explore_subgroup(group, 0 if group.subgroups else None, [group.name])
|
300
302
|
|
301
303
|
for i, subgroup in enumerate(group.subgroups):
|
302
|
-
_explore_subgroup(subgroup, i, [group.name, subgroup.name])
|
304
|
+
_explore_subgroup(subgroup, i + 1, [group.name, subgroup.name])
|
303
305
|
|
304
306
|
|
305
307
|
def _get_necessary_generators_for_groups(
|
@@ -433,7 +435,7 @@ def generate_standalone(
|
|
433
435
|
validator_digest,
|
434
436
|
)
|
435
437
|
if not ok:
|
436
|
-
_print_error_header('
|
438
|
+
_print_error_header('failed validating testcase.')
|
437
439
|
console.console.print(f'[error]Message:[/error] {message}')
|
438
440
|
console.console.print(
|
439
441
|
f'Testcase written at [item]{spec.copied_to.inputPath}[/item]'
|
@@ -19,7 +19,7 @@ def test_generator_works(pkg_from_testdata: pathlib.Path):
|
|
19
19
|
print_directory_tree(pkg_from_testdata)
|
20
20
|
|
21
21
|
assert (
|
22
|
-
package.get_build_testgroup_path('gen1') / '0-
|
22
|
+
package.get_build_testgroup_path('gen1') / '0-000.in'
|
23
23
|
).read_text() == '777\n'
|
24
24
|
assert (
|
25
25
|
package.get_build_testgroup_path('gen1') / '1-gen-000.in'
|
@@ -25,6 +25,7 @@ from rbx.box import (
|
|
25
25
|
builder,
|
26
26
|
cd,
|
27
27
|
setter_config,
|
28
|
+
state,
|
28
29
|
creation,
|
29
30
|
download,
|
30
31
|
environment,
|
@@ -83,6 +84,11 @@ app.add_typer(
|
|
83
84
|
)
|
84
85
|
|
85
86
|
|
87
|
+
@app.callback()
|
88
|
+
def main():
|
89
|
+
state.STATE.run_through_cli = True
|
90
|
+
|
91
|
+
|
86
92
|
# @app.command('ui', hidden=True)
|
87
93
|
# @package.within_problem
|
88
94
|
# def ui():
|
@@ -255,6 +261,7 @@ def _time_impl(check: bool, detailed: bool) -> Optional[int]:
|
|
255
261
|
tracked_solutions=tracked_solutions,
|
256
262
|
check=check,
|
257
263
|
verification=VerificationLevel(verification),
|
264
|
+
timelimit_override=600, # 10 minute time limit for estimation
|
258
265
|
)
|
259
266
|
|
260
267
|
console.console.print()
|
@@ -352,6 +359,12 @@ def irun(
|
|
352
359
|
'-t',
|
353
360
|
help='Testcase to run, in the format "[group]/[index]". If not specified, will run interactively.',
|
354
361
|
),
|
362
|
+
output: bool = typer.Option(
|
363
|
+
False,
|
364
|
+
'--output',
|
365
|
+
'-o',
|
366
|
+
help='Whether to ask user for custom output.',
|
367
|
+
),
|
355
368
|
print: bool = typer.Option(
|
356
369
|
False, '--print', '-p', help='Whether to print outputs to terminal.'
|
357
370
|
),
|
@@ -414,6 +427,7 @@ def irun(
|
|
414
427
|
if generator is not None
|
415
428
|
else None,
|
416
429
|
testcase_entry=TestcaseEntry.parse(testcase) if testcase else None,
|
430
|
+
custom_output=output,
|
417
431
|
print=print,
|
418
432
|
sanitized=sanitized,
|
419
433
|
)
|
@@ -156,11 +156,11 @@ class CodeItem(BaseModel):
|
|
156
156
|
)
|
157
157
|
|
158
158
|
language: Optional[str] = Field(
|
159
|
-
None, description="""The language of the code file."""
|
159
|
+
default=None, description="""The language of the code file."""
|
160
160
|
)
|
161
161
|
|
162
162
|
compilationFiles: Optional[List[str]] = Field(
|
163
|
-
[],
|
163
|
+
default=[],
|
164
164
|
description="""
|
165
165
|
Extra files that should be placed alongside the code file during its compilation,
|
166
166
|
such as testlib.h, jngen.h, etc.
|
@@ -189,7 +189,7 @@ class GeneratorCall(BaseModel):
|
|
189
189
|
name: str = FNameField(description='The name of the generator to call.')
|
190
190
|
|
191
191
|
args: Optional[str] = Field(
|
192
|
-
None, description='The arguments to pass to the generator.'
|
192
|
+
default=None, description='The arguments to pass to the generator.'
|
193
193
|
)
|
194
194
|
|
195
195
|
|
@@ -199,31 +199,31 @@ class TestcaseSubgroup(BaseModel):
|
|
199
199
|
name: str = NameField(description='The name of the test group.')
|
200
200
|
|
201
201
|
testcases: List[Testcase] = Field(
|
202
|
-
[],
|
202
|
+
default=[],
|
203
203
|
description="""
|
204
204
|
The path of testcases to add to this group,
|
205
205
|
in the order they're defined.""",
|
206
206
|
)
|
207
207
|
|
208
208
|
testcaseGlob: Optional[str] = Field(
|
209
|
-
None,
|
209
|
+
default=None,
|
210
210
|
description="""
|
211
211
|
A Python glob that matches input file paths relative to the
|
212
212
|
package directory. The globbed files should end with the extension
|
213
213
|
".in", and their corresponding outputs, if defined, should have the same file name,
|
214
|
-
but ending with ".
|
214
|
+
but ending with ".ans".
|
215
215
|
""",
|
216
216
|
)
|
217
217
|
|
218
218
|
generators: List[GeneratorCall] = Field(
|
219
|
-
[],
|
219
|
+
default=[],
|
220
220
|
description="""
|
221
221
|
A list of generators to call to generate testcases for this group.
|
222
222
|
""",
|
223
223
|
)
|
224
224
|
|
225
225
|
generatorScript: Optional[CodeItem] = Field(
|
226
|
-
None,
|
226
|
+
default=None,
|
227
227
|
description="""
|
228
228
|
A generator script to call to generate testcases for this group.
|
229
229
|
""",
|
@@ -247,14 +247,14 @@ class TestcaseGroup(TestcaseSubgroup):
|
|
247
247
|
model_config = ConfigDict(extra='forbid')
|
248
248
|
|
249
249
|
subgroups: List[TestcaseSubgroup] = Field(
|
250
|
-
[],
|
250
|
+
default=[],
|
251
251
|
description="""
|
252
252
|
A list of test subgroups to define for this group.
|
253
253
|
""",
|
254
254
|
)
|
255
255
|
|
256
256
|
validator: Optional[CodeItem] = Field(
|
257
|
-
None,
|
257
|
+
default=None,
|
258
258
|
description="""
|
259
259
|
A validator to use to validate the testcases of this group.
|
260
260
|
If not specified, will use the package-level validator.
|
@@ -263,7 +263,7 @@ Useful in cases where the constraints vary across test groups.
|
|
263
263
|
)
|
264
264
|
|
265
265
|
weight: Optional[float] = Field(
|
266
|
-
1.0,
|
266
|
+
default=1.0,
|
267
267
|
description="""
|
268
268
|
The weight of this group in the final score. Useful for
|
269
269
|
problems that have points.
|
@@ -301,29 +301,29 @@ class Stress(BaseModel):
|
|
301
301
|
|
302
302
|
class Limits(BaseModel):
|
303
303
|
time: Optional[int] = Field(
|
304
|
-
None, description='Value to override time limit with, in milliseconds.'
|
304
|
+
default=None, description='Value to override time limit with, in milliseconds.'
|
305
305
|
)
|
306
306
|
memory: Optional[int] = Field(
|
307
|
-
None, description='Value to override memory limit with, in MB.'
|
307
|
+
default=None, description='Value to override memory limit with, in MB.'
|
308
308
|
)
|
309
309
|
output: Optional[int] = Field(
|
310
|
-
None, description='Value to override output limit with, in KB.'
|
310
|
+
default=None, description='Value to override output limit with, in KB.'
|
311
311
|
)
|
312
312
|
|
313
313
|
isDoubleTL: bool = Field(
|
314
|
-
False, description='Whether to use double TL for this language.'
|
314
|
+
default=False, description='Whether to use double TL for this language.'
|
315
315
|
)
|
316
316
|
|
317
317
|
|
318
318
|
class LimitModifiers(BaseModel):
|
319
319
|
timeMultiplier: Optional[float] = Field(
|
320
|
-
None, description='Multiplier for time limit.'
|
320
|
+
default=None, description='Multiplier for time limit.'
|
321
321
|
)
|
322
322
|
time: Optional[int] = Field(
|
323
|
-
None, description='Value to override time limit with, in milliseconds.'
|
323
|
+
default=None, description='Value to override time limit with, in milliseconds.'
|
324
324
|
)
|
325
325
|
memory: Optional[int] = Field(
|
326
|
-
None, description='Value to override memory limit with, in MB.'
|
326
|
+
default=None, description='Value to override memory limit with, in MB.'
|
327
327
|
)
|
328
328
|
|
329
329
|
|
@@ -338,28 +338,30 @@ class Package(BaseModel):
|
|
338
338
|
memoryLimit: int = Field(description='Memory limit of the problem, in MB.')
|
339
339
|
|
340
340
|
outputLimit: int = Field(
|
341
|
-
4 * 1024, description='Output limit of the problem, in KB.'
|
341
|
+
default=4 * 1024, description='Output limit of the problem, in KB.'
|
342
342
|
)
|
343
343
|
|
344
344
|
modifiers: Dict[str, LimitModifiers] = Field(
|
345
|
-
{},
|
345
|
+
default={},
|
346
346
|
description="""
|
347
347
|
Limit modifiers that can be specified per language.
|
348
348
|
""",
|
349
349
|
)
|
350
350
|
|
351
351
|
checker: Optional[CodeItem] = Field(
|
352
|
-
None, description='The checker for this problem.'
|
352
|
+
default=None, description='The checker for this problem.'
|
353
353
|
)
|
354
354
|
|
355
355
|
validator: Optional[CodeItem] = Field(
|
356
|
-
None, description='The validator for this problem.'
|
356
|
+
default=None, description='The validator for this problem.'
|
357
357
|
)
|
358
358
|
|
359
|
-
generators: List[Generator] = Field(
|
359
|
+
generators: List[Generator] = Field(
|
360
|
+
default=[], description='Generators for this problem.'
|
361
|
+
)
|
360
362
|
|
361
363
|
solutions: List[Solution] = Field(
|
362
|
-
[],
|
364
|
+
default=[],
|
363
365
|
description="""
|
364
366
|
All tested solutions for this problem.
|
365
367
|
|
@@ -368,17 +370,23 @@ that is correct and used as reference -- and should have the `accepted` outcome.
|
|
368
370
|
""",
|
369
371
|
)
|
370
372
|
|
371
|
-
testcases: List[TestcaseGroup] = Field(
|
373
|
+
testcases: List[TestcaseGroup] = Field(
|
374
|
+
default=[], description='Testcases for the problem.'
|
375
|
+
)
|
372
376
|
|
373
|
-
stresses: List[Stress] = Field(
|
377
|
+
stresses: List[Stress] = Field(
|
378
|
+
default=[], description='Stress tests for the problem.'
|
379
|
+
)
|
374
380
|
|
375
|
-
statements: List[Statement] = Field(
|
381
|
+
statements: List[Statement] = Field(
|
382
|
+
default=[], description='Statements for the problem.'
|
383
|
+
)
|
376
384
|
|
377
385
|
# Vars to be re-used across the package.
|
378
386
|
# - It will be passed as --key=value arguments to the validator.
|
379
387
|
# - It will be available as \VAR{key} variables in the rbx statement.
|
380
388
|
vars: Dict[str, Primitive] = Field(
|
381
|
-
{}, description='Variables to be re-used across the package.'
|
389
|
+
default={}, description='Variables to be re-used across the package.'
|
382
390
|
)
|
383
391
|
|
384
392
|
@property
|
@@ -19,36 +19,36 @@ _CONFIG_FILE_NAME_MAC = 'default_setter_config.mac.yml'
|
|
19
19
|
|
20
20
|
class SanitizersConfig(BaseModel):
|
21
21
|
enabled: bool = Field(
|
22
|
-
False,
|
22
|
+
default=False,
|
23
23
|
description='Whether to use sanitizers when running solutions.',
|
24
24
|
)
|
25
25
|
|
26
26
|
command_substitutions: Dict[str, str] = Field(
|
27
|
-
{},
|
27
|
+
default={},
|
28
28
|
description='Substitutions to apply to commands before running them with sanitizers.',
|
29
29
|
)
|
30
30
|
|
31
31
|
|
32
32
|
class WarningsConfig(BaseModel):
|
33
33
|
enabled: bool = Field(
|
34
|
-
False,
|
34
|
+
default=False,
|
35
35
|
description='Whether to use warning flags when running solutions.',
|
36
36
|
)
|
37
37
|
|
38
38
|
|
39
39
|
class RepeatsConfig(BaseModel):
|
40
40
|
reps: int = Field(
|
41
|
-
1,
|
41
|
+
default=1,
|
42
42
|
description='Number of times to repeat the solution.',
|
43
43
|
)
|
44
44
|
|
45
45
|
retries: int = Field(
|
46
|
-
0,
|
46
|
+
default=0,
|
47
47
|
description='Number of times to retry if the solution TLs.',
|
48
48
|
)
|
49
49
|
|
50
50
|
retries_for_stress: int = Field(
|
51
|
-
0,
|
51
|
+
default=0,
|
52
52
|
description='Number of times to retry in stress mode if the solution TLs.',
|
53
53
|
)
|
54
54
|
|
@@ -69,7 +69,7 @@ class SetterConfig(BaseModel):
|
|
69
69
|
)
|
70
70
|
|
71
71
|
command_substitutions: Dict[str, str] = Field(
|
72
|
-
{},
|
72
|
+
default={},
|
73
73
|
description='Substitutions to apply to commands before running them.',
|
74
74
|
)
|
75
75
|
|