rbx.cp 0.5.2__py3-none-any.whl → 0.5.4__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/environment.py +1 -0
- rbx/box/presets/__init__.py +1 -0
- rbx/box/stresses.py +5 -12
- rbx/box/stressing/finder_parser.py +83 -24
- rbx/resources/presets/default/problem/problem.rbx.yml +1 -1
- {rbx_cp-0.5.2.dist-info → rbx_cp-0.5.4.dist-info}/METADATA +1 -1
- {rbx_cp-0.5.2.dist-info → rbx_cp-0.5.4.dist-info}/RECORD +10 -10
- {rbx_cp-0.5.2.dist-info → rbx_cp-0.5.4.dist-info}/LICENSE +0 -0
- {rbx_cp-0.5.2.dist-info → rbx_cp-0.5.4.dist-info}/WHEEL +0 -0
- {rbx_cp-0.5.2.dist-info → rbx_cp-0.5.4.dist-info}/entry_points.txt +0 -0
rbx/box/environment.py
CHANGED
@@ -212,6 +212,7 @@ def install_environment(name: str, file: pathlib.Path):
|
|
212
212
|
)
|
213
213
|
raise typer.Exit(1)
|
214
214
|
|
215
|
+
get_environment_path(name).parent.mkdir(parents=True, exist_ok=True)
|
215
216
|
get_environment_path(name).write_bytes(file.read_bytes())
|
216
217
|
console.console.print(
|
217
218
|
f'[success]Environment [item]{name}[/item] was installed from [item]{file}[/item].'
|
rbx/box/presets/__init__.py
CHANGED
@@ -316,6 +316,7 @@ def _install(root: pathlib.Path = pathlib.Path(), force: bool = False):
|
|
316
316
|
should_copy_env = False
|
317
317
|
|
318
318
|
if should_copy_env:
|
319
|
+
get_environment_path(preset.name).parent.mkdir(parents=True, exist_ok=True)
|
319
320
|
shutil.rmtree(get_environment_path(preset.name), ignore_errors=True)
|
320
321
|
shutil.copyfile(str(root / preset.env), get_environment_path(preset.name))
|
321
322
|
|
rbx/box/stresses.py
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
import dataclasses
|
2
1
|
import functools
|
3
2
|
import time
|
4
3
|
from shutil import rmtree
|
@@ -175,11 +174,13 @@ def run_stress(
|
|
175
174
|
|
176
175
|
@functools.cache
|
177
176
|
def run_solution_and_checker_fn(
|
178
|
-
|
179
|
-
checker: Optional[finder_parser.FinderChecker],
|
177
|
+
call: finder_parser.FinderCall,
|
180
178
|
input_path=input_path,
|
181
179
|
expected_output_path=expected_output_path,
|
182
180
|
) -> finder_parser.FinderResult:
|
181
|
+
solution = call.solution
|
182
|
+
checker = call.checker
|
183
|
+
|
183
184
|
solution_result = run_solution_fn(solution)
|
184
185
|
|
185
186
|
if checker is None:
|
@@ -196,19 +197,11 @@ def run_stress(
|
|
196
197
|
solution=solution,
|
197
198
|
outcome=checker_result.outcome,
|
198
199
|
checker=checker,
|
199
|
-
truth_value=True,
|
200
200
|
solution_result=solution_result,
|
201
201
|
checker_result=checker_result,
|
202
202
|
)
|
203
203
|
|
204
|
-
|
205
|
-
call: finder_parser.FinderCall,
|
206
|
-
) -> finder_parser.FinderResult:
|
207
|
-
finder_result = run_solution_and_checker_fn(call.solution, call.checker)
|
208
|
-
truth_value = call.expected_outcome.match(finder_result.outcome)
|
209
|
-
return dataclasses.replace(finder_result, truth_value=truth_value)
|
210
|
-
|
211
|
-
runner = finder_parser.FinderTreeRunner(runner=run_fn)
|
204
|
+
runner = finder_parser.FinderTreeRunner(runner=run_solution_and_checker_fn)
|
212
205
|
finder_outcome: finder_parser.FinderOutcome = runner.transform(parsed_finder)
|
213
206
|
|
214
207
|
internal_error_results = [
|
@@ -2,7 +2,7 @@ import dataclasses
|
|
2
2
|
import pathlib
|
3
3
|
import typing
|
4
4
|
from enum import Enum
|
5
|
-
from typing import Callable, List, Optional
|
5
|
+
from typing import Callable, List, Optional, Union
|
6
6
|
|
7
7
|
import lark
|
8
8
|
import typer
|
@@ -20,23 +20,34 @@ disjunction: conjunction | disjunction _OR conjunction
|
|
20
20
|
|
21
21
|
conjunction: _atom | conjunction _AND _atom
|
22
22
|
|
23
|
-
_atom:
|
23
|
+
_atom: logical | "(" disjunction ")" | negation
|
24
24
|
negation: _NOT "(" disjunction ")"
|
25
25
|
|
26
|
-
|
26
|
+
// Expressions
|
27
|
+
logical: eval matcher expected_outcome -> matching
|
28
|
+
| eval equality (eval | outcome) -> equating
|
27
29
|
|
30
|
+
eval: "[" solution checking? "]"
|
31
|
+
|
32
|
+
// Eval
|
28
33
|
solution: _filename | WILDCARD
|
29
|
-
outcome: CNAME
|
30
34
|
checking: "ON"i (checking_mode? checker | ":nil")
|
31
35
|
checking_mode: MODE ":"
|
32
36
|
MODE: "2" | "3"
|
33
37
|
checker: _filename | WILDCARD
|
34
38
|
|
39
|
+
// Outcomes
|
40
|
+
expected_outcome: CNAME
|
41
|
+
outcome: CNAME
|
42
|
+
|
35
43
|
// Operators
|
36
44
|
matcher: MATCHES | NOT_MATCHES
|
45
|
+
equality: EQUALS | NOT_EQUALS
|
37
46
|
|
38
47
|
MATCHES: "~"
|
39
48
|
NOT_MATCHES: "!~"
|
49
|
+
EQUALS: "=="
|
50
|
+
NOT_EQUALS: "!="
|
40
51
|
_OR: "||"
|
41
52
|
_AND: "&&"
|
42
53
|
_NOT: "!"
|
@@ -46,7 +57,14 @@ WILDCARD: "$"
|
|
46
57
|
_filename: FILENAME | "\"" FILENAME "\""
|
47
58
|
FILENAME: /[\/A-Za-z0-9\-_\.]/+
|
48
59
|
|
49
|
-
|
60
|
+
// Names (Variables)
|
61
|
+
LCASE_LETTER: "a".."z"
|
62
|
+
UCASE_LETTER: "A".."Z"
|
63
|
+
DIGIT: "0".."9"
|
64
|
+
LETTER: UCASE_LETTER | LCASE_LETTER
|
65
|
+
WORD: LETTER+
|
66
|
+
CNAME: ("_"|LETTER) ("_"|LETTER|DIGIT|"+")*
|
67
|
+
|
50
68
|
%ignore " "
|
51
69
|
"""
|
52
70
|
|
@@ -67,7 +85,6 @@ class FinderChecker:
|
|
67
85
|
@dataclasses.dataclass(frozen=True)
|
68
86
|
class FinderCall:
|
69
87
|
solution: str
|
70
|
-
expected_outcome: ExpectedOutcome
|
71
88
|
checker: Optional[FinderChecker]
|
72
89
|
|
73
90
|
|
@@ -83,7 +100,6 @@ class FinderResult:
|
|
83
100
|
solution: str
|
84
101
|
outcome: Outcome
|
85
102
|
checker: Optional[FinderChecker]
|
86
|
-
truth_value: bool
|
87
103
|
|
88
104
|
# Auxiliary information.
|
89
105
|
solution_result: Optional[FinderSolutionResult] = None
|
@@ -155,8 +171,8 @@ def _get_checker_from_token(token: lark.Token) -> str:
|
|
155
171
|
return path
|
156
172
|
|
157
173
|
|
158
|
-
def
|
159
|
-
checking_nodes = list(
|
174
|
+
def _get_eval_checker(eval: lark.ParseTree) -> Optional[FinderChecker]:
|
175
|
+
checking_nodes = list(eval.find_data('checking'))
|
160
176
|
if not checking_nodes:
|
161
177
|
return _get_default_checker_for_finder()
|
162
178
|
(checking,) = checking_nodes
|
@@ -227,11 +243,11 @@ def get_all_solution_items(tree: lark.ParseTree) -> List[CodeItem]:
|
|
227
243
|
|
228
244
|
|
229
245
|
def _get_all_finder_checkers(tree: lark.ParseTree) -> List[FinderChecker]:
|
230
|
-
|
246
|
+
eval_nodes = tree.find_data('eval')
|
231
247
|
res = []
|
232
248
|
|
233
|
-
for
|
234
|
-
finder_checker =
|
249
|
+
for eval_node in eval_nodes:
|
250
|
+
finder_checker = _get_eval_checker(eval_node)
|
235
251
|
if finder_checker is not None:
|
236
252
|
res.append(finder_checker)
|
237
253
|
|
@@ -299,8 +315,6 @@ def validate(tree: lark.ParseTree):
|
|
299
315
|
|
300
316
|
@lark.v_args(inline=True)
|
301
317
|
class FinderTreeRunner(lark.Transformer):
|
302
|
-
outcome = ExpectedOutcome
|
303
|
-
|
304
318
|
def __init__(
|
305
319
|
self,
|
306
320
|
runner: Callable[[FinderCall], FinderResult],
|
@@ -310,27 +324,72 @@ class FinderTreeRunner(lark.Transformer):
|
|
310
324
|
def solution(self, token: lark.Token) -> str:
|
311
325
|
return _get_solution_from_token(token)
|
312
326
|
|
327
|
+
def outcome(self, token: lark.Token) -> Outcome:
|
328
|
+
try:
|
329
|
+
outcome = Outcome(token.value)
|
330
|
+
except ValueError:
|
331
|
+
try:
|
332
|
+
expected_outcome = self.expected_outcome(token)
|
333
|
+
except ValueError:
|
334
|
+
raise ValueError(f'"{token.value}" is not a valid Outcome.') from None
|
335
|
+
outcomes = expected_outcome.get_matches()
|
336
|
+
if len(outcomes) != 1:
|
337
|
+
raise ValueError(
|
338
|
+
f'"{token.value}" is not a valid Outcome. You are trying to specify an ExpectedOutcome, instead of a single Outcome.'
|
339
|
+
) from None
|
340
|
+
return outcomes[0]
|
341
|
+
return outcome
|
342
|
+
|
343
|
+
def expected_outcome(self, token: lark.Token) -> ExpectedOutcome:
|
344
|
+
return ExpectedOutcome(token.value)
|
345
|
+
|
313
346
|
def matcher(self, op: lark.Token) -> bool:
|
314
347
|
return op.value == '~'
|
315
348
|
|
349
|
+
def equality(self, op: lark.Token) -> bool:
|
350
|
+
return op.value == '=='
|
351
|
+
|
316
352
|
@lark.v_args(inline=False, tree=True)
|
317
|
-
def
|
353
|
+
def eval(self, tree: lark.ParseTree) -> FinderResult:
|
354
|
+
solution = typing.cast(str, tree.children[0])
|
355
|
+
checker: Optional[FinderChecker] = _get_eval_checker(tree)
|
356
|
+
|
357
|
+
call = FinderCall(solution, checker=checker)
|
358
|
+
return self.run_fn(call)
|
359
|
+
|
360
|
+
def matching(
|
318
361
|
self,
|
319
|
-
|
362
|
+
eval_result: FinderResult,
|
363
|
+
is_positive: bool,
|
364
|
+
expected_outcome: ExpectedOutcome,
|
320
365
|
) -> FinderOutcome:
|
321
|
-
|
322
|
-
|
323
|
-
|
366
|
+
truth_value = expected_outcome.match(eval_result.outcome)
|
367
|
+
if not is_positive:
|
368
|
+
truth_value = not truth_value
|
369
|
+
|
370
|
+
return FinderOutcome(truth_value=truth_value, results=[eval_result])
|
371
|
+
|
372
|
+
def equating(
|
373
|
+
self,
|
374
|
+
eval_result: FinderResult,
|
375
|
+
is_positive: bool,
|
376
|
+
result_or_outcome: Union[FinderResult, Outcome],
|
377
|
+
) -> FinderOutcome:
|
378
|
+
results = [eval_result]
|
379
|
+
truth_value = True
|
324
380
|
|
325
|
-
|
381
|
+
if isinstance(result_or_outcome, Outcome):
|
382
|
+
outcome: Outcome = result_or_outcome
|
383
|
+
truth_value = eval_result.outcome == outcome
|
384
|
+
else:
|
385
|
+
result: FinderResult = result_or_outcome
|
386
|
+
truth_value = eval_result.outcome == result.outcome
|
387
|
+
results.append(result)
|
326
388
|
|
327
|
-
call = FinderCall(solution, expected_outcome=expected_outcome, checker=checker)
|
328
|
-
result = self.run_fn(call)
|
329
|
-
truth_value = result.truth_value
|
330
389
|
if not is_positive:
|
331
390
|
truth_value = not truth_value
|
332
391
|
|
333
|
-
return FinderOutcome(truth_value=truth_value, results=
|
392
|
+
return FinderOutcome(truth_value=truth_value, results=results)
|
334
393
|
|
335
394
|
def negation(self, value: FinderOutcome) -> FinderOutcome:
|
336
395
|
return dataclasses.replace(value, truth_value=not value.truth_value)
|
@@ -38,7 +38,7 @@ stresses:
|
|
38
38
|
generator:
|
39
39
|
name: 'gen'
|
40
40
|
args: '[1..<MAX_N>] @' # `@` generates a random string
|
41
|
-
finder: 'sols/wa.cpp ~ INCORRECT'
|
41
|
+
finder: '[sols/wa.cpp] ~ INCORRECT'
|
42
42
|
vars:
|
43
43
|
"MAX_N": 1000000000 # Can be used in the validator, in stress tests and in the statement.
|
44
44
|
|
@@ -17,7 +17,7 @@ rbx/box/contest/schema.py,sha256=rxzjJasMWPKKhvSJs4eW4A2oCiA4gXgfF-MzqsbPslQ,491
|
|
17
17
|
rbx/box/contest/statements.py,sha256=iG_E4bqhc7hof4LlAliw4m9VO8HcDzvnhsWmxzVRQM4,2690
|
18
18
|
rbx/box/creation.py,sha256=mZ7kEt1F-0scwDBc6oWsJxFRW69AccZlKuJfN1QyDd4,2203
|
19
19
|
rbx/box/download.py,sha256=MFP-R26JiYGAP89I0TK-0fYc69Fsd20tsBqgtRCy5AE,2234
|
20
|
-
rbx/box/environment.py,sha256=
|
20
|
+
rbx/box/environment.py,sha256=i-IGHDyFDaYF1fyr0QHdGZ3z4NWp5sj6nxsbnxhAYq4,10924
|
21
21
|
rbx/box/extensions.py,sha256=p0iLaU28KswOBDX2HGVO_dR2gk-JSAWb6sXC6GZ1d0w,738
|
22
22
|
rbx/box/generators.py,sha256=UJNyvwbY4JBVpmdMoVsYi16O3oodMgguH_dmZAoOFm4,16104
|
23
23
|
rbx/box/generators_test.py,sha256=mQqHepAMYa6zV_PseQALI0nIX6AdQktt6lh94muFhNw,1758
|
@@ -31,7 +31,7 @@ rbx/box/packaging/packager.py,sha256=suCT_SLnWa915rV2j8VFqzH43HGKRTr9mGGlrvj45aw
|
|
31
31
|
rbx/box/packaging/polygon/packager.py,sha256=CcjHzDr4MwSyp270gsPY6RWoz8bUJeykDqXPvQ3XZ1U,10773
|
32
32
|
rbx/box/packaging/polygon/test.py,sha256=bgEju5PwudgyfwxXJagm8fM6CJVlWM6l_-2q1V-oKaQ,3069
|
33
33
|
rbx/box/packaging/polygon/xml_schema.py,sha256=-r24bCeRMGLrGGoT9FIgmqr87xHL-JzrFaR6bztbYtw,2703
|
34
|
-
rbx/box/presets/__init__.py,sha256=
|
34
|
+
rbx/box/presets/__init__.py,sha256=bDmaBWnwh71lkn2pfGIREN-xlo3HpMZBN9ucodbxscc,16573
|
35
35
|
rbx/box/presets/fetch.py,sha256=F-BCOlvEBEyDqtOhiDuGPn4EDtA4Bwm-fqHJ7zZGlW8,1975
|
36
36
|
rbx/box/presets/lock_schema.py,sha256=6sRPnyePOC8yy-5WcD5JRZdDJHf8loqbvpQ1IPiOU9s,349
|
37
37
|
rbx/box/presets/schema.py,sha256=mZmSPkQsw7eQM0lQN6er1MO_LiW1ObwwAZFDK0F5fxE,1962
|
@@ -45,9 +45,9 @@ rbx/box/statements/joiners.py,sha256=ZbxomnMjEFT8yf5WSWUB4tBa3DL3AhjGEuh8uqHyDdg
|
|
45
45
|
rbx/box/statements/latex.py,sha256=LkcHwXjMFxbw--Gj9T1VkFKQFsXhY9dN7xZHpZycNW8,1346
|
46
46
|
rbx/box/statements/latex_jinja.py,sha256=7WBfn1h8DpqCAmSE6Av64HfURMnJ2AO4QX1CD72sz5E,7096
|
47
47
|
rbx/box/statements/schema.py,sha256=g3KgBn4nIqx-0utH8R2FCqPmJP969chhYfn96chQgd4,3851
|
48
|
-
rbx/box/stresses.py,sha256=
|
48
|
+
rbx/box/stresses.py,sha256=mbKa70QyPOmgXfhGcArTKsdXjH0PFDVmydY3W8bgZlk,10596
|
49
49
|
rbx/box/stressing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
50
|
-
rbx/box/stressing/finder_parser.py,sha256=
|
50
|
+
rbx/box/stressing/finder_parser.py,sha256=Hw9m2viRGnVqVgO39D51s2qAEjZK1LKWe94rkqCx7VA,11919
|
51
51
|
rbx/box/stressing/generator_parser.py,sha256=oHZryjR3YohgaSO9WEirQ7b2e-98WgZStF0N99W4Thw,7380
|
52
52
|
rbx/box/testcases.py,sha256=bi7T5xXkwyWOkoI6ILcaf2gSSVuuNtZjhP5yL0DJAu4,1452
|
53
53
|
rbx/box/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -116,7 +116,7 @@ rbx/resources/presets/default/contest/statement/template.rbx.tex,sha256=XSGtd8JJ
|
|
116
116
|
rbx/resources/presets/default/preset.rbx.yml,sha256=hYesK08n17FBNThr4iaGrDfC0L3us_pzGDkhD33Ryt4,313
|
117
117
|
rbx/resources/presets/default/problem/.gitignore,sha256=zc-lnGQQZsLBaXpSshesA_QfxhiZdNCSJDEuKqlPtjw,29
|
118
118
|
rbx/resources/presets/default/problem/gen.cpp,sha256=rn6sGRjZ1sFE1Rq02r6488iquY9xTrutcvLv4d1sohA,178
|
119
|
-
rbx/resources/presets/default/problem/problem.rbx.yml,sha256=
|
119
|
+
rbx/resources/presets/default/problem/problem.rbx.yml,sha256=sgOTa7LedlY3nFOno28XHAgUN89w9p5dl0aIafq1dQs,1379
|
120
120
|
rbx/resources/presets/default/problem/random.py,sha256=-iPorU24QHfp39EYRJX9jMKcTIxxz5ejKoAzPLIuu1g,98
|
121
121
|
rbx/resources/presets/default/problem/random.txt,sha256=oDS_a9LdKSTKj4MvGLWvHSljI3AjRY6MclaxEwK794I,23
|
122
122
|
rbx/resources/presets/default/problem/sols/main.cpp,sha256=AW-j65DiFYUN18rddTKCWc_VyYCMgCbjZ0jAJ-0JLuA,124
|
@@ -157,8 +157,8 @@ rbx/testdata/caching/executable.py,sha256=WKRHNf_fprFJd1Fq1ubmQtR3mZzTYVNwKPLWuZ
|
|
157
157
|
rbx/testdata/compatible,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
158
158
|
rbx/testing_utils.py,sha256=ZZLKMUHlZ4HwsuNY50jqSBJ9HhpnFdba7opjDsvXE1U,2084
|
159
159
|
rbx/utils.py,sha256=OkOLjNG8Pq7y2ylqhXQyAOVDfUsva_4Mfjd8OmII55E,4145
|
160
|
-
rbx_cp-0.5.
|
161
|
-
rbx_cp-0.5.
|
162
|
-
rbx_cp-0.5.
|
163
|
-
rbx_cp-0.5.
|
164
|
-
rbx_cp-0.5.
|
160
|
+
rbx_cp-0.5.4.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
|
161
|
+
rbx_cp-0.5.4.dist-info/METADATA,sha256=M7IsN4Rby6iiSRtncAAu_JTiiw-Yi_tNXFYohcCDHhA,3253
|
162
|
+
rbx_cp-0.5.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
163
|
+
rbx_cp-0.5.4.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
|
164
|
+
rbx_cp-0.5.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|