weco 0.3.1__py3-none-any.whl → 0.3.2__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.
weco/utils.py CHANGED
@@ -2,13 +2,13 @@ from typing import Any, Dict, List, Tuple, Union
2
2
  import json
3
3
  import time
4
4
  import subprocess
5
+ import psutil
5
6
  from rich.layout import Layout
6
7
  from rich.live import Live
7
8
  from rich.panel import Panel
8
9
  import pathlib
9
10
  import requests
10
11
  from packaging.version import parse as parse_version
11
-
12
12
  from .constants import TRUNCATION_THRESHOLD, TRUNCATION_KEEP_LENGTH, DEFAULT_MODEL, SUPPORTED_FILE_EXTENSIONS
13
13
 
14
14
 
@@ -108,22 +108,52 @@ def truncate_output(output: str) -> str:
108
108
 
109
109
  def run_evaluation(eval_command: str, timeout: int | None = None) -> str:
110
110
  """Run the evaluation command on the code and return the output."""
111
+ process = subprocess.Popen(
112
+ eval_command, shell=True, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True
113
+ )
111
114
 
112
- # Run the eval command as is
113
115
  try:
114
- result = subprocess.run(eval_command, shell=True, capture_output=True, text=True, check=False, timeout=timeout)
115
- # Combine stdout and stderr for complete output
116
- output = result.stderr if result.stderr else ""
117
- if result.stdout:
118
- if len(output) > 0:
119
- output += "\n"
120
- output += result.stdout
121
- return output # Return full output, no truncation
116
+ # NOTE: Process tree cleanup only happens on timeout. Normal completion relies on the OS/shell to clean up child processes, which works for typical evaluation scripts.
117
+ output, _ = process.communicate(timeout=timeout)
118
+ return output
119
+
122
120
  except subprocess.TimeoutExpired:
121
+ # Kill process tree
122
+ try:
123
+ parent = psutil.Process(process.pid)
124
+ children = parent.children(recursive=True)
125
+
126
+ # Terminate gracefully
127
+ for child in children:
128
+ try:
129
+ child.terminate()
130
+ except psutil.NoSuchProcess:
131
+ pass
132
+ try:
133
+ parent.terminate()
134
+ except psutil.NoSuchProcess:
135
+ pass
136
+
137
+ # Wait, then force kill survivors
138
+ _, alive = psutil.wait_procs(children + [parent], timeout=1)
139
+ for proc in alive:
140
+ try:
141
+ proc.kill()
142
+ except psutil.NoSuchProcess:
143
+ pass
144
+
145
+ except psutil.NoSuchProcess:
146
+ pass
147
+
148
+ # Drain pipes
149
+ try:
150
+ process.communicate(timeout=1)
151
+ except (subprocess.TimeoutExpired, ValueError, OSError):
152
+ pass
153
+
123
154
  return f"Evaluation timed out after {'an unspecified duration' if timeout is None else f'{timeout} seconds'}."
124
155
 
125
156
 
126
- # Update Check Function
127
157
  def check_for_cli_updates():
128
158
  """Checks PyPI for a newer version of the weco package and notifies the user."""
129
159
  try:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: weco
3
- Version: 0.3.1
3
+ Version: 0.3.2
4
4
  Summary: Documentation for `weco`, a CLI for using Weco AI's code optimizer.
5
5
  Author-email: Weco AI Team <contact@weco.ai>
6
6
  License:
@@ -219,6 +219,7 @@ Requires-Dist: packaging
219
219
  Requires-Dist: gitingest
220
220
  Requires-Dist: fastapi
221
221
  Requires-Dist: slowapi
222
+ Requires-Dist: psutil
222
223
  Provides-Extra: dev
223
224
  Requires-Dist: ruff; extra == "dev"
224
225
  Requires-Dist: build; extra == "dev"
@@ -7,10 +7,10 @@ weco/constants.py,sha256=V6yFugTznKm5EC2_jr4I_whd7sqI80HiPggRn0az580,406
7
7
  weco/credits.py,sha256=C08x-TRcLg3ccfKqMGNRY7zBn7t3r7LZ119bxgfztaI,7629
8
8
  weco/optimizer.py,sha256=mJU8_0bo_6dS2PEj1E3dQHvNH9V4e8NSLNE55tmvspw,42291
9
9
  weco/panels.py,sha256=fnGPtmvxpx21AuBCtCFu1f_BpSxybNr2lhjIIKIutrY,16133
10
- weco/utils.py,sha256=TT57S0YGMuMWPFNsn0tcexNHZd-kBEjDeiOLWxANiQU,6117
11
- weco-0.3.1.dist-info/licenses/LICENSE,sha256=9LUfoGHjLPtak2zps2kL2tm65HAZIICx_FbLaRuS4KU,11337
12
- weco-0.3.1.dist-info/METADATA,sha256=e5xozCmFPB7ih2ntFNYQAMXAU_O8Kw3NDSiRhaNEu4c,31856
13
- weco-0.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
- weco-0.3.1.dist-info/entry_points.txt,sha256=ixJ2uClALbCpBvnIR6BXMNck8SHAab8eVkM9pIUowcs,39
15
- weco-0.3.1.dist-info/top_level.txt,sha256=F0N7v6e2zBSlsorFv-arAq2yDxQbzX3KVO8GxYhPUeE,5
16
- weco-0.3.1.dist-info/RECORD,,
10
+ weco/utils.py,sha256=erDDrA_g3KSlel6YEAGALlV_k8ftT-VQnPT1BrmzK8k,7021
11
+ weco-0.3.2.dist-info/licenses/LICENSE,sha256=9LUfoGHjLPtak2zps2kL2tm65HAZIICx_FbLaRuS4KU,11337
12
+ weco-0.3.2.dist-info/METADATA,sha256=TDJIvT1vw3VFrjEj9o8VkLuxis2MWWAL0pnDYqpFfak,31878
13
+ weco-0.3.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
14
+ weco-0.3.2.dist-info/entry_points.txt,sha256=ixJ2uClALbCpBvnIR6BXMNck8SHAab8eVkM9pIUowcs,39
15
+ weco-0.3.2.dist-info/top_level.txt,sha256=F0N7v6e2zBSlsorFv-arAq2yDxQbzX3KVO8GxYhPUeE,5
16
+ weco-0.3.2.dist-info/RECORD,,
File without changes