rbx.cp 0.5.64__py3-none-any.whl → 0.5.65__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 CHANGED
@@ -3,7 +3,7 @@ import shlex
3
3
  import shutil
4
4
  import sys
5
5
  import tempfile
6
- from typing import Annotated, Optional
6
+ from typing import Annotated, List, Optional
7
7
 
8
8
  import rich
9
9
  import rich.prompt
@@ -32,6 +32,7 @@ from rbx.box.packaging import main as packaging
32
32
  from rbx.box.schema import CodeItem, ExpectedOutcome, TestcaseGroup
33
33
  from rbx.box.solutions import (
34
34
  estimate_time_limit,
35
+ expand_solutions,
35
36
  get_exact_matching_solutions,
36
37
  get_matching_solutions,
37
38
  pick_solutions,
@@ -178,10 +179,10 @@ async def build(verification: environment.VerificationParam):
178
179
  @syncer.sync
179
180
  async def run(
180
181
  verification: environment.VerificationParam,
181
- solution: Annotated[
182
- Optional[str],
182
+ solutions: Annotated[
183
+ Optional[List[str]],
183
184
  typer.Argument(
184
- help='Path to solution to run. If not specified, will run all solutions.'
185
+ help='Path to solutions to run. If not specified, will run all solutions.'
185
186
  ),
186
187
  ] = None,
187
188
  outcome: Optional[str] = typer.Option(
@@ -235,11 +236,16 @@ async def run(
235
236
  str(solution.path)
236
237
  for solution in get_matching_solutions(ExpectedOutcome(outcome))
237
238
  }
238
- if solution:
239
- tracked_solutions = {solution}
239
+ if solutions:
240
+ tracked_solutions = set(solutions)
240
241
 
241
242
  if choice:
242
- tracked_solutions = set(await pick_solutions(tracked_solutions))
243
+ tracked_solutions = set(
244
+ await pick_solutions(
245
+ tracked_solutions,
246
+ extra_solutions=await expand_solutions(solutions or []),
247
+ )
248
+ )
243
249
  if not tracked_solutions:
244
250
  console.console.print('[error]No solutions selected. Exiting.[/error]')
245
251
  raise typer.Exit(1)
@@ -395,10 +401,10 @@ async def time(
395
401
  @syncer.sync
396
402
  async def irun(
397
403
  verification: environment.VerificationParam,
398
- solution: Annotated[
399
- Optional[str],
404
+ solutions: Annotated[
405
+ Optional[List[str]],
400
406
  typer.Argument(
401
- help='Path to solution to run. If not specified, will run all solutions.'
407
+ help='Path to solutions to run. If not specified, will run all solutions.'
402
408
  ),
403
409
  ] = None,
404
410
  outcome: Optional[str] = typer.Option(
@@ -466,11 +472,16 @@ async def irun(
466
472
  str(solution.path)
467
473
  for solution in get_matching_solutions(ExpectedOutcome(outcome))
468
474
  }
469
- if solution:
470
- tracked_solutions = {solution}
475
+ if solutions:
476
+ tracked_solutions = set(solutions)
471
477
 
472
478
  if choice:
473
- tracked_solutions = set(await pick_solutions(tracked_solutions))
479
+ tracked_solutions = set(
480
+ await pick_solutions(
481
+ tracked_solutions,
482
+ extra_solutions=await expand_solutions(solutions or []),
483
+ )
484
+ )
474
485
  if not tracked_solutions:
475
486
  console.console.print('[error]No solutions selected. Exiting.[/error]')
476
487
  raise typer.Exit(1)
rbx/box/formatting.py CHANGED
@@ -20,7 +20,11 @@ def href(url: os.PathLike[str], text: Optional[str] = None, style: str = 'item')
20
20
 
21
21
  if isinstance(url, pathlib.Path):
22
22
  url = url.resolve()
23
- return f'[{style}][link={url}]{text}[/link][/{style}]'
23
+
24
+ url_str = str(url)
25
+ if pathlib.Path(url_str).exists():
26
+ url_str = f'file://{url_str}'
27
+ return f'[{style}][link={url_str}]{text}[/link][/{style}]'
24
28
 
25
29
 
26
30
  def get_formatted_memory(memory_in_bytes: int, mib_decimal_places: int = 0) -> str:
rbx/box/solutions.py CHANGED
@@ -726,20 +726,53 @@ def _get_solution_repr(sol: Solution) -> List[Tuple[str, str]]:
726
726
  ]
727
727
 
728
728
 
729
- async def pick_solutions(tracked_solutions: Optional[Set[str]]) -> List[str]:
729
+ async def expand_solutions(sols: List[str]) -> List[Solution]:
730
730
  pkg = package.find_problem_package_or_die()
731
- if tracked_solutions is None:
732
- tracked_solutions = set(str(sol.path) for sol in pkg.solutions)
731
+ seen_sols = set(str(sol.path) for sol in pkg.solutions)
733
732
 
733
+ # Dedup sols.
734
+ sols = [sol for sol in sols if str(sol) not in seen_sols]
735
+
736
+ # Ensure sols exist.
737
+ sols = [sol for sol in sols if pathlib.Path(sol).is_file()]
738
+
739
+ return [
740
+ Solution(path=pathlib.Path(sol), outcome=ExpectedOutcome.ACCEPTED)
741
+ for sol in sols
742
+ ]
743
+
744
+
745
+ async def pick_solutions(
746
+ tracked_solutions: Optional[Set[str]],
747
+ extra_solutions: Optional[Iterable[Solution]] = None,
748
+ ) -> List[str]:
749
+ extra_sols = set(extra_solutions) if extra_solutions is not None else set()
750
+
751
+ pkg = package.find_problem_package_or_die()
734
752
  # Store in a separate list to maintain order with the package declaration.
735
753
  import questionary
736
754
 
737
755
  choices = [
738
- questionary.Choice(title=_get_solution_repr(sol), value=str(sol.path))
756
+ questionary.Choice(
757
+ title=_get_solution_repr(sol),
758
+ value=str(sol.path),
759
+ checked=tracked_solutions is None or str(sol.path) in tracked_solutions,
760
+ )
739
761
  for sol in pkg.solutions
740
- if str(sol.path) in tracked_solutions
741
762
  ]
742
763
 
764
+ seen_sols = set(str(sol.path) for sol in pkg.solutions)
765
+
766
+ if extra_sols:
767
+ # Add only new solutions.
768
+ choices.extend(
769
+ questionary.Choice(
770
+ title=_get_solution_repr(sol), value=str(sol.path), checked=True
771
+ )
772
+ for sol in extra_sols
773
+ if str(sol.path) not in seen_sols
774
+ )
775
+
743
776
  picked = await questionary.checkbox('Select solutions', choices=choices).ask_async()
744
777
  if picked is None:
745
778
  raise typer.Abort()
rbx/box/testcase_utils.py CHANGED
@@ -172,6 +172,7 @@ def parse_interaction(file: pathlib.Path) -> TestcaseInteraction:
172
172
  )
173
173
  raise typer.Exit(1) from None
174
174
 
175
+ # Crop file.
175
176
  rest = f.read()
176
177
  start = 0
177
178
 
@@ -202,13 +203,17 @@ def parse_interaction(file: pathlib.Path) -> TestcaseInteraction:
202
203
  nxt_start, _ = nxt
203
204
  return (pipe, (prefix_end, nxt_start))
204
205
 
205
- while True:
206
+ # TODO: optimize
207
+ blocks = 0
208
+ MAX_BLOCKS = 1024
209
+ while blocks < MAX_BLOCKS:
206
210
  block = _find_next_block()
207
211
  if block is None:
208
212
  break
209
213
  pipe, (st, nd) = block
210
214
  entries.append(TestcaseInteractionEntry(data=rest[st:nd], pipe=pipe))
211
215
  start = nd
216
+ blocks += 1
212
217
 
213
218
  return TestcaseInteraction(
214
219
  prefixes=(interactor_prefix, solution_prefix),
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rbx.cp
3
- Version: 0.5.64
3
+ Version: 0.5.65
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9,<4.0
@@ -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=KGaqXHnv2hCumZS2VdMezFfwFEQcSq0rt05_KZtuQAo,1570
7
7
  rbx/box/checkers.py,sha256=aGciafGNQ39UqndTEJRT3J8ngv_UigYxOT30yMzCwEI,12752
8
- rbx/box/cli.py,sha256=mockAftbBYRt587_Fjbkpk7GZtj0MxcRJGoHBQxfTXE,27139
8
+ rbx/box/cli.py,sha256=gCgXxUA243WmG7hXuDeGb0D9tF11dwzPtxobzKQM2DA,27445
9
9
  rbx/box/code.py,sha256=2oC1JbZiwfeg53ZICPig-KJYchqFRIZz-inlM-cLc7Q,19911
10
10
  rbx/box/compile.py,sha256=OJLthDQ921w9vyoE6Gk1Df54i5RwtRJ2YG-8XEfefcs,2489
11
11
  rbx/box/conftest.py,sha256=sEmciXSeDC-wmrZ1JSxbsUenKNP_VWW32mrCun2pY3I,1070
@@ -22,7 +22,7 @@ rbx/box/download.py,sha256=DxAiAk4lDYWEz1C9UTvZzHTq6hgm4fxGezApm2IkCTM,2601
22
22
  rbx/box/dump_schemas.py,sha256=3j5t47_vJmXj0BCczxDX6ByOcsfolGEDNCBXlPpk86w,593
23
23
  rbx/box/environment.py,sha256=Kp69MekUwwoVpupnafUcN5KAbP-ZTCwe0OQXt1h0FN8,11859
24
24
  rbx/box/extensions.py,sha256=Von8kIeXvNFTkGlMRMTvL2HIHPwlkuiMswr-ydbGV1w,519
25
- rbx/box/formatting.py,sha256=csscjgWrTa6zjs2ueVCFRzA3WxdUFbzkzOxHWyQVerw,1049
25
+ rbx/box/formatting.py,sha256=pPijbtoF2zK-8_y_Q7TOxMJAojZcMmFew4aCCSVfNRQ,1154
26
26
  rbx/box/generators.py,sha256=RE0-D91BB-3rNDQXvCFWzU9iMhKIc_ALp960oGfM-rY,13780
27
27
  rbx/box/generators_test.py,sha256=J7aBfuJhU84MWDWzgReRoOuQw_hVa09B8gTKAvL2XVo,1987
28
28
  rbx/box/git_utils.py,sha256=VlUgzuHOCnrjjiJQnDB32qDHbHw_zkwgA7wm4bloibc,750
@@ -52,7 +52,7 @@ rbx/box/retries.py,sha256=cZcNYLVHFDbhbeqMzxITgo8SYY8qzyxm0tIYcmWl1Ek,4877
52
52
  rbx/box/sanitizers/warning_stack.py,sha256=RI97_GJgdjTKIXY_r0EKp5h0qQQSDSdNDh5K7zINrqs,2861
53
53
  rbx/box/schema.py,sha256=y736-wZdGw56T6eDC_m7NAm2XRUdauBXJRQkQO79fpc,16264
54
54
  rbx/box/setter_config.py,sha256=9iObg6BwxQhFAhIOk31Jc0BDDpRYVGf3SyLIOsWIltM,4393
55
- rbx/box/solutions.py,sha256=pQG_4HVpFds6C0gcxmvKr557s7IhYmLoYB_s_1GgtAI,49049
55
+ rbx/box/solutions.py,sha256=LQio9FJL51XlEZ20QohWpgTbBiyTN7tZ72eY-K3p3DY,49981
56
56
  rbx/box/solutions_test.py,sha256=PX1TQoRzNd9mi1SGsG7WFrpqFgNrNX5Kwt0mkwFdoOA,1749
57
57
  rbx/box/state.py,sha256=MMf3DvfQji0jKEliCHct2Tpp_0epL1tvP8HbHNArQIc,166
58
58
  rbx/box/statements/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -68,7 +68,7 @@ rbx/box/stressing/finder_parser.py,sha256=jXpYNa4FyugzmHi3r96Uv4rU1krRQJc5Ihr9jf
68
68
  rbx/box/stressing/generator_parser.py,sha256=oHZryjR3YohgaSO9WEirQ7b2e-98WgZStF0N99W4Thw,7380
69
69
  rbx/box/tasks.py,sha256=sVPR6a3CSU28pN6bMjZcZATYZBV7JlZvhvxcPRH8-MI,10514
70
70
  rbx/box/testcase_extractors.py,sha256=J43eG7vpxc5nP_2yhrXJODkd4EYlV4WiYVbM6hzipY4,11944
71
- rbx/box/testcase_utils.py,sha256=lvQ58D-R8vYx5AFA9sJ9xMIZJvtjYjisTpAjMIoyG4Y,7686
71
+ rbx/box/testcase_utils.py,sha256=0HydSzmy1Olqws6iPMkX6dnPnl45sPZf83SlrjQxs40,7816
72
72
  rbx/box/testcases/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
73
73
  rbx/box/testcases/main.py,sha256=_I7h_obRcpNLRQ6dDJDIE5NAvTyn5nBOhdsBhRA_PvU,5442
74
74
  rbx/box/ui/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -212,8 +212,8 @@ rbx/testcase.py,sha256=yKOq3CAJZ1YTmInvnoIs0u1iJnRj_X85XiWbLI-p9d8,1951
212
212
  rbx/testcase_rendering.py,sha256=nfmv6dSEqd4aR3TsaODwkKGK6AXty_DDKtWf_ejiQpI,2084
213
213
  rbx/testing_utils.py,sha256=x_PqD8Zd2PkN91NxVHUnSTs044-1WK5KKtttKQBXpFs,2083
214
214
  rbx/utils.py,sha256=SfR844_i0ebRDMkmS_w1YdZiWPc6h2RGADygewlWRbA,4845
215
- rbx_cp-0.5.64.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
216
- rbx_cp-0.5.64.dist-info/METADATA,sha256=rBpsAACES-Q_TSMl1doYvu3m29ymEtfkYx62vfrI75E,3604
217
- rbx_cp-0.5.64.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
218
- rbx_cp-0.5.64.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
219
- rbx_cp-0.5.64.dist-info/RECORD,,
215
+ rbx_cp-0.5.65.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
216
+ rbx_cp-0.5.65.dist-info/METADATA,sha256=TBx0q_SnA7K1cbAXvTbdgdLbCgTq7phrGbGBJSiKefk,3604
217
+ rbx_cp-0.5.65.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
218
+ rbx_cp-0.5.65.dist-info/entry_points.txt,sha256=qBTLBOeifT1F00LWaEewRRE_jQPgvH7BUdJfZ-dYsFU,57
219
+ rbx_cp-0.5.65.dist-info/RECORD,,