rbx.cp 0.5.40__py3-none-any.whl → 0.5.45__py3-none-any.whl
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/box/builder.py +6 -6
- rbx/box/checkers.py +100 -25
- rbx/box/cli.py +868 -0
- rbx/box/code.py +272 -84
- rbx/box/contest/statements.py +4 -2
- rbx/box/generators.py +55 -49
- rbx/box/generators_test.py +7 -7
- rbx/box/main.py +1 -868
- rbx/box/package.py +57 -2
- rbx/box/packaging/boca/packager.py +2 -1
- rbx/box/packaging/main.py +17 -9
- rbx/box/packaging/moj/packager.py +49 -10
- rbx/box/retries.py +5 -5
- rbx/box/schema.py +20 -4
- rbx/box/solutions.py +46 -108
- rbx/box/solutions_test.py +5 -6
- rbx/box/state.py +1 -0
- rbx/box/statements/build_statements.py +4 -2
- rbx/box/stresses.py +23 -12
- rbx/box/tasks.py +277 -0
- rbx/box/testcase_extractors.py +21 -21
- rbx/box/testcases/main.py +19 -14
- rbx/box/unit.py +10 -7
- rbx/box/validators.py +10 -10
- rbx/box/validators_test.py +3 -3
- rbx/grading/judge/cacher.py +0 -4
- rbx/grading/judge/digester.py +0 -3
- rbx/grading/judge/sandbox.py +15 -0
- rbx/grading/judge/sandboxes/stupid_sandbox.py +20 -6
- rbx/grading/judge/sandboxes/timeit.py +117 -7
- rbx/grading/judge/storage.py +0 -4
- rbx/grading/steps.py +76 -2
- rbx/grading/steps_with_caching.py +45 -3
- rbx/grading/steps_with_caching_run_test.py +51 -49
- rbx/main.py +0 -4
- rbx/resources/packagers/moj/scripts/compare.sh +25 -6
- rbx/test.py +6 -4
- {rbx_cp-0.5.40.dist-info → rbx_cp-0.5.45.dist-info}/METADATA +2 -2
- {rbx_cp-0.5.40.dist-info → rbx_cp-0.5.45.dist-info}/RECORD +42 -55
- {rbx_cp-0.5.40.dist-info → rbx_cp-0.5.45.dist-info}/WHEEL +1 -1
- rbx/testdata/box1/gen1.cpp +0 -7
- rbx/testdata/box1/gen2.cpp +0 -9
- rbx/testdata/box1/genScript.py +0 -2
- rbx/testdata/box1/hard-tle.sol.cpp +0 -26
- rbx/testdata/box1/ole.cpp +0 -17
- rbx/testdata/box1/problem.rbx.yml +0 -39
- rbx/testdata/box1/re.sol.cpp +0 -23
- rbx/testdata/box1/sol.cpp +0 -22
- rbx/testdata/box1/tests/1.in +0 -1
- rbx/testdata/box1/tle-and-incorrect.sol.cpp +0 -33
- rbx/testdata/box1/tle.sol.cpp +0 -35
- rbx/testdata/box1/validator.cpp +0 -11
- rbx/testdata/box1/wa.sol.cpp +0 -22
- rbx/testdata/caching/executable.py +0 -1
- rbx/testdata/compatible +0 -0
- {rbx_cp-0.5.40.dist-info → rbx_cp-0.5.45.dist-info}/LICENSE +0 -0
- {rbx_cp-0.5.40.dist-info → rbx_cp-0.5.45.dist-info}/entry_points.txt +0 -0
rbx/box/builder.py
CHANGED
@@ -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:
|
rbx/box/checkers.py
CHANGED
@@ -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
|