rbx.cp 0.5.49__py3-none-any.whl → 0.5.50__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/cli.py +1 -0
- rbx/box/packaging/main.py +3 -0
- rbx/box/solutions.py +40 -11
- rbx/box/testcase_utils.py +12 -0
- rbx/box/testcases/main.py +2 -0
- rbx/box/unit.py +31 -9
- {rbx_cp-0.5.49.dist-info → rbx_cp-0.5.50.dist-info}/METADATA +1 -1
- {rbx_cp-0.5.49.dist-info → rbx_cp-0.5.50.dist-info}/RECORD +11 -11
- {rbx_cp-0.5.49.dist-info → rbx_cp-0.5.50.dist-info}/LICENSE +0 -0
- {rbx_cp-0.5.49.dist-info → rbx_cp-0.5.50.dist-info}/WHEEL +0 -0
- {rbx_cp-0.5.49.dist-info → rbx_cp-0.5.50.dist-info}/entry_points.txt +0 -0
rbx/box/cli.py
CHANGED
rbx/box/packaging/main.py
CHANGED
@@ -64,6 +64,7 @@ async def run_packager(
|
|
64
64
|
|
65
65
|
|
66
66
|
@app.command('polygon', help='Build a package for Polygon.')
|
67
|
+
@package.within_problem
|
67
68
|
@syncer.sync
|
68
69
|
async def polygon(
|
69
70
|
verification: environment.VerificationParam,
|
@@ -74,6 +75,7 @@ async def polygon(
|
|
74
75
|
|
75
76
|
|
76
77
|
@app.command('boca', help='Build a package for BOCA.')
|
78
|
+
@package.within_problem
|
77
79
|
@syncer.sync
|
78
80
|
async def boca(
|
79
81
|
verification: environment.VerificationParam,
|
@@ -84,6 +86,7 @@ async def boca(
|
|
84
86
|
|
85
87
|
|
86
88
|
@app.command('moj', help='Build a package for MOJ.')
|
89
|
+
@package.within_problem
|
87
90
|
@syncer.sync
|
88
91
|
async def moj(
|
89
92
|
verification: environment.VerificationParam,
|
rbx/box/solutions.py
CHANGED
@@ -47,7 +47,12 @@ from rbx.box.tasks import (
|
|
47
47
|
run_solution_on_testcase,
|
48
48
|
)
|
49
49
|
from rbx.box.testcase_extractors import extract_generation_testcases
|
50
|
-
from rbx.box.testcase_utils import
|
50
|
+
from rbx.box.testcase_utils import (
|
51
|
+
TestcaseEntry,
|
52
|
+
find_built_testcases,
|
53
|
+
parse_interaction,
|
54
|
+
print_interaction,
|
55
|
+
)
|
51
56
|
from rbx.grading.steps import (
|
52
57
|
Evaluation,
|
53
58
|
Outcome,
|
@@ -323,6 +328,19 @@ def _produce_solution_items(
|
|
323
328
|
return res
|
324
329
|
|
325
330
|
|
331
|
+
def print_best_output(output_files: List[pathlib.Path], empty_warning: bool = False):
|
332
|
+
for output_file in output_files:
|
333
|
+
if not output_file.is_file():
|
334
|
+
continue
|
335
|
+
if output_file.suffix == '.pio':
|
336
|
+
print_interaction(parse_interaction(output_file))
|
337
|
+
else:
|
338
|
+
console.console.print(output_file.read_text())
|
339
|
+
return
|
340
|
+
if empty_warning:
|
341
|
+
console.console.print('[warning]Solution produced no output.[/warning]')
|
342
|
+
|
343
|
+
|
326
344
|
def run_solutions(
|
327
345
|
progress: Optional[StatusProgress] = None,
|
328
346
|
tracked_solutions: Optional[Set[str]] = None,
|
@@ -528,6 +546,7 @@ def _run_interactive_solutions(
|
|
528
546
|
output_dir=output_dir,
|
529
547
|
interactor_digest=interactor_digest,
|
530
548
|
verification=verification,
|
549
|
+
capture_pipes=True,
|
531
550
|
)
|
532
551
|
|
533
552
|
yield EvaluationItem(
|
@@ -589,18 +608,28 @@ async def run_and_print_interactive_solutions(
|
|
589
608
|
)
|
590
609
|
|
591
610
|
stdout_path = eval.log.stdout_absolute_path
|
592
|
-
if print:
|
611
|
+
if print and stdout_path is not None:
|
612
|
+
if pkg.type == TaskType.COMMUNICATION:
|
613
|
+
console.console.rule('Interaction', style='status')
|
614
|
+
output_files = [
|
615
|
+
stdout_path.with_suffix('.pio'),
|
616
|
+
stdout_path.with_suffix('.pout'),
|
617
|
+
]
|
618
|
+
print_best_output(output_files, empty_warning=True)
|
619
|
+
|
593
620
|
console.console.rule('Output', style='status')
|
594
|
-
|
595
|
-
|
596
|
-
and stdout_path is not None
|
597
|
-
and stdout_path.is_file()
|
598
|
-
):
|
599
|
-
console.console.print(stdout_path.read_text())
|
600
|
-
else:
|
601
|
-
console.console.print('[warning]Solution produced no output.[/warning]')
|
621
|
+
output_files = [stdout_path]
|
622
|
+
print_best_output(output_files, empty_warning=True)
|
602
623
|
elif stdout_path is not None:
|
603
|
-
|
624
|
+
if stdout_path.with_suffix('.pout').is_file():
|
625
|
+
stdout_path = stdout_path.with_suffix('.pout')
|
626
|
+
|
627
|
+
if stdout_path.is_file():
|
628
|
+
console.console.print(f'[status]Output:[/status] {stdout_path}')
|
629
|
+
if stdout_path.with_suffix('.pio').is_file():
|
630
|
+
console.console.print(
|
631
|
+
f'[status]Interaction:[/status] {stdout_path.with_suffix(".pio")}'
|
632
|
+
)
|
604
633
|
if eval.log.stderr_absolute_path is not None:
|
605
634
|
console.console.print(
|
606
635
|
f'[status]Stderr:[/status] {eval.log.stderr_absolute_path}'
|
rbx/box/testcase_utils.py
CHANGED
@@ -2,6 +2,8 @@ import pathlib
|
|
2
2
|
import shutil
|
3
3
|
from typing import List, Optional, Tuple
|
4
4
|
|
5
|
+
import rich
|
6
|
+
import rich.text
|
5
7
|
import typer
|
6
8
|
from pydantic import BaseModel
|
7
9
|
|
@@ -209,3 +211,13 @@ def parse_interaction(file: pathlib.Path) -> TestcaseInteraction:
|
|
209
211
|
prefixes=(interactor_prefix, solution_prefix),
|
210
212
|
entries=entries,
|
211
213
|
)
|
214
|
+
|
215
|
+
|
216
|
+
def print_interaction(interaction: TestcaseInteraction):
|
217
|
+
for entry in interaction.entries:
|
218
|
+
text = rich.text.Text(entry.data)
|
219
|
+
if entry.pipe == 0:
|
220
|
+
text.stylize('status')
|
221
|
+
else:
|
222
|
+
text.stylize('info')
|
223
|
+
console.console.print(text, end='')
|
rbx/box/testcases/main.py
CHANGED
@@ -90,6 +90,7 @@ async def _generate_for_editing(
|
|
90
90
|
|
91
91
|
|
92
92
|
@app.command('view, v', help='View a testcase in your default editor.')
|
93
|
+
@package.within_problem
|
93
94
|
@syncer.sync
|
94
95
|
async def view(
|
95
96
|
tc: Annotated[
|
@@ -126,6 +127,7 @@ async def view(
|
|
126
127
|
|
127
128
|
|
128
129
|
@app.command('info, i', help='Show information about testcases.')
|
130
|
+
@package.within_problem
|
129
131
|
@syncer.sync
|
130
132
|
async def info(
|
131
133
|
pattern: Annotated[
|
rbx/box/unit.py
CHANGED
@@ -29,6 +29,16 @@ class CheckerTestEntry(BaseModel):
|
|
29
29
|
answer: Optional[pathlib.Path] = None
|
30
30
|
outcome: ExpectedOutcome
|
31
31
|
|
32
|
+
def running_tests_formatted_string(self) -> str:
|
33
|
+
res = []
|
34
|
+
if self.input:
|
35
|
+
res.append(f'[item]{self.input}[/item]')
|
36
|
+
if self.output:
|
37
|
+
res.append(f'[item]{self.output}[/item]')
|
38
|
+
if self.answer:
|
39
|
+
res.append(f'[item]{self.answer}[/item]')
|
40
|
+
return ', '.join(res)
|
41
|
+
|
32
42
|
|
33
43
|
def _extract_validator_test_entries(
|
34
44
|
tests: List[ValidatorTest],
|
@@ -91,13 +101,16 @@ async def run_validator_unit_tests(progress: StatusProgress):
|
|
91
101
|
if val is not None:
|
92
102
|
vals.append(val)
|
93
103
|
|
104
|
+
console.console.rule('Validator tests', style='info')
|
105
|
+
if not entries:
|
106
|
+
console.console.print(']No validator unit tests found.')
|
107
|
+
return
|
108
|
+
|
94
109
|
compiled_validators = validators.compile_validators(vals, progress=progress)
|
95
110
|
|
96
111
|
if progress:
|
97
112
|
progress.update('Running validator unit tests...')
|
98
113
|
|
99
|
-
console.console.rule('Validator tests', style='info')
|
100
|
-
|
101
114
|
for i, test in enumerate(entries):
|
102
115
|
val = _get_validator_for_test(test)
|
103
116
|
if val is None:
|
@@ -127,7 +140,10 @@ async def run_validator_unit_tests(progress: StatusProgress):
|
|
127
140
|
if info.ok:
|
128
141
|
console.console.print(' [status]Actual[/status] VALID')
|
129
142
|
else:
|
130
|
-
console.console.print(
|
143
|
+
console.console.print(' [status]Actual[/status] INVALID')
|
144
|
+
|
145
|
+
if info.message:
|
146
|
+
console.console.print(f' [status]Message[/status] {info.message}')
|
131
147
|
|
132
148
|
|
133
149
|
async def run_checker_unit_tests(progress: StatusProgress):
|
@@ -141,15 +157,19 @@ async def run_checker_unit_tests(progress: StatusProgress):
|
|
141
157
|
)
|
142
158
|
return
|
143
159
|
|
160
|
+
console.console.rule('Checker tests', style='info')
|
161
|
+
|
162
|
+
entries = _extract_checker_test_entries(pkg.unitTests.checker)
|
163
|
+
if not entries:
|
164
|
+
console.console.print('No checker unit tests found.')
|
165
|
+
return
|
166
|
+
|
144
167
|
compiled_digest = checkers.compile_checker(progress=progress)
|
145
168
|
|
146
169
|
if progress:
|
147
170
|
progress.update('Running checker unit tests...')
|
148
171
|
|
149
|
-
console.console.rule('Checker tests', style='info')
|
150
|
-
|
151
172
|
empty_file = package.get_empty_sentinel_path()
|
152
|
-
entries = _extract_checker_test_entries(pkg.unitTests.checker)
|
153
173
|
|
154
174
|
for i, test in enumerate(entries):
|
155
175
|
result = await checkers.check(
|
@@ -169,13 +189,15 @@ async def run_checker_unit_tests(progress: StatusProgress):
|
|
169
189
|
else '[error]FAIL[/error]'
|
170
190
|
)
|
171
191
|
|
172
|
-
console.console.print(
|
192
|
+
console.console.print(
|
193
|
+
f'{markup} Unit test [item]#{i + 1}[/item] ({test.running_tests_formatted_string()})'
|
194
|
+
)
|
173
195
|
console.console.print(f' [status]Expected[/status] {test.outcome.name}')
|
174
196
|
|
175
197
|
if not test.outcome.match(result.outcome):
|
176
198
|
console.console.print(f' [status]Actual[/status] {result.outcome.name}')
|
177
|
-
|
178
|
-
|
199
|
+
if result.message:
|
200
|
+
console.console.print(f' [status]Message[/status] {result.message}')
|
179
201
|
|
180
202
|
|
181
203
|
@syncer.sync
|
@@ -5,7 +5,7 @@ rbx/box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
5
5
|
rbx/box/builder.py,sha256=MDm2qqmhedAbhn3rWP6cDwbBsGhV6sz_2sg1zLkPDw0,3613
|
6
6
|
rbx/box/cd.py,sha256=9a_SOnzoJBXxxffp4Wbf3UKXIwKuN3Hvj7K6SocALwE,1194
|
7
7
|
rbx/box/checkers.py,sha256=eb4tqtVUJYlme_Vkj2TGkUABM7EMS0P1EswhMYjN7BI,11459
|
8
|
-
rbx/box/cli.py,sha256=
|
8
|
+
rbx/box/cli.py,sha256=0JeJSVTK_5coijsm1b1zKQzuv7RBgexoM3klDeveabY,26487
|
9
9
|
rbx/box/code.py,sha256=Cnts7noJaaoM35DZ9xcJAKXLwsKB4oBebMidqmMMO4M,18795
|
10
10
|
rbx/box/compile.py,sha256=OJLthDQ921w9vyoE6Gk1Df54i5RwtRJ2YG-8XEfefcs,2489
|
11
11
|
rbx/box/conftest.py,sha256=sEmciXSeDC-wmrZ1JSxbsUenKNP_VWW32mrCun2pY3I,1070
|
@@ -32,7 +32,7 @@ rbx/box/package.py,sha256=YuX_FS6yKx6FaFz0NF0cx3v6jzhqwvsLr3Oprx_TTJA,13645
|
|
32
32
|
rbx/box/packaging/boca/extension.py,sha256=EQALNEOv4zVDXSKs_dk11n92y7cBZVn8TogIK683lE0,890
|
33
33
|
rbx/box/packaging/boca/packager.py,sha256=CUMoQICrkQQBFElmI9SrvXlFFnpwkTiJ9qbOSJOy6AE,12512
|
34
34
|
rbx/box/packaging/contest_main.py,sha256=nMdgPE4OK_tsnUMdRI1cJwLpgxGrwW_mJjox0oOALWw,2757
|
35
|
-
rbx/box/packaging/main.py,sha256=
|
35
|
+
rbx/box/packaging/main.py,sha256=WOW0JRYcZRuWOEsfd4AKX5wLqu8Br1TYaEfHjqWmu9Q,3070
|
36
36
|
rbx/box/packaging/moj/packager.py,sha256=Ro_TO3RVCCRAxNcCio0u42TLfW8FnX9IohMChmGlrvo,8499
|
37
37
|
rbx/box/packaging/packager.py,sha256=da2haC1L9cG30myneMrRIAdGubtid0Xmy38BHKPCZZ4,3633
|
38
38
|
rbx/box/packaging/polygon/packager.py,sha256=qTGOUckevdOCt_ES63pN3uhmhDl9JuNcZ1XEnGNq-tU,10833
|
@@ -46,7 +46,7 @@ rbx/box/retries.py,sha256=tRk2K1bXw2xnwkAj2CsktRHTEhw7YKcPxMQTT6mCy-E,4707
|
|
46
46
|
rbx/box/sanitizers/warning_stack.py,sha256=RI97_GJgdjTKIXY_r0EKp5h0qQQSDSdNDh5K7zINrqs,2861
|
47
47
|
rbx/box/schema.py,sha256=tOQ1tLHqc_5V-UgrzM44aS8ULAkq-IkeErxjLCFVA8I,16778
|
48
48
|
rbx/box/setter_config.py,sha256=s53talhwM6FTGDCcBhY7IlZ6_6mJ3PMp6V4kTtaSs50,4262
|
49
|
-
rbx/box/solutions.py,sha256=
|
49
|
+
rbx/box/solutions.py,sha256=eTMpxIvhU3IUF1gfR_y20o_6NZ4hDtMGhTi4ookG9TY,43766
|
50
50
|
rbx/box/solutions_test.py,sha256=TCowbxBG3SvDlFO5-qtBj_M_HrAHe0IJaI1XwoQ1d00,1718
|
51
51
|
rbx/box/state.py,sha256=MMf3DvfQji0jKEliCHct2Tpp_0epL1tvP8HbHNArQIc,166
|
52
52
|
rbx/box/statements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -62,15 +62,15 @@ rbx/box/stressing/finder_parser.py,sha256=jXpYNa4FyugzmHi3r96Uv4rU1krRQJc5Ihr9jf
|
|
62
62
|
rbx/box/stressing/generator_parser.py,sha256=oHZryjR3YohgaSO9WEirQ7b2e-98WgZStF0N99W4Thw,7380
|
63
63
|
rbx/box/tasks.py,sha256=oyWtgZvIEIkVV6e-GcJx7x8Z3T5tIDFBZbp0638sLeY,10036
|
64
64
|
rbx/box/testcase_extractors.py,sha256=T5vCW5qERlqitGrFP6RuITEVr9o8XQozNa4AsxfuV_Y,11871
|
65
|
-
rbx/box/testcase_utils.py,sha256=
|
65
|
+
rbx/box/testcase_utils.py,sha256=Ppg_P1Nq48cuKo1XiIi4b8FZkMW8IBp_4Wf1Yf42YuI,7019
|
66
66
|
rbx/box/testcases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
67
|
-
rbx/box/testcases/main.py,sha256=
|
67
|
+
rbx/box/testcases/main.py,sha256=_I7h_obRcpNLRQ6dDJDIE5NAvTyn5nBOhdsBhRA_PvU,5442
|
68
68
|
rbx/box/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
69
69
|
rbx/box/ui/captured_log.py,sha256=ptICDPViVnz-_2NfrcB0SSBXNW5L74zI-vAZNN7kSok,11319
|
70
70
|
rbx/box/ui/css/app.tcss,sha256=apd5PkPEvl5jK3kE2qrxPyVED1VnvSsj08QQwzUPwEA,786
|
71
71
|
rbx/box/ui/main.py,sha256=b0rHcBF42W4AOCv7WhtiGf_rUnY0yxpqO5oj3wfR4R4,984
|
72
72
|
rbx/box/ui/run.py,sha256=wMEXrEFdQvMHz2hRKAFIithTnTtaL0kNQZu0jKmb8jI,7060
|
73
|
-
rbx/box/unit.py,sha256=
|
73
|
+
rbx/box/unit.py,sha256=ySnosNg-b50mJU_9jEpRYm5wiiZxkdhKR9AVQXbtTOE,6478
|
74
74
|
rbx/box/validators.py,sha256=oqlNhw7jivbbH5l8g3xwihPRy76AM7MA3G4A8nyI_V0,10416
|
75
75
|
rbx/box/validators_test.py,sha256=WY4Ho-wlsPHc0YNuz0KFVd6KQ9ouuiou3w5_zMOZ4Fs,362
|
76
76
|
rbx/checker.py,sha256=pj1jO3my48ru-qugbER5onccANCjoR0-PaFe3H3VGEY,4118
|
@@ -188,8 +188,8 @@ rbx/testcase.py,sha256=yKOq3CAJZ1YTmInvnoIs0u1iJnRj_X85XiWbLI-p9d8,1951
|
|
188
188
|
rbx/testcase_rendering.py,sha256=nfmv6dSEqd4aR3TsaODwkKGK6AXty_DDKtWf_ejiQpI,2084
|
189
189
|
rbx/testing_utils.py,sha256=ZXMysGXpTtvS1lfLL38FuD5iSIyxi3ARjQePDrUmEtc,2067
|
190
190
|
rbx/utils.py,sha256=6e1eXRzNE-52D0UVtqclePxqR4Haiqt8qWCrSVjnGuE,4585
|
191
|
-
rbx_cp-0.5.
|
192
|
-
rbx_cp-0.5.
|
193
|
-
rbx_cp-0.5.
|
194
|
-
rbx_cp-0.5.
|
195
|
-
rbx_cp-0.5.
|
191
|
+
rbx_cp-0.5.50.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
192
|
+
rbx_cp-0.5.50.dist-info/METADATA,sha256=ScwTLSdZ7ISYKsmPKdWkq1hT0AOfAm25GBzQT9c4u-E,3261
|
193
|
+
rbx_cp-0.5.50.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
|
194
|
+
rbx_cp-0.5.50.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
|
195
|
+
rbx_cp-0.5.50.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|