rbx.cp 0.5.45__py3-none-any.whl → 0.5.46__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/generators.py CHANGED
@@ -1,6 +1,5 @@
1
1
  import pathlib
2
2
  import shutil
3
- import tempfile
4
3
  from typing import Dict, List, Optional, Set
5
4
 
6
5
  import typer
@@ -63,6 +62,47 @@ def _copy_testcase_over(
63
62
  )
64
63
 
65
64
 
65
+ def _copy_testcase_output_over(
66
+ src_output_path: pathlib.Path, dest_output_path: pathlib.Path, suffix: str
67
+ ) -> bool:
68
+ dest_output_path.parent.mkdir(parents=True, exist_ok=True)
69
+
70
+ src_path = src_output_path.with_suffix(suffix)
71
+ if not src_path.is_file():
72
+ return False
73
+
74
+ shutil.copy(str(src_path), str(dest_output_path.with_suffix(suffix)))
75
+ return True
76
+
77
+
78
+ def _copy_testcase_outputs_over(
79
+ testcase: Testcase, dest: Testcase, pipes: bool = False
80
+ ):
81
+ assert dest.outputPath is not None
82
+ dest.outputPath.parent.mkdir(parents=True, exist_ok=True)
83
+
84
+ has_copied = False
85
+
86
+ if testcase.outputPath is not None and testcase.outputPath.is_file():
87
+ shutil.copy(str(testcase.outputPath), str(dest.outputPath))
88
+ has_copied = True
89
+
90
+ if not pipes:
91
+ return has_copied
92
+
93
+ reference_path = testcase.outputPath or testcase.inputPath
94
+ if _copy_testcase_output_over(reference_path, dest.outputPath, '.pin'):
95
+ has_copied = True
96
+
97
+ if _copy_testcase_output_over(reference_path, dest.outputPath, '.pout'):
98
+ has_copied = True
99
+
100
+ if _copy_testcase_output_over(reference_path, dest.outputPath, '.pio'):
101
+ has_copied = True
102
+
103
+ return has_copied
104
+
105
+
66
106
  def get_all_built_testcases() -> Dict[str, List[Testcase]]:
67
107
  pkg = package.find_problem_package_or_die()
68
108
  res = {group.name: find_built_testcases(group) for group in pkg.testcases}
