rbx.cp 0.13.6__py3-none-any.whl → 0.13.7__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/code.py CHANGED
@@ -174,7 +174,7 @@ def _ignore_warning_in_cxx_input(input: GradingFileInput):
174
174
  input.src = preprocessed_path
175
175
 
176
176
 
177
- def _maybe_rename_java_class(
177
+ def maybe_rename_java_class(
178
178
  compilable_path: pathlib.Path, file_mapping: FileMapping
179
179
  ) -> pathlib.Path:
180
180
  mapped_path = PosixPath(file_mapping.compilable)
@@ -540,7 +540,7 @@ def compile_item(
540
540
  download.maybe_add_testlib(code, artifacts)
541
541
  download.maybe_add_jngen(code, artifacts)
542
542
  download.maybe_add_rbx_header(code, artifacts)
543
- compilable_path = _maybe_rename_java_class(compilable_path, file_mapping)
543
+ compilable_path = maybe_rename_java_class(compilable_path, file_mapping)
544
544
  artifacts.inputs.append(
545
545
  GradingFileInput(src=compilable_path, dest=PosixPath(file_mapping.compilable))
546
546
  )
@@ -119,7 +119,7 @@ def scientific_notation(
119
119
  mult, exp, rest = _process_zeroes(value)
120
120
  if exp < zeroes:
121
121
  return str(value)
122
- res = '10' if exp == 1 else f'10^{exp}'
122
+ res = '10' if exp == 1 else f'10^{{{exp}}}'
123
123
  if rest > 0 and len(str(rest)) + 1 >= len(str(value)):
124
124
  # Should not convert numbers like 532 to 5*10^2 + 32.
125
125
  return str(value)
@@ -30,7 +30,7 @@ def _get_group_output(
30
30
  return group_path / f'{subgroup_prefix}{i:03d}.out'
31
31
 
32
32
 
33
- async def _run_generator_script(testcase: TestcaseSubgroup) -> str:
33
+ async def run_generator_script(testcase: TestcaseSubgroup) -> str:
34
34
  assert testcase.generatorScript is not None
35
35
 
36
36
  cacher = package.get_file_cacher()
@@ -240,7 +240,7 @@ async def run_testcase_visitor(visitor: TestcaseVisitor):
240
240
 
241
241
  # Run generator script.
242
242
  if subgroup.generatorScript is not None:
243
- script = await _run_generator_script(subgroup)
243
+ script = await run_generator_script(subgroup)
244
244
 
245
245
  # Run each line from generator script.
246
246
  for generator_name, args, line_number in _extract_script_lines(script):
rbx/box/testcase_utils.py CHANGED
@@ -40,6 +40,8 @@ class TestcaseEntry(BaseModel):
40
40
 
41
41
 
42
42
  class TestcasePattern(BaseModel):
43
+ __test__ = False
44
+
43
45
  group_prefix: List[str]
44
46
  index: Optional[int] = None
45
47
 
@@ -1,6 +1,6 @@
1
1
  import pathlib
2
2
  from dataclasses import dataclass
3
- from typing import Dict, List, Optional
3
+ from typing import Any, Dict, List, Optional
4
4
 
5
5
  from rbx import console, utils
6
6
  from rbx.box import package, presets
@@ -10,11 +10,14 @@ from rbx.box.schema import (
10
10
  CodeItem,
11
11
  ExpectedOutcome,
12
12
  Generator,
13
+ GeneratorCall,
13
14
  Interactor,
14
15
  Package,
15
16
  Solution,
16
17
  TaskType,
18
+ Testcase,
17
19
  TestcaseGroup,
20
+ TestcaseSubgroup,
18
21
  ValidatorOutcome,
19
22
  ValidatorTest,
20
23
  )
@@ -229,6 +232,154 @@ class TestingPackage(TestingShared):
229
232
  ]
230
233
  self.save()
231
234
 
235
+ def add_testgroup_with_subgroups(
236
+ self,
237
+ name: str,
238
+ subgroups: List[Dict[str, Any]],
239
+ validator: Optional[PathOrStr] = None,
240
+ extra_validators: Optional[List[PathOrStr]] = None,
241
+ ):
242
+ """Add a testgroup with subgroups.
243
+
244
+ Args:
245
+ name: Name of the testgroup
246
+ subgroups: List of subgroup definitions, each containing fields like:
247
+ - name: subgroup name
248
+ - generators: list of generator calls
249
+ - testcases: list of testcase objects
250
+ - testcaseGlob: glob pattern
251
+ - generatorScript: generator script path
252
+ - extraValidators: list of extra validators
253
+ """
254
+
255
+ subgroup_objects = []
256
+ for subgroup_data in subgroups:
257
+ subgroup_dict = {'name': subgroup_data['name']}
258
+
259
+ if 'generators' in subgroup_data:
260
+ subgroup_dict['generators'] = [
261
+ GeneratorCall(name=gen['name'], args=gen.get('args'))
262
+ for gen in subgroup_data['generators']
263
+ ]
264
+
265
+ if 'testcases' in subgroup_data:
266
+ subgroup_dict['testcases'] = [
267
+ Testcase(
268
+ inputPath=pathlib.Path(tc['inputPath']),
269
+ outputPath=pathlib.Path(tc['outputPath'])
270
+ if tc.get('outputPath')
271
+ else None,
272
+ )
273
+ for tc in subgroup_data['testcases']
274
+ ]
275
+
276
+ if 'testcaseGlob' in subgroup_data:
277
+ subgroup_dict['testcaseGlob'] = subgroup_data['testcaseGlob']
278
+
279
+ if 'generatorScript' in subgroup_data:
280
+ subgroup_dict['generatorScript'] = CodeItem(
281
+ path=pathlib.Path(subgroup_data['generatorScript'])
282
+ )
283
+
284
+ if 'extraValidators' in subgroup_data:
285
+ subgroup_dict['extraValidators'] = [
286
+ CodeItem(path=pathlib.Path(v))
287
+ for v in subgroup_data['extraValidators']
288
+ ]
289
+
290
+ subgroup_objects.append(TestcaseSubgroup(**subgroup_dict))
291
+
292
+ self.yml.testcases = self.yml.testcases + [
293
+ TestcaseGroup(
294
+ name=name,
295
+ subgroups=subgroup_objects,
296
+ validator=CodeItem(path=pathlib.Path(validator)) if validator else None,
297
+ extraValidators=[
298
+ CodeItem(path=pathlib.Path(v)) for v in extra_validators
299
+ ]
300
+ if extra_validators
301
+ else [],
302
+ )
303
+ ]
304
+ self.save()
305
+
306
+ def add_testgroup_with_manual_testcases(
307
+ self,
308
+ name: str,
309
+ testcases: List[Dict[str, str]],
310
+ validator: Optional[PathOrStr] = None,
311
+ extra_validators: Optional[List[PathOrStr]] = None,
312
+ ):
313
+ """Add a testgroup with manually defined testcases.
314
+
315
+ Args:
316
+ name: Name of the testgroup
317
+ testcases: List of testcase definitions, each containing:
318
+ - inputPath: path to input file
319
+ - outputPath: optional path to output file
320
+ """
321
+
322
+ testcase_objects = []
323
+ for tc_data in testcases:
324
+ testcase_objects.append(
325
+ Testcase(
326
+ inputPath=pathlib.Path(tc_data['inputPath']),
327
+ outputPath=pathlib.Path(tc_data['outputPath'])
328
+ if tc_data.get('outputPath')
329
+ else None,
330
+ )
331
+ )
332
+
333
+ self.yml.testcases = self.yml.testcases + [
334
+ TestcaseGroup(
335
+ name=name,
336
+ testcases=testcase_objects,
337
+ validator=CodeItem(path=pathlib.Path(validator)) if validator else None,
338
+ extraValidators=[
339
+ CodeItem(path=pathlib.Path(v)) for v in extra_validators
340
+ ]
341
+ if extra_validators
342
+ else [],
343
+ )
344
+ ]
345
+ self.save()
346
+
347
+ def add_testgroup_with_generators(
348
+ self,
349
+ name: str,
350
+ generators: List[Dict[str, str]],
351
+ validator: Optional[PathOrStr] = None,
352
+ extra_validators: Optional[List[PathOrStr]] = None,
353
+ ):
354
+ """Add a testgroup with generator calls.
355
+
356
+ Args:
357
+ name: Name of the testgroup
358
+ generators: List of generator definitions, each containing:
359
+ - name: generator name
360
+ - args: optional generator arguments
361
+ """
362
+
363
+ generator_objects = []
364
+ for gen_data in generators:
365
+ generator_objects.append(
366
+ GeneratorCall(name=gen_data['name'], args=gen_data.get('args'))
367
+ )
368
+
369
+ self.yml.testcases = self.yml.testcases + [
370
+ TestcaseGroup(
371
+ name=name,
372
+ generators=generator_objects,
373
+ validator=CodeItem(path=pathlib.Path(validator)) if validator else None,
374
+ extraValidators=[
375
+ CodeItem(path=pathlib.Path(v)) for v in extra_validators
376
+ ]
377
+ if extra_validators
378
+ else [],
379
+ )
380
+ ]
381
+ self.save()
382
+
232
383
  def get_build_testgroup_path(self, name: str) -> pathlib.Path:
233
384
  return self.root / 'build' / 'tests' / name
234
385
 
@@ -55,7 +55,10 @@ class TestingShared:
55
55
  return filename
56
56
 
57
57
  def relpath(self, path: PathOrStr) -> pathlib.Path:
58
- return pathlib.Path(path).relative_to(self.root)
58
+ path = pathlib.Path(path)
59
+ if not path.is_relative_to(self.root):
60
+ return path
61
+ return path.relative_to(self.root)
59
62
 
60
63
  def add_from_testdata(self, path: PathOrStr, src: PathOrStr):
61
64
  testdata_path = get_testdata_path()
@@ -316,7 +316,10 @@ class StupidSandbox(SandboxBase):
316
316
  interactor_tee.pipes.output.close()
317
317
 
318
318
  if idx == 0 and program_result.exitcode != 0:
319
- os.killpg(group_id, signal.SIGKILL)
319
+ try:
320
+ os.killpg(group_id, signal.SIGKILL)
321
+ except Exception:
322
+ pass
320
323
  elif pid == program.pid:
321
324
  program_result = program.process_exit(status, ru)
322
325
  results[0] = self._get_sandbox_log(program_result, params)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rbx.cp
3
- Version: 0.13.6
3
+ Version: 0.13.7
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9.1,<4.0.0
@@ -6,7 +6,7 @@ rbx/box/builder.py,sha256=umrTdVAwvsOosBDVvDZ6kq1yWg3Z2Lxp2o1zK-V7BBk,3594
6
6
  rbx/box/cd.py,sha256=_XAzb3kV1NUaaRs8hc9SGDo10O1yh2_gr1EiAKzfUjI,2711
7
7
  rbx/box/checkers.py,sha256=mRovZyTZdySFEaYFVc3Lc-xgEsu6F9FjVPOxDwub7aY,13226
8
8
  rbx/box/cli.py,sha256=eBXiy3zG6IzrIHPYplFWhGn7cB7nmA7F1GiAGoYFWp0,29904
9
- rbx/box/code.py,sha256=SXjce-rBr_B4bVNgCYBuN6KZJTtb9GfYqIxPmrO2XWo,25467
9
+ rbx/box/code.py,sha256=2e1tDdrVqHUIT6qaW-MiU2YeuYSdRBhTCTJX78E82do,25465
10
10
  rbx/box/compile.py,sha256=Kzn5mEQu4vb91W9vjyt0DS6cfPJzFLTUoowFj7uHLUo,2539
11
11
  rbx/box/contest/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
12
12
  rbx/box/contest/build_contest_statements.py,sha256=N7TQ8Ki7ZM94sATHploDsSKbY41Xey_FlXclEdCBpJI,13010
@@ -66,7 +66,7 @@ rbx/box/statements/builders.py,sha256=t3q1BX1SaELQVZB0tynuhAs_0UI3yzpUcvsQEEaUE-
66
66
  rbx/box/statements/expander.py,sha256=sdbMtNcJQCbXGIkFIl9h24pGr77vhFLnM31V5AfuduI,1715
67
67
  rbx/box/statements/joiners.py,sha256=jItNXkAbTjFQpPMgfDMW86n3vMTbaE8sgo9I8Yf4Txg,2886
68
68
  rbx/box/statements/latex.py,sha256=ipTGjL4kjAsnqgiH6Pk1PwKFegBumQP4-y0pFAbNN8I,1584
69
- rbx/box/statements/latex_jinja.py,sha256=iMx47ynKMjLNcfymzHV24jtWrRVnit0Va9H8yTfgmiA,10379
69
+ rbx/box/statements/latex_jinja.py,sha256=1VWabl8dD0ix3XNABANA1Qt00D4ww0HR2L5lmywmdWU,10383
70
70
  rbx/box/statements/schema.py,sha256=n1OXbcmte-cGQn7PlSGOzBEYi0gRYUNDSubgYFKxo7I,5429
71
71
  rbx/box/stats.py,sha256=rUAnmp7kTgUvIQ56NLpQaIQkazB37MVcUos5en3xUQw,3258
72
72
  rbx/box/stresses.py,sha256=SV0Hx7SPZZEIhwasWDVpTWuMhWWTjfJs2IEW-H0xJZw,12092
@@ -74,14 +74,14 @@ rbx/box/stressing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU
74
74
  rbx/box/stressing/finder_parser.py,sha256=PnONJD2yun5X5EmHqkaz-rh3DHhn_BkTPHZrIXRKZbw,11898
75
75
  rbx/box/stressing/generator_parser.py,sha256=oHZryjR3YohgaSO9WEirQ7b2e-98WgZStF0N99W4Thw,7380
76
76
  rbx/box/tasks.py,sha256=CJ7TqzhVMPP4VUSrMpp3ofSDJn0rbuwIUWgFOiup_vE,11426
77
- rbx/box/testcase_extractors.py,sha256=J43eG7vpxc5nP_2yhrXJODkd4EYlV4WiYVbM6hzipY4,11944
78
- rbx/box/testcase_utils.py,sha256=HoDr_RxWpfviLd2oTj_m2wg1e4XaY9LD-QBqx_QjDI0,6899
77
+ rbx/box/testcase_extractors.py,sha256=vyT3Qw9FkQ-SABcgjyL9UBdKT1SktJ3-_4A-HRj6FQA,11942
78
+ rbx/box/testcase_utils.py,sha256=Ywz9c9zH96IZAj8rDDuhS7xmdLXeLM6JsKZf2x9X5Go,6921
79
79
  rbx/box/testcases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
80
80
  rbx/box/testcases/main.py,sha256=_I7h_obRcpNLRQ6dDJDIE5NAvTyn5nBOhdsBhRA_PvU,5442
81
81
  rbx/box/testing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
82
- rbx/box/testing/testing_package.py,sha256=kzvSbL_4fkjD2l3hfYapyOezLHhhySi9sp4u92MoycY,10121
82
+ rbx/box/testing/testing_package.py,sha256=szNc8GcxI0ywCjzV8fOuZh5F0fMtQ6_tLOfivF7hu10,15401
83
83
  rbx/box/testing/testing_preset.py,sha256=7TxfL4fT9JetRMRkQ3Iko99N5gzfKz8_lPM0rkkQx_k,1135
84
- rbx/box/testing/testing_shared.py,sha256=rX7w5VrCzf4l9zYhq3eFW1iHaWDLU-Xkn5oCjnAavhA,2558
84
+ rbx/box/testing/testing_shared.py,sha256=3j1n61ROVDxU2vZbLLIQuGEeYDs_CxsnnK9d7lT6hPI,2649
85
85
  rbx/box/tooling/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
86
86
  rbx/box/tooling/boca/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
87
87
  rbx/box/tooling/boca/main.py,sha256=knl1rpaHIwA63KkzMJMZQrejzMpbTPBhYqGx1IpuNm4,289
@@ -127,7 +127,7 @@ rbx/grading/judge/digester.py,sha256=gtOIe_iL4PEWA7OKelW1gjSI-nBvbOpDPJGV8VQyjSg
127
127
  rbx/grading/judge/program.py,sha256=ttT7X_uLls4ARIbid0MnSteo8Eti1fRw73FL_Ej6S_o,9683
128
128
  rbx/grading/judge/sandbox.py,sha256=mcqJscMPhMfjKhxKFkwIP-I4bnQHHMWeBcXiWHGVS-k,21324
129
129
  rbx/grading/judge/sandboxes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
130
- rbx/grading/judge/sandboxes/stupid_sandbox.py,sha256=-fSYt0WNf04rrakhxdrunYlmwO2uM2Pf1HmUX8qfxrI,11458
130
+ rbx/grading/judge/sandboxes/stupid_sandbox.py,sha256=QJkazyqvTq9nQjupLVkH0HbdP13RH52T2jLBExAEQwE,11554
131
131
  rbx/grading/judge/sandboxes/tee.py,sha256=fLulB8fV7k5cO-ikRgURpsETrvr6LoUSjGxFM3GZs5U,672
132
132
  rbx/grading/judge/storage.py,sha256=A88O81-vzv8vMBGrO9gtFk8iB5fTD7ObpO8mvNH4OmA,14576
133
133
  rbx/grading/limits.py,sha256=ev312UTOo8S4-3AAVibQdXZclWCxS96CdbZxqW4y1kE,770
@@ -219,8 +219,8 @@ rbx/submitors/codeforces.py,sha256=s8c7sXfm5k76SKMC8g0Y93-RRf8wY2uWbBtA8ODD5eM,4
219
219
  rbx/submitors/submitor.py,sha256=8q-Hbdahxt30ciT_R9j_xF6lEPUh9IcfAUnzjQjbvHU,457
220
220
  rbx/testing_utils.py,sha256=965vlkQpUW8cEqjB6S2g_C_avL5fn503mJPbqjY_zt4,2317
221
221
  rbx/utils.py,sha256=xDqmry5rpqRGPFrx3ipNGBt2WxWDAD5LwU7jvgibXkk,8630
222
- rbx_cp-0.13.6.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
223
- rbx_cp-0.13.6.dist-info/METADATA,sha256=YRfhn0e29x1tf9DRjJbTE2kL19oQN3gx7Cz1evofaUg,4659
224
- rbx_cp-0.13.6.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
225
- rbx_cp-0.13.6.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
226
- rbx_cp-0.13.6.dist-info/RECORD,,
222
+ rbx_cp-0.13.7.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
223
+ rbx_cp-0.13.7.dist-info/METADATA,sha256=TcJSmgIQFD7R_zuGbOLun5EixzDKQevwsn-7lJ6ln98,4659
224
+ rbx_cp-0.13.7.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
225
+ rbx_cp-0.13.7.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
226
+ rbx_cp-0.13.7.dist-info/RECORD,,