rbx.cp 0.13.2__py3-none-any.whl → 0.13.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.
Files changed (54) hide show
  1. rbx/annotations.py +5 -5
  2. rbx/box/checkers.py +24 -13
  3. rbx/box/cli.py +1 -4
  4. rbx/box/contest/build_contest_statements.py +16 -3
  5. rbx/box/contest/schema.py +1 -2
  6. rbx/box/fields.py +25 -1
  7. rbx/box/generators.py +5 -2
  8. rbx/box/global_package.py +5 -1
  9. rbx/box/header.py +19 -11
  10. rbx/box/package.py +3 -1
  11. rbx/box/presets/__init__.py +2 -2
  12. rbx/box/schema.py +4 -25
  13. rbx/box/statements/build_statements.py +5 -1
  14. rbx/box/statements/builders.py +7 -7
  15. rbx/box/statements/schema.py +11 -2
  16. rbx/box/testcase_utils.py +2 -0
  17. rbx/box/testing/__init__.py +0 -0
  18. rbx/box/testing/testing_package.py +241 -0
  19. rbx/box/testing/testing_preset.py +36 -0
  20. rbx/box/testing/testing_shared.py +81 -0
  21. rbx/box/tooling/main.py +2 -1
  22. rbx/box/validators.py +2 -1
  23. rbx/grading/caching.py +3 -2
  24. rbx/resources/presets/default/shared/contest_template.rbx.tex +1 -1
  25. rbx/resources/presets/default/shared/problem_template.rbx.tex +5 -1
  26. rbx/testing_utils.py +1 -1
  27. rbx/utils.py +8 -0
  28. {rbx_cp-0.13.2.dist-info → rbx_cp-0.13.4.dist-info}/METADATA +2 -1
  29. {rbx_cp-0.13.2.dist-info → rbx_cp-0.13.4.dist-info}/RECORD +32 -50
  30. rbx/box/conftest.py +0 -42
  31. rbx/box/generators_test.py +0 -67
  32. rbx/box/lazy_importing_test.py +0 -25
  33. rbx/box/solutions_test.py +0 -47
  34. rbx/box/validators_test.py +0 -15
  35. rbx/checker.py +0 -128
  36. rbx/clone.py +0 -197
  37. rbx/conftest.py +0 -38
  38. rbx/create.py +0 -37
  39. rbx/edit.py +0 -24
  40. rbx/grading/conftest.py +0 -33
  41. rbx/grading/steps_with_caching_run_test.py +0 -707
  42. rbx/grading_utils.py +0 -148
  43. rbx/hydration.py +0 -101
  44. rbx/main.py +0 -118
  45. rbx/metadata.py +0 -105
  46. rbx/run.py +0 -45
  47. rbx/schema.py +0 -64
  48. rbx/submit.py +0 -61
  49. rbx/test.py +0 -349
  50. rbx/testcase.py +0 -70
  51. rbx/testcase_rendering.py +0 -79
  52. {rbx_cp-0.13.2.dist-info → rbx_cp-0.13.4.dist-info}/LICENSE +0 -0
  53. {rbx_cp-0.13.2.dist-info → rbx_cp-0.13.4.dist-info}/WHEEL +0 -0
  54. {rbx_cp-0.13.2.dist-info → rbx_cp-0.13.4.dist-info}/entry_points.txt +0 -0
rbx/box/conftest.py DELETED
@@ -1,42 +0,0 @@
1
- import os
2
- import pathlib
3
- import shutil
4
- from collections.abc import Iterator
5
-
6
- import pytest
7
-
8
- from rbx import testing_utils
9
- from rbx.box import package
10
-
11
-
12
- @pytest.fixture
13
- def pkg_cleandir(cleandir: pathlib.Path) -> Iterator[pathlib.Path]:
14
- old_temp_dir = package.TEMP_DIR
15
- package.TEMP_DIR = cleandir
16
-
17
- pkgdir = cleandir / 'pkg'
18
- pkgdir.mkdir(exist_ok=True, parents=True)
19
- lwd = pathlib.Path.cwd()
20
- os.chdir(str(pkgdir))
21
- try:
22
- yield pkgdir.absolute()
23
- finally:
24
- os.chdir(str(lwd))
25
- package.TEMP_DIR = old_temp_dir
26
-
27
-
28
- @pytest.fixture
29
- def pkg_from_testdata(
30
- request, testdata_path: pathlib.Path, pkg_cleandir: pathlib.Path
31
- ) -> Iterator[pathlib.Path]:
32
- marker = request.node.get_closest_marker('test_pkg')
33
- if marker is None:
34
- raise ValueError('test_pkg marker not found')
35
- testdata = testdata_path / marker.args[0]
36
- shutil.copytree(str(testdata), str(pkg_cleandir), dirs_exist_ok=True)
37
- yield pkg_cleandir
38
-
39
-
40
- @pytest.fixture(autouse=True)
41
- def clear_cache():
42
- testing_utils.clear_all_functools_cache()
@@ -1,67 +0,0 @@
1
- import pathlib
2
-
3
- import pytest
4
-
5
- from rbx.box import package
6
- from rbx.box.generators import (
7
- generate_outputs_for_testcases,
8
- generate_testcases,
9
- )
10
- from rbx.box.testcase_extractors import extract_generation_testcases_from_groups
11
- from rbx.testing_utils import print_directory_tree
12
-
13
-
14
- @pytest.mark.test_pkg('box1')
15
- async def test_generator_works(pkg_from_testdata: pathlib.Path):
16
- await generate_testcases()
17
- entries = [
18
- entry.group_entry for entry in await extract_generation_testcases_from_groups()
19
- ]
20
- await generate_outputs_for_testcases(entries)
21
-
22
- # Debug when fail.
23
- print_directory_tree(pkg_from_testdata)
24
-
25
- assert (
26
- package.get_build_testgroup_path('gen1') / '0-000.in'
27
- ).read_text() == '777\n'
28
- assert (
29
- package.get_build_testgroup_path('gen1') / '1-gen-000.in'
30
- ).read_text() == '123\n'
31
- assert (
32
- package.get_build_testgroup_path('gen1') / '1-gen-001.in'
33
- ).read_text() == '424242\n'
34
- assert (
35
- package.get_build_testgroup_path('gen1') / '2-genScript-000.in'
36
- ).read_text() == '25\n'
37
-
38
-
39
- @pytest.mark.test_pkg('box1')
40
- async def test_generator_cache_works(
41
- pkg_from_testdata: pathlib.Path,
42
- ):
43
- # Run the first time.
44
- await generate_testcases()
45
- assert (
46
- package.get_build_testgroup_path('gen1') / '1-gen-000.in'
47
- ).read_text() == '123\n'
48
- assert (
49
- package.get_build_testgroup_path('gen1') / '1-gen-001.in'
50
- ).read_text() == '424242\n'
51
-
52
- # Change the generator `gen1`, but keep `gen2` as is.
53
- gen_path = pkg_from_testdata / 'gen1.cpp'
54
- gen_path.write_text(gen_path.read_text().replace('123', '4567'))
55
-
56
- # Run the second time.
57
- await generate_testcases()
58
-
59
- # Debug when fail.
60
- print_directory_tree(pkg_from_testdata)
61
-
62
- assert (
63
- package.get_build_testgroup_path('gen1') / '1-gen-000.in'
64
- ).read_text() == '4567\n'
65
- assert (
66
- package.get_build_testgroup_path('gen1') / '1-gen-001.in'
67
- ).read_text() == '424242\n'
@@ -1,25 +0,0 @@
1
- import subprocess
2
- import sys
3
- from pathlib import Path
4
-
5
- LAZY_MODULES = {
6
- 'gitpython',
7
- 'questionary',
8
- 'fastapi',
9
- 'requests',
10
- 'pydantic_xml',
11
- 'rbx.box.packaging.polygon.packager',
12
- 'rbx.box.stresses',
13
- }
14
-
15
-
16
- def test_rich_not_imported_unnecessary():
17
- file_path = Path(__file__).parent / 'lazy_importing_main.py'
18
- result = subprocess.run(
19
- [sys.executable, '-m', 'coverage', 'run', str(file_path)],
20
- capture_output=True,
21
- encoding='utf-8',
22
- )
23
- modules = result.stdout.splitlines()
24
- modules = [module for module in modules if module in LAZY_MODULES]
25
- assert not modules
rbx/box/solutions_test.py DELETED
@@ -1,47 +0,0 @@
1
- import pathlib
2
-
3
- import pytest
4
-
5
- from rbx.box.environment import VerificationLevel
6
- from rbx.box.generators import (
7
- generate_outputs_for_testcases,
8
- generate_testcases,
9
- )
10
- from rbx.box.solutions import (
11
- convert_list_of_solution_evaluations_to_dict,
12
- run_solutions,
13
- )
14
- from rbx.box.testcase_extractors import extract_generation_testcases_from_groups
15
- from rbx.grading.steps import Outcome
16
-
17
-
18
- @pytest.mark.test_pkg('box1')
19
- async def test_solutions(pkg_from_testdata: pathlib.Path):
20
- await generate_testcases()
21
- entries = [
22
- entry.group_entry for entry in await extract_generation_testcases_from_groups()
23
- ]
24
- await generate_outputs_for_testcases(entries)
25
-
26
- result = run_solutions(verification=VerificationLevel.FULL)
27
- res = await convert_list_of_solution_evaluations_to_dict(
28
- result.skeleton, result.items
29
- )
30
-
31
- # First solution should pass all tests.
32
- assert all(chk.result.outcome == Outcome.ACCEPTED for chk in res[0]['gen1'])
33
- # 25 test should be WA for the second solution.
34
- assert res[1]['gen1'][3].result.outcome == Outcome.WRONG_ANSWER
35
- # Runtime error for third solution.
36
- assert all(chk.result.outcome == Outcome.RUNTIME_ERROR for chk in res[2]['gen1'])
37
- # 1e9 test should be TLE for the fourth solution (soft TLE)
38
- assert res[3]['gen1'][4].result.outcome == Outcome.TIME_LIMIT_EXCEEDED
39
- # no TLE outcome should be WA (soft TLE)
40
- assert res[4]['gen1'][4].result.no_tle_outcome == Outcome.WRONG_ANSWER
41
- # hard TLE
42
- assert res[5]['gen1'][4].result.outcome == Outcome.TIME_LIMIT_EXCEEDED
43
- assert res[5]['gen1'][4].result.no_tle_outcome is None
44
- # OLE
45
- assert all(
46
- chk.result.outcome == Outcome.OUTPUT_LIMIT_EXCEEDED for chk in res[6]['gen1']
47
- )
@@ -1,15 +0,0 @@
1
- import pathlib
2
-
3
- import pytest
4
-
5
- from rbx.box.generators import generate_testcases
6
- from rbx.box.validators import validate_testcases
7
-
8
-
9
- @pytest.mark.test_pkg('box1')
10
- async def test_validators(pkg_from_testdata: pathlib.Path):
11
- await generate_testcases()
12
- validation_infos = await validate_testcases()
13
-
14
- for info in validation_infos:
15
- assert info.ok
rbx/checker.py DELETED
@@ -1,128 +0,0 @@
1
- import pathlib
2
- from typing import Optional
3
-
4
- import typer
5
- from typing_extensions import Annotated
6
-
7
- from rbx import annotations, config, metadata, utils
8
- from rbx.config import get_builtin_checker, get_testlib
9
- from rbx.console import console
10
-
11
- app = typer.Typer(no_args_is_help=True)
12
-
13
-
14
- @app.command('add, a')
15
- def add(
16
- problem: annotations.Problem,
17
- template: Annotated[
18
- Optional[str],
19
- typer.Option(
20
- '--template', '-t', help='Checker that should be used as template.'
21
- ),
22
- ] = None,
23
- ):
24
- """
25
- Add a new checker for the problem.
26
- """
27
- dumped_problem = metadata.find_problem_by_anything(problem)
28
- if dumped_problem is None:
29
- console.print(f'[error]Problem [item]{problem}[/item] not found.[/error]')
30
- return
31
-
32
- template_path = get_builtin_checker(template or 'boilerplate.cpp')
33
-
34
- if not template_path.is_file():
35
- console.print(f'[error]Template file {template} not found.[/error]')
36
- return
37
-
38
- testlib_path = get_testlib()
39
- if not testlib_path.is_file():
40
- console.print('[error]Testlib file not found.[/error]')
41
- return
42
-
43
- checker_name = f'{dumped_problem.code}.checker.cpp'
44
- checker_path = pathlib.Path() / checker_name
45
-
46
- # Create both files.
47
- checker_path.write_text(template_path.read_text())
48
- (checker_path.parent / 'testlib.h').write_text(testlib_path.read_text())
49
-
50
- # Set checker.
51
- problem_to_dump = dumped_problem.model_copy()
52
- problem_to_dump.checker = checker_name
53
- problem_path = metadata.find_problem_path_by_code(dumped_problem.code)
54
- if not problem_path:
55
- raise typer.Exit(1)
56
- problem_path.write_text(utils.model_json(problem_to_dump))
57
- console.print(
58
- f'Checker [item]{checker_name}[/item] added to problem [item]{dumped_problem.pretty_name()}[/item].'
59
- )
60
-
61
-
62
- @app.command('set, s')
63
- def set(problem: annotations.Problem, checker: annotations.Checker):
64
- """
65
- Set a checker for the problem.
66
- """
67
- dumped_problem = metadata.find_problem_by_anything(problem)
68
- if dumped_problem is None:
69
- console.print(f'[error]Problem [item]{problem}[/item] not found.[/error]')
70
- return
71
-
72
- problem_to_dump = dumped_problem.model_copy()
73
- problem_to_dump.checker = checker
74
- problem_path = metadata.find_problem_path_by_code(dumped_problem.code)
75
- if not problem_path:
76
- raise typer.Exit(1)
77
- problem_path.write_text(utils.model_json(problem_to_dump))
78
- console.print(
79
- f'Checker [item]{checker}[/item] will be used for problem [item]{dumped_problem.pretty_name()}[/item].'
80
- )
81
-
82
-
83
- @app.command('unset, u')
84
- def unset(problem: annotations.Problem):
85
- """
86
- Use the default checker for a problem.
87
- """
88
- dumped_problem = metadata.find_problem_by_anything(problem)
89
- if dumped_problem is None:
90
- console.print(f'[error]Problem [item]{problem}[/item] not found.[/error]')
91
- return
92
-
93
- problem_to_dump = dumped_problem.model_copy()
94
- problem_to_dump.checker = None
95
- problem_path = metadata.find_problem_path_by_code(dumped_problem.code)
96
- if not problem_path:
97
- raise typer.Exit(1)
98
- problem_path.write_text(utils.model_json(problem_to_dump))
99
- console.print(
100
- f'Default checker will be used for problem [item]{dumped_problem.pretty_name()}[/item].'
101
- )
102
-
103
-
104
- @app.command('edit, e')
105
- def edit(problem: annotations.Problem):
106
- """
107
- Edit the checker for a problem.
108
- """
109
- dumped_problem = metadata.find_problem_by_anything(problem)
110
- if dumped_problem is None:
111
- console.print(f'[error]Problem [item]{problem}[/item] not found.[/error]')
112
- return
113
-
114
- checker = dumped_problem.checker
115
- if checker is None:
116
- console.print(
117
- f'[error]No checker set for problem [item]{dumped_problem.pretty_name()}[/item].[/error]'
118
- )
119
- return
120
-
121
- checker_path = pathlib.Path() / checker
122
- if not checker_path.is_file():
123
- console.print(
124
- f'[error]Checker [item]{checker}[/item] not found in the problems folder. You cannot edit a builtin checker.[/error]'
125
- )
126
- return
127
-
128
- config.open_editor(checker_path)
rbx/clone.py DELETED
@@ -1,197 +0,0 @@
1
- import logging
2
- import pathlib
3
- import threading
4
- import time
5
- from typing import List, Optional
6
-
7
- import fastapi
8
- import jinja2
9
- import rich
10
- import rich.prompt
11
- import rich.status
12
- import uvicorn
13
-
14
- from rbx import hydration, metadata, providers, utils
15
- from rbx.config import Language, get_config
16
- from rbx.console import console
17
- from rbx.schema import DumpedProblem, Problem
18
-
19
-
20
- def clear_loggers():
21
- for logger_name in [
22
- 'uvicorn',
23
- 'uvicorn.access',
24
- 'uvicorn.asgi',
25
- ]:
26
- logging.getLogger(logger_name).handlers.clear()
27
- logging.getLogger(logger_name).propagate = False
28
-
29
-
30
- def create_problem_structure(
31
- root: pathlib.Path,
32
- problem: Problem,
33
- lang: Language,
34
- status: Optional[rich.status.Status],
35
- should_simplify: bool = False,
36
- verbose: bool = False,
37
- ) -> Optional[DumpedProblem]:
38
- # Create directory structure.
39
- root.parent.mkdir(parents=True, exist_ok=True)
40
-
41
- problem_to_dump = DumpedProblem.from_problem(
42
- problem,
43
- code=providers.get_code(problem, simplify=should_simplify),
44
- aliases=providers.get_aliases(problem),
45
- )
46
-
47
- if verbose:
48
- console.print(
49
- f'Creating problem structure for [item]{problem_to_dump.pretty_name()}[/item]...'
50
- )
51
-
52
- code_path = root / lang.get_file(problem_to_dump.code)
53
- json_path = root / f'{problem_to_dump.code}.rbx.json'
54
-
55
- existing_problem = metadata.find_problem_by_code(problem_to_dump.code, root)
56
- if existing_problem:
57
- console.print(
58
- f'[error]Problem with identifier [item]{problem_to_dump.code}[/item] already exists in this folder.[/error]'
59
- )
60
- if not utils.confirm_on_status(
61
- status, 'Do you want to overwrite it?', default=False
62
- ):
63
- console.print(
64
- f'Skipping problem [item]{problem_to_dump.pretty_name()}[/item].'
65
- )
66
- return None
67
-
68
- json_path.write_text(utils.model_json(problem_to_dump))
69
- code = jinja2.Template(lang.get_template()).render(**problem_to_dump.get_vars())
70
- code_path.write_text(code)
71
-
72
- if verbose:
73
- console.print(
74
- f'Problem structure for [item]{problem_to_dump.pretty_name()}[/item] created successfully.'
75
- )
76
- return problem_to_dump
77
-
78
-
79
- def process_problems(
80
- problems: List[Problem], lang: Language, status: rich.status.Status
81
- ):
82
- console.print(
83
- f'Creating problem structure for [item]{len(problems)}[/item] problems...'
84
- )
85
-
86
- should_simplify = False
87
- if providers.should_simplify_contest_problems(problems):
88
- console.print('Detected the parsed problems are from a contest.')
89
- if utils.confirm_on_status(
90
- status,
91
- 'Do you want to identify these problems by their letters?',
92
- default=True,
93
- ):
94
- should_simplify = True
95
-
96
- root = pathlib.Path()
97
- dumped_problems = []
98
- for problem in problems:
99
- dumped_problem = create_problem_structure(
100
- root, problem, lang, status, should_simplify=should_simplify
101
- )
102
- if dumped_problem:
103
- dumped_problems.append(dumped_problem)
104
- console.print(f'Hydrating [item]{len(dumped_problems)}[/item] problems...')
105
- for problem in dumped_problems:
106
- hydration.hydrate_problem(root, problem)
107
-
108
-
109
- def main(lang: Optional[str] = None):
110
- if get_config().get_language(lang) is None:
111
- console.print(
112
- f'[error]Language {lang or get_config().defaultLanguage} not found in config. Please check your configuration.[/error]'
113
- )
114
- return
115
-
116
- app = fastapi.FastAPI()
117
-
118
- async def shutdown():
119
- server.should_exit = True
120
-
121
- batch_to_left_lock = threading.Lock()
122
- batch_to_left = {}
123
- ignored = set()
124
- saved_status = None
125
- problems_to_process = []
126
-
127
- def process_batch_item(problem: Problem):
128
- batch_to_left_lock.acquire()
129
- if problem.batch.id in ignored:
130
- batch_to_left_lock.release()
131
- return True
132
- if problem.batch.id not in batch_to_left:
133
- if len(batch_to_left) > 0:
134
- console.print(
135
- f'[error]Ignoring extra batch [item]{problem.batch.id}[/item] since other batch is being parsed.[/error]'
136
- )
137
- ignored.add(problem.batch.id)
138
- batch_to_left_lock.release()
139
- return True
140
- if problem.batch.size > 1 and saved_status:
141
- saved_status.update(
142
- f'[rbx]rbx[/rbx] is parsing problems from group [item]{problem.group}[/item]'
143
- )
144
- elif saved_status:
145
- saved_status.update('[rbx]rbx[/rbx] is parsing problems...')
146
- console.print(
147
- f'Started parsing batch [item]{problem.batch.id}[/item] with size [item]{problem.batch.size}[/item].'
148
- )
149
- batch_to_left[problem.batch.id] = problem.batch.size
150
- console.print(f'Parsing problem [item]{problem.name}[/item]...')
151
- problems_to_process.append(problem)
152
- finished = False
153
- if batch_to_left[problem.batch.id] == 1:
154
- finished = True
155
- if problem.batch.size > 1:
156
- console.print(
157
- f'[status][rbx]rbx[/rbx] parsed all problems from group [item]{problem.group}[/item].[/status]'
158
- )
159
- else:
160
- console.print(
161
- f'[status][rbx]rbx[/rbx] parsed problem from [item]{problem.url}[/item][/status]'
162
- )
163
- else:
164
- batch_to_left[problem.batch.id] -= 1
165
- batch_to_left_lock.release()
166
- return not finished
167
-
168
- clock = None
169
-
170
- @app.post('/')
171
- async def parse(problem: Problem, background_tasks: fastapi.BackgroundTasks):
172
- nonlocal clock
173
- if clock is None:
174
- clock = time.monotonic()
175
- if not process_batch_item(problem):
176
- duration = time.monotonic() - clock
177
- console.print(
178
- f'Parsed all problems in [item]{duration:.2f}[/item] seconds.'
179
- )
180
- background_tasks.add_task(shutdown)
181
- return {}
182
-
183
- config = uvicorn.Config(app, port=1327)
184
- server = uvicorn.Server(config=config)
185
- clear_loggers()
186
- with console.status('Waiting for Competitive Companion request...') as status:
187
- saved_status = status
188
- server.run()
189
-
190
- with console.status('Processing parsed problems...') as status:
191
- language = get_config().get_language(lang)
192
- if not language:
193
- console.print(
194
- f'[error]Language {lang or get_config().defaultLanguage} not found in config. Please check your configuration.[/error]'
195
- )
196
- return
197
- process_problems(problems_to_process, language, status)
rbx/conftest.py DELETED
@@ -1,38 +0,0 @@
1
- import os
2
- import pathlib
3
- import shutil
4
- import tempfile
5
- from collections.abc import Iterator
6
-
7
- import pytest
8
-
9
- from rbx.testing_utils import get_testdata_path
10
-
11
-
12
- @pytest.fixture
13
- def testdata_path() -> pathlib.Path:
14
- return get_testdata_path()
15
-
16
-
17
- @pytest.fixture
18
- def cleandir() -> Iterator[pathlib.Path]:
19
- with tempfile.TemporaryDirectory() as newpath:
20
- abspath = pathlib.Path(newpath).absolute()
21
- old_cwd = pathlib.Path.cwd()
22
- os.chdir(newpath)
23
- try:
24
- yield abspath
25
- finally:
26
- os.chdir(str(old_cwd))
27
-
28
-
29
- @pytest.fixture
30
- def cleandir_with_testdata(
31
- request, testdata_path: pathlib.Path, cleandir: pathlib.Path
32
- ) -> Iterator[pathlib.Path]:
33
- marker = request.node.get_closest_marker('test_pkg')
34
- if marker is None:
35
- raise ValueError('test_pkg marker not found')
36
- testdata = testdata_path / marker.args[0]
37
- shutil.copytree(str(testdata), str(cleandir), dirs_exist_ok=True)
38
- yield cleandir
rbx/create.py DELETED
@@ -1,37 +0,0 @@
1
- import pathlib
2
-
3
- from rbx import annotations
4
- from rbx.clone import create_problem_structure
5
- from rbx.config import get_config
6
- from rbx.console import console
7
- from rbx.schema import Batch, Problem
8
-
9
-
10
- def main(
11
- name: str,
12
- lang: annotations.Language,
13
- timelimit: annotations.Timelimit = 1000,
14
- memorylimit: annotations.Memorylimit = 256,
15
- multitest: annotations.Multitest = False,
16
- ):
17
- language = get_config().get_language(lang)
18
- if language is None:
19
- console.print(
20
- f'[error]Language {lang or get_config().defaultLanguage} not found in config. Please check your configuration.[/error]'
21
- )
22
- return
23
-
24
- problem = Problem(
25
- name=name,
26
- timeLimit=timelimit,
27
- memoryLimit=memorylimit,
28
- testType='multiNumber' if multitest else 'single',
29
- batch=Batch.create(),
30
- )
31
- create_problem_structure(
32
- pathlib.Path(),
33
- problem,
34
- language,
35
- status=None,
36
- verbose=True,
37
- )
rbx/edit.py DELETED
@@ -1,24 +0,0 @@
1
- import pathlib
2
- from typing import Optional
3
-
4
- from rbx import annotations, console, metadata
5
- from rbx.config import get_config, open_editor
6
-
7
-
8
- def main(problem: str, language: Optional[annotations.LanguageWithDefault] = None):
9
- lang = get_config().get_language(language)
10
- if lang is None:
11
- console.console.print(
12
- f'[error]Language {language or get_config().defaultLanguage} not found in config. Please check your configuration.[/error]'
13
- )
14
- return
15
-
16
- dumped_problem = metadata.find_problem_by_anything(problem)
17
- if not dumped_problem:
18
- console.console.print(
19
- f'[error]Problem with identifier {problem} not found.[/error]'
20
- )
21
- return
22
-
23
- filename = lang.get_file(dumped_problem.code)
24
- open_editor(pathlib.Path(filename))
rbx/grading/conftest.py DELETED
@@ -1,33 +0,0 @@
1
- import pathlib
2
- from collections.abc import Iterator
3
-
4
- import pytest
5
-
6
- from rbx.grading.caching import DependencyCache
7
- from rbx.grading.judge.cacher import FileCacher
8
- from rbx.grading.judge.sandbox import SandboxBase
9
- from rbx.grading.judge.sandboxes.stupid_sandbox import StupidSandbox
10
- from rbx.grading.judge.storage import FilesystemStorage, Storage
11
-
12
-
13
- @pytest.fixture
14
- def storage(request, cleandir: pathlib.Path) -> Iterator[Storage]:
15
- storage_path = cleandir / '.box' / '.storage'
16
- yield FilesystemStorage(storage_path)
17
-
18
-
19
- @pytest.fixture
20
- def file_cacher(request, storage: Storage) -> Iterator[FileCacher]:
21
- yield FileCacher(storage)
22
-
23
-
24
- @pytest.fixture
25
- def sandbox(request, file_cacher: FileCacher) -> Iterator[SandboxBase]:
26
- yield StupidSandbox(file_cacher=file_cacher)
27
-
28
-
29
- @pytest.fixture
30
- def dependency_cache(
31
- request, cleandir: pathlib.Path, file_cacher: FileCacher
32
- ) -> Iterator[DependencyCache]:
33
- yield DependencyCache(cleandir / '.box', file_cacher)