Skip to content

fix: use context managers for file writes to prevent resource leaks#575

Open
Kailigithub wants to merge 1 commit into
lsdefine:mainfrom
Kailigithub:fix/bare-open-write-resource-leaks
Open

fix: use context managers for file writes to prevent resource leaks#575
Kailigithub wants to merge 1 commit into
lsdefine:mainfrom
Kailigithub:fix/bare-open-write-resource-leaks

Conversation

@Kailigithub
Copy link
Copy Markdown
Contributor

Summary

Replace six open(path, mode, ...).write(...) call sites with proper with open(...) as f: context managers so file handles are deterministically closed and writes are guaranteed to flush.

The bare form relies on garbage collection to release file descriptors, which can leave buffered writes un-flushed if the interpreter is interrupted (Ctrl+C, OOM, crash). The most exposed call site is ga.py's file_write tool in prepend mode, which reads the existing file then rewrites it in one shot — without with, an abort between read and re-flush would silently truncate the user's file.

Call sites changed

File Line Context
agentmain.py 27 global_mem.txt seed write (first-run init)
agentmain.py 31 global_mem_insight.txt template copy (first-run init)
agentmain.py 36 tmwd_cdp_bridge/config.js (first-run init)
agentmain.py 276 reflect log append (per-task)
ga.py 401 file_write tool, prepend mode (per-call, rewrites entire file)
frontends/wechatapp.py 266 WeChat media download write (per-message)

Behavior

Unchanged. Each call site preserves the same read/write ordering, the same encoding, and the same conditional semantics (e.g. the template copy still only reads the source file if os.path.exists(t) returns True).

Verification

  • python3 -m py_compile agentmain.py ga.py frontends/wechatapp.py — passes
  • python3 -c "import ast; ast.parse(open('agentmain.py').read())" (and same for ga.py, wechatapp.py) — passes
  • ruff check — no new findings introduced by this change; pre-existing project-style warnings (E701, F541 etc.) are untouched
  • Project has no test suite (tests/ is empty), so runtime behavior was checked by AST + manual review only
  • git diff reviewed for read-then-write ordering preservation

Six call sites in three files wrote to disk via bare `open(...).write(...)`,
which leaks file handles until garbage collection and can leave writes
un-flushed if the interpreter exits before GC. Wrap each in `with` so the
handle is deterministically closed after the write.

  - agentmain.py:27  global_mem.txt seed write (first-run init)
  - agentmain.py:31  global_mem_insight.txt template copy (first-run init)
  - agentmain.py:36  tmwd_cdp_bridge/config.js (first-run init)
  - agentmain.py:276 reflect log append (per-task)
  - ga.py:401        file_write tool, prepend mode (per-call, rewrites entire file)
  - frontends/wechatapp.py:266 WeChat media download (per-message)

Behavior is unchanged: reads still happen iff the source file exists, writes
still produce byte-identical output, and the same encoding flags are used.

Notable: the ga.py prepend path is the most exposed — it reads the existing
file then rewrites the whole thing in one shot. Without `with`, an
interpreter abort between read and re-flush would silently truncate the
user's file. After this change the write is always flushed and closed before
the line returns.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant