rbx.cp 0.17.5__py3-none-any.whl → 0.17.7__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/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.17.5'
1
+ __version__ = '0.17.7'
@@ -29,9 +29,9 @@ class WarningStack:
29
29
  f = reference.get_file(cacher)
30
30
  if f is None:
31
31
  return
32
- with dest_path.open('wb') as fout:
33
- shutil.copyfileobj(f, fout)
34
- f.close()
32
+ with f:
33
+ with dest_path.open('wb') as fout:
34
+ shutil.copyfileobj(f, fout)
35
35
  self.sanitizer_warnings[code.path] = dest_path
36
36
 
37
37
  def clear(self):
rbx/box/schema.py CHANGED
@@ -106,6 +106,11 @@ class ExpectedOutcome(AutoEnum):
106
106
 
107
107
  Especially useful for environments where TLE and RTE are indistinguishable."""
108
108
 
109
+ JUDGE_FAILED = alias('judge failed', 'jf') # type: ignore
110
+ """Expected outcome for solutions that finish with a judge failed verdict.
111
+
112
+ Only useful for checker tests."""
113
+
109
114
  def style(self) -> str:
110
115
  if self == ExpectedOutcome.ANY:
111
116
  return 'orange'
@@ -161,6 +166,8 @@ class ExpectedOutcome(AutoEnum):
161
166
  return outcome in {Outcome.RUNTIME_ERROR} or outcome.is_slow()
162
167
  if self == ExpectedOutcome.OUTPUT_LIMIT_EXCEEDED:
163
168
  return outcome == Outcome.OUTPUT_LIMIT_EXCEEDED
169
+ if self == ExpectedOutcome.JUDGE_FAILED:
170
+ return outcome == Outcome.JUDGE_FAILED
164
171
  return False
165
172
 
166
173
  def get_matches(self) -> List[Outcome]:
@@ -20,8 +20,12 @@ FileLike = Union[PathOrStr, IO[bytes], int]
20
20
  def _maybe_close_files(files):
21
21
  for fobj in files:
22
22
  if isinstance(fobj, int):
23
- continue
24
- fobj.close()
23
+ try:
24
+ os.close(fobj)
25
+ except OSError:
26
+ pass
27
+ else:
28
+ fobj.close()
25
29
 
26
30
 
27
31
  def _is_pathlike(obj: Any) -> bool:
@@ -250,6 +254,20 @@ class Program:
250
254
  threading.Thread(target=self._handle_wall, daemon=True).start()
251
255
  threading.Thread(target=self._handle_alarm, daemon=True).start()
252
256
 
257
+ def close_pipes(self):
258
+ if self.popen is None:
259
+ return
260
+ if self.params.io.input == subprocess.PIPE and self.pipes.input is not None:
261
+ self.pipes.input.close()
262
+ if self.params.io.output == subprocess.PIPE and self.pipes.output is not None:
263
+ self.pipes.output.close()
264
+ if self.params.io.stderr == subprocess.PIPE and self.pipes.stderr is not None:
265
+ self.pipes.stderr.close()
266
+
267
+ def close(self):
268
+ self.close_pipes()
269
+ _maybe_close_files(self._files)
270
+
253
271
  def process_exit(self, exitstatus, ru) -> ProgramResult:
254
272
  _maybe_close_files(self._files)
255
273
 
@@ -307,4 +325,6 @@ class Program:
307
325
  def wait(self):
308
326
  assert self.popen is not None
309
327
  _, exitstatus, ru = os.wait4(self.pid, 0)
310
- return self.process_exit(exitstatus, ru)
328
+ res = self.process_exit(exitstatus, ru)
329
+ self.close_pipes()
330
+ return res
@@ -335,6 +335,12 @@ class StupidSandbox(SandboxBase):
335
335
  else:
336
336
  raise RuntimeError(f'Unknown pid: {pid}')
337
337
 
338
+ for p in (interactor, program):
339
+ p.close()
340
+ if should_tee:
341
+ for p in (solution_tee, interactor_tee):
342
+ p.close()
343
+
338
344
  return typing.cast(Tuple[SandboxLog, SandboxLog], tuple(results))
339
345
 
340
346
  def cleanup(self, delete=False):
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  # yaml-language-server: $schema=https://rsalesc.github.io/rbx/schemas/Preset.json
3
3
  name: "default"
4
- min_version: "0.17.5"
4
+ min_version: "0.17.7"
5
5
  uri: "rsalesc/rbx/rbx/resources/presets/default"
6
6
  problem: "problem"
7
7
  contest: "contest"
rbx/utils.py CHANGED
@@ -1,13 +1,11 @@
1
1
  import contextlib
2
2
  import enum
3
- import fcntl
4
3
  import functools
5
4
  import json
6
5
  import os
7
6
  import os.path
8
7
  import pathlib
9
8
  import re
10
- import resource
11
9
  import shutil
12
10
  import subprocess
13
11
  import sys
@@ -54,7 +52,7 @@ def get_upgrade_command(
54
52
  parsed_version = (
55
53
  semver.VersionInfo.parse(version) if isinstance(version, str) else version
56
54
  ) or get_semver()
57
- return f'pipx install --upgrade {PIP_NAME}@{parsed_version.major}'
55
+ return f'uv tool install {PIP_NAME}@{parsed_version.major}'
58
56
 
59
57
 
60
58
  def check_version_compatibility_between(
@@ -75,19 +73,41 @@ def check_version_compatibility(required: str) -> SemVerCompatibility:
75
73
  return check_version_compatibility_between(installed, required)
76
74
 
77
75
 
78
- def print_open_fd_count() -> int:
76
+ def print_open_fd_count(id: Optional[str] = None) -> int:
79
77
  import psutil
80
78
 
81
79
  try:
82
- current_process = psutil.Process()
83
- open_fds = len(current_process.open_files())
84
- print(f'Number of opened file descriptors: {open_fds}')
80
+ open_fds = get_open_fds()
81
+ print(f'Number of opened file descriptors for {id or "..."}: {open_fds}')
85
82
  except psutil.AccessDenied:
86
83
  print('Access denied. Run with appropriate permissions (e.g., sudo) if needed.')
87
84
  except Exception as e:
88
85
  print(f'An error occurred: {e}')
89
86
 
90
87
 
88
+ class FdLeakDetector:
89
+ def __init__(self, id: Optional[str] = None, diff: bool = False):
90
+ self.open_fds = 0
91
+ self.id = id
92
+ self.diff = diff
93
+
94
+ def __enter__(self):
95
+ self.open_fds = get_open_fds()
96
+ return self
97
+
98
+ def __exit__(self, *args, **kwargs):
99
+ open_fds = get_open_fds()
100
+ if open_fds > self.open_fds:
101
+ print(
102
+ f'File descriptor leak detected for {self.id or "..."}: {open_fds - self.open_fds} new file descriptors opened'
103
+ )
104
+ elif self.diff and open_fds < self.open_fds:
105
+ print(
106
+ f'File descriptor diff detected for {self.id or "..."}: {self.open_fds - open_fds} file descriptors closed'
107
+ )
108
+ self.open_fds = open_fds
109
+
110
+
91
111
  def create_and_write(path: pathlib.Path, *args, **kwargs):
92
112
  path.parent.mkdir(parents=True, exist_ok=True)
93
113
  path.write_text(*args, **kwargs)
@@ -256,16 +276,28 @@ def confirm_on_status(status: Optional[rich.status.Status], *args, **kwargs) ->
256
276
  return res
257
277
 
258
278
 
259
- def get_open_fds():
260
- fds = []
261
- soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
262
- for fd in range(0, soft):
263
- try:
264
- fcntl.fcntl(fd, fcntl.F_GETFD)
265
- except IOError:
266
- continue
267
- fds.append(fd)
268
- return fds
279
+ def get_open_fds() -> int:
280
+ import psutil
281
+
282
+ try:
283
+ current_process = psutil.Process()
284
+ open_fds = current_process.num_fds()
285
+ return open_fds
286
+ except psutil.AccessDenied:
287
+ return 0
288
+ except Exception as e:
289
+ print(f'An error occurred: {e}')
290
+ return 0
291
+
292
+ # fds = []
293
+ # soft, hard = resource.getrlimit(resource.RLIMIT_NOFILE)
294
+ # for fd in range(0, soft):
295
+ # try:
296
+ # fcntl.fcntl(fd, fcntl.F_GETFD)
297
+ # except IOError:
298
+ # continue
299
+ # fds.append(fd)
300
+ # return fds
269
301
 
270
302
 
271
303
  def command_exists(command):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: rbx.cp
3
- Version: 0.17.5
3
+ Version: 0.17.7
4
4
  Summary:
5
5
  Author: Roberto Sales
6
6
  Requires-Python: >=3.9.1,<4.0.0
@@ -1,5 +1,5 @@
1
1
  rbx/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
- rbx/__version__.py,sha256=rZYsXJU98B0OEia0ZbSa3uP1L8XPNy2IvM2kzP3BE4s,23
2
+ rbx/__version__.py,sha256=LhXO4wjASxNtbb9ULVbPs3Z2KD8fcjHapdbGc9c2q90,23
3
3
  rbx/annotations.py,sha256=_TkLhgZWiUyon3bonHwUo03ls1jY8LwgcR4bVgtgnc0,3519
4
4
  rbx/autoenum.py,sha256=cusv8ClXRlDVvhZ8eDrtYcL_2peXlHugAey_ht8roXk,12025
5
5
  rbx/box/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -60,8 +60,8 @@ rbx/box/presets/schema.py,sha256=5Nw72QrSsA39cUCCLlVfSYMImK_-TfJEGu5TSIDv3W8,291
60
60
  rbx/box/remote.py,sha256=hCdiZSmh6Y1vnSEwLZ_gtAMYV-WLVlU3iVnvcObRpRc,5274
61
61
  rbx/box/retries.py,sha256=BZsi4sYBjm3VK5zb_pBQSYQuKo3ZntmtEFoVPZHg4QI,4982
62
62
  rbx/box/sanitizers/issue_stack.py,sha256=nHtF8bksTIbvOlmDEy72SoXnXfQyIDBHU_3NOn-X1Ss,3534
63
- rbx/box/sanitizers/warning_stack.py,sha256=6-rr3dkMq6MpfjrVZ8lSQjF4RZ5YzZSAPMzHCfm-6h4,2876
64
- rbx/box/schema.py,sha256=3rkRkBiyZw0Dq3GMKX1zh5BE4-aSURFZogAQGoYqVck,20006
63
+ rbx/box/sanitizers/warning_stack.py,sha256=3-5quni5NWMs2k2NI6MWVFR_ec8BeGFVZ29xyifZ_dY,2882
64
+ rbx/box/schema.py,sha256=Q4rDXssTVsmf8kc_0tvZ1SnyXauYi-XubV2WiLBHIBY,20292
65
65
  rbx/box/setter_config.py,sha256=vyZbsbgkjelZOblMLX5A1j4CLqPNQkrv83IZr_3-46Y,5301
66
66
  rbx/box/solutions.py,sha256=Id5X9711p5VX0kZfVXpj_klADPz8k5GvQsV3oXvhgrU,52848
67
67
  rbx/box/state.py,sha256=MMf3DvfQji0jKEliCHct2Tpp_0epL1tvP8HbHNArQIc,166
@@ -132,10 +132,10 @@ rbx/grading/grading_context.py,sha256=TaRyLwPkkxvspQIFUFk8Ok0T8EST2pHMMNoVDx9lbF
132
132
  rbx/grading/judge/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
133
133
  rbx/grading/judge/cacher.py,sha256=zPyOqd7hP_zjuAGAauckFs6EvQE8pP7Mrug7fylIZvY,21929
134
134
  rbx/grading/judge/digester.py,sha256=gtOIe_iL4PEWA7OKelW1gjSI-nBvbOpDPJGV8VQyjSg,912
135
- rbx/grading/judge/program.py,sha256=8hVme1IbyZlrgg8j-po3KZJsYqUbgqfpax-vSZbobRA,9993
135
+ rbx/grading/judge/program.py,sha256=VJ-ItHGsumAvR7YWYtnmAFairfAIu_ASHfyhu7bqvRw,10671
136
136
  rbx/grading/judge/sandbox.py,sha256=e9Nstf9EoFGE0OBQgqcz5BD5hYDegIeGP5dWVZSA29Q,21342
137
137
  rbx/grading/judge/sandboxes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
138
- rbx/grading/judge/sandboxes/stupid_sandbox.py,sha256=QuIP93lBOm7bnkwB3NlhHWxRTs4DTosa_EYPqHq2QCY,11600
138
+ rbx/grading/judge/sandboxes/stupid_sandbox.py,sha256=0Pw-Jvh2A7Jbm5mpx3r4mojP9HgFkDhSREWFuS3ixKs,11765
139
139
  rbx/grading/judge/sandboxes/tee.py,sha256=fLulB8fV7k5cO-ikRgURpsETrvr6LoUSjGxFM3GZs5U,672
140
140
  rbx/grading/judge/storage.py,sha256=8o3pz0Ansanc5t23XGtshJHCD_q4dIR_XorpeVEvg1g,15621
141
141
  rbx/grading/limits.py,sha256=zCyRTEtUQFd1RKL_fFKl3qSiRSIDCalBaSLlt1yhi0Y,896
@@ -201,7 +201,7 @@ rbx/resources/presets/default/contest/statement/info.rbx.tex,sha256=Wz8Tbmi2lPWM
201
201
  rbx/resources/presets/default/contest/statement/instructions.tex,sha256=JG_eR13ukZgEahrrmrbg40H8cUzpoUE8QLocihN-fZ8,2414
202
202
  rbx/resources/presets/default/contest/statement/logo.png,sha256=RLNYmZoc-BR6AZKkmr4UEg3h01YeFzvy604jMAQC7aA,414485
203
203
  rbx/resources/presets/default/env.rbx.yml,sha256=quSPG5Xs9KroYLATNLPNtORLGRWtrLLt2Fx81T1enAM,1692
204
- rbx/resources/presets/default/preset.rbx.yml,sha256=e5kETGeZhY5r9QkFB9Wgn3s2NmSOOKt2i_dEc5L9_vw,520
204
+ rbx/resources/presets/default/preset.rbx.yml,sha256=wItvMn_dh0Gyd7o_fJd6MtaafVQ7Jwihk6moGYYrETA,520
205
205
  rbx/resources/presets/default/problem/.gitignore,sha256=1rt95y9Q7ZHIQn28JyZQUdD5zkpRosjAl9ZqoQmX2cE,149
206
206
  rbx/resources/presets/default/problem/gens/gen.cpp,sha256=rn6sGRjZ1sFE1Rq02r6488iquY9xTrutcvLv4d1sohA,178
207
207
  rbx/resources/presets/default/problem/manual_tests/samples/000.in,sha256=w66OEtCJGqjUNj8cJrqgImgGVm8W_OlIUtF255ds-ow,4
@@ -222,9 +222,9 @@ rbx/resources/presets/default/shared/problem_template.rbx.tex,sha256=KDibf4LtUio
222
222
  rbx/resources/templates/rbx.h,sha256=0AZds9R0PmuPgnlTENb33Y81LW0LlnmOJFaoN8oG3Yo,3638
223
223
  rbx/resources/templates/template.cpp,sha256=xXWpWo7fa7HfmPNqkmHcmv3i46Wm0ZL-gPmkRfGvLn4,317
224
224
  rbx/testing_utils.py,sha256=vNNdaytowJfuopszVHeFzVtHWlPfipPW4zpqCOvdZKU,2908
225
- rbx/utils.py,sha256=yBIp6vwY2hhY2s7bJtvlP5U5LEnZLfG8Y044VDKy6B4,10343
226
- rbx_cp-0.17.5.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
227
- rbx_cp-0.17.5.dist-info/METADATA,sha256=YFq-MJGMCLVJH7JC3l11zpuxlb6Ky2DcSzqY-N8bfnU,4799
228
- rbx_cp-0.17.5.dist-info/WHEEL,sha256=fGIA9gx4Qxk2KDKeNJCbOEwSrmLtjWCwzBz351GyrPQ,88
229
- rbx_cp-0.17.5.dist-info/entry_points.txt,sha256=Gw2_BZ5Jon61biaH_ETbAQGXy8fR5On9gw2U4A1erpo,40
230
- rbx_cp-0.17.5.dist-info/RECORD,,
225
+ rbx/utils.py,sha256=ua7qzt5rrpTKgEZXC6cKVDVklOReIYWL6sNsSWkrWE4,11355
226
+ rbx_cp-0.17.7.dist-info/LICENSE,sha256=QwcOLU5TJoTeUhuIXzhdCEEDDvorGiC6-3YTOl4TecE,11356
227
+ rbx_cp-0.17.7.dist-info/METADATA,sha256=9RJ8D--x5pfsbzJ7dm7TaJdhAJYc2AXarRMHazUQuRw,4799
228
+ rbx_cp-0.17.7.dist-info/WHEEL,sha256=b4K_helf-jlQoXBBETfwnf4B04YC67LOev0jo4fX5m8,88
229
+ rbx_cp-0.17.7.dist-info/entry_points.txt,sha256=Gw2_BZ5Jon61biaH_ETbAQGXy8fR5On9gw2U4A1erpo,40
230
+ rbx_cp-0.17.7.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: poetry-core 2.1.2
2
+ Generator: poetry-core 2.1.3
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any