rbx.cp 0.8.0__py3-none-any.whl → 0.9.0__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/cd.py +2 -2
- rbx/box/cli.py +8 -2
- rbx/box/code.py +2 -2
- rbx/box/contest/build_contest_statements.py +2 -2
- rbx/box/contest/contest_package.py +1 -1
- rbx/box/contest/main.py +29 -2
- rbx/box/environment.py +140 -80
- rbx/box/formatting.py +2 -1
- rbx/box/package.py +5 -5
- rbx/box/packaging/__init__.py +0 -0
- rbx/box/packaging/boca/__init__.py +0 -0
- rbx/box/packaging/polygon/packager.py +3 -3
- rbx/box/presets/__init__.py +369 -53
- rbx/box/presets/lock_schema.py +42 -2
- rbx/box/presets/schema.py +4 -0
- rbx/box/remote.py +3 -3
- rbx/box/retries.py +3 -2
- rbx/box/sanitizers/warning_stack.py +2 -2
- rbx/box/solutions.py +24 -18
- rbx/box/statements/build_statements.py +6 -6
- rbx/box/statements/builders.py +1 -1
- rbx/box/stresses.py +2 -2
- rbx/box/testcase_utils.py +3 -3
- rbx/grading/judge/sandbox.py +2 -1
- rbx/grading/judge/sandboxes/isolate.py +3 -2
- rbx/grading/judge/sandboxes/stupid_sandbox.py +3 -2
- rbx/grading/judge/storage.py +2 -1
- rbx/grading/steps.py +2 -1
- rbx/resources/envs/default.rbx.yml +2 -3
- rbx/resources/envs/isolate.rbx.yml +2 -3
- rbx/resources/presets/default/contest/.gitignore +5 -1
- rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -1
- rbx/resources/presets/default/env.rbx.yml +67 -0
- rbx/resources/presets/default/preset.rbx.yml +6 -2
- rbx/resources/presets/default/problem/.gitignore +1 -1
- rbx/resources/presets/default/{contest/statement/template.rbx.tex → shared/problem_template.rbx.tex} +13 -7
- rbx/submitors/codeforces.py +3 -2
- rbx/test.py +1 -1
- rbx/utils.py +6 -1
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.0.dist-info}/METADATA +2 -1
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.0.dist-info}/RECORD +46 -44
- rbx/resources/presets/default/problem/statement/icpc.sty +0 -322
- /rbx/resources/presets/default/{problem/statement/template.rbx.tex → shared/contest_template.rbx.tex} +0 -0
- /rbx/resources/presets/default/{contest/statement → shared}/icpc.sty +0 -0
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.0.dist-info}/LICENSE +0 -0
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.0.dist-info}/WHEEL +0 -0
- {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.0.dist-info}/entry_points.txt +0 -0
rbx/box/remote.py
CHANGED
@@ -5,7 +5,7 @@ from typing import List, Optional, Tuple, Union
|
|
5
5
|
|
6
6
|
import typer
|
7
7
|
|
8
|
-
from rbx import console
|
8
|
+
from rbx import console, utils
|
9
9
|
from rbx.box import cd, package
|
10
10
|
from rbx.box.formatting import href, ref
|
11
11
|
|
@@ -85,7 +85,7 @@ REGISTERED_EXPANDERS: List['Expander'] = [
|
|
85
85
|
|
86
86
|
|
87
87
|
def _relative_to_pkg(path: pathlib.Path) -> pathlib.Path:
|
88
|
-
return
|
88
|
+
return utils.abspath(path).relative_to(pathlib.Path.cwd())
|
89
89
|
|
90
90
|
|
91
91
|
def _try_cacheable_paths(
|
@@ -167,4 +167,4 @@ def expand_file(file: str) -> pathlib.Path:
|
|
167
167
|
|
168
168
|
def is_path_remote(path: pathlib.Path) -> bool:
|
169
169
|
remote_dir = package.get_problem_remote_dir()
|
170
|
-
return
|
170
|
+
return utils.abspath(path).is_relative_to(utils.abspath(remote_dir))
|
rbx/box/retries.py
CHANGED
@@ -5,6 +5,7 @@ import tempfile
|
|
5
5
|
from contextlib import contextmanager
|
6
6
|
from typing import Awaitable, Callable, List, Optional
|
7
7
|
|
8
|
+
from rbx import utils
|
8
9
|
from rbx.box import package
|
9
10
|
from rbx.box.setter_config import RepeatsConfig, get_setter_config
|
10
11
|
from rbx.grading.steps import Evaluation, Outcome
|
@@ -59,8 +60,8 @@ class FileToRecover:
|
|
59
60
|
|
60
61
|
def _move_to_temp_dir(path: pathlib.Path, temp_dir: pathlib.Path) -> FileToRecover:
|
61
62
|
problem_path = package.find_problem()
|
62
|
-
path =
|
63
|
-
temp_dir =
|
63
|
+
path = utils.abspath(path)
|
64
|
+
temp_dir = utils.abspath(temp_dir)
|
64
65
|
relative = path.relative_to(problem_path)
|
65
66
|
|
66
67
|
temp_path = temp_dir / relative
|
@@ -2,7 +2,7 @@ import functools
|
|
2
2
|
import pathlib
|
3
3
|
import shutil
|
4
4
|
|
5
|
-
from rbx import console
|
5
|
+
from rbx import console, utils
|
6
6
|
from rbx.box.schema import CodeItem
|
7
7
|
from rbx.grading.judge.cacher import FileCacher
|
8
8
|
from rbx.grading.steps import GradingFileOutput
|
@@ -60,7 +60,7 @@ def _get_warning_runs_dir(root: pathlib.Path) -> pathlib.Path:
|
|
60
60
|
|
61
61
|
|
62
62
|
def get_warning_stack() -> WarningStack:
|
63
|
-
current_root = pathlib.Path.cwd()
|
63
|
+
current_root = utils.abspath(pathlib.Path.cwd())
|
64
64
|
return _get_warning_stack(current_root)
|
65
65
|
|
66
66
|
|
rbx/box/solutions.py
CHANGED
@@ -54,6 +54,7 @@ from rbx.box.testcase_utils import (
|
|
54
54
|
parse_interaction,
|
55
55
|
print_interaction,
|
56
56
|
)
|
57
|
+
from rbx.grading import grading_context
|
57
58
|
from rbx.grading.limits import Limits
|
58
59
|
from rbx.grading.steps import (
|
59
60
|
Evaluation,
|
@@ -498,7 +499,7 @@ async def _generate_testcase_interactively(
|
|
498
499
|
console.console.print(testcase.inputPath.read_text())
|
499
500
|
else:
|
500
501
|
console.console.print(
|
501
|
-
f'Input was written to [item]{testcase.inputPath
|
502
|
+
f'Input was written to [item]{utils.abspath(testcase.inputPath)}[/item]'
|
502
503
|
)
|
503
504
|
console.console.print()
|
504
505
|
|
@@ -660,23 +661,28 @@ async def run_and_print_interactive_solutions(
|
|
660
661
|
tracked_solutions,
|
661
662
|
verification=verification,
|
662
663
|
)
|
663
|
-
|
664
|
-
|
665
|
-
|
666
|
-
|
667
|
-
|
668
|
-
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
664
|
+
|
665
|
+
should_cache = testcase_entry is not None
|
666
|
+
with grading_context.cache_level(
|
667
|
+
grading_context.CacheLevel.CACHE_COMPILATION, when=not should_cache
|
668
|
+
):
|
669
|
+
testcase = await _generate_testcase_interactively(
|
670
|
+
progress=progress,
|
671
|
+
generator=generator,
|
672
|
+
testcase_entry=testcase_entry,
|
673
|
+
check=check,
|
674
|
+
custom_output=custom_output,
|
675
|
+
sanitized=sanitized,
|
676
|
+
print=print,
|
677
|
+
)
|
678
|
+
items = _run_interactive_solutions(
|
679
|
+
testcase,
|
680
|
+
skeleton=skeleton,
|
681
|
+
progress=progress,
|
682
|
+
verification=verification,
|
683
|
+
check=check,
|
684
|
+
sanitized=sanitized,
|
685
|
+
)
|
680
686
|
|
681
687
|
for item in items:
|
682
688
|
sol = skeleton.find_solution_skeleton(item.solution)
|
@@ -6,7 +6,7 @@ from typing import Annotated, Any, Dict, List, Optional, Tuple
|
|
6
6
|
import syncer
|
7
7
|
import typer
|
8
8
|
|
9
|
-
from rbx import annotations, console
|
9
|
+
from rbx import annotations, console, utils
|
10
10
|
from rbx.box import environment, naming, package
|
11
11
|
from rbx.box.formatting import href
|
12
12
|
from rbx.box.schema import Package, expand_any_vars
|
@@ -46,7 +46,7 @@ def get_environment_languages_for_statement() -> List[StatementCodeLanguage]:
|
|
46
46
|
res.append(
|
47
47
|
StatementCodeLanguage(
|
48
48
|
id=language.name,
|
49
|
-
name=language.
|
49
|
+
name=language.readableName or language.name,
|
50
50
|
command=cmd or '',
|
51
51
|
)
|
52
52
|
)
|
@@ -173,7 +173,7 @@ def get_relative_assets(
|
|
173
173
|
relative_to: pathlib.Path,
|
174
174
|
assets: List[str],
|
175
175
|
) -> List[Tuple[pathlib.Path, pathlib.Path]]:
|
176
|
-
relative_to =
|
176
|
+
relative_to = utils.abspath(relative_to)
|
177
177
|
if not relative_to.is_dir():
|
178
178
|
relative_to = relative_to.parent
|
179
179
|
res = []
|
@@ -192,7 +192,7 @@ def get_relative_assets(
|
|
192
192
|
raise typer.Exit(1)
|
193
193
|
res.extend(get_relative_assets(relative_to, list(map(str, globbed))))
|
194
194
|
continue
|
195
|
-
if not
|
195
|
+
if not utils.abspath(relative_path).is_relative_to(relative_to):
|
196
196
|
console.console.print(
|
197
197
|
f'[error]Asset [item]{asset}[/item] is not relative to your statement.[/error]'
|
198
198
|
)
|
@@ -200,8 +200,8 @@ def get_relative_assets(
|
|
200
200
|
|
201
201
|
res.append(
|
202
202
|
(
|
203
|
-
|
204
|
-
|
203
|
+
utils.abspath(relative_path),
|
204
|
+
utils.abspath(relative_path).relative_to(relative_to),
|
205
205
|
)
|
206
206
|
)
|
207
207
|
|
rbx/box/statements/builders.py
CHANGED
@@ -319,7 +319,7 @@ class rbxTeXBuilder(StatementBuilder):
|
|
319
319
|
params = typing.cast(rbxToTeX, params)
|
320
320
|
if not params.template:
|
321
321
|
return []
|
322
|
-
return [((root / params.template)
|
322
|
+
return [(utils.abspath(root / params.template), params.template)]
|
323
323
|
|
324
324
|
def build(
|
325
325
|
self,
|
rbx/box/stresses.py
CHANGED
@@ -9,7 +9,7 @@ import syncer
|
|
9
9
|
import typer
|
10
10
|
from pydantic import BaseModel
|
11
11
|
|
12
|
-
from rbx import console
|
12
|
+
from rbx import console, utils
|
13
13
|
from rbx.box import checkers, generators, package, tasks, validators
|
14
14
|
from rbx.box.code import SanitizationLevel, compile_item
|
15
15
|
from rbx.box.generators import (
|
@@ -311,7 +311,7 @@ def print_stress_report(report: StressReport):
|
|
311
311
|
console.console.print(f'Found [item]{len(report.findings)}[/item] testcases.')
|
312
312
|
|
313
313
|
findings_dir = package.get_problem_runs_dir() / '.stress' / 'findings'
|
314
|
-
console.console.print(f'Findings: {
|
314
|
+
console.console.print(f'Findings: {utils.abspath(findings_dir)}')
|
315
315
|
console.console.print()
|
316
316
|
|
317
317
|
for i, finding in enumerate(report.findings):
|
rbx/box/testcase_utils.py
CHANGED
@@ -7,7 +7,7 @@ import rich.text
|
|
7
7
|
import typer
|
8
8
|
from pydantic import BaseModel
|
9
9
|
|
10
|
-
from rbx import console
|
10
|
+
from rbx import console, utils
|
11
11
|
from rbx.box import package
|
12
12
|
from rbx.box.package import get_build_testgroup_path, get_build_tests_path
|
13
13
|
from rbx.box.schema import Testcase, TestcaseGroup
|
@@ -141,8 +141,8 @@ def get_samples() -> List[Testcase]:
|
|
141
141
|
tcs = find_built_testcases(package.get_testgroup('samples'))
|
142
142
|
return [
|
143
143
|
Testcase(
|
144
|
-
inputPath=tc.inputPath
|
145
|
-
outputPath=tc.outputPath
|
144
|
+
inputPath=utils.abspath(tc.inputPath),
|
145
|
+
outputPath=utils.abspath(tc.outputPath)
|
146
146
|
if tc.outputPath is not None and tc.outputPath.is_file()
|
147
147
|
else None,
|
148
148
|
)
|
rbx/grading/judge/sandbox.py
CHANGED
@@ -16,6 +16,7 @@ from typing import IO, Any, Dict, List, Optional
|
|
16
16
|
|
17
17
|
import pydantic
|
18
18
|
|
19
|
+
from rbx import utils
|
19
20
|
from rbx.grading.judge import cacher, storage
|
20
21
|
|
21
22
|
logger = logging.getLogger(__name__)
|
@@ -468,7 +469,7 @@ class SandboxBase(abc.ABC):
|
|
468
469
|
if override:
|
469
470
|
real_path.unlink(missing_ok=True)
|
470
471
|
try:
|
471
|
-
real_path.symlink_to(
|
472
|
+
real_path.symlink_to(utils.abspath(from_path))
|
472
473
|
except NotImplementedError:
|
473
474
|
return None
|
474
475
|
return real_path
|
@@ -9,6 +9,7 @@ import subprocess
|
|
9
9
|
import tempfile
|
10
10
|
from typing import IO, Any, Dict, List, Optional
|
11
11
|
|
12
|
+
from rbx import utils
|
12
13
|
from rbx.config import get_app_path
|
13
14
|
from rbx.grading.judge.cacher import FileCacher
|
14
15
|
from rbx.grading.judge.sandbox import (
|
@@ -180,10 +181,10 @@ class IsolateSandbox(SandboxBase):
|
|
180
181
|
"""
|
181
182
|
outer_paths: List[pathlib.Path] = []
|
182
183
|
for inner_path in inner_paths:
|
183
|
-
abs_inner_path = (self._home_dest / inner_path)
|
184
|
+
abs_inner_path = utils.abspath(self._home_dest / inner_path)
|
184
185
|
# If an inner path is absolute (e.g., /fifo0/u0_to_m) then
|
185
186
|
# it may be outside home and we should ignore it.
|
186
|
-
if not abs_inner_path.is_relative_to(self._home_dest
|
187
|
+
if not abs_inner_path.is_relative_to(utils.abspath(self._home_dest)):
|
187
188
|
continue
|
188
189
|
rel_inner_path = abs_inner_path.relative_to(self._home_dest)
|
189
190
|
outer_path = self._home / rel_inner_path
|
@@ -11,6 +11,7 @@ import sys
|
|
11
11
|
import tempfile
|
12
12
|
from typing import Any, Dict, List, Optional
|
13
13
|
|
14
|
+
from rbx import utils
|
14
15
|
from rbx.grading.judge.cacher import FileCacher
|
15
16
|
from rbx.grading.judge.sandbox import (
|
16
17
|
SandboxBase,
|
@@ -303,8 +304,8 @@ class StupidSandbox(SandboxBase):
|
|
303
304
|
real_command = (
|
304
305
|
[
|
305
306
|
sys.executable,
|
306
|
-
str(self.get_timeit_executable()
|
307
|
-
str(self.relative_path(self.get_current_log_name())
|
307
|
+
str(utils.abspath(self.get_timeit_executable())),
|
308
|
+
str(utils.abspath(self.relative_path(self.get_current_log_name()))),
|
308
309
|
]
|
309
310
|
+ self.get_timeit_args()
|
310
311
|
+ command
|
rbx/grading/judge/storage.py
CHANGED
@@ -10,6 +10,7 @@ from typing import IO, AnyStr, Dict, List, Optional, Type, TypeVar
|
|
10
10
|
import lz4.frame
|
11
11
|
from pydantic import BaseModel
|
12
12
|
|
13
|
+
from rbx import utils
|
13
14
|
from rbx.grading import grading_context
|
14
15
|
|
15
16
|
logger = logging.getLogger(__name__)
|
@@ -408,7 +409,7 @@ class FilesystemStorage(Storage):
|
|
408
409
|
def filename_from_symlink(self, link: pathlib.Path) -> Optional[str]:
|
409
410
|
if not link.is_symlink():
|
410
411
|
return None
|
411
|
-
filename = link.readlink()
|
412
|
+
filename = utils.abspath(link.readlink())
|
412
413
|
if not filename.is_file():
|
413
414
|
return None
|
414
415
|
return str(filename.relative_to(self.path))
|
rbx/grading/steps.py
CHANGED
@@ -523,7 +523,8 @@ def _get_system_bits_stdcpp(command: str) -> Optional[GradingFileInput]:
|
|
523
523
|
if not bits_candidate.is_file():
|
524
524
|
continue
|
525
525
|
return GradingFileInput(
|
526
|
-
src=
|
526
|
+
src=utils.abspath(bits_candidate),
|
527
|
+
dest=pathlib.Path('bits/stdc++.h'),
|
527
528
|
)
|
528
529
|
return None
|
529
530
|
|
@@ -18,7 +18,7 @@ defaultExecution:
|
|
18
18
|
memoryLimit: 1024 # 1gb
|
19
19
|
languages:
|
20
20
|
- name: "cpp"
|
21
|
-
|
21
|
+
readableName: "C++17"
|
22
22
|
extension: "cpp"
|
23
23
|
compilation:
|
24
24
|
commands:
|
@@ -28,10 +28,9 @@ languages:
|
|
28
28
|
fileMapping:
|
29
29
|
compilable: "compilable.cpp"
|
30
30
|
- name: "py"
|
31
|
-
|
31
|
+
readableName: "Python3"
|
32
32
|
extension: "py"
|
33
33
|
execution:
|
34
34
|
command: "python3 {executable}"
|
35
35
|
fileMapping:
|
36
36
|
executable: "executable.py"
|
37
|
-
|
@@ -18,7 +18,7 @@ defaultExecution:
|
|
18
18
|
memoryLimit: 1024 # 1gb
|
19
19
|
languages:
|
20
20
|
- name: "cpp"
|
21
|
-
|
21
|
+
readableName: "C++17"
|
22
22
|
extension: "cpp"
|
23
23
|
compilation:
|
24
24
|
commands:
|
@@ -28,10 +28,9 @@ languages:
|
|
28
28
|
fileMapping:
|
29
29
|
compilable: "compilable.cpp"
|
30
30
|
- name: "py"
|
31
|
-
|
31
|
+
readableName: "Python3"
|
32
32
|
extension: "py"
|
33
33
|
execution:
|
34
34
|
command: "/usr/bin/python3 {executable}"
|
35
35
|
fileMapping:
|
36
36
|
executable: "executable.py"
|
37
|
-
|
@@ -0,0 +1,67 @@
|
|
1
|
+
---
|
2
|
+
sandbox: "stupid"
|
3
|
+
defaultCompilation:
|
4
|
+
sandbox:
|
5
|
+
maxProcesses: 1000
|
6
|
+
timeLimit: 50000 # 50 seconds
|
7
|
+
wallTimeLimit: 50000 # 50 seconds
|
8
|
+
memoryLimit: 1024 # 1gb
|
9
|
+
defaultExecution:
|
10
|
+
sandbox:
|
11
|
+
# Useful for checkers, validators, etc.
|
12
|
+
timeLimit: 50000 # 50 seconds
|
13
|
+
wallTimeLimit: 50000 # 50 seconds
|
14
|
+
memoryLimit: 1024 # 1gb
|
15
|
+
languages:
|
16
|
+
- name: "cpp"
|
17
|
+
readableName: "C++20"
|
18
|
+
extension: "cpp"
|
19
|
+
compilation:
|
20
|
+
commands: ["g++ -std=c++20 -O2 -o {executable} {compilable}"]
|
21
|
+
execution:
|
22
|
+
command: "./{executable}"
|
23
|
+
fileMapping:
|
24
|
+
compilable: "compilable.cpp"
|
25
|
+
extensions:
|
26
|
+
boca:
|
27
|
+
bocaLanguage: "cc"
|
28
|
+
- name: "c"
|
29
|
+
readableName: "C"
|
30
|
+
extension: "c"
|
31
|
+
compilation:
|
32
|
+
commands: ["gcc -std=gnu11 -O2 -lm -o {executable} {compilable}"]
|
33
|
+
execution:
|
34
|
+
command: "./{executable}"
|
35
|
+
fileMapping:
|
36
|
+
compilable: "compilable.c"
|
37
|
+
- name: "py"
|
38
|
+
readableName: "Python3"
|
39
|
+
extension: "py"
|
40
|
+
execution:
|
41
|
+
command: "python3 {executable}"
|
42
|
+
fileMapping:
|
43
|
+
executable: "executable.py"
|
44
|
+
extensions:
|
45
|
+
boca:
|
46
|
+
bocaLanguage: "py3"
|
47
|
+
- name: "java"
|
48
|
+
readableName: "Java"
|
49
|
+
extension: "java"
|
50
|
+
compilation:
|
51
|
+
commands:
|
52
|
+
- "javac -Xlint -encoding UTF-8 {compilable}"
|
53
|
+
- "jar cvf {executable} @glob:*.class"
|
54
|
+
execution:
|
55
|
+
command:
|
56
|
+
"java -Xss100m -Xmx{{memory}}m -Xms{{initialMemory}}m -cp {executable}
|
57
|
+
Main"
|
58
|
+
fileMapping:
|
59
|
+
compilable: "Main.java"
|
60
|
+
executable: "Main.jar"
|
61
|
+
extensions:
|
62
|
+
boca:
|
63
|
+
languages: ["c", "cc", "java", "py3"]
|
64
|
+
flags:
|
65
|
+
c: "-O2 -lm -static"
|
66
|
+
cc: "-std=c++20 -O2 -lm -static"
|
67
|
+
preferContestLetter: true
|
@@ -4,11 +4,15 @@ name: "default"
|
|
4
4
|
uri: "rsalesc/rbx/rbx/resources/presets/default"
|
5
5
|
problem: "problem"
|
6
6
|
contest: "contest"
|
7
|
+
env: "env.rbx.yml"
|
7
8
|
tracking:
|
8
9
|
problem:
|
9
|
-
- path: "
|
10
|
+
- path: ".gitignore"
|
10
11
|
- path: "statement/icpc.sty"
|
11
|
-
contest:
|
12
12
|
- path: "statement/template.rbx.tex"
|
13
|
+
contest:
|
14
|
+
- path: ".gitignore"
|
13
15
|
- path: "statement/icpc.sty"
|
16
|
+
- path: "statement/template.rbx.tex"
|
14
17
|
- path: "statement/contest.rbx.tex"
|
18
|
+
symlink: true
|
rbx/resources/presets/default/{contest/statement/template.rbx.tex → shared/problem_template.rbx.tex}
RENAMED
@@ -1,4 +1,14 @@
|
|
1
|
-
|
1
|
+
\documentclass[a4paper,11pt]{article}
|
2
|
+
|
3
|
+
\def\lang{\VAR{lang}}
|
4
|
+
\usepackage{icpc}
|
5
|
+
|
6
|
+
%- if problem.blocks.preamble is defined
|
7
|
+
\VAR{problem.blocks.preamble}
|
8
|
+
%- endif
|
9
|
+
|
10
|
+
\begin{document}
|
11
|
+
|
2
12
|
\includeProblem
|
3
13
|
%- if problem.short_name is defined
|
4
14
|
[\VAR{problem.short_name}]
|
@@ -39,13 +49,9 @@
|
|
39
49
|
%- endif
|
40
50
|
|
41
51
|
%- if problem.blocks.notes is defined
|
42
|
-
\subsection*{
|
52
|
+
\subsection*{Observações}
|
43
53
|
\VAR{problem.blocks.notes}
|
44
54
|
%- endif
|
45
55
|
}
|
46
|
-
|
56
|
+
\end{document}
|
47
57
|
|
48
|
-
%- if problem.blocks.editorial is nonnull and vars.editorial is truthy
|
49
|
-
\subsection*{\strSolution}
|
50
|
-
\VAR{problem.blocks.editorial}
|
51
|
-
%- endif
|
rbx/submitors/codeforces.py
CHANGED
@@ -3,6 +3,7 @@ from typing import Any
|
|
3
3
|
|
4
4
|
import mechanize
|
5
5
|
|
6
|
+
from rbx import utils
|
6
7
|
from rbx.console import console
|
7
8
|
from rbx.schema import Problem
|
8
9
|
from rbx.submitors.submitor import Submitor
|
@@ -55,7 +56,7 @@ class Session:
|
|
55
56
|
)
|
56
57
|
|
57
58
|
def submit_from_contest(self, url: str, file: pathlib.Path, typeid: int):
|
58
|
-
filename = str(
|
59
|
+
filename = str(utils.abspath(file))
|
59
60
|
self.br.open(url)
|
60
61
|
form = self.select_form_by_class('submit-form', self.br.forms())
|
61
62
|
if form is None:
|
@@ -67,7 +68,7 @@ class Session:
|
|
67
68
|
self.br.submit()
|
68
69
|
|
69
70
|
def submit(self, url: str, file: pathlib.Path, typeid: int):
|
70
|
-
filename = str(
|
71
|
+
filename = str(utils.abspath(file))
|
71
72
|
response = self.br.open(url)
|
72
73
|
if response is None:
|
73
74
|
raise Exception('Response was not received')
|
rbx/test.py
CHANGED
@@ -159,7 +159,7 @@ def _pretty_print_outcome_panel(
|
|
159
159
|
) -> Panel:
|
160
160
|
result: steps.CheckerResult = eval.result
|
161
161
|
is_tle = result.outcome.is_slow() or (
|
162
|
-
problem.timeLimit and eval.log.time * 1000 > problem.timeLimit
|
162
|
+
problem.timeLimit and (eval.log.time or 0) * 1000 > problem.timeLimit
|
163
163
|
)
|
164
164
|
|
165
165
|
text = Text()
|
rbx/utils.py
CHANGED
@@ -3,6 +3,7 @@ import fcntl
|
|
3
3
|
import functools
|
4
4
|
import json
|
5
5
|
import os
|
6
|
+
import os.path
|
6
7
|
import pathlib
|
7
8
|
import resource
|
8
9
|
from typing import Any, Optional, Type, TypeVar
|
@@ -34,6 +35,10 @@ def highlight_str(s: str) -> text.Text:
|
|
34
35
|
return txt
|
35
36
|
|
36
37
|
|
38
|
+
def abspath(path: pathlib.Path) -> pathlib.Path:
|
39
|
+
return pathlib.Path(os.path.abspath(path))
|
40
|
+
|
41
|
+
|
37
42
|
def highlight_json_obj(obj: Any) -> text.Text:
|
38
43
|
js = json.dumps(obj)
|
39
44
|
return highlight_str(js)
|
@@ -70,7 +75,7 @@ def dump_schema(model: Type[BaseModel], path: pathlib.Path):
|
|
70
75
|
def ensure_schema(model: Type[BaseModel]) -> pathlib.Path:
|
71
76
|
path = get_app_path() / 'schemas' / f'{model.__name__}.json'
|
72
77
|
dump_schema(model, path)
|
73
|
-
return path
|
78
|
+
return abspath(path)
|
74
79
|
|
75
80
|
|
76
81
|
def model_json(model: BaseModel) -> str:
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.3
|
2
2
|
Name: rbx.cp
|
3
|
-
Version: 0.
|
3
|
+
Version: 0.9.0
|
4
4
|
Summary:
|
5
5
|
Author: Roberto Sales
|
6
6
|
Requires-Python: >=3.9.1,<4.0.0
|
@@ -18,6 +18,7 @@ Requires-Dist: dateparser (>=1.2.1,<2.0.0)
|
|
18
18
|
Requires-Dist: deepmerge (>=2.0,<3.0)
|
19
19
|
Requires-Dist: fastapi (>=0.115.8,<0.116.0)
|
20
20
|
Requires-Dist: filelock (>=3.14.0,<4.0.0)
|
21
|
+
Requires-Dist: gitignore-parser (>=0.1.12,<0.2.0)
|
21
22
|
Requires-Dist: gitpython (>=3.1.43,<4.0.0)
|
22
23
|
Requires-Dist: jinja2 (>=3.1.4,<4.0.0)
|
23
24
|
Requires-Dist: lark (>=1.2.2,<2.0.0)
|