@@ -256,59 +296,46 @@ async def generate_testcases(
256
296
  async def generate_output_for_testcase(
257
297
  main_solution_digest: str,
258
298
  testcase: Testcase,
259
- stderr_path: Optional[pathlib.Path] = None,
260
299
  interactor_digest: Optional[str] = None,
261
300
  ):
262
301
  assert testcase.outputPath is not None
263
302
  testcase.inputPath.parent.mkdir(parents=True, exist_ok=True)
264
303
  testcase.outputPath.parent.mkdir(parents=True, exist_ok=True)
265
304
 
266
- if testcase.outputPath.is_file():
267
- # Output file was already copied over from manual tests.
268
- return
269
-
270
305
  main_solution = package.get_main_solution()
271
306
  if main_solution is None:
272
307
  return
273
308
 
274
- with tempfile.TemporaryDirectory() as dir:
275
- output_dir = pathlib.Path(dir)
309
+ eval: Evaluation = await run_solution_on_testcase(
310
+ main_solution,
311
+ main_solution_digest,
312
+ None,
313
+ testcase,
314
+ interactor_digest=interactor_digest,
315
+ use_retries=False,
316
+ use_timelimit=False,
317
+ capture_pipes=True,
318
+ )
276
319
 
277
- eval: Evaluation = await run_solution_on_testcase(
278
- main_solution,
279
- main_solution_digest,
280
- None,
281
- testcase,
282
- output_dir,
283
- interactor_digest=interactor_digest,
284
- use_retries=False,
285
- use_timelimit=False,
320
+ if eval.result.outcome != Outcome.ACCEPTED:
321
+ console.console.print(
322
+ f'[error]Failed generating output for [item]{testcase.inputPath}[/item][/error]',
286
323
  )
287
-
288
- if eval.log.stdout_absolute_path is not None:
289
- shutil.copy(eval.log.stdout_absolute_path, testcase.outputPath)
290
- if eval.log.stderr_absolute_path is not None and stderr_path is not None:
291
- shutil.copy(eval.log.stderr_absolute_path, stderr_path)
292
-
293
- if eval.result.outcome != Outcome.ACCEPTED:
294
- console.console.print(
295
- f'[error]Failed generating output for [item]{testcase.inputPath}[/item][/error]',
296
- )
297
- console.console.print(f'[error]Summary:[/error] {eval.log.get_summary()}')
298
- console.console.print(
299
- f'[warning]Verdict: [item]{eval.result.outcome.value}[/item][/warning]',
300
- )
301
- console.console.print(
302
- f'[warning]Message: [info]{eval.result.message}[/info][/warning]',
303
- )
304
- console.console.print(f'Input written at [item]{testcase.inputPath}[/item]')
324
+ console.console.print(f'[error]Summary:[/error] {eval.log.get_summary()}')
325
+ console.console.print(
326
+ f'[warning]Verdict: [item]{eval.result.outcome.value}[/item][/warning]',
327
+ )
328
+ console.console.print(
329
+ f'[warning]Message: [info]{eval.result.message}[/info][/warning]',
330
+ )
331
+ console.console.print(f'Input written at [item]{testcase.inputPath}[/item]')
332
+ console.console.print(f'Output written at [item]{testcase.outputPath}[/item]')
333
+ if eval.log.stderr_absolute_path is not None:
305
334
  console.console.print(
306
- f'Output written at [item]{testcase.outputPath}[/item]'
335
+ f'Stderr written at [item]{eval.log.stderr_absolute_path}[/item]'
307
336
  )
308
- if stderr_path is not None:
309
- console.console.print(f'Stderr written at [item]{stderr_path}[/item]')
310
337
 
311
- raise typer.Exit(1)
338
+ raise typer.Exit(1)
312
339
 
313
340
 
314
341
  async def generate_outputs_for_testcases(
@@ -350,6 +377,14 @@ async def generate_outputs_for_testcases(
350
377
  return
351
378
  assert tc.outputPath is not None
352
379
 
380
+ if entry.metadata.copied_from is not None and _copy_testcase_outputs_over(
381
+ entry.metadata.copied_from, tc
382
+ ):
383
+ # Copy remaining pipe files.
384
+ _copy_testcase_outputs_over(entry.metadata.copied_from, tc, pipes=True)
385
+ step()
386
+ continue
387
+
353
388
  if (
354
389
  main_solution is None or solution_digest is None
355
390
  ) and not tc.outputPath.is_file():
@@ -362,7 +397,9 @@ async def generate_outputs_for_testcases(
362
397
  await generate_output_for_testcase(
363
398
  solution_digest,
364
399
  tc,
365
- gen_runs_dir / 'main.stderr',
366
400
  interactor_digest=interactor_digest,
367
401
  )
402
+ if entry.metadata.copied_from is not None:
403
+ # Copy remaining pipe files.
404
+ _copy_testcase_outputs_over(entry.metadata.copied_from, tc, pipes=True)
368
405
  step()
rbx/box/solutions.py CHANGED
@@ -185,7 +185,7 @@ def _run_solution(
185
185
  compiled_digest,
186
186
  checker_digest,
187
187
  testcase,
188
- output_path,
188
+ output_dir=output_path,
189
189
  interactor_digest=interactor_digest,
190
190
  testcase_index=i,
191
191
  verification=verification,
@@ -367,6 +367,7 @@ async def _generate_testcase_interactively(
367
367
  )
368
368
 
369
369
  is_manual = False
370
+ is_output_manual = False
370
371
  generation_metadata = None
371
372
  if generator is not None:
372
373
  generation_metadata = GenerationMetadata(
@@ -398,6 +399,7 @@ async def _generate_testcase_interactively(
398
399
  output = console.multiline_prompt('Testcase output')
399
400
  testcase.outputPath.write_text(output)
400
401
  console.console.print()
402
+ is_output_manual = True
401
403
 
402
404
  generation_metadata = GenerationMetadata(
403
405
  copied_to=testcase,
@@ -453,7 +455,7 @@ async def _generate_testcase_interactively(
453
455
  )
454
456
  raise
455
457
 
456
- if main_solution_digest is not None:
458
+ if main_solution_digest is not None and not is_output_manual:
457
459
  pkg = package.find_problem_package_or_die()
458
460
  if pkg.type == TaskType.COMMUNICATION:
459
461
  interactor_digest = checkers.compile_interactor(progress)
@@ -523,7 +525,7 @@ def _run_interactive_solutions(
523
525
  compiled_solutions[solution.path],
524
526
  checker_digest,
525
527
  testcase,
526
- output_dir,
528
+ output_dir=output_dir,
527
529
  interactor_digest=interactor_digest,
528
530
  verification=verification,
529
531
  )
@@ -25,6 +25,7 @@ from rbx.box.statements.schema import (
25
25
  TexToPDF,
26
26
  rbxToTeX,
27
27
  )
28
+ from rbx.box.testcase_utils import TestcaseInteraction, parse_interaction
28
29
 
29
30
 
30
31
  @dataclasses.dataclass
@@ -63,13 +64,31 @@ class StatementSample(BaseModel):
63
64
  inputPath: pathlib.Path
64
65
  outputPath: pathlib.Path
65
66
  hasOutput: bool = True
67
+ interaction: Optional[TestcaseInteraction] = None
66
68
 
67
69
  @staticmethod
68
70
  def from_testcase(testcase: Testcase) -> 'StatementSample':
71
+ input_path = testcase.inputPath
72
+ output_path = testcase.outputPath
73
+
74
+ pin_path = input_path.with_suffix('.pin')
75
+ pout_path = input_path.with_suffix('.pout')
76
+ pio_path = input_path.with_suffix('.pio')
77
+
78
+ if pin_path.is_file():
79
+ input_path = pin_path
80
+ if pout_path.is_file():
81
+ output_path = pout_path
82
+
83
+ interaction = None
84
+ if pio_path.is_file():
85
+ interaction = parse_interaction(pio_path)
86
+
69
87
  return StatementSample(
70
- inputPath=testcase.inputPath,
71
- outputPath=testcase.outputPath or utils.get_empty_sentinel_path(),
72
- hasOutput=testcase.outputPath is not None,
88
+ inputPath=input_path,
89
+ outputPath=output_path or utils.get_empty_sentinel_path(),
90
+ hasOutput=output_path is not None,
91
+ interaction=interaction,
73
92
  )
74
93
 
75
94
  @staticmethod
rbx/box/tasks.py CHANGED
@@ -42,7 +42,7 @@ async def run_solution_on_testcase(
42
42
  compiled_digest: str,
43
43
  checker_digest: Optional[str],
44
44
  testcase: Testcase,
45
- output_dir: pathlib.Path,
45
+ output_dir: Optional[pathlib.Path] = None,
46
46
  interactor_digest: Optional[str] = None,
47
47
  testcase_index: int = 0,
48
48
  verification: VerificationLevel = VerificationLevel.NONE,
@@ -78,7 +78,11 @@ async def run_solution_on_testcase(
78
78
  )
79
79
  extra_config = _get_execution_config(limits, actual_sandbox)
80
80
 
81
- output_path = output_dir / testcase.inputPath.with_suffix('.out').name
81
+ if output_dir is None:
82
+ assert testcase.outputPath is not None
83
+ output_path = testcase.outputPath
84
+ else:
85
+ output_path = output_dir / testcase.inputPath.with_suffix('.out').name
82
86
  error_path = output_path.with_suffix('.err')
83
87
  log_path = output_path.with_suffix('.log')
84
88
  output_path.parent.mkdir(parents=True, exist_ok=True)
@@ -151,7 +155,7 @@ async def _run_communication_solution_on_testcase(
151
155
  interactor_digest: str,
152
156
  checker_digest: Optional[str],
153
157
  testcase: Testcase,
154
- output_dir: pathlib.Path,
158
+ output_dir: Optional[pathlib.Path] = None,
155
159
  testcase_index: int = 0,
156
160
  verification: VerificationLevel = VerificationLevel.NONE,
157
161
  timelimit_override: Optional[int] = None,
@@ -185,7 +189,11 @@ async def _run_communication_solution_on_testcase(
185
189
  )
186
190
  # TODO: maybe combine wall time limits?
187
191
 
188
- output_path = output_dir / testcase.inputPath.with_suffix('.out').name
192
+ if output_dir is None:
193
+ assert testcase.outputPath is not None
194
+ output_path = testcase.outputPath
195
+ else:
196
+ output_path = output_dir / testcase.inputPath.with_suffix('.out').name
189
197
  error_path = output_path.with_suffix('.err')
190
198
  log_path = output_path.with_suffix('.log')
191
199
  output_path.parent.mkdir(parents=True, exist_ok=True)
rbx/box/testcase_utils.py CHANGED
@@ -97,6 +97,16 @@ class TestcaseData(BaseModel):
97
97
  output: str
98
98
 
99
99
 
100
+ class TestcaseInteractionEntry(BaseModel):
101
+ data: str
102
+ pipe: int
103
+
104
+
105
+ class TestcaseInteraction(BaseModel):
106
+ entries: List[TestcaseInteractionEntry]
107
+ prefixes: Tuple[str, str]
108
+
109
+
100
110
  def find_built_testcases(group: TestcaseGroup) -> List[Testcase]:
101
111
  inputs = find_built_testcase_inputs(group)
102
112
 
@@ -143,3 +153,59 @@ def fill_output_for_defined_testcase(testcase: Testcase) -> Testcase:
143
153
  if output_path.is_file():
144
154
  res.outputPath = output_path
145
155
  return res
156
+
157
+
158
+ def parse_interaction(file: pathlib.Path) -> TestcaseInteraction:
159
+ entries = []
160
+ with file.open('r') as f:
161
+ try:
162
+ interactor_prefix = f.readline().strip()
163
+ solution_prefix = f.readline().strip()
164
+ except Exception:
165
+ console.console.print(
166
+ f'[error]Failed to read interaction file [item]{file}[/item]. Expected the first two lines to be the interactor and solution prefixes.[/error]'
167
+ )
168
+ raise typer.Exit(1) from None
169
+
170
+ rest = f.read()
171
+ start = 0
172
+
173
+ def _find_next_prefix(start: int) -> Optional[Tuple[int, int]]:
174
+ interactor_idx = rest.find(interactor_prefix, start)
175
+ solution_idx = rest.find(solution_prefix, start)
176
+ if interactor_idx == -1 and solution_idx == -1:
177
+ return None
178
+ if interactor_idx == -1:
179
+ return (solution_idx, solution_idx + len(solution_prefix))
180
+ if solution_idx == -1:
181
+ return (interactor_idx, interactor_idx + len(interactor_prefix))
182
+ if interactor_idx < solution_idx:
183
+ return (interactor_idx, interactor_idx + len(interactor_prefix))
184
+ return (solution_idx, solution_idx + len(solution_prefix))
185
+
186
+ def _find_next_block() -> Optional[Tuple[int, Tuple[int, int]]]:
187
+ prefix = _find_next_prefix(start)
188
+ if prefix is None:
189
+ return None
190
+ prefix_start, prefix_end = prefix
191
+ prefix = rest[prefix_start:prefix_end]
192
+ pipe = 1 if prefix == solution_prefix else 0
193
+
194
+ nxt = _find_next_prefix(prefix_end)
195
+ if nxt is None:
196
+ return (pipe, (prefix_end, len(rest)))
197
+ nxt_start, _ = nxt
198
+ return (pipe, (prefix_end, nxt_start))
199
+
200
+ while True:
201
+ block = _find_next_block()
202
+ if block is None:
203
+ break
204
+ pipe, (st, nd) = block
205
+ entries.append(TestcaseInteractionEntry(data=rest[st:nd], pipe=pipe))
206
+ start = nd
207
+
208
+ return TestcaseInteraction(
209
+ prefixes=(interactor_prefix, solution_prefix),
210
+ entries=entries,
211
+ )
@@ -556,7 +556,7 @@ class IsolateSandbox(SandboxBase):
556
556
  )
557
557
  except OSError:
558
558
  logger.critical(
559
- 'Failed to execute program in sandbox ' 'with command: %s',
559
+ 'Failed to execute program in sandbox with command: %s',
560
560
  str(args),
561
561
  exc_info=True,
562
562
  )
@@ -680,4 +680,4 @@ class IsolateSandbox(SandboxBase):
680
680
  if delete:
681
681
  logger.debug('Deleting sandbox in %s.', self._outer_dir)
682
682
  # Delete the working directory.
683
- shutil.rmtree(str(self._outer_dir))
683
+ shutil.rmtree(str(self._outer_dir), ignore_errors=True)
@@ -321,4 +321,4 @@ class StupidSandbox(SandboxBase):
321
321
  # This sandbox doesn't have any cleanup, but we might want to delete.
322
322
  if delete:
323
323
  logger.debug('Deleting sandbox in %s.', self._path)
324
- shutil.rmtree(str(self._path))
324
+ shutil.rmtree(str(self._path), ignore_errors=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rbx.cp
3
- Version: 0.5.45
3
+ Version: 0.5.46
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9,<4.0
@@ -22,7 +22,7 @@ rbx/box/download.py,sha256=MFP-R26JiYGAP89I0TK-0fYc69Fsd20tsBqgtRCy5AE,2234
22
22
  rbx/box/environment.py,sha256=47NtyuVC6zSQKAtQaXPEXvqcD-KJiuWRpWF8pYvcG4c,11158
23
23
  rbx/box/extensions.py,sha256=Von8kIeXvNFTkGlMRMTvL2HIHPwlkuiMswr-ydbGV1w,519
24
24
  rbx/box/formatting.py,sha256=3phFRHzqVXj4Ok1yDhCq6Clbw6KlqwJNpMhs--oTWFI,405
25
- rbx/box/generators.py,sha256=081wKmLQpR7rGGxL9RUWULZef-1DpUWg4U8mWrHvTI0,12431
25
+ rbx/box/generators.py,sha256=5-3K0JSLR9GbV0LmOkvNsWiQaMvhFBrI56ZaV1WgodQ,13472
26
26
  rbx/box/generators_test.py,sha256=J7aBfuJhU84MWDWzgReRoOuQw_hVa09B8gTKAvL2XVo,1987
27
27
  rbx/box/lazy_importing_main.py,sha256=6Z8As7qVFFT619xHH9Xt8VCH57NjC4aDxfAgkWiUwT8,116
28
28
  rbx/box/lazy_importing_test.py,sha256=B0-b3y_DkxEmtVfu4NfmVsgVdFl6kRCsEL6GLMHJISo,628
@@ -45,12 +45,12 @@ rbx/box/retries.py,sha256=tRk2K1bXw2xnwkAj2CsktRHTEhw7YKcPxMQTT6mCy-E,4707
45
45
  rbx/box/sanitizers/warning_stack.py,sha256=RI97_GJgdjTKIXY_r0EKp5h0qQQSDSdNDh5K7zINrqs,2861
46
46
  rbx/box/schema.py,sha256=P1jVaeqe4OcotAJOqu3T5WD8DR-amZyyq3cau5rPiM8,17086
47
47
  rbx/box/setter_config.py,sha256=s53talhwM6FTGDCcBhY7IlZ6_6mJ3PMp6V4kTtaSs50,4262
48
- rbx/box/solutions.py,sha256=lzvk72PsQOE0TMK6AOk-qNROK0fRAKcGINtokq6gypU,42554
48
+ rbx/box/solutions.py,sha256=MEpbLvD2Wnj9NZ4Fm5SqE1xQkg1TNgnfWUDd0IsG9RE,42666
49
49
  rbx/box/solutions_test.py,sha256=TCowbxBG3SvDlFO5-qtBj_M_HrAHe0IJaI1XwoQ1d00,1718
50
50
  rbx/box/state.py,sha256=MMf3DvfQji0jKEliCHct2Tpp_0epL1tvP8HbHNArQIc,166
51
51
  rbx/box/statements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
52
52
  rbx/box/statements/build_statements.py,sha256=uHlC3y3PtKaGUd2ZS_zYxi6-AKco6v_yd-lvm6BfrNA,12091
53
- rbx/box/statements/builders.py,sha256=L67i-CP6ftDm2wR6VWywTd3ad7-fhWSSMfaN66Gt13s,11201
53
+ rbx/box/statements/builders.py,sha256=6lYV-cnC-NXMnJf1wasbq_AMbjdIuPpMirm7QsjZI6s,11825
54
54
  rbx/box/statements/joiners.py,sha256=jItNXkAbTjFQpPMgfDMW86n3vMTbaE8sgo9I8Yf4Txg,2886
55
55
  rbx/box/statements/latex.py,sha256=LkcHwXjMFxbw--Gj9T1VkFKQFsXhY9dN7xZHpZycNW8,1346
56
56
  rbx/box/statements/latex_jinja.py,sha256=7WBfn1h8DpqCAmSE6Av64HfURMnJ2AO4QX1CD72sz5E,7096
@@ -59,9 +59,9 @@ rbx/box/stresses.py,sha256=E4JU1JrUcikPA6QEACKnEOBkRocpEhswkF1iE7aRD5U,12147
59
59
  rbx/box/stressing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
60
  rbx/box/stressing/finder_parser.py,sha256=jXpYNa4FyugzmHi3r96Uv4rU1krRQJc5Ihr9jf1cvNo,11918
61
61
  rbx/box/stressing/generator_parser.py,sha256=oHZryjR3YohgaSO9WEirQ7b2e-98WgZStF0N99W4Thw,7380
62
- rbx/box/tasks.py,sha256=upcj8aQjJ5Oi0XHD4CVutAvzh-K0gIbpikAhu6_nTMM,9537
62
+ rbx/box/tasks.py,sha256=t_yZE7dqgh0vzxbmvuvsDbQq9BzbWALA5jUx3hZ_2pA,9863
63
63
  rbx/box/testcase_extractors.py,sha256=T5vCW5qERlqitGrFP6RuITEVr9o8XQozNa4AsxfuV_Y,11871
64
- rbx/box/testcase_utils.py,sha256=qtv7-bJbbblMgINvcf_3YTdD85MTtWpD23KUSZUL1as,4327
64
+ rbx/box/testcase_utils.py,sha256=eeE7pr0vwxTEdHcZcpr9bIQlgIY5qI4-HpqR041LKxQ,6697
65
65
  rbx/box/testcases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  rbx/box/testcases/main.py,sha256=sLEgpVCDjRc3tJcU--DNWMmc58KgrkQe4zGzBorO-rk,5394
67
67
  rbx/box/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -87,8 +87,8 @@ rbx/grading/judge/cacher.py,sha256=TDgYDhehnJIv64EFiXxPAtVADD8q9WcJa_BE9TsE-JM,1
87
87
  rbx/grading/judge/digester.py,sha256=gtOIe_iL4PEWA7OKelW1gjSI-nBvbOpDPJGV8VQyjSg,912
88
88
  rbx/grading/judge/sandbox.py,sha256=Pc1JAh_ZZ46m-S10rmoYCA7ZWGpLCYB0UnhdzSFMDyY,24054
89
89
  rbx/grading/judge/sandboxes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
90
- rbx/grading/judge/sandboxes/isolate.py,sha256=9xgBuNfAvGtO2zME1FXRah2rcPvzDShsPG0TTuX_UDU,25649
91
- rbx/grading/judge/sandboxes/stupid_sandbox.py,sha256=RDnCA4EmEgA2D0MOuD1y7eTRX_jKNRhVQkmUAb2dsgg,10606
90
+ rbx/grading/judge/sandboxes/isolate.py,sha256=TToY4IEIBwdxlcvVn7s6lzoC3hKvsenF58kLxuBKAsg,25666
91
+ rbx/grading/judge/sandboxes/stupid_sandbox.py,sha256=O-HK6n5Swu3BiER8W03AeV_emmdDZqaoxL6WQc4-yBY,10626
92
92
  rbx/grading/judge/sandboxes/timeit.py,sha256=HR_5CRyuY4OHZ1rTcEXZ796UfqlAJGX8HiZpgxOApkk,10475
93
93
  rbx/grading/judge/storage.py,sha256=3vv0HvtenbUZBH33CB5ZzX66ppL22G6munBaAA9BgwQ,9418
94
94
  rbx/grading/judge/test.py,sha256=ll0Iw7zyOpGdKPD_PGH7dvUkb4stQLu-ikbQnqJvuAc,944
@@ -160,8 +160,8 @@ rbx/testcase.py,sha256=yKOq3CAJZ1YTmInvnoIs0u1iJnRj_X85XiWbLI-p9d8,1951
160
160
  rbx/testcase_rendering.py,sha256=nfmv6dSEqd4aR3TsaODwkKGK6AXty_DDKtWf_ejiQpI,2084
161
161
  rbx/testing_utils.py,sha256=ZXMysGXpTtvS1lfLL38FuD5iSIyxi3ARjQePDrUmEtc,2067
162
162
  rbx/utils.py,sha256=6e1eXRzNE-52D0UVtqclePxqR4Haiqt8qWCrSVjnGuE,4585
163
- rbx_cp-0.5.45.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
164
- rbx_cp-0.5.45.dist-info/METADATA,sha256=C1zyfAGCq-sfkXX8y52EA2XJIjBgD5X_N4vPE5oDrDk,3261
165
- rbx_cp-0.5.45.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
166
- rbx_cp-0.5.45.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
167
- rbx_cp-0.5.45.dist-info/RECORD,,
163
+ rbx_cp-0.5.46.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
164
+ rbx_cp-0.5.46.dist-info/METADATA,sha256=3rjgO4K3_womzC9XQhPR2R1JNTJTk2gEBxUrhNPBBec,3261
165
+ rbx_cp-0.5.46.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
166
+ rbx_cp-0.5.46.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
167
+ rbx_cp-0.5.46.dist-info/RECORD,,