Conversation
…phasespace-labs#212) Replace os.kill(pid, 0) on Windows with ctypes OpenProcess and WaitForSingleObject probe to avoid signalling or interrupting console processes. Preserves POSIX os.kill(pid, 0) unchanged and maintains fail-safe liveness invariant on access-denied/unexpected errors.
|
This is strong work and I want to name the best decision in it before the one thing I am holding on. You didn't take the issue's suggestion to read the exit code, and you were right not to: What I am holding on: the error capture. The fix is small: To be clear about what I have and haven't done: I have not reproduced this on Windows, and I'm not claiming an intervening call definitely overwrites the value. The problem is narrower — the current form gives no guaranteed immediate capture, the code's correctness depends on having it, and there is a documented idiom that provides it. One smaller thing for the same push.
Everything else stands: fail-safe on every wait branch including Push onto the same branch and I'll review and merge once checks are green. |
…rue and split platform tests
|
@Paul-Kyle Thanks for catching that - using Also updated the test suite with Pushed commit |
|
The code change is exactly right, and I want to be clear that what I am asking for now is my mistake, not yours. Deleting the The one thing I need before merging is a native run of the new head. Your 15/15 on #212 was posted just before Could you run Everything else stands and I'll merge on the result. |
|
@Paul-Kyle Here is the native Windows run receipt on commit Environment: Windows 11 (build 26200), Python 3.12.7, pytest 9.1.1 The unmocked dead-PID check in |
Summary
Fixes #212.
On Windows,
os.kill(pid, 0)maps toCTRL_C_EVENT, which signals the console process group instead of probing process existence without side effects.This PR replaces the Windows probe with a non-signalling Win32 API query using
OpenProcesswithPROCESS_QUERY_LIMITED_INFORMATION | SYNCHRONIZE(0x00101000) andWaitForSingleObject(handle, 0):WAIT_TIMEOUT(0x102) -> Process is actively running (True).WAIT_OBJECT_0(0x0) -> Process has exited / signaled (False).259 (STILL_ACTIVE)exit-code trap.ERROR_ACCESS_DENIED (5)and unexpected OS errors resolve toTrue(alive);ERROR_INVALID_PARAMETER (87)resolves toFalse.> 0xFFFFFFFF)._under_claude_worktreeson Windows usingos.path.normcase.os.kill(pid, 0)completely unchanged.Test Plan