rbx.cp 0.5.63__tar.gz → 0.5.65__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 (219) hide show
  1. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/PKG-INFO +1 -1
  2. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/pyproject.toml +1 -1
  3. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/cli.py +24 -13
  4. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/contest/build_contest_statements.py +2 -1
  5. rbx_cp-0.5.65/rbx/box/formatting.py +39 -0
  6. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/boca/upload.py +18 -0
  7. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/main.py +4 -3
  8. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/setter_config.py +4 -0
  9. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/solutions.py +48 -15
  10. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/statements/build_statements.py +2 -1
  11. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/testcase_utils.py +6 -1
  12. rbx_cp-0.5.63/rbx/box/formatting.py +0 -10
  13. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/LICENSE +0 -0
  14. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/README.md +0 -0
  15. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/__init__.py +0 -0
  16. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/annotations.py +0 -0
  17. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/autoenum.py +0 -0
  18. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/__init__.py +0 -0
  19. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/builder.py +0 -0
  20. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/cd.py +0 -0
  21. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/checkers.py +0 -0
  22. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/code.py +0 -0
  23. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/compile.py +0 -0
  24. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/conftest.py +0 -0
  25. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/contest/__init__.py +0 -0
  26. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/contest/contest_package.py +0 -0
  27. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/contest/contest_utils.py +0 -0
  28. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/contest/main.py +0 -0
  29. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/contest/schema.py +0 -0
  30. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/contest/statements.py +0 -0
  31. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/creation.py +0 -0
  32. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/deferred.py +0 -0
  33. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/download.py +0 -0
  34. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/dump_schemas.py +0 -0
  35. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/environment.py +0 -0
  36. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/extensions.py +0 -0
  37. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/generators.py +0 -0
  38. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/generators_test.py +0 -0
  39. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/git_utils.py +0 -0
  40. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/header.py +0 -0
  41. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/lazy_importing_main.py +0 -0
  42. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/lazy_importing_test.py +0 -0
  43. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/main.py +0 -0
  44. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/naming.py +0 -0
  45. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/package.py +0 -0
  46. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/boca/extension.py +0 -0
  47. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/boca/packager.py +0 -0
  48. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/contest_main.py +0 -0
  49. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/moj/packager.py +0 -0
  50. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/packager.py +0 -0
  51. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/polygon/packager.py +0 -0
  52. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/polygon/polygon_api.py +0 -0
  53. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/polygon/test.py +0 -0
  54. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/polygon/upload.py +0 -0
  55. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/packaging/polygon/xml_schema.py +0 -0
  56. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/presets/__init__.py +0 -0
  57. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/presets/fetch.py +0 -0
  58. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/presets/lock_schema.py +0 -0
  59. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/presets/schema.py +0 -0
  60. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/retries.py +0 -0
  61. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/sanitizers/warning_stack.py +0 -0
  62. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/schema.py +0 -0
  63. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/solutions_test.py +0 -0
  64. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/state.py +0 -0
  65. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/statements/__init__.py +0 -0
  66. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/statements/builders.py +0 -0
  67. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/statements/joiners.py +0 -0
  68. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/statements/latex.py +0 -0
  69. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/statements/latex_jinja.py +0 -0
  70. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/statements/schema.py +0 -0
  71. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/stresses.py +0 -0
  72. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/stressing/__init__.py +0 -0
  73. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/stressing/finder_parser.py +0 -0
  74. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/stressing/generator_parser.py +0 -0
  75. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/tasks.py +0 -0
  76. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/testcase_extractors.py +0 -0
  77. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/testcases/__init__.py +0 -0
  78. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/testcases/main.py +0 -0
  79. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/__init__.py +0 -0
  80. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/captured_log.py +0 -0
  81. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/css/app.tcss +0 -0
  82. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/main.py +0 -0
  83. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/screens/__init__.py +0 -0
  84. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/screens/build.py +0 -0
  85. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/screens/command.py +0 -0
  86. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/screens/error.py +0 -0
  87. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/screens/run.py +0 -0
  88. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/screens/run_explorer.py +0 -0
  89. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/screens/run_test_explorer.py +0 -0
  90. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/screens/selector.py +0 -0
  91. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/screens/test_explorer.py +0 -0
  92. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/utils/__init__.py +0 -0
  93. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/utils/run_ui.py +0 -0
  94. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/widgets/__init__.py +0 -0
  95. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/widgets/file_log.py +0 -0
  96. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/widgets/interaction_box.py +0 -0
  97. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/widgets/rich_log_box.py +0 -0
  98. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/widgets/test_output_box.py +0 -0
  99. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/ui/widgets/two_sided_test_output_box.py +0 -0
  100. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/unit.py +0 -0
  101. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/validators.py +0 -0
  102. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/box/validators_test.py +0 -0
  103. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/checker.py +0 -0
  104. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/clone.py +0 -0
  105. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/config.py +0 -0
  106. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/conftest.py +0 -0
  107. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/console.py +0 -0
  108. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/create.py +0 -0
  109. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/edit.py +0 -0
  110. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/__init__.py +0 -0
  111. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/caching.py +0 -0
  112. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/conftest.py +0 -0
  113. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/__init__.py +0 -0
  114. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/cacher.py +0 -0
  115. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/digester.py +0 -0
  116. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/sandbox.py +0 -0
  117. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/sandboxes/__init__.py +0 -0
  118. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/sandboxes/isolate.py +0 -0
  119. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/sandboxes/stupid_sandbox.py +0 -0
  120. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/sandboxes/timeit.py +0 -0
  121. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/storage.py +0 -0
  122. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/test.py +0 -0
  123. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/judge/testiso.py +0 -0
  124. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/limits.py +0 -0
  125. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/processing_context.py +0 -0
  126. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/steps.py +0 -0
  127. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/steps_with_caching.py +0 -0
  128. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading/steps_with_caching_run_test.py +0 -0
  129. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/grading_utils.py +0 -0
  130. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/hydration.py +0 -0
  131. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/main.py +0 -0
  132. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/metadata.py +0 -0
  133. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/providers/__init__.py +0 -0
  134. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/providers/codeforces.py +0 -0
  135. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/providers/provider.py +0 -0
  136. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/checkers/boilerplate.cpp +0 -0
  137. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/default_config.json +0 -0
  138. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/default_setter_config.mac.yml +0 -0
  139. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/default_setter_config.yml +0 -0
  140. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/envs/default.rbx.yml +0 -0
  141. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/envs/isolate.rbx.yml +0 -0
  142. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/checker.sh +0 -0
  143. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/compare.sh +0 -0
  144. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/compile/c +0 -0
  145. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/compile/cc +0 -0
  146. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/compile/cpp +0 -0
  147. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/compile/java +0 -0
  148. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/compile/kt +0 -0
  149. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/compile/pas +0 -0
  150. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/compile/py2 +0 -0
  151. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/compile/py3 +0 -0
  152. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/interactive/c +0 -0
  153. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/interactive/cc +0 -0
  154. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/interactive/cpp +0 -0
  155. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/interactive/java +0 -0
  156. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/interactive/kt +0 -0
  157. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/interactive/py2 +0 -0
  158. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/interactive/py3 +0 -0
  159. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/interactor_compile.sh +0 -0
  160. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/run/bkp +0 -0
  161. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/run/c +0 -0
  162. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/run/cc +0 -0
  163. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/run/cpp +0 -0
  164. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/run/java +0 -0
  165. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/run/kt +0 -0
  166. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/run/py2 +0 -0
  167. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/boca/run/py3 +0 -0
  168. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/c/compile.sh +0 -0
  169. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/c/prep.sh +0 -0
  170. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/c/run.sh +0 -0
  171. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/compare.sh +0 -0
  172. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/cpp/compile.sh +0 -0
  173. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/cpp/prep.sh +0 -0
  174. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/cpp/run.sh +0 -0
  175. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/interactor_prep.sh +0 -0
  176. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/interactor_run.sh +0 -0
  177. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/java/compile.sh +0 -0
  178. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/java/prep.sh +0 -0
  179. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/java/run.sh +0 -0
  180. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/py2/compile.sh +0 -0
  181. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/py2/prep.sh +0 -0
  182. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/py2/run.sh +0 -0
  183. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/py3/compile.sh +0 -0
  184. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/py3/prep.sh +0 -0
  185. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/packagers/moj/scripts/py3/run.sh +0 -0
  186. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/contest/contest.rbx.yml +0 -0
  187. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -0
  188. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/contest/statement/olymp.sty +0 -0
  189. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/contest/statement/template.rbx.tex +0 -0
  190. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/preset.rbx.yml +0 -0
  191. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/.gitignore +0 -0
  192. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/gen.cpp +0 -0
  193. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/problem.rbx.yml +0 -0
  194. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/random.py +0 -0
  195. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/random.txt +0 -0
  196. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/sols/main.cpp +0 -0
  197. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/sols/slow.cpp +0 -0
  198. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/sols/wa.cpp +0 -0
  199. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/statement/olymp.sty +0 -0
  200. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/statement/projecao.png +0 -0
  201. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/statement/statement.rbx.tex +0 -0
  202. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/statement/template.rbx.tex +0 -0
  203. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/tests/samples/000.in +0 -0
  204. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/tests/samples/001.in +0 -0
  205. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/validator.cpp +0 -0
  206. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/presets/default/problem/wcmp.cpp +0 -0
  207. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/templates/rbx.h +0 -0
  208. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/resources/templates/template.cpp +0 -0
  209. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/run.py +0 -0
  210. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/schema.py +0 -0
  211. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/submit.py +0 -0
  212. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/submitors/__init__.py +0 -0
  213. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/submitors/codeforces.py +0 -0
  214. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/submitors/submitor.py +0 -0
  215. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/test.py +0 -0
  216. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/testcase.py +0 -0
  217. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/testcase_rendering.py +0 -0
  218. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/testing_utils.py +0 -0
  219. {rbx_cp-0.5.63 → rbx_cp-0.5.65}/rbx/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rbx.cp
3
- Version: 0.5.63
3
+ Version: 0.5.65
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.63"
3
+ version = "0.5.65"
4
4
  description = ""
5
5
  packages = [
6
6
  {include = "rbx"}
@@ -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)
@@ -10,6 +10,7 @@ from rbx import console, testing_utils
10
10
  from rbx.box import cd, package
11
11
  from rbx.box.contest.contest_package import get_problems
12
12
  from rbx.box.contest.schema import Contest, ContestProblem, ContestStatement
13
+ from rbx.box.formatting import href
13
14
  from rbx.box.schema import Package, Testcase
14
15
  from rbx.box.statements import build_statements
15
16
  from rbx.box.statements.build_statements import (
@@ -344,6 +345,6 @@ def build_statement(
344
345
  console.console.print(
345
346
  f'Statement built successfully for language '
346
347
  f'[item]{statement.language}[/item] at '
347
- f'[item]{statement_path.resolve()}[/item]'
348
+ f'{href(statement_path)}'
348
349
  )
349
350
  return statement_path
@@ -0,0 +1,39 @@
1
+ import os
2
+ import pathlib
3
+ from typing import Optional
4
+
5
+ from rbx.box import setter_config
6
+
7
+
8
+ def href(url: os.PathLike[str], text: Optional[str] = None, style: str = 'item') -> str:
9
+ custom_text = False
10
+ if text is None:
11
+ text = str(url)
12
+ else:
13
+ custom_text = True
14
+
15
+ if not custom_text:
16
+ if not setter_config.get_setter_config().hyperlinks:
17
+ return f'[{style}]{text}[/{style}]'
18
+ if os.environ.get('TERM') in ['vscode']:
19
+ return f'[{style}]{text}[/{style}]'
20
+
21
+ if isinstance(url, pathlib.Path):
22
+ url = url.resolve()
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}]'
28
+
29
+
30
+ def get_formatted_memory(memory_in_bytes: int, mib_decimal_places: int = 0) -> str:
31
+ if memory_in_bytes < 1024 * 1024:
32
+ if memory_in_bytes < 1024:
33
+ return f'{memory_in_bytes} B'
34
+ return f'{memory_in_bytes / 1024:.0f} KiB'
35
+ return f'{memory_in_bytes / (1024 * 1024):.{mib_decimal_places}f} MiB'
36
+
37
+
38
+ def get_formatted_time(time_in_ms: int) -> str:
39
+ return f'{time_in_ms} ms'
@@ -1,4 +1,5 @@
1
1
  import datetime
