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.
Files changed (57) hide show
  1. rbx/box/builder.py +6 -6
  2. rbx/box/checkers.py +100 -25
  3. rbx/box/cli.py +868 -0
  4. rbx/box/code.py +272 -84
  5. rbx/box/contest/statements.py +4 -2
  6. rbx/box/generators.py +55 -49
  7. rbx/box/generators_test.py +7 -7
  8. rbx/box/main.py +1 -868
  9. rbx/box/package.py +57 -2
  10. rbx/box/packaging/boca/packager.py +2 -1
  11. rbx/box/packaging/main.py +17 -9
  12. rbx/box/packaging/moj/packager.py +49 -10
  13. rbx/box/retries.py +5 -5
  14. rbx/box/schema.py +20 -4
  15. rbx/box/solutions.py +46 -108
  16. rbx/box/solutions_test.py +5 -6
  17. rbx/box/state.py +1 -0
  18. rbx/box/statements/build_statements.py +4 -2
  19. rbx/box/stresses.py +23 -12
  20. rbx/box/tasks.py +277 -0
  21. rbx/box/testcase_extractors.py +21 -21
  22. rbx/box/testcases/main.py +19 -14
  23. rbx/box/unit.py +10 -7
  24. rbx/box/validators.py +10 -10
  25. rbx/box/validators_test.py +3 -3
  26. rbx/grading/judge/cacher.py +0 -4
  27. rbx/grading/judge/digester.py +0 -3
  28. rbx/grading/judge/sandbox.py +15 -0
  29. rbx/grading/judge/sandboxes/stupid_sandbox.py +20 -6
  30. rbx/grading/judge/sandboxes/timeit.py +117 -7
  31. rbx/grading/judge/storage.py +0 -4
  32. rbx/grading/steps.py +76 -2
  33. rbx/grading/steps_with_caching.py +45 -3
  34. rbx/grading/steps_with_caching_run_test.py +51 -49
  35. rbx/main.py +0 -4
  36. rbx/resources/packagers/moj/scripts/compare.sh +25 -6
  37. rbx/test.py +6 -4
  38. {rbx_cp-0.5.40.dist-info → rbx_cp-0.5.45.dist-info}/METADATA +2 -2
  39. {rbx_cp-0.5.40.dist-info → rbx_cp-0.5.45.dist-info}/RECORD +42 -55
  40. {rbx_cp-0.5.40.dist-info → rbx_cp-0.5.45.dist-info}/WHEEL +1 -1
  41. rbx/testdata/box1/gen1.cpp +0 -7
  42. rbx/testdata/box1/gen2.cpp +0 -9
  43. rbx/testdata/box1/genScript.py +0 -2
  44. rbx/testdata/box1/hard-tle.sol.cpp +0 -26
  45. rbx/testdata/box1/ole.cpp +0 -17
  46. rbx/testdata/box1/problem.rbx.yml +0 -39
  47. rbx/testdata/box1/re.sol.cpp +0 -23
  48. rbx/testdata/box1/sol.cpp +0 -22
  49. rbx/testdata/box1/tests/1.in +0 -1
  50. rbx/testdata/box1/tle-and-incorrect.sol.cpp +0 -33
  51. rbx/testdata/box1/tle.sol.cpp +0 -35
  52. rbx/testdata/box1/validator.cpp +0 -11
  53. rbx/testdata/box1/wa.sol.cpp +0 -22
  54. rbx/testdata/caching/executable.py +0 -1
  55. rbx/testdata/compatible +0 -0
  56. {rbx_cp-0.5.40.dist-info → rbx_cp-0.5.45.dist-info}/LICENSE +0 -0
  57. {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
- if (
143
- checker_run_log is not None
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
- console.console.print(
154
- f'[error]Summary:[/error] {checker_run_log.get_summary()}'
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
- if checker_run_log is None or checker_run_log.exitcode not in [0, 1, 2, 3]:
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(checker_digest, run_log, testcase, program_output, skip_run_log)
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