rbx.cp 0.8.0__py3-none-any.whl → 0.9.1__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 (55) hide show
  1. rbx/box/cd.py +2 -2
  2. rbx/box/cli.py +11 -2
  3. rbx/box/code.py +2 -2
  4. rbx/box/contest/build_contest_statements.py +2 -2
  5. rbx/box/contest/contest_package.py +1 -1
  6. rbx/box/contest/main.py +29 -2
  7. rbx/box/environment.py +143 -83
  8. rbx/box/formatting.py +2 -1
  9. rbx/box/package.py +5 -5
  10. rbx/box/packaging/__init__.py +0 -0
  11. rbx/box/packaging/boca/__init__.py +0 -0
  12. rbx/box/packaging/polygon/packager.py +3 -3
  13. rbx/box/presets/__init__.py +369 -53
  14. rbx/box/presets/lock_schema.py +42 -2
  15. rbx/box/presets/schema.py +4 -0
  16. rbx/box/remote.py +3 -3
  17. rbx/box/retries.py +3 -2
  18. rbx/box/sanitizers/warning_stack.py +2 -2
  19. rbx/box/setter_config.py +18 -0
  20. rbx/box/solutions.py +24 -18
  21. rbx/box/statements/build_statements.py +6 -6
  22. rbx/box/statements/builders.py +1 -1
  23. rbx/box/stresses.py +2 -2
  24. rbx/box/testcase_utils.py +3 -3
  25. rbx/config.py +7 -0
  26. rbx/grading/caching.py +24 -2
  27. rbx/grading/conftest.py +2 -2
  28. rbx/grading/grading_context.py +25 -0
  29. rbx/grading/judge/sandbox.py +2 -1
  30. rbx/grading/judge/sandboxes/isolate.py +3 -2
  31. rbx/grading/judge/sandboxes/stupid_sandbox.py +3 -2
  32. rbx/grading/judge/storage.py +2 -1
  33. rbx/grading/steps.py +2 -1
  34. rbx/grading/steps_with_caching_run_test.py +281 -5
  35. rbx/resources/default_setter_config.mac.yml +15 -0
  36. rbx/resources/default_setter_config.yml +15 -0
  37. rbx/resources/envs/default.rbx.yml +43 -13
  38. rbx/resources/envs/isolate.rbx.yml +2 -3
  39. rbx/resources/presets/default/contest/.gitignore +5 -1
  40. rbx/resources/presets/default/contest/statement/contest.rbx.tex +0 -1
  41. rbx/resources/presets/default/env.rbx.yml +67 -0
  42. rbx/resources/presets/default/preset.rbx.yml +6 -2
  43. rbx/resources/presets/default/problem/.gitignore +1 -1
  44. rbx/resources/presets/default/{contest/statement/template.rbx.tex → shared/problem_template.rbx.tex} +13 -7
  45. rbx/submitors/codeforces.py +3 -2
  46. rbx/test.py +1 -1
  47. rbx/utils.py +6 -1
  48. {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/METADATA +2 -1
  49. {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/RECORD +54 -52
  50. rbx/resources/presets/default/problem/statement/icpc.sty +0 -322
  51. /rbx/resources/presets/default/{problem/statement/template.rbx.tex → shared/contest_template.rbx.tex} +0 -0
  52. /rbx/resources/presets/default/{contest/statement → shared}/icpc.sty +0 -0
  53. {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/LICENSE +0 -0
  54. {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/WHEEL +0 -0
  55. {rbx_cp-0.8.0.dist-info → rbx_cp-0.9.1.dist-info}/entry_points.txt +0 -0
@@ -2,9 +2,12 @@ import os
2
2
  import pathlib
3
3
  import sys
4
4
 
5
- from rbx.grading import steps_with_caching
5
+ import pytest
6
+
7
+ from rbx.grading import grading_context, steps_with_caching
6
8
  from rbx.grading.caching import DependencyCache
7
9
  from rbx.grading.judge.cacher import FileCacher
10
+ from rbx.grading.judge.digester import digest_cooperatively
8
11
  from rbx.grading.judge.sandbox import SandboxBase, SandboxParams
9
12
  from rbx.grading.steps import (
10
13
  DigestOrSource,
@@ -74,6 +77,124 @@ async def test_run_from_disk(
74
77
  assert not artifacts.logs.cached
75
78
 
76
79
 
80
+ async def test_run_reruns_if_cache_disabled(
81
+ cleandir: pathlib.Path,
82
+ dependency_cache: DependencyCache,
83
+ sandbox: SandboxBase,
84
+ file_cacher: FileCacher,
85
+ ):
86
+ async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
87
+ executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
88
+ artifacts = GradingArtifacts()
89
+ artifacts.inputs.append(
90
+ GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
91
+ )
92
+ artifacts.outputs.append(
93
+ GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
94
+ )
95
+ with grading_context.cache_level(grading_context.CacheLevel.NO_CACHE):
96
+ await steps_with_caching.run(
97
+ f'{sys.executable} executable.py',
98
+ params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
99
+ sandbox=sandbox,
100
+ artifacts=artifacts,
101
+ dependency_cache=dependency_cache,
102
+ )
103
+ return artifacts
104
+
105
+ artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
106
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
107
+ assert artifacts.logs is not None
108
+ assert not artifacts.logs.cached
109
+
110
+ another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
111
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
112
+ assert another_artifacts.logs is not None
113
+ assert not another_artifacts.logs.cached
114
+
115
+
116
+ async def test_run_reruns_if_first_run_cache_disabled(
117
+ cleandir: pathlib.Path,
118
+ dependency_cache: DependencyCache,
119
+ sandbox: SandboxBase,
120
+ file_cacher: FileCacher,
121
+ ):
122
+ async def configure_and_run_with_dest(
123
+ dest: pathlib.Path, cache: bool = True
124
+ ) -> GradingArtifacts:
125
+ executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
126
+ artifacts = GradingArtifacts()
127
+ artifacts.inputs.append(
128
+ GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
129
+ )
130
+ artifacts.outputs.append(
131
+ GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
132
+ )
133
+ with grading_context.cache_level(
134
+ grading_context.CacheLevel.NO_CACHE, when=cache
135
+ ):
136
+ await steps_with_caching.run(
137
+ f'{sys.executable} executable.py',
138
+ params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
139
+ sandbox=sandbox,
140
+ artifacts=artifacts,
141
+ dependency_cache=dependency_cache,
142
+ )
143
+ return artifacts
144
+
145
+ artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'), cache=False)
146
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
147
+ assert artifacts.logs is not None
148
+ assert not artifacts.logs.cached
149
+
150
+ another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
151
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
152
+ assert another_artifacts.logs is not None
153
+ assert not another_artifacts.logs.cached
154
+
155
+
156
+ async def test_run_reruns_if_second_run_cache_disabled(
157
+ cleandir: pathlib.Path,
158
+ dependency_cache: DependencyCache,
159
+ sandbox: SandboxBase,
160
+ file_cacher: FileCacher,
161
+ ):
162
+ async def configure_and_run_with_dest(
163
+ dest: pathlib.Path, cache: bool = True
164
+ ) -> GradingArtifacts:
165
+ executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
166
+ artifacts = GradingArtifacts()
167
+ artifacts.inputs.append(
168
+ GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
169
+ )
170
+ artifacts.outputs.append(
171
+ GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
172
+ )
173
+ with grading_context.cache_level(
174
+ grading_context.CacheLevel.NO_CACHE, when=cache
175
+ ):
176
+ await steps_with_caching.run(
177
+ f'{sys.executable} executable.py',
178
+ params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
179
+ sandbox=sandbox,
180
+ artifacts=artifacts,
181
+ dependency_cache=dependency_cache,
182
+ )
183
+ return artifacts
184
+
185
+ artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
186
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
187
+ assert artifacts.logs is not None
188
+ assert not artifacts.logs.cached
189
+
190
+ another_artifacts = await configure_and_run_with_dest(
191
+ pathlib.Path('out.txt'), cache=False
192
+ )
193
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
194
+ assert another_artifacts.logs is not None
195
+ assert not another_artifacts.logs.cached
196
+
197
+
77
198
  async def test_run_caches_intermediate_digest_if_dest_changes(
78
199
  cleandir: pathlib.Path,
79
200
  dependency_cache: DependencyCache,
@@ -106,12 +227,127 @@ async def test_run_caches_intermediate_digest_if_dest_changes(
106
227
  another_artifacts = await configure_and_run_with_dest(
107
228
  pathlib.Path('another-out.txt')
108
229
  )
230
+ assert (cleandir / 'another-out.txt').read_text().strip() == '5'
231
+ assert another_artifacts.logs is not None
232
+ assert another_artifacts.logs.cached
233
+
234
+
235
+ async def test_run_caches_intermediate_digest_if_dest_changes_and_cache_transient(
236
+ cleandir: pathlib.Path,
237
+ dependency_cache: DependencyCache,
238
+ sandbox: SandboxBase,
239
+ file_cacher: FileCacher,
240
+ ):
241
+ async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
242
+ executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
243
+ artifacts = GradingArtifacts()
244
+ artifacts.inputs.append(
245
+ GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
246
+ )
247
+ artifacts.outputs.append(
248
+ GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
249
+ )
250
+
251
+ with grading_context.cache_level(grading_context.CacheLevel.CACHE_TRANSIENTLY):
252
+ await steps_with_caching.run(
253
+ f'{sys.executable} executable.py',
254
+ params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
255
+ sandbox=sandbox,
256
+ artifacts=artifacts,
257
+ dependency_cache=dependency_cache,
258
+ )
259
+ return artifacts
260
+
261
+ artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
262
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
263
+ assert artifacts.logs is not None
264
+ assert not artifacts.logs.cached
265
+
266
+ another_artifacts = await configure_and_run_with_dest(
267
+ pathlib.Path('another-out.txt')
268
+ )
269
+ assert (cleandir / 'another-out.txt').read_text().strip() == '5'
270
+ assert another_artifacts.logs is not None
271
+ assert another_artifacts.logs.cached
272
+
273
+
274
+ async def test_run_overwrites_changed_file_when_storage_value_is_changed_and_cache_transient(
275
+ cleandir: pathlib.Path,
276
+ dependency_cache: DependencyCache,
277
+ sandbox: SandboxBase,
278
+ file_cacher: FileCacher,
279
+ ):
280
+ async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
281
+ executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
282
+ artifacts = GradingArtifacts()
283
+ artifacts.inputs.append(
284
+ GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
285
+ )
286
+ artifacts.outputs.append(
287
+ GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
288
+ )
289
+ with grading_context.cache_level(grading_context.CacheLevel.CACHE_TRANSIENTLY):
290
+ await steps_with_caching.run(
291
+ f'{sys.executable} executable.py',
292
+ params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
293
+ sandbox=sandbox,
294
+ artifacts=artifacts,
295
+ dependency_cache=dependency_cache,
296
+ )
297
+ return artifacts
298
+
299
+ artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
300
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
301
+ assert artifacts.logs is not None
302
+ assert not artifacts.logs.cached
303
+
304
+ pathlib.Path('out.txt').write_text('42')
305
+
306
+ another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
307
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
308
+ assert another_artifacts.logs is not None
309
+ assert another_artifacts.logs.cached
310
+
311
+
312
+ async def test_run_overwrites_changed_file_when_file_deleted_and_cache_transient(
313
+ cleandir: pathlib.Path,
314
+ dependency_cache: DependencyCache,
315
+ sandbox: SandboxBase,
316
+ file_cacher: FileCacher,
317
+ ):
318
+ async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
319
+ executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
320
+ artifacts = GradingArtifacts()
321
+ artifacts.inputs.append(
322
+ GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
323
+ )
324
+ artifacts.outputs.append(
325
+ GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
326
+ )
327
+ with grading_context.cache_level(grading_context.CacheLevel.CACHE_TRANSIENTLY):
328
+ await steps_with_caching.run(
329
+ f'{sys.executable} executable.py',
330
+ params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
331
+ sandbox=sandbox,
332
+ artifacts=artifacts,
333
+ dependency_cache=dependency_cache,
334
+ )
335
+ return artifacts
336
+
337
+ artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
338
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
339
+ assert artifacts.logs is not None
340
+ assert not artifacts.logs.cached
341
+
342
+ pathlib.Path('out.txt').unlink()
343
+
344
+ another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
109
345
  assert (cleandir / 'out.txt').read_text().strip() == '5'
110
346
  assert another_artifacts.logs is not None
111
347
  assert another_artifacts.logs.cached
112
348
 
113
349
 
114
- async def test_run_overwrite_changed_file_with_storage_value(
350
+ async def test_run_fails_when_storage_value_is_changed_and_integrity_check_is_enabled(
115
351
  cleandir: pathlib.Path,
116
352
  dependency_cache: DependencyCache,
117
353
  sandbox: SandboxBase,
@@ -142,13 +378,50 @@ async def test_run_overwrite_changed_file_with_storage_value(
142
378
 
143
379
  pathlib.Path('out.txt').write_text('42')
144
380
 
381
+ with pytest.raises(ValueError) as exc_info:
382
+ await configure_and_run_with_dest(pathlib.Path('out.txt'))
383
+ assert 'rbx clean' in str(exc_info.value)
384
+ assert (cleandir / 'out.txt').read_text().strip() == '42'
385
+
386
+
387
+ async def test_run_evicts_and_recreates_deleted_file_with_storage_value(
388
+ cleandir: pathlib.Path,
389
+ dependency_cache: DependencyCache,
390
+ sandbox: SandboxBase,
391
+ file_cacher: FileCacher,
392
+ ):
393
+ async def configure_and_run_with_dest(dest: pathlib.Path) -> GradingArtifacts:
394
+ executable = DigestOrSource.create(file_cacher.put_file_text('print(5)'))
395
+ artifacts = GradingArtifacts()
396
+ artifacts.inputs.append(
397
+ GradingFileInput(**executable.expand(), dest=pathlib.Path('executable.py'))
398
+ )
399
+ artifacts.outputs.append(
400
+ GradingFileOutput(src=pathlib.Path('box-out.txt'), dest=dest)
401
+ )
402
+ await steps_with_caching.run(
403
+ f'{sys.executable} executable.py',
404
+ params=SandboxParams(stdout_file=pathlib.Path('box-out.txt')),
405
+ sandbox=sandbox,
406
+ artifacts=artifacts,
407
+ dependency_cache=dependency_cache,
408
+ )
409
+ return artifacts
410
+
411
+ artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
412
+ assert (cleandir / 'out.txt').read_text().strip() == '5'
413
+ assert artifacts.logs is not None
414
+ assert not artifacts.logs.cached
415
+
416
+ pathlib.Path('out.txt').unlink()
417
+
145
418
  another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
146
419
  assert (cleandir / 'out.txt').read_text().strip() == '5'
147
420
  assert another_artifacts.logs is not None
148
421
  assert another_artifacts.logs.cached
149
422
 
150
423
 
151
- async def test_run_recreates_deleted_file_with_storage_value(
424
+ async def test_run_evicts_when_storage_value_deleted(
152
425
  cleandir: pathlib.Path,
153
426
  dependency_cache: DependencyCache,
154
427
  sandbox: SandboxBase,
@@ -177,12 +450,15 @@ async def test_run_recreates_deleted_file_with_storage_value(
177
450
  assert artifacts.logs is not None
178
451
  assert not artifacts.logs.cached
179
452
 
180
- pathlib.Path('out.txt').unlink()
453
+ # Delete the file from the cache
454
+ with pathlib.Path('out.txt').open('rb') as f:
455
+ digest = digest_cooperatively(f)
456
+ file_cacher.delete(digest)
181
457
 
182
458
  another_artifacts = await configure_and_run_with_dest(pathlib.Path('out.txt'))
183
459
  assert (cleandir / 'out.txt').read_text().strip() == '5'
184
460
  assert another_artifacts.logs is not None
185
- assert another_artifacts.logs.cached
461
+ assert not another_artifacts.logs.cached
186
462
 
187
463
 
188
464
  async def test_run_overwrite_exec_bit_when_changed(
@@ -14,6 +14,21 @@ command_substitutions:
14
14
  python2: python2
15
15
  python3: python3
16
16
 
17
+ caching:
18
+ # Set the caching level.
19
+ #
20
+ # CACHE_ALL: Cache everything.
21
+ # CACHE_COMPILATION: Cache only compilation.
22
+ # NO_CACHE: Do not cache anything.
23
+ level: CACHE_ALL
24
+
25
+ # Whether to check the integrity of the cached result, and evict it
26
+ # if file has changed since it was cached.
27
+ #
28
+ # Disable for more performance, but be careful to not modify any generated
29
+ # files.
30
+ check_integrity: true
31
+
17
32
  repeats:
18
33
  # Number of times to run the solution.
19
34
  reps: 1
@@ -14,6 +14,21 @@ command_substitutions:
14
14
  python2: python2
15
15
  python3: python3
16
16
 
17
+ caching:
18
+ # Set the caching level.
19
+ #
20
+ # CACHE_ALL: Cache everything.
21
+ # CACHE_COMPILATION: Cache only compilation.
22
+ # NO_CACHE: Do not cache anything.
23
+ level: CACHE_ALL
24
+
25
+ # Whether to check the integrity of the cached result, and evict it
26
+ # if file has changed since it was cached.
27
+ #
28
+ # Disable for more performance, but be careful to not modify any generated
29
+ # files.
30
+ check_integrity: true
31
+
17
32
  repeats:
18
33
  # Number of times to run the solution.
19
34
  reps: 1
@@ -3,35 +3,65 @@ sandbox: "stupid"
3
3
  defaultCompilation:
4
4
  sandbox:
5
5
  maxProcesses: 1000
6
- timeLimit: 10000 # 10 seconds
7
- wallTimeLimit: 10000 # 10 seconds
6
+ timeLimit: 50000 # 50 seconds
7
+ wallTimeLimit: 50000 # 50 seconds
8
8
  memoryLimit: 1024 # 1gb
9
- preserveEnv: true
10
- mirrorDirs:
11
- - "/etc"
12
- - "/usr"
13
9
  defaultExecution:
14
10
  sandbox:
15
11
  # Useful for checkers, validators, etc.
16
- timeLimit: 10000 # 10 seconds
17
- wallTimeLimit: 10000 # 10 seconds
12
+ timeLimit: 50000 # 50 seconds
13
+ wallTimeLimit: 50000 # 50 seconds
18
14
  memoryLimit: 1024 # 1gb
19
15
  languages:
20
16
  - name: "cpp"
21
- readable_name: "C++17"
17
+ readableName: "C++20"
22
18
  extension: "cpp"
23
19
  compilation:
24
- commands:
25
- - "g++ -std=c++17 -O2 -o {executable} {compilable}"
20
+ commands: ["g++ -std=c++20 -O2 -o {executable} {compilable}"]
26
21
  execution:
27
22
  command: "./{executable}"
28
23
  fileMapping:
29
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"
30
37
  - name: "py"
31
- readable_name: "Python3"
38
+ readableName: "Python3"
32
39
  extension: "py"
33
40
  execution:
34
41
  command: "python3 {executable}"
35
42
  fileMapping:
36
43
  executable: "executable.py"
37
-
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
@@ -18,7 +18,7 @@ defaultExecution:
18
18
  memoryLimit: 1024 # 1gb
19
19
  languages:
20
20
  - name: "cpp"
21
- readable_name: "C++17"
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
- readable_name: "Python3"
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
-
@@ -1,2 +1,6 @@
1
- build/
2
1
  .box/
2
+ build/
3
+
4
+ *.o
5
+ *.aux
6
+ *.log
@@ -33,4 +33,3 @@
33
33
 
34
34
  \label{lastpage}
35
35
  \end{document}
36
-
@@ -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: "statement/template.rbx.tex"
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
@@ -3,4 +3,4 @@ build/
3
3
 
4
4
  *.o
5
5
  *.aux
6
- *.log
6
+ *.log
@@ -1,4 +1,14 @@
1
- %- if vars.show_problem is truthy
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*{\strNotes}
52
+ \subsection*{Observações}
43
53
  \VAR{problem.blocks.notes}
44
54
  %- endif
45
55
  }
46
- %- endif
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
@@ -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(file.resolve())
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(file.resolve())
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.resolve()
78
+ return abspath(path)
74
79
 
75
80
 
76
81
  def model_json(model: BaseModel) -> str: