On POSIX, `subprocess.Popen.poll()` can quietly hide a real error. Internally `poll()` calls `os.waitpid()` and catches `OSError`. It handles two cases: `ECHILD` (the child was already reaped) and the case where the call comes from `__del__`. If `waitpid()` fails with anything else, such as `EINVAL`, the exception is caught and dropped. `returncode` stays `None`, so `poll()` returns `None` as if the process were still running and the real failure disappears. Here is a way to reproduce it. Note that `poll()` uses a copy of `os.waitpid` that subprocess saves at import time, so you have to patch it through `subprocess._del_safe`, not `os.waitpid`: ```python import subprocess, errno from unittest import mock p = subprocess.Popen(["sleep", "30"]) def fake_waitpid(pid, flags): raise OSError(errno.EINVAL, "simulated") with mock.patch.object(subprocess._del_safe, "waitpid", fake_waitpid): print(p.poll(), p.returncode) # prints: None None p.kill(); p.wait() ``` The fix is to re-raise the unexpected errors instead of ignoring them. The `__del__` path is handled first (it passes a deadstate value), so it stays unaffected, and the `ECHILD` handling doesn't change. Found while going through devdanzin's audit of the standard library, item 8: https://gist.github.com/devdanzin/3198710e3c0128fda5e0a7b4e0768e5f <!-- gh-linked-prs --> ### Linked PRs * gh-153964 <!-- /gh-linked-prs -->