fix: close bare open() in host.py and ResourceWarning in test_host_thread_cli
- host.py: 7 one-shot reads switched to with open (run_health_check pidfile, daemon-status pid/log, daemon-stop pid, daemon old pid, interrupt poll state, parallel jobs); read content, encoding args and error semantics unchanged. - tests/test_host_thread_cli.py: test_old_archive_unchanged state read switched to with open; added a warnings-capture assertion scoped to the state read so a regression fails the test. - Intentionally untouched: daemonize log handle (daemon-lifetime dup2 target) and the two _load_config_file / init sites owned by PR #266.
This commit is contained in:
1 parent
72d343b2c7
commit
436a92ba1d
2 files changed
+29
-9
No files matched your search
@@ -1120,7 +1120,8 @@ def run_health_check(state_path, cfg, codex_bin, codex_home, approval,
|
||||
checks["daemon_pidfile"] = pidfile
|
||||
if os.path.exists(pidfile):
|
||||
try:
|
||||
pid = int(open(pidfile).read().strip())
|
||||
with open(pidfile) as f:
|
||||
pid = int(f.read().strip())
|
||||
os.kill(pid, 0)
|
||||
checks["daemon_alive"] = True
|
||||
checks["daemon_pid"] = pid
|
||||
@@ -2707,7 +2708,8 @@ def main():
|
||||
pid = None
|
||||
if os.path.exists(pidfile):
|
||||
try:
|
||||
pid = int(open(pidfile).read().strip())
|
||||
with open(pidfile) as f:
|
||||
pid = int(f.read().strip())
|
||||
os.kill(pid, 0)
|
||||
alive = True
|
||||
except Exception:
|
||||
@@ -2715,7 +2717,8 @@ def main():
|
||||
tail = ""
|
||||
if os.path.exists(logfile):
|
||||
try:
|
||||
tail = "\n".join(open(logfile).read().splitlines()[-5:])
|
||||
with open(logfile) as f:
|
||||
tail = "\n".join(f.read().splitlines()[-5:])
|
||||
except Exception:
|
||||
pass
|
||||
print(json.dumps({"alive": alive, "pid": pid, "pidfile": pidfile,
|
||||
@@ -2728,7 +2731,8 @@ def main():
|
||||
print("daemon 未运行(无 pidfile)")
|
||||
return
|
||||
try:
|
||||
pid = int(open(pidfile).read().strip())
|
||||
with open(pidfile) as f:
|
||||
pid = int(f.read().strip())
|
||||
except Exception:
|
||||
print("pidfile 损坏,直接删除")
|
||||
os.remove(pidfile)
|
||||
@@ -2758,7 +2762,8 @@ def main():
|
||||
if not args.foreground:
|
||||
if os.path.exists(pidfile):
|
||||
try:
|
||||
old_pid = int(open(pidfile).read().strip())
|
||||
with open(pidfile) as f:
|
||||
old_pid = int(f.read().strip())
|
||||
os.kill(old_pid, 0)
|
||||
print(f"daemon 已在运行:pid {old_pid},先 daemon-stop 再起")
|
||||
return
|
||||
@@ -3272,8 +3277,8 @@ def main():
|
||||
for _ in range(10):
|
||||
time.sleep(1)
|
||||
try:
|
||||
cur = json.load(open(args.state,
|
||||
encoding="utf-8"))
|
||||
with open(args.state, encoding="utf-8") as f:
|
||||
cur = json.load(f)
|
||||
if (cur.get("tasks", {}).get(args.task, {})
|
||||
.get("status") == "interrupted"):
|
||||
print(f"interrupt {args.task}: 属主已响应,"
|
||||
@@ -3424,7 +3429,8 @@ def main():
|
||||
last_turn_status=t.get("goal_last_turn_status"),
|
||||
last_turn_text=last_result.get("text", "") or "")
|
||||
elif args.cmd == "parallel":
|
||||
jobs = json.load(open(args.jobs))
|
||||
with open(args.jobs) as f:
|
||||
jobs = json.load(f)
|
||||
# 依赖 + 优先级:先拓扑排序,缺依赖/成环直接报错不跑;
|
||||
# 按波次派发 + 跑:依赖都 completed 的任务才进本波,
|
||||
# 依赖 failed/skipped 的任务标 skipped 不跑,避免在坏
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import gc
|
||||
import io
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import unittest
|
||||
import warnings
|
||||
from contextlib import redirect_stdout
|
||||
from unittest import mock
|
||||
import host
|
||||
@@ -246,7 +248,19 @@ class ThreadCliTest(unittest.TestCase):
|
||||
code = e.code if isinstance(e.code, int) else 1
|
||||
self.assertEqual(code, 0)
|
||||
self.assertIn("archived t1", out.getvalue())
|
||||
saved = json.loads(Path(state_path).read_text(encoding="utf-8"))
|
||||
# 第 4 项回归:此处裸 open() 曾在 GC 时报 ResourceWarning;
|
||||
# 只捕获本段读 state 的警告断言(_load_config_file 的
|
||||
# 警告属 #266 轨,不在此断言范围内)。
|
||||
with warnings.catch_warnings(record=True) as caught:
|
||||
warnings.simplefilter("always", ResourceWarning)
|
||||
with open(state_path, encoding="utf-8") as f:
|
||||
saved = json.load(f)
|
||||
gc.collect()
|
||||
self.assertEqual(
|
||||
[w for w in caught
|
||||
if issubclass(w.category, ResourceWarning)
|
||||
and "host-state.json" in str(w.message)],
|
||||
[])
|
||||
self.assertEqual(saved["tasks"]["t1"]["status"], "archived")
|
||||
calls = self._calls_before_close(fake)
|
||||
self.assertEqual(calls, [("archive", "th-1")])
|
||||
|
||||
Reference in new issue
Block a user