rbx.cp 0.5.16__py3-none-any.whl → 0.5.17__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/solutions_test.py CHANGED
@@ -1,3 +1,4 @@
1
+ import asyncio
1
2
  import pathlib
2
3
 
3
4
  import pytest
@@ -20,7 +21,7 @@ def test_solutions(pkg_from_testdata: pathlib.Path):
20
21
  generate_outputs_for_testcases()
21
22
 
22
23
  result = run_solutions(verification=VerificationLevel.FULL)
23
- res = convert_list_of_solution_evaluations_to_dict(result.items)
24
+ res = asyncio.run(convert_list_of_solution_evaluations_to_dict(result.items))
24
25
 
25
26
  # First solution should pass all tests.
26
27
  assert all(chk.result.outcome == Outcome.ACCEPTED for chk in res[0]['gen1'])
rbx/box/stresses.py CHANGED
@@ -8,7 +8,7 @@ from pydantic import BaseModel
8
8
 
9
9
  from rbx import console
10
10
  from rbx.box import checkers, package, validators
11
- from rbx.box.code import compile_item, run_item
11
+ from rbx.box.code import SanitizationLevel, compile_item, run_item
12
12
  from rbx.box.generators import generate_standalone
13
13
  from rbx.box.schema import CodeItem, GeneratorCall, Stress, Testcase
14
14
  from rbx.box.solutions import compile_solutions, get_outcome_style_verdict
@@ -49,6 +49,7 @@ def run_stress(
49
49
  findingsLimit: int = 1,
50
50
  verbose: bool = False,
51
51
  progress: Optional[StatusProgress] = None,
52
+ sanitized: bool = False,
52
53
  ) -> StressReport:
53
54
  if finder:
