rbx.cp 0.5.24__tar.gz → 0.5.25__tar.gz

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.
Files changed (168) hide show
  1. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/PKG-INFO +1 -1
  2. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/pyproject.toml +1 -1
  3. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/code.py +1 -1
  4. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/main.py +72 -34
  5. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/solutions.py +39 -9
  6. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/steps.py +11 -4
  7. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/LICENSE +0 -0
  8. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/README.md +0 -0
  9. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/__init__.py +0 -0
  10. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/annotations.py +0 -0
  11. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/autoenum.py +0 -0
  12. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/__init__.py +0 -0
  13. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/builder.py +0 -0
  14. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/cd.py +0 -0
  15. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/checkers.py +0 -0
  16. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/compile.py +0 -0
  17. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/conftest.py +0 -0
  18. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/contest/__init__.py +0 -0
  19. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/contest/build_contest_statements.py +0 -0
  20. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/contest/contest_package.py +0 -0
  21. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/contest/contest_utils.py +0 -0
  22. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/contest/main.py +0 -0
  23. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/contest/schema.py +0 -0
  24. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/contest/statements.py +0 -0
  25. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/creation.py +0 -0
  26. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/deferred.py +0 -0
  27. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/download.py +0 -0
  28. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/environment.py +0 -0
  29. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/extensions.py +0 -0
  30. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/generators.py +0 -0
  31. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/generators_test.py +0 -0
  32. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/package.py +0 -0
  33. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/packaging/boca/extension.py +0 -0
  34. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/packaging/boca/packager.py +0 -0
  35. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/packaging/contest_main.py +0 -0
  36. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/packaging/main.py +0 -0
  37. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/packaging/packager.py +0 -0
  38. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/packaging/polygon/packager.py +0 -0
  39. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/packaging/polygon/test.py +0 -0
  40. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/packaging/polygon/xml_schema.py +0 -0
  41. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/presets/__init__.py +0 -0
  42. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/presets/fetch.py +0 -0
  43. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/presets/lock_schema.py +0 -0
  44. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/presets/schema.py +0 -0
  45. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/sanitizers/warning_stack.py +0 -0
  46. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/schema.py +0 -0
  47. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/setter_config.py +0 -0
  48. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/solutions_test.py +0 -0
  49. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/statements/__init__.py +0 -0
  50. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/statements/build_statements.py +0 -0
  51. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/statements/builders.py +0 -0
  52. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/statements/joiners.py +0 -0
  53. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/statements/latex.py +0 -0
  54. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/statements/latex_jinja.py +0 -0
  55. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/statements/schema.py +0 -0
  56. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/stresses.py +0 -0
  57. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/stressing/__init__.py +0 -0
  58. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/stressing/finder_parser.py +0 -0
  59. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/stressing/generator_parser.py +0 -0
  60. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/testcases.py +0 -0
  61. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/ui/__init__.py +0 -0
  62. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/ui/captured_log.py +0 -0
  63. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/ui/css/app.tcss +0 -0
  64. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/ui/main.py +0 -0
  65. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/ui/run.py +0 -0
  66. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/validators.py +0 -0
  67. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/box/validators_test.py +0 -0
  68. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/checker.py +0 -0
  69. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/clone.py +0 -0
  70. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/config.py +0 -0
  71. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/conftest.py +0 -0
  72. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/console.py +0 -0
  73. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/create.py +0 -0
  74. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/edit.py +0 -0
  75. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/__init__.py +0 -0
  76. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/caching.py +0 -0
  77. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/conftest.py +0 -0
  78. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/__init__.py +0 -0
  79. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/cacher.py +0 -0
  80. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/digester.py +0 -0
  81. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/sandbox.py +0 -0
  82. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/sandboxes/__init__.py +0 -0
  83. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/sandboxes/isolate.py +0 -0
  84. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/sandboxes/stupid_sandbox.py +0 -0
  85. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/sandboxes/timeit.py +0 -0
  86. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/storage.py +0 -0
  87. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/test.py +0 -0
  88. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/judge/testiso.py +0 -0
  89. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/steps_with_caching.py +0 -0
  90. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading/steps_with_caching_run_test.py +0 -0
  91. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/grading_utils.py +0 -0
  92. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/hydration.py +0 -0
  93. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/main.py +0 -0
  94. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/metadata.py +0 -0
  95. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/providers/__init__.py +0 -0
  96. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/providers/codeforces.py +0 -0
  97. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/providers/provider.py +0 -0
  98. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/checkers/boilerplate.cpp +0 -0
  99. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/default_config.json +0 -0
  100. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/default_setter_config.mac.yml +0 -0
  101. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/default_setter_config.yml +0 -0
  102. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/envs/default.rbx.yml +0 -0
  103. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/envs/isolate.rbx.yml +0 -0
  104. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/checker.sh +0 -0
  105. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/compare +0 -0
  106. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/compile/c +0 -0
  107. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/compile/cc +0 -0
  108. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/compile/cpp +0 -0
  109. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/compile/java +0 -0
  110. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/compile/kt +0 -0
  111. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/compile/pas +0 -0
  112. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/compile/py2 +0 -0
  113. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/compile/py3 +0 -0
  114. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/run/c +0 -0
  115. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/run/cc +0 -0
  116. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/run/cpp +0 -0
  117. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/run/java +0 -0
  118. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/run/kt +0 -0
  119. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/run/py2 +0 -0
  120. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/packagers/boca/run/py3 +0 -0
  121. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
  122. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
  123. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/contest/statement/olymp.sty +0 -0
  124. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/contest/statement/template.rbx.tex +0 -0
  125. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/preset.rbx.yml +0 -0
  126. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/.gitignore +0 -0
  127. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/gen.cpp +0 -0
  128. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/problem.rbx.yml +0 -0
  129. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/random.py +0 -0
  130. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/random.txt +0 -0
  131. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
  132. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/sols/slow.cpp +0 -0
  133. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/sols/wa.cpp +0 -0
  134. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/statement/olymp.sty +0 -0
  135. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/statement/projecao.png +0 -0
  136. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
  137. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/statement/template.rbx.tex +0 -0
  138. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/tests/samples/000.in +0 -0
  139. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/tests/samples/001.in +0 -0
  140. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/validator.cpp +0 -0
  141. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
  142. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/resources/templates/template.cpp +0 -0
  143. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/run.py +0 -0
  144. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/schema.py +0 -0
  145. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/submit.py +0 -0
  146. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/submitors/__init__.py +0 -0
  147. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/submitors/codeforces.py +0 -0
  148. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/submitors/submitor.py +0 -0
  149. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/test.py +0 -0
  150. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testcase.py +0 -0
  151. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testcase_rendering.py +0 -0
  152. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/gen1.cpp +0 -0
  153. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/gen2.cpp +0 -0
  154. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/genScript.py +0 -0
  155. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/hard-tle.sol.cpp +0 -0
  156. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/ole.cpp +0 -0
  157. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/problem.rbx.yml +0 -0
  158. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/re.sol.cpp +0 -0
  159. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/sol.cpp +0 -0
  160. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/tests/1.in +0 -0
  161. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/tle-and-incorrect.sol.cpp +0 -0
  162. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/tle.sol.cpp +0 -0
  163. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/validator.cpp +0 -0
  164. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/box1/wa.sol.cpp +0 -0
  165. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/caching/executable.py +0 -0
  166. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testdata/compatible +0 -0
  167. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/testing_utils.py +0 -0
  168. {rbx_cp-0.5.24 → rbx_cp-0.5.25}/rbx/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: rbx.cp