2
+ import functools
2
3
  import hashlib
3
4
  import os
4
5
  import pathlib
@@ -41,6 +42,8 @@ class BocaUploader:
41
42
  self.username = _parse_env_var('BOCA_USERNAME', username)
42
43
  self.password = _parse_env_var('BOCA_PASSWORD', password)
43
44
 
45
+ self.loggedIn = False
46
+
44
47
  self.br = mechanize.Browser()
45
48
  self.br.set_handle_robots(False)
46
49
  self.br.addheaders = [ # type: ignore
@@ -140,6 +143,9 @@ class BocaUploader:
140
143
  return self.log_response_alert(response, error_msg)
141
144
 
142
145
  def login(self):
146
+ if self.loggedIn:
147
+ return
148
+
143
149
  _, html = self.open(
144
150
  f'{self.base_url}', error_msg='Error while opening BOCA login page'
145
151
  )
@@ -157,6 +163,8 @@ class BocaUploader:
157
163
  login_url = f'{self.base_url}?name={self.username}&password={pwd_hash}'
158
164
  self.open(login_url, error_msg='Error while logging in to BOCA')
159
165
 
166
+ self.loggedIn = True
167
+
160
168
  def upload(self, file: pathlib.Path) -> bool:
161
169
  self.open(
162
170
  f'{self.base_url}/admin/problem.php',
@@ -226,6 +234,7 @@ class BocaUploader:
226
234
  console.console.print(
227
235
  f'[warning]Potentially transient error while uploading problem to BOCA. Retrying ({tries}/{RETRIES})...[/warning]'
228
236
  )
237
+ self.loggedIn = False
229
238
  continue
230
239
 
231
240
  ok = True
@@ -245,3 +254,12 @@ class BocaUploader:
245
254
  '[warning]Check [item]https://www.php.net/manual/en/ini.core.php#ini.sect.file-uploads[/item] for more information.[/warning]'
246
255
  )
247
256
  raise typer.Exit(1)
257
+
258
+
259
+ @functools.lru_cache
260
+ def get_boca_uploader(
261
+ base_url: Optional[str] = None,
262
+ username: Optional[str] = None,
263
+ password: Optional[str] = None,
264
+ ) -> BocaUploader:
265
+ return BocaUploader(base_url, username, password)
@@ -7,6 +7,7 @@ import typer
7
7
 
8
8
  from rbx import annotations, console
9
9
  from rbx.box import environment, header, package
10
+ from rbx.box.formatting import href
10
11
  from rbx.box.naming import get_problem_name_with_contest_info
11
12
  from rbx.box.package import get_build_path
12
13
  from rbx.box.packaging.packager import BasePackager, BuiltStatement
@@ -62,7 +63,7 @@ async def run_packager(
62
63
  console.console.print(
63
64
  f'[success]Problem packaged for [item]{packager.name()}[/item]![/success]'
64
65
  )
65
- console.console.print(f'Package was saved at [item]{result_path.resolve()}[/item]')
66
+ console.console.print(f'Package was saved at {href(result_path)}')
66
67
  return result_path
67
68
 
68
69
 
@@ -105,9 +106,9 @@ async def boca(
105
106
  result_path = await run_packager(BocaPackager, verification=verification)
106
107
 
107
108
  if upload:
108
- from rbx.box.packaging.boca.upload import BocaUploader
109
+ from rbx.box.packaging.boca.upload import get_boca_uploader
109
110
 
110
- uploader = BocaUploader()
111
+ uploader = get_boca_uploader()
111
112
  uploader.login_and_upload(result_path)
112
113
 
113
114
 
@@ -71,6 +71,10 @@ class SetterConfig(BaseModel):
71
71
  default={},
72
72
  description='Substitutions to apply to commands before running them.',
73
73
  )
74
+ hyperlinks: bool = Field(
75
+ default=True,
76
+ description='Whether to use hyperlinks in the terminal output.',
77
+ )
74
78
 
75
79
  def substitute_command(self, command: str, sanitized: bool = False) -> str:
76
80
  exe = shlex.split(command)[0]
@@ -26,7 +26,7 @@ from rbx.box.deferred import Deferred
26
26
  from rbx.box.environment import (
27
27
  VerificationLevel,
28
28
  )
29
- from rbx.box.formatting import get_formatted_memory, get_formatted_time
29
+ from rbx.box.formatting import get_formatted_memory, get_formatted_time, href
30
30
  from rbx.box.generators import (
31
31
  GenerationMetadata,
32
32
  expand_generator_call,
@@ -166,7 +166,7 @@ def compile_solutions(
166
166
  ):
167
167
  continue
168
168
  if progress:
169
- progress.update(f'Compiling solution [item]{solution.path}[/item]...')
169
+ progress.update(f'Compiling solution {href(solution.path)}...')
170
170
  try:
171
171
  compiled_solutions[solution.path] = compile_item(
172
172
  solution,
@@ -176,7 +176,7 @@ def compile_solutions(
176
176
  )
177
177
  except:
178
178
  console.console.print(
179
- f'[error]Failed compiling solution [item]{solution.path}[/item][/error]'
179
+ f'[error]Failed compiling solution {href(solution.path)}.[/error]'
180
180
  )
181
181
  raise
182
182
 
@@ -204,7 +204,7 @@ def _run_solution(
204
204
 
205
205
  if progress:
206
206
  progress.update(
207
- f'Running solution [item]{solution.path}[/item] on test [item]{group.name}[/item] / [item]{i}[/item]...'
207
+ f'Running solution {href(solution.path)} on test [item]{group.name}[/item] / [item]{i}[/item]...'
208
208
  )
209
209
 
210
210
  async def run_fn(i=i, testcase=testcase, output_path=output_path):
@@ -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()
@@ -1026,8 +1059,8 @@ def _print_solution_header(
1026
1059
  solution: SolutionSkeleton,
1027
1060
  console: rich.console.Console,
1028
1061
  ):
1029
- console.print(f'[item]{solution.path}[/item]', end=' ')
1030
- console.print(f'({solution.runs_dir})')
1062
+ console.print(f'{href(solution.path)}', end=' ')
1063
+ console.print(f'({href(solution.runs_dir, style="info")})')
1031
1064
 
1032
1065
 
1033
1066
  @dataclasses.dataclass
@@ -1052,14 +1085,14 @@ class TimingSummary:
1052
1085
  def print(self, console: rich.console.Console, tl: Optional[int] = None):
1053
1086
  if self.slowest_good is not None:
1054
1087
  console.print(
1055
- f'Slowest [success]OK[/success] solution: {self.slowest_good.time} ms, [item]{self.slowest_good.solution.path}[/item]'
1088
+ f'Slowest [success]OK[/success] solution: {self.slowest_good.time} ms, {href(self.slowest_good.solution.path)}'
1056
1089
  )
1057
1090
  if self.fastest_slow is not None:
1058
1091
  fastest_slow = self.fastest_slow.time
1059
1092
  if tl is not None and self.fastest_slow.time > tl:
1060
1093
  fastest_slow = f'>{tl}'
1061
1094
  console.print(
1062
- f'Fastest [error]slow[/error] solution: {fastest_slow} ms, [item]{self.fastest_slow.solution.path}[/item]'
1095
+ f'Fastest [error]slow[/error] solution: {fastest_slow} ms, {href(self.fastest_slow.solution.path)}'
1063
1096
  )
1064
1097
 
1065
1098
 
@@ -1184,7 +1217,7 @@ async def _render_detailed_group_table(
1184
1217
  ) -> rich.table.Table:
1185
1218
  table = rich.table.Table()
1186
1219
  for solution in skeleton.solutions:
1187
- table.add_column(f'[item]{solution.path}[/item]', justify='full')
1220
+ table.add_column(f'{href(solution.path)}', justify='full')
1188
1221
 
1189
1222
  padded_rows = []
1190
1223
 
@@ -1424,7 +1457,7 @@ async def estimate_time_limit(
1424
1457
 
1425
1458
  if not timings:
1426
1459
  console.print(
1427
- f'[warning]No timings for solution [item]{solution.path}[/item].[/warning]'
1460
+ f'[warning]No timings for solution {href(solution.path)}.[/warning]'
1428
1461
  )
1429
1462
  continue
1430
1463
 
@@ -8,6 +8,7 @@ import typer
8
8
 
9
9
  from rbx import annotations, console
10
10
  from rbx.box import environment, naming, package
11
+ from rbx.box.formatting import href
11
12
  from rbx.box.schema import Package
12
13
  from rbx.box.statements.builders import (
13
14
  BUILDER_LIST,
@@ -302,7 +303,7 @@ def build_statement(
302
303
  console.console.print(
303
304
  f'Statement built successfully for language '
304
305
  f'[item]{statement.language}[/item] at '
305
- f'[item]{statement_path.resolve()}[/item]'
306
+ f'{href(statement_path)}'
306
307
  )
307
308
  return statement_path
308
309
 
@@ -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,10 +0,0 @@
1
- def get_formatted_memory(memory_in_bytes: int, mib_decimal_places: int = 0) -> str:
2
- if memory_in_bytes < 1024 * 1024:
3
- if memory_in_bytes < 1024:
4
- return f'{memory_in_bytes} B'
5
- return f'{memory_in_bytes / 1024:.0f} KiB'
6
- return f'{memory_in_bytes / (1024 * 1024):.{mib_decimal_places}f} MiB'
7
-
8
-
9
- def get_formatted_time(time_in_ms: int) -> str:
10
- return f'{time_in_ms} ms'
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