54
55
  stress = Stress(
@@ -63,7 +64,7 @@ def run_stress(
63
64
  generator = package.get_generator(call.name)
64
65
 
65
66
  try:
66
- generator_digest = compile_item(generator)
67
+ generator_digest = compile_item(generator, sanitized=SanitizationLevel.PREFER)
67
68
  except:
68
69
  console.console.print(
69
70
  f'[error]Failed compiling generator [item]{generator.name}[/item].[/error]'
@@ -79,7 +80,8 @@ def run_stress(
79
80
 
80
81
  solution_indices = {str(solution.path): i for i, solution in enumerate(solutions)}
81
82
  solutions_digest = compile_solutions(
82
- tracked_solutions=set(str(solution.path) for solution in solutions)
83
+ tracked_solutions=set(str(solution.path) for solution in solutions),
84
+ sanitized=sanitized,
83
85
  )
84
86
  if progress:
85
87
  progress.update('Compiling finders...')
rbx/box/validators.py CHANGED
@@ -1,13 +1,13 @@
1
1
  import pathlib
2
2
  import shlex
3
- from typing import Dict, List, Optional, Set, Tuple
3
+ from typing import Dict, Iterable, List, Optional, Set, Tuple
4
4
 
5
5
  import typer
6
6
  from pydantic import BaseModel
7
7
 
8
8
  from rbx import console
9
9
  from rbx.box import package
10
- from rbx.box.code import compile_item, run_item
10
+ from rbx.box.code import SanitizationLevel, compile_item, run_item
11
11
  from rbx.box.schema import CodeItem, Primitive
12
12
  from rbx.box.testcases import find_built_testcase_inputs
13
13
  from rbx.grading.judge.sandbox import SandboxBase
@@ -32,7 +32,7 @@ class TestcaseValidationInfo(BaseModel):
32
32
 
33
33
  def _compile_validator(validator: CodeItem) -> str:
34
34
  try:
35
- digest = compile_item(validator)
35
+ digest = compile_item(validator, sanitized=SanitizationLevel.PREFER)
36
36
  except:
37
37
  console.console.print(
38
38
  f'[error]Failed compiling validator [item]{validator.path}[/item][/error]'
@@ -65,7 +65,7 @@ def _process_bounds(log: str) -> HitBounds:
65
65
  return bounds
66
66
 
67
67
 
68
- def _merge_hit_bounds(hit_bounds: List[HitBounds]) -> HitBounds:
68
+ def _merge_hit_bounds(hit_bounds: Iterable[HitBounds]) -> HitBounds:
69
69
  res: HitBounds = {}
70
70
  for hb in hit_bounds:
71
71
  for k, hit in hb.items():
@@ -241,7 +241,7 @@ def has_validation_errors(infos: List[TestcaseValidationInfo]) -> bool:
241
241
 
242
242
  def print_validation_report(infos: List[TestcaseValidationInfo]):
243
243
  console.console.rule('Validation report', style='status')
244
- hit_bounds_per_group: Dict[str, HitBounds] = {}
244
+ hit_bounds_per_group: Dict[Optional[str], HitBounds] = {}
245
245
  for info in infos:
246
246
  if not info.ok:
247
247
  console.console.print(
rbx/config.py CHANGED
@@ -268,4 +268,7 @@ def edit():
268
268
  """
269
269
  Open the config in an editor.
270
270
  """
271
+ # Ensure config is created before calling the editor.
272
+ get_config()
273
+
271
274
  open_editor(get_config_path())
rbx/grading/caching.py CHANGED
@@ -334,6 +334,10 @@ class DependencyCache:
334
334
  for logs, reference_logs in zip(fingerprint.logs, reference_fingerprint.logs):
335
335
  if logs.run is not None:
336
336
  reference_logs.run = logs.run.model_copy(deep=True)
337
+ if logs.preprocess is not None:
338
+ reference_logs.preprocess = [
339
+ log.model_copy(deep=True) for log in logs.preprocess
340
+ ]
337
341
  reference_logs.cached = True
338
342
 
339
343
  return True
@@ -3,6 +3,7 @@ from __future__ import annotations
3
3
  import importlib
4
4
  import importlib.resources
5
5
  import logging
6
+ import os
6
7
  import pathlib
7
8
  import shutil
8
9
  import signal
@@ -291,6 +292,7 @@ class StupidSandbox(SandboxBase):
291
292
  stdin=subprocess.PIPE,
292
293
  stdout=subprocess.PIPE,
293
294
  stderr=subprocess.STDOUT,
295
+ env={**os.environ, **self.params.set_env},
294
296
  )
295
297
  self.hydrate_logs()
296
298
  return self.translate_box_exitcode(self.returncode)
rbx/grading/steps.py CHANGED
@@ -1,12 +1,13 @@
1
1
  import functools
2
- import os
3
2
  import pathlib
4
3
  import shlex
5
4
  import shutil
6
5
  import subprocess
6
+ import sys
7
7
  from enum import Enum
8
- from typing import Any, Dict, List, Optional, Tuple, Union
8
+ from typing import IO, Any, Dict, List, Optional, Tuple, Union
9
9
 
10
+ import typer
10
11
  from pydantic import BaseModel
11
12
  from rich.text import Text
12
13
 
@@ -14,7 +15,7 @@ from rbx import utils
14
15
  from rbx.config import get_bits_stdcpp, get_jngen, get_testlib
15
16
  from rbx.console import console
16
17
  from rbx.grading.judge.sandbox import SandboxBase, SandboxParams
17
- from rbx.grading.judge.storage import copyfileobj
18
+ from rbx.grading.judge.storage import Storage, copyfileobj
18
19
 
19
20
  MAX_STDOUT_LEN = 1024 * 1024 * 128 # 128 MB
20
21
 
@@ -36,6 +37,7 @@ class DigestHolder(BaseModel):
36
37
 
37
38
  class GradingLogsHolder(BaseModel):
38
39
  run: Optional['RunLog'] = None
40
+ preprocess: Optional[List['PreprocessLog']] = None
39
41
  cached: bool = False
40
42
 
41
43
 
@@ -114,6 +116,17 @@ class GradingFileOutput(BaseModel):
114
116
  # Whether to track file through its hash (disable for optimization).
115
117
  hash: bool = True
116
118
 
119
+ def get_file(self, storage: Storage) -> Optional[IO[bytes]]:
120
+ if self.dest is not None:
121
+ if self.optional and not self.dest.exists():
122
+ return None
123
+ return self.dest.open('rb')
124
+ if self.digest is not None and self.digest.value is not None:
125
+ if self.optional and not storage.exists(self.digest.value):
126
+ return None
127
+ return storage.get_file(self.digest.value)
128
+ raise ValueError('No file to get')
129
+
117
130
 
118
131
  class GradingArtifacts(BaseModel):
119
132
  # Root directory for the produced artifacts.
@@ -125,6 +138,18 @@ class GradingArtifacts(BaseModel):
125
138
  # Capture certain logs of the execution.
126
139
  logs: Optional[GradingLogsHolder] = None
127
140
 
141
+ def get_input_file_for_dest(self, dest: pathlib.Path) -> Optional[GradingFileInput]:
142
+ for input in self.inputs:
143
+ if input.dest == dest:
144
+ return input
145
+ return None
146
+
147
+ def get_output_file_for_src(self, src: pathlib.Path) -> Optional[GradingFileOutput]:
148
+ for output in self.outputs:
149
+ if output.src == src:
150
+ return output
151
+ return None
152
+
128
153
 
129
154
  class TestcaseIO(BaseModel):
130
155
  index: int
@@ -134,6 +159,7 @@ class TestcaseIO(BaseModel):
134
159
 
135
160
  class RunLogMetadata(BaseModel):
136
161
  language: Optional[str] = None
162
+ is_sanitized: bool = False
137
163
 
138
164
 
139
165
  class RunLog(BaseModel):
@@ -141,6 +167,7 @@ class RunLog(BaseModel):
141
167
  exitstatus: str = SandboxBase.EXIT_SANDBOX_ERROR
142
168
  time: Optional[float] = 0.0
143
169
  memory: Optional[int] = 0
170
+ warnings: bool = False
144
171
  metadata: Optional[RunLogMetadata] = None
145
172
 
146
173
  def get_run_language(self) -> Optional[str]:
@@ -160,6 +187,9 @@ class PreprocessLog(RunLog):
160
187
  cmd: List[str]
161
188
  log: str
162
189
 
190
+ def get_command(self) -> str:
191
+ return ' '.join(self.cmd)
192
+
163
193
 
164
194
  class TestcaseLog(RunLog):
165
195
  stdout_absolute_path: Optional[pathlib.Path] = None
@@ -171,6 +201,7 @@ class CheckerResult(BaseModel):
171
201
  outcome: Outcome
172
202
  message: str = ''
173
203
  no_tle_outcome: Optional[Outcome] = None
204
+ sanitizer_warnings: bool = False
174
205
 
175
206
 
176
207
  class Evaluation(BaseModel):
@@ -260,11 +291,25 @@ def _split_and_expand(command: str, sandbox: SandboxBase) -> List[str]:
260
291
 
261
292
 
262
293
  def _is_c_command(exe_command: str) -> bool:
263
- return exe_command.endswith('gcc') or exe_command.endswith('clang')
294
+ return 'gcc' in exe_command or 'clang' in exe_command
264
295
 
265
296
 
266
297
  def _is_cpp_command(exe_command: str) -> bool:
267
- return exe_command.endswith('g++') or exe_command.endswith('clang++')
298
+ return 'g++' in exe_command or 'clang++' in exe_command
299
+
300
+
301
+ def is_cxx_command(exe_command: str) -> bool:
302
+ return _is_cpp_command(exe_command) or _is_c_command(exe_command)
303
+
304
+
305
+ def is_cxx_sanitizer_command(command: str) -> bool:
306
+ cmds = shlex.split(command)
307
+ if not cmds:
308
+ return False
309
+ exe = cmds[0]
310
+ if not is_cxx_command(exe):
311
+ return False
312
+ return 'fsanitize' in command
268
313
 
269
314
 
270
315
  @functools.cache
@@ -279,27 +324,35 @@ def _complain_about_clang() -> None:
279
324
  )
280
325
 
281
326
 
282
- def _maybe_get_bits_stdcpp_for_clang(command: str) -> Optional[GradingFileInput]:
327
+ def _get_cxx_version_output(command: str) -> Optional[str]:
283
328
  cmds = shlex.split(command)
284
329
  if not cmds:
285
330
  return None
286
331
  exe = cmds[0]
287
-
288
- if not _is_cpp_command(exe):
332
+ if not is_cxx_command(exe):
289
333
  return None
290
334
 
335
+ exe = cmds[0]
291
336
  output = subprocess.run([exe, '-v'], capture_output=True)
292
337
  if output.returncode != 0:
293
- console.print('[error]Failed to get g++/clang compiler version.[/error]')
338
+ console.print('[error]Failed to get C/C++ compiler version.[/error]')
339
+ return None
340
+ return output.stderr.decode()
341
+
342
+
343
+ def _maybe_get_bits_stdcpp_for_clang(command: str) -> Optional[GradingFileInput]:
344
+ version_output = _get_cxx_version_output(command)
345
+ if version_output is None:
294
346
  return None
295
- lines = output.stderr.decode().splitlines()
347
+ lines = version_output.splitlines()
296
348
  if not lines:
297
349
  return None
298
350
  # Check the first line for `clang`.
299
351
  if 'clang' not in lines[0]:
300
352
  return None
301
353
 
302
- _complain_about_clang()
354
+ if not is_cxx_sanitizer_command(command):
355
+ _complain_about_clang()
303
356
  bits = get_bits_stdcpp()
304
357
  return GradingFileInput(src=bits, dest=pathlib.Path('bits/stdc++.h'))
305
358
 
@@ -316,10 +369,6 @@ def _maybe_get_bits_stdcpp_for_commands(
316
369
 
317
370
  @functools.cache
318
371
  def _try_following_alias_for_exe(exe: str) -> Optional[str]:
319
- if _is_c_command(exe) and os.environ.get('RBX_C_PATH'):
320
- return os.environ['RBX_C_PATH']
321
- if _is_cpp_command(exe) and os.environ.get('RBX_CXX_PATH'):
322
- return os.environ['RBX_CXX_PATH']
323
372
  output = subprocess.run(
324
373
  f'which {exe}', shell=True, executable=shutil.which('bash'), capture_output=True
325
374
  )
@@ -346,6 +395,57 @@ def _try_following_alias_for_commands(commands: List[str]) -> List[str]:
346
395
  return res
347
396
 
348
397
 
398
+ @functools.cache
399
+ def _maybe_complain_about_sanitization(command: str) -> None:
400
+ if not is_cxx_sanitizer_command(command):
401
+ return
402
+ if sys.platform != 'darwin':
403
+ return
404
+
405
+ version_output = _get_cxx_version_output(command)
406
+ if version_output is None:
407
+ return
408
+ lines = version_output.splitlines()
409
+ if not lines:
410
+ return
411
+ if 'gcc' in lines[-1]:
412
+ console.print(
413
+ '[error]Notice you are using sanitizers in [item]MacOS[/item], but your C/C++ compiler is [item]gcc[/item].[/error]'
414
+ )
415
+ console.print('[error]GCC does not support sanitization in MacOS.[/error]')
416
+ console.print(
417
+ '[warning]See [item]https://rsalesc.github.io/rbx/cpp-on-macos[/item] for instructions on how to use C/C++ sanitizers on MacOS.[/warning]'
418
+ )
419
+ raise typer.Exit(1)
420
+
421
+
422
+ def _check_for_sanitizer_warnings_in_line(line: str) -> bool:
423
+ line = line.lower()
424
+ return 'runtime error:' in line or '==error' in line
425
+
426
+
427
+ def _check_for_sanitizer_warnings(
428
+ sandbox: SandboxBase, stderr_file: Optional[pathlib.Path]
429
+ ) -> bool:
430
+ if stderr_file is None:
431
+ return False
432
+ if not sandbox.file_exists(stderr_file):
433
+ return False
434
+ with sandbox.get_file(stderr_file) as f:
435
+ return any(_check_for_sanitizer_warnings_in_line(line.decode()) for line in f)
436
+
437
+
438
+ def _check_for_compilation_warnings(
439
+ sandbox: SandboxBase, stderr_file: Optional[pathlib.Path]
440
+ ) -> bool:
441
+ if stderr_file is None:
442
+ return False
443
+ if not sandbox.file_exists(stderr_file):
444
+ return False
445
+ with sandbox.get_file(stderr_file) as f:
446
+ return any(line.strip() for line in f)
447
+
448
+
349
449
  def compile(
350
450
  commands: List[str],
351
451
  params: SandboxParams,
@@ -366,6 +466,7 @@ def compile(
366
466
  sandbox.set_params(params)
367
467
 
368
468
  for i, command in enumerate(commands):
469
+ _maybe_complain_about_sanitization(command)
369
470
  cmd = _split_and_expand(command, sandbox)
370
471
  stdout_file = pathlib.PosixPath(f'compile-{i}.stdout')
371
472
  stderr_file = pathlib.PosixPath(f'compile-{i}.stderr')
@@ -399,6 +500,7 @@ def compile(
399
500
  exitstatus=sandbox.get_exit_status(),
400
501
  time=sandbox.get_execution_time(),
401
502
  memory=sandbox.get_memory_used(),
503
+ warnings=_check_for_compilation_warnings(sandbox, stderr_file),
402
504
  log='\n'.join(std_outputs),
403
505
  )
404
506
  logs.append(log)
@@ -406,6 +508,9 @@ def compile(
406
508
  if log.exitcode != 0:
407
509
  break
408
510
 
511
+ if artifacts.logs is not None:
512
+ artifacts.logs.preprocess = logs
513
+
409
514
  if logs and logs[-1].exitcode != 0:
410
515
  console.print(
411
516
  '[error]FAILED[/error] Preprocessing failed with command',
@@ -455,6 +560,11 @@ def run(
455
560
  memory=sandbox.get_memory_used(),
456
561
  metadata=metadata,
457
562
  )
563
+ if metadata is not None and metadata.is_sanitized:
564
+ run_log.warnings = _check_for_sanitizer_warnings(
565
+ sandbox,
566
+ params.stderr_file,
567
+ )
458
568
  if artifacts.logs is not None:
459
569
  artifacts.logs.run = run_log.model_copy()
460
570
  return run_log
@@ -18,6 +18,8 @@ def compile(
18
18
  artifacts: GradingArtifacts,
19
19
  dependency_cache: DependencyCache,
20
20
  ):
21
+ artifacts.logs = GradingLogsHolder()
22
+
21
23
  ok = True
22
24
  with dependency_cache(
23
25
  commands, [artifacts], params.get_cacheable_params()
@@ -0,0 +1,31 @@
1
+ # Whether to enable warnings when running solutions.
2
+ warnings:
3
+ enabled: true
4
+
5
+ # A list of command substitutions to apply to rbx.
6
+ # Useful when replacing compilers in OS such as Mac.
7
+ command_substitutions:
8
+ g++: g++
9
+ gcc: gcc
10
+ java: java
11
+ javac: javac
12
+ jar: jar
13
+ python: python
14
+ python2: python2
15
+ python3: python3
16
+
17
+ # Whether sanitizers will be enabled by default
18
+ # when running testlib components.
19
+ # This flag has no effect on running solutions with
20
+ # sanitizers. For this, you have to use the `-s` flag in `rbx run`.
21
+ sanitizers:
22
+ enabled: false
23
+
24
+ # A list of command substitutions to apply to rbx when
25
+ # sanitizers are enabled.
26
+ #
27
+ # This is useful when replacing compilers in OS such as Mac,
28
+ # since GCC on Mac does not support sanitizers.
29
+ command_substitutions:
30
+ g++: clang++
31
+ gcc: clang
@@ -0,0 +1,29 @@
1
+ # Whether to enable warnings when running solutions.
2
+ warnings:
3
+ enabled: true
4
+
5
+ # A list of command substitutions to apply to rbx.
6
+ # Useful when replacing compilers in OS such as Mac.
7
+ command_substitutions:
8
+ g++: g++
9
+ gcc: gcc
10
+ java: java
11
+ javac: javac
12
+ jar: jar
13
+ python: python
14
+ python2: python2
15
+ python3: python3
16
+
17
+ # Whether sanitizers will be enabled by default
18
+ # when running testlib components.
19
+ # This flag has no effect on running solutions with
20
+ # sanitizers. For this, you have to use the `-s` flag in `rbx run`.
21
+ sanitizers:
22
+ enabled: false
23
+
24
+ # A list of command substitutions to apply to rbx when
25
+ # sanitizers are enabled.
26
+ #
27
+ # This is useful when replacing compilers in OS such as Mac,
28
+ # since GCC on Mac does not support sanitizers.
29
+ command_substitutions: {}
rbx/utils.py CHANGED
@@ -113,7 +113,7 @@ def get_open_fds():
113
113
 
114
114
 
115
115
  @contextlib.contextmanager
116
- def new_cd(x):
116
+ def new_cd(x: pathlib.Path):
117
117
  d = os.getcwd()
118
118
 
119
119
  # This could raise an exception, but it's probably
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rbx.cp
3
- Version: 0.5.16
3
+ Version: 0.5.17
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9,<4.0
@@ -2,30 +2,31 @@ rbx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
2
  rbx/annotations.py,sha256=Z3jBUyZoXkrz34jko3Rft0bnMME6nWb0vsV5I3HlgR0,3064
3
3
  rbx/autoenum.py,sha256=cusv8ClXRlDVvhZ8eDrtYcL_2peXlHugAey_ht8roXk,12025
4
4
  rbx/box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
5
- rbx/box/builder.py,sha256=QVKp7VL7YC8xs4oevcsam8DT_tjkSqu76nUoad1EwVY,3229
6
- rbx/box/cd.py,sha256=NF0gqQso7a1IZzzZ6YJU8ip744AYAQ8Hp7vuzBRmZak,956
7
- rbx/box/checkers.py,sha256=u5Pk-xViWxb_-KqAdEvnydbfppkYg0lBYoRQl5m_U_4,5380
8
- rbx/box/code.py,sha256=0UfxzemrObXQq-cvAtSAImCm4sKV_4Xog-TMUZBRFwc,5761
9
- rbx/box/compile.py,sha256=DHf9MNhfigXufe3Q5LghuTNsAYcpCoFho-6nG8F0t38,1315
5
+ rbx/box/builder.py,sha256=Fz-3DpKg4kfciOz-ZcxpYPRjDqKVzKN9q2NtFsHA6Rc,3241
6
+ rbx/box/cd.py,sha256=9a_SOnzoJBXxxffp4Wbf3UKXIwKuN3Hvj7K6SocALwE,1194
7
+ rbx/box/checkers.py,sha256=VpgDzevOK7hrffG2zJGxquNiu-a9Fl3wquLn7xadcK0,6285
8
+ rbx/box/code.py,sha256=LE-KDrYNIfdPPXGUU46_tO8hiwH7A_5cV2s8IUDxsNg,9802
9
+ rbx/box/compile.py,sha256=OJLthDQ921w9vyoE6Gk1Df54i5RwtRJ2YG-8XEfefcs,2489
10
10
  rbx/box/conftest.py,sha256=sEmciXSeDC-wmrZ1JSxbsUenKNP_VWW32mrCun2pY3I,1070
11
11
  rbx/box/contest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
- rbx/box/contest/build_contest_statements.py,sha256=qar6h5u1xAlOKHl3P7-A1d0aYtaqu4PspGw_DYUGOLY,11260
13
- rbx/box/contest/contest_package.py,sha256=GhZZSOC95wbypyeKFDgUIaaTjhldASudQBvjvurHbDw,2623
12
+ rbx/box/contest/build_contest_statements.py,sha256=qnwymzqWmuey4t3tvoTPV1-dlujMs2bgcpl2V7Kbro4,11326
13
+ rbx/box/contest/contest_package.py,sha256=vGmp3F9FVJkFj6rbfIZx5BjE_vtiIHBx2FkHdq1b31s,2651
14
14
  rbx/box/contest/contest_utils.py,sha256=vWv4iNWdJT5motAznfdNzl8o-tEoCU4xmdyaPTPJZuY,490
15
- rbx/box/contest/main.py,sha256=FeTe_Qz9t233dTe1QQ6DxMDq5mcXHx59x9vgaLM8vTY,6976
15
+ rbx/box/contest/main.py,sha256=cUjLnGe6WFJIsQI3VnFL_JFZLMhrkea6FK1aMpylBHM,6985
16
16
  rbx/box/contest/schema.py,sha256=rxzjJasMWPKKhvSJs4eW4A2oCiA4gXgfF-MzqsbPslQ,4914
17
- rbx/box/contest/statements.py,sha256=cRK5ndsywotUm66QqvtReqVAc-fW4c-2OZufK3Xd8_c,2947
17
+ rbx/box/contest/statements.py,sha256=Cb-ReKcK_xZc757ZiFV9fwgZt8LO_2roMtPiDsIoRVI,2949
18
18
  rbx/box/creation.py,sha256=mVHVVj8ozX9D5qpkLewE5WSjF6HtTm74Pkwubk-bATg,2259
19
+ rbx/box/deferred.py,sha256=II3X9e87JCOZtmspnHh-n4PFqh-FsH_oc0XJHZ9ZYVQ,691
19
20
  rbx/box/download.py,sha256=MFP-R26JiYGAP89I0TK-0fYc69Fsd20tsBqgtRCy5AE,2234
20
21
  rbx/box/environment.py,sha256=GjwnJwtkTdkHmUh1b23zagjLsTiJQAOpP36A93mA-zc,11159
21
- rbx/box/extensions.py,sha256=p0iLaU28KswOBDX2HGVO_dR2gk-JSAWb6sXC6GZ1d0w,738
22
- rbx/box/generators.py,sha256=e-kXtx8rFsvuHmW7bMsKiE6MOtwQosYgO5clZ624Vig,15997
22
+ rbx/box/extensions.py,sha256=gIC73VbF1897er3iIMhaIw6GE8o1t43M7q97Iz7-_lg,503
23
+ rbx/box/generators.py,sha256=YpwtT-SmbiBMdnNSGsJ6kXuF4vOEoqXOq9MC9T92Sng,16157
23
24
  rbx/box/generators_test.py,sha256=mQqHepAMYa6zV_PseQALI0nIX6AdQktt6lh94muFhNw,1758
24
- rbx/box/main.py,sha256=id1YpYKb7GHWoEMdiRAwfT08kY-ol52ulGcaCaPhtqw,16411
25
- rbx/box/package.py,sha256=Hds0WIvhAWXnYOmIXGULcLLVeFM1YkllOPSKHB5QSkk,10532
25
+ rbx/box/main.py,sha256=cOn3zMSn-iGozVUxaF5rZyZngAJWfTT8RrZLMfZM0R0,21772
26
+ rbx/box/package.py,sha256=sdALOweAQtPaXln5NDuJ8esM85qWvJBa0J8WuUjeMLg,10541
26
27
  rbx/box/packaging/boca/extension.py,sha256=hQhcbocNfW2ESv5RalS1wf6uvOoOfOnR_gHvbXUbSzY,852
27
28
  rbx/box/packaging/boca/packager.py,sha256=FOhSRg5K5Y4qNB0WyTR3DKgrpObf9I0JbyGpJHOtxpo,10673
28
- rbx/box/packaging/contest_main.py,sha256=ypiBS8dd0yCqoFJIqiK1Fo02dQmUB_G-Z7G926jomrk,2746
29
+ rbx/box/packaging/contest_main.py,sha256=VyJnnS7WET1-C7bFcxditdhG8Hl_x3YOf81fm5Af3Vo,2748
29
30
  rbx/box/packaging/main.py,sha256=CyjfuvwmRsJGk4lKVp2LT_WCQ5jZ5L_7NfZQEC40nuY,2228
30
31
  rbx/box/packaging/packager.py,sha256=suCT_SLnWa915rV2j8VFqzH43HGKRTr9mGGlrvj45aw,3267
31
32
  rbx/box/packaging/polygon/packager.py,sha256=HNpxP2nclLChSnrQtkT7tLwDdXHl1dzXMIF5RZwr9M4,10811
@@ -35,9 +36,11 @@ rbx/box/presets/__init__.py,sha256=Wiegp1onXPaZs8RE1J3PKT5j3PFWKw2U2rkgOSbnYeM,1
35
36
  rbx/box/presets/fetch.py,sha256=F-BCOlvEBEyDqtOhiDuGPn4EDtA4Bwm-fqHJ7zZGlW8,1975
36
37
  rbx/box/presets/lock_schema.py,sha256=6sRPnyePOC8yy-5WcD5JRZdDJHf8loqbvpQ1IPiOU9s,349
37
38
  rbx/box/presets/schema.py,sha256=mZmSPkQsw7eQM0lQN6er1MO_LiW1ObwwAZFDK0F5fxE,1962
38
- rbx/box/schema.py,sha256=J6gUkVO1o2zT9UO1008N0CqMomdAyfmyXbB8LP-PFW0,12672
39
- rbx/box/solutions.py,sha256=uO8mg0AbcG1doVQVoDJp1UMUJithFnkSxroUygRduos,27771
40
- rbx/box/solutions_test.py,sha256=DetQj7ZVnV3tBXBpCrFeK_Yv3XUtdEf29y_6qnyeyfY,1496
39
+ rbx/box/sanitizers/warning_stack.py,sha256=RI97_GJgdjTKIXY_r0EKp5h0qQQSDSdNDh5K7zINrqs,2861
40
+ rbx/box/schema.py,sha256=MerNqhIeOxRBUw0CEbtfNFsHEJVsILilAjEGwW0nujQ,13227
41
+ rbx/box/setter_config.py,sha256=6nGTPMvnJ7y1sM-EBuI493NSZOIiOZ1DTypSXrL-HRY,3686
42
+ rbx/box/solutions.py,sha256=FTdeMBZC1-Gj3eqqfvtt3RXH1CsA_QrYgbvKmbqdFus,30991
43
+ rbx/box/solutions_test.py,sha256=Cx7Goon_0sz_PaUcD8qa8gmjgzOVub6VHss3CB0GaA0,1524
41
44
  rbx/box/statements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
42
45
  rbx/box/statements/build_statements.py,sha256=24ZUM5H33NhmqnDL0ofA1anUKWxuZG1paA1tCV4AKns,11911
43
46
  rbx/box/statements/builders.py,sha256=W3VkmtjfzrT5MkIVXgfR9fM-OWK007ihm5hfzvp9cfc,10474
@@ -45,7 +48,7 @@ rbx/box/statements/joiners.py,sha256=ZbxomnMjEFT8yf5WSWUB4tBa3DL3AhjGEuh8uqHyDdg
45
48
  rbx/box/statements/latex.py,sha256=LkcHwXjMFxbw--Gj9T1VkFKQFsXhY9dN7xZHpZycNW8,1346
46
49
  rbx/box/statements/latex_jinja.py,sha256=7WBfn1h8DpqCAmSE6Av64HfURMnJ2AO4QX1CD72sz5E,7096
47
50
  rbx/box/statements/schema.py,sha256=g3KgBn4nIqx-0utH8R2FCqPmJP969chhYfn96chQgd4,3851
48
- rbx/box/stresses.py,sha256=DUc8TWFlVXUvh-iaBnvwVNmgoCi1puOJiKTHMP8COds,10595
51
+ rbx/box/stresses.py,sha256=VZQEXE65qbvaPbIKr4aXqHpH_Y47Lf56LJy4ViNPQeA,10709
49
52
  rbx/box/stressing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
50
53
  rbx/box/stressing/finder_parser.py,sha256=syZGg_Wm762jAe2eN0oBCNeiM0H8lfZRWT5HKOXpkuQ,11917
51
54
  rbx/box/stressing/generator_parser.py,sha256=oHZryjR3YohgaSO9WEirQ7b2e-98WgZStF0N99W4Thw,7380
@@ -55,17 +58,17 @@ rbx/box/ui/captured_log.py,sha256=ptICDPViVnz-_2NfrcB0SSBXNW5L74zI-vAZNN7kSok,11
55
58
  rbx/box/ui/css/app.tcss,sha256=apd5PkPEvl5jK3kE2qrxPyVED1VnvSsj08QQwzUPwEA,786
56
59
  rbx/box/ui/main.py,sha256=b0rHcBF42W4AOCv7WhtiGf_rUnY0yxpqO5oj3wfR4R4,984
57
60
  rbx/box/ui/run.py,sha256=wMEXrEFdQvMHz2hRKAFIithTnTtaL0kNQZu0jKmb8jI,7060
58
- rbx/box/validators.py,sha256=pRBYCJRbA_7FrthJG9tNHQyTxq7yBNuu8lTgd7irc3s,8309
61
+ rbx/box/validators.py,sha256=Vro6PytOsaenEnufR40NcY2k5OHyyrEDEcMT3gypBgw,8388
59
62
  rbx/box/validators_test.py,sha256=hriR6rD32Ouu64eKYYTPLZVvqMxXj7Q2h1l_JAefL7U,344
60
63
  rbx/checker.py,sha256=pj1jO3my48ru-qugbER5onccANCjoR0-PaFe3H3VGEY,4118
61
64
  rbx/clone.py,sha256=wpHyED0_7ST7LD3vj7HjXhzqEzlwh6dRQvKQVDYhGeU,6744
62
- rbx/config.py,sha256=2B0PwgDaLjfs5PI8-kfDia6UVOAJq4rpWvb8VmweSXg,7360
65
+ rbx/config.py,sha256=gM0-3ORnCoXNpIxIA3EAXEaiNY7s_NPzD7WbFYGbrlA,7436
63
66
  rbx/conftest.py,sha256=ouilbOIpvX8jTEdCAiWT85CbdBQKUUf41BjmDI82u-Y,967
64
67
  rbx/console.py,sha256=l0iulQH3_jQEm455W66TbDtC4a8owkWTHIIQpJaXofQ,715
65
68
  rbx/create.py,sha256=ezUq9KiSA-88ASd8CtjWXw8UB4LCaQ3Gib3OgvsLK-Q,986
66
69
  rbx/edit.py,sha256=Zqnx_Pt06ijCxV-pZKGCJhjKB-nVO0QCM6xSBwPWGoE,798
67
70
  rbx/grading/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
- rbx/grading/caching.py,sha256=oGPnKpk9NIUJKwDMsPbEF0bMUtjHN8CEeAOvCzfM5dk,11848
71
+ rbx/grading/caching.py,sha256=tnCQl08kUC0IYx5XKxfvaUGJIvEC_C2LPJHNv90clOw,12029
69
72
  rbx/grading/conftest.py,sha256=iN9LUG1IQqhK5JjkctcP68v6675oYsiD2sQSgyLMTqw,960
70
73
  rbx/grading/judge/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
71
74
  rbx/grading/judge/cacher.py,sha256=W4bdPIvI8tXOl8A7B4Ncuzi9-zXCp0DX40i1XKQGOAU,17761
@@ -73,13 +76,13 @@ rbx/grading/judge/digester.py,sha256=m6o-kjwyFOXKdImUXtVbdMHhwrgrXk8FDnJFVefnTIw
73
76
  rbx/grading/judge/sandbox.py,sha256=0h3YCmGabf9OfORJgx6v2Bed4kE-i8FyuZkPux-sDVk,23569
74
77
  rbx/grading/judge/sandboxes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
75
78
  rbx/grading/judge/sandboxes/isolate.py,sha256=9xgBuNfAvGtO2zME1FXRah2rcPvzDShsPG0TTuX_UDU,25649
76
- rbx/grading/judge/sandboxes/stupid_sandbox.py,sha256=Gpu1I-VroS_NUSRUotZ72IFRaH8yxjp9860WiTkOvFw,10090
79
+ rbx/grading/judge/sandboxes/stupid_sandbox.py,sha256=2rFinUSafape4ad_r0TXBX0ZwnAfuVgEnDviozXbYlo,10155
77
80
  rbx/grading/judge/sandboxes/timeit.py,sha256=Ct3pxY2Uawaz4O3xIufD49DSTZnbTOhYIch1QcHLVdY,6558
78
81
  rbx/grading/judge/storage.py,sha256=FirqjwDqb0m0h2OTFyWrZL7CQ4XjZNxhqB4JpnDIhZY,9485
79
82
  rbx/grading/judge/test.py,sha256=ll0Iw7zyOpGdKPD_PGH7dvUkb4stQLu-ikbQnqJvuAc,944
80
83
  rbx/grading/judge/testiso.py,sha256=v14DtkWiZFJ9AKMzrb0_vZKPWDt8jz8iIw1Z2O-Advk,1397
81
- rbx/grading/steps.py,sha256=pJM3Xnog6ZXia2xvWMeJmNij_ipRg2hec_WBf1n5O44,18598
82
- rbx/grading/steps_with_caching.py,sha256=C_IA_dStxp6poJyGggFFyEouU9y_739UOLKUiJITb8M,1489
84
+ rbx/grading/steps.py,sha256=v1qw5gqR3Cw-nEBuEowuT2iwrSbjcsNwi_CfkiDvtmk,22174
85
+ rbx/grading/steps_with_caching.py,sha256=5cI71VSjEaDzCPQikpamG_EjZqkkFKKdBtyJeA4QB7Q,1531
83
86
  rbx/grading/steps_with_caching_run_test.py,sha256=nRzB4OcXkb-kQ4WCj0iTGVfBACllxZ0Ek5RSwfoJRgo,15262
84
87
  rbx/grading_utils.py,sha256=lL2KtSkOsMElqrRoApQTbFcqVOeHVWUDTMCa3IsLpC4,4484
85
88
  rbx/hydration.py,sha256=WqbgIfCZNwqspVhMuUlx8-sNOYhq_ZWbeZnkcetuAZI,3669
@@ -90,6 +93,8 @@ rbx/providers/codeforces.py,sha256=HWQN3Zb9UfXgCfwcNMEk6m1HoXQ-UE2odVfZoPukyCg,2
90
93
  rbx/providers/provider.py,sha256=CNRB-uJZkNFIWv8xhW2s8PY9EwUSK8Ey1Yvxk4YLvcg,688
91
94
  rbx/resources/checkers/boilerplate.cpp,sha256=vj1Qjy59JKEzb4ZpaX_MkL1FaZn_tTLZXjrIkP0nGfc,363
92
95
  rbx/resources/default_config.json,sha256=8GZVHns4nci0-e5ALk9C1lfO6TO9W2ZlmZtxHkL6ibA,949
96
+ rbx/resources/default_setter_config.mac.yml,sha256=_E6BAzAvB3J15Ld3CaaVY2q5bqSk6i1UL8y5Eyhw1aU,816
97
+ rbx/resources/default_setter_config.yml,sha256=ZGPwlIkQby0bWRtKCwVVZpUZlDHxxw-tO4m8_MXf8Vs,787
93
98
  rbx/resources/envs/default.rbx.yml,sha256=8gl4DXc5mVISx__1libPQfmuHYdW32xjysfqpNESIAo,853
94
99
  rbx/resources/envs/isolate.rbx.yml,sha256=VZAJ-Mu-A5Rt4m0VtMygOXA7eLLvCCmoorv_0acDmXQ,870
95
100
  rbx/resources/packagers/boca/checker.sh,sha256=c7EBnKZXJKNDv_HxBv62Jt2bLV-GIOJ8FgxJisMJ1Ys,1033
@@ -156,9 +161,9 @@ rbx/testdata/box1/wa.sol.cpp,sha256=qsHmvtLJOFI_sdvUT6ITqk7FJYqhrRTCmEIRdy4gSGE,
156
161
  rbx/testdata/caching/executable.py,sha256=WKRHNf_fprFJd1Fq1ubmQtR3mZzTYVNwKPLWuZ4HrWg,10
157
162
  rbx/testdata/compatible,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
158
163
  rbx/testing_utils.py,sha256=ZZLKMUHlZ4HwsuNY50jqSBJ9HhpnFdba7opjDsvXE1U,2084
159
- rbx/utils.py,sha256=wy8zQRb97n3lptilK7UxM4A44KjXb1W5Z1tD61a-K4A,4173
160
- rbx_cp-0.5.16.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
161
- rbx_cp-0.5.16.dist-info/METADATA,sha256=0aYK6Ake0EcUtZVVdXVY6IUIV9F76Jj_wM9yi2h_xz8,3249
162
- rbx_cp-0.5.16.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
163
- rbx_cp-0.5.16.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
164
- rbx_cp-0.5.16.dist-info/RECORD,,
164
+ rbx/utils.py,sha256=w0XrC9Xl_2-242rn7jqPnkQOGobKnTOBQsYK_BJ1Azo,4187
165
+ rbx_cp-0.5.17.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
166
+ rbx_cp-0.5.17.dist-info/METADATA,sha256=pnPy7dsaqkQRWYQO5MLaKcJm7s_oiF0SNrJ_E2qob94,3249
167
+ rbx_cp-0.5.17.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
168
+ rbx_cp-0.5.17.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
169
+ rbx_cp-0.5.17.dist-info/RECORD,,