3
- Version: 0.5.24
3
+ Version: 0.5.25
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9,<4.0
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "rbx.cp"
3
- version = "0.5.24"
3
+ version = "0.5.25"
4
4
  description = ""
5
5
  packages = [
6
6
  {include = "rbx"}
@@ -75,7 +75,7 @@ def is_executable_sanitized(executable: DigestOrSource) -> bool:
75
75
 
76
76
  def add_sanitizer_flags_to_command(command: str) -> str:
77
77
  if is_cxx_command(command):
78
- return command + ' -fsanitize=address,undefined -fno-omit-frame-pointer'
78
+ return command + ' -fsanitize=address,undefined -fno-omit-frame-pointer -g'
79
79
  return command
80
80
 
81
81
 
@@ -42,6 +42,7 @@ from rbx.box.solutions import (
42
42
  estimate_time_limit,
43
43
  get_exact_matching_solutions,
44
44
  get_matching_solutions,
45
+ pick_solutions,
45
46
  print_run_report,
46
47
  run_and_print_interactive_solutions,
47
48
  run_solutions,
@@ -143,6 +144,13 @@ def run(
143
144
  '-s',
144
145
  help='Whether to compile the solutions with sanitizers enabled.',
145
146
  ),
147
+ choice: bool = typer.Option(
148
+ False,
149
+ '--choice',
150
+ '--choose',
151
+ '-c',
152
+ help='Whether to pick solutions interactively.',
153
+ ),
146
154
  ):
147
155
  main_solution = package.get_main_solution()
148
156
  if check and main_solution is None:
@@ -174,31 +182,37 @@ def run(
174
182
  if override_tl is None:
175
183
  raise typer.Exit(1)
176
184
 
177
- with utils.StatusProgress('Running solutions...') as s:
178
- if sanitized:
179
- console.console.print(
180
- '[warning]Sanitizers are running, so the time limit for the problem will be dropped, '
181
- 'and the environment default time limit will be used instead.[/warning]'
182
- )
185
+ if sanitized:
186
+ console.console.print(
187
+ '[warning]Sanitizers are running, so the time limit for the problem will be dropped, '
188
+ 'and the environment default time limit will be used instead.[/warning]'
189
+ )
183
190
 
184
- tracked_solutions = None
185
- if outcome is not None:
186
- tracked_solutions = {
187
- str(solution.path)
188
- for solution in get_matching_solutions(ExpectedOutcome(outcome))
189
- }
190
- if solution:
191
- tracked_solutions = {solution}
191
+ tracked_solutions = None
192
+ if outcome is not None:
193
+ tracked_solutions = {
194
+ str(solution.path)
195
+ for solution in get_matching_solutions(ExpectedOutcome(outcome))
196
+ }
197
+ if solution:
198
+ tracked_solutions = {solution}
192
199
 
193
- if sanitized and tracked_solutions is None:
194
- console.console.print(
195
- '[warning]Sanitizers are running, and no solutions were specified to run. Will only run [item]ACCEPTED[/item] solutions.'
196
- )
197
- tracked_solutions = {
198
- str(solution.path)
199
- for solution in get_exact_matching_solutions(ExpectedOutcome.ACCEPTED)
200
- }
200
+ if sanitized and tracked_solutions is None:
201
+ console.console.print(
202
+ '[warning]Sanitizers are running, and no solutions were specified to run. Will only run [item]ACCEPTED[/item] solutions.'
203
+ )
204
+ tracked_solutions = {
205
+ str(solution.path)
206
+ for solution in get_exact_matching_solutions(ExpectedOutcome.ACCEPTED)
207
+ }
208
+
209
+ if choice:
210
+ tracked_solutions = set(pick_solutions(tracked_solutions))
211
+ if not tracked_solutions:
212
+ console.console.print('[error]No solutions selected. Exiting.[/error]')
213
+ raise typer.Exit(1)
201
214
 
215
+ with utils.StatusProgress('Running solutions...') as s:
202
216
  solution_result = run_solutions(
203
217
  progress=s,
204
218
  tracked_solutions=tracked_solutions,
@@ -338,6 +352,13 @@ def irun(
338
352
  '-s',
339
353
  help='Whether to compile the solutions with sanitizers enabled.',
340
354
  ),
355
+ choice: bool = typer.Option(
356
+ False,
357
+ '--choice',
358
+ '--choose',
359
+ '-c',
360
+ help='Whether to pick solutions interactively.',
361
+ ),
341
362
  ):
342
363
  if not print:
343
364
  console.console.print(
@@ -373,18 +394,26 @@ def irun(
373
394
  for solution in get_exact_matching_solutions(ExpectedOutcome.ACCEPTED)
374
395
  }
375
396
 
376
- asyncio.run(
377
- run_and_print_interactive_solutions(
378
- tracked_solutions=tracked_solutions,
379
- check=check,
380
- verification=VerificationLevel(verification),
381
- generator=generators.get_call_from_string(generator)
382
- if generator is not None
383
- else None,
384
- print=print,
385
- sanitized=sanitized,
397
+ if choice:
398
+ tracked_solutions = set(pick_solutions(tracked_solutions))
399
+ if not tracked_solutions:
400
+ console.console.print('[error]No solutions selected. Exiting.[/error]')
401
+ raise typer.Exit(1)
402
+
403
+ with utils.StatusProgress('Running solutions...') as s:
404
+ asyncio.run(
405
+ run_and_print_interactive_solutions(
406
+ progress=s,
407
+ tracked_solutions=tracked_solutions,
408
+ check=check,
409
+ verification=VerificationLevel(verification),
410
+ generator=generators.get_call_from_string(generator)
411
+ if generator is not None
412
+ else None,
413
+ print=print,
414
+ sanitized=sanitized,
415
+ )
386
416
  )
387
- )
388
417
 
389
418
 
390
419
  @app.command('create, c', help='Create a new problem package.')
@@ -551,7 +580,10 @@ def stress(
551
580
  @app.command('compile', help='Compile an asset given its path.')
552
581
  @package.within_problem
553
582
  def compile_command(
554
- path: Annotated[str, typer.Argument(help='Path to the asset to compile.')],
583
+ path: Annotated[
584
+ Optional[str],
585
+ typer.Argument(help='Path to the asset to compile.'),
586
+ ] = None,
555
587
  sanitized: bool = typer.Option(
556
588
  False,
557
589
  '--sanitized',
@@ -565,6 +597,12 @@ def compile_command(
565
597
  help='Whether to compile the asset with warnings enabled.',
566
598
  ),
567
599
  ):
600
+ if path is None:
601
+ path = questionary.path("What's the path to your asset?").ask()
602
+ if path is None:
603
+ console.console.print('[error]No path specified.[/error]')
604
+ raise typer.Exit(1)
605
+
568
606
  compile.any(path, sanitized, warnings)
569
607
 
570
608
 
@@ -7,6 +7,7 @@ import shutil
7
7
  from collections.abc import Iterator
8
8
  from typing import Dict, Iterable, List, Optional, Set, Tuple
9
9
 
10
+ import questionary
10
11
  import rich
11
12
  import rich.live
12
13
  import rich.markup
@@ -410,6 +411,7 @@ def run_solutions(
410
411
 
411
412
 
412
413
  def _run_interactive_solutions(
414
+ progress: Optional[StatusProgress] = None,
413
415
  tracked_solutions: Optional[Set[str]] = None,
414
416
  verification: VerificationLevel = VerificationLevel.NONE,
415
417
  generator: Optional[GeneratorCall] = None,
@@ -423,7 +425,7 @@ def _run_interactive_solutions(
423
425
 
424
426
  checker_digest = checkers.compile_checker() if check else None
425
427
  compiled_solutions = compile_solutions(
426
- tracked_solutions=tracked_solutions, sanitized=sanitized
428
+ progress=progress, tracked_solutions=tracked_solutions, sanitized=sanitized
427
429
  )
428
430
 
429
431
  main_solution_digest = None
@@ -498,6 +500,7 @@ def _run_interactive_solutions(
498
500
 
499
501
 
500
502
  async def run_and_print_interactive_solutions(
503
+ progress: Optional[StatusProgress] = None,
501
504
  tracked_solutions: Optional[Set[str]] = None,
502
505
  verification: VerificationLevel = VerificationLevel.NONE,
503
506
  generator: Optional[GeneratorCall] = None,
@@ -507,6 +510,7 @@ async def run_and_print_interactive_solutions(
507
510
  ):
508
511
  pkg = package.find_problem_package_or_die()
509
512
  items = _run_interactive_solutions(
513
+ progress=progress,
510
514
  tracked_solutions=tracked_solutions,
511
515
  verification=verification,
512
516
  check=check,
@@ -515,6 +519,9 @@ async def run_and_print_interactive_solutions(
515
519
  print=print,
516
520
  )
517
521
 
522
+ if progress:
523
+ progress.stop()
524
+
518
525
  for item in items:
519
526
  sol = pkg.solutions[item.solution_index]
520
527
  _print_solution_header(sol, console.console, is_irun=True)
@@ -540,6 +547,16 @@ async def run_and_print_interactive_solutions(
540
547
  console.console.print()
541
548
 
542
549
 
550
+ def pick_solutions(tracked_solutions: Optional[Set[str]]) -> List[str]:
551
+ pkg = package.find_problem_package_or_die()
552
+ if tracked_solutions is None:
553
+ tracked_solutions = set(str(sol.path) for sol in pkg.solutions)
554
+
555
+ return questionary.checkbox(
556
+ 'Select solutions', choices=list(tracked_solutions)
557
+ ).ask()
558
+
559
+
543
560
  def get_outcome_style_verdict(outcome: Outcome) -> str:
544
561
  if outcome == Outcome.ACCEPTED:
545
562
  return 'green'
@@ -554,21 +571,25 @@ def get_outcome_style_verdict(outcome: Outcome) -> str:
554
571
  return 'magenta'
555
572
 
556
573
 
557
- def get_testcase_markup_verdict(eval: Evaluation) -> str:
574
+ def get_outcome_markup_verdict(outcome: Outcome) -> str:
558
575
  res = '✓'
559
- if eval.result.outcome != Outcome.ACCEPTED:
576
+ if outcome != Outcome.ACCEPTED:
560
577
  res = '✗'
561
- if eval.result.outcome == Outcome.TIME_LIMIT_EXCEEDED:
578
+ if outcome == Outcome.TIME_LIMIT_EXCEEDED:
562
579
  res = '⧖'
563
- if eval.result.outcome == Outcome.RUNTIME_ERROR:
580
+ if outcome == Outcome.RUNTIME_ERROR:
564
581
  res = '✗'
565
- style = get_outcome_style_verdict(eval.result.outcome)
582
+ style = get_outcome_style_verdict(outcome)
566
583
  res = f'[{style}]{res}[/{style}]'
584
+ return res
585
+
586
+
587
+ def get_testcase_markup_verdict(eval: Evaluation) -> str:
567
588
  # if eval.log.stdout_absolute_path:
568
589
  # output_path = eval.log.stdout_absolute_path.resolve()
569
590
  # output_link = f'file://{output_path}'
570
591
  # res = f'[link={output_link}]{res}[/link]'
571
- return res
592
+ return get_outcome_markup_verdict(eval.result.outcome)
572
593
 
573
594
 
574
595
  def _get_evals_time_in_ms(evals: List[Evaluation]) -> int:
@@ -632,6 +653,10 @@ def get_evals_formatted_memory(evals: List[Evaluation]) -> str:
632
653
  return get_formatted_memory(max_memory)
633
654
 
634
655
 
656
+ def get_worst_outcome(evals: List[Evaluation]) -> Outcome:
657
+ return Outcome.worst_outcome(eval.result.outcome for eval in evals)
658
+
659
+
635
660
  def _print_solution_outcome(
636
661
  solution: Solution,
637
662
  evals: List[Evaluation],
@@ -880,7 +905,11 @@ async def _render_detailed_group_table(
880
905
  solution, non_null_evals, verification
881
906
  )
882
907
  formatted_memory = get_evals_formatted_memory(non_null_evals)
883
- summary_row.append(('', '', formatted_time, '/', formatted_memory, ''))
908
+ worst_outcome = get_worst_outcome(non_null_evals)
909
+ verdict = get_outcome_markup_verdict(worst_outcome)
910
+ summary_row.append(
911
+ ('', verdict, formatted_time, '/', formatted_memory, '')
912
+ )
884
913
  padded_rows.append(summary_row)
885
914
 
886
915
  for row in _render_padded_rows(padded_rows):
@@ -1020,12 +1049,13 @@ async def print_run_report(
1020
1049
  )
1021
1050
  console.print()
1022
1051
 
1023
- ok = ok and _print_solution_outcome(
1052
+ cur_ok = _print_solution_outcome(
1024
1053
  solution,
1025
1054
  solution_evals,
1026
1055
  console,
1027
1056
  verification=verification,
1028
1057
  )
1058
+ ok = ok and cur_ok
1029
1059
  console.print()
1030
1060
 
1031
1061
  await _print_timing(console, result.skeleton, structured_evaluations)
@@ -6,7 +6,7 @@ import shutil
6
6
  import subprocess
7
7
  import sys
8
8
  from enum import Enum
9
- from typing import IO, Any, Dict, List, Optional, Tuple, Union
9
+ from typing import IO, Any, Dict, Iterable, List, Optional, Tuple, Union
10
10
 
11
11
  import typer
12
12
  from pydantic import BaseModel
@@ -24,13 +24,20 @@ MAX_STDOUT_LEN = 1024 * 1024 * 128 # 128 MB
24
24
  class Outcome(Enum):
25
25
  ACCEPTED = 'accepted'
26
26
  WRONG_ANSWER = 'wrong-answer'
27
- JUDGE_FAILED = 'judge-failed'
28
- RUNTIME_ERROR = 'runtime-error'
29
- TIME_LIMIT_EXCEEDED = 'time-limit-exceeded'
30
27
  MEMORY_LIMIT_EXCEEDED = 'memory-limit-exceeded'
28
+ TIME_LIMIT_EXCEEDED = 'time-limit-exceeded'
29
+ RUNTIME_ERROR = 'runtime-error'
31
30
  OUTPUT_LIMIT_EXCEEDED = 'output-limit-exceeded'
31
+ JUDGE_FAILED = 'judge-failed'
32
32
  INTERNAL_ERROR = 'internal-error'
33
33
 
34
+ @classmethod
35
+ def worst_outcome(cls, outcomes: Iterable['Outcome']) -> 'Outcome':
36
+ def _outcome_to_int(o: 'Outcome') -> int:
37
+ return cls._member_names_.index(o.name)
38
+
39
+ return max(outcomes, key=_outcome_to_int)
40
+
34
41
 
35
42
  class DigestHolder(BaseModel):
36
43
  value: Optional[str] = None
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes