Skip to content

gh-153962: Re-raise unexpected OSError in subprocess Popen._internal_poll#153964

Open
fedonman wants to merge 3 commits into
python:mainfrom
fedonman:fix-gh-153962-internal-poll-oserror
Open

gh-153962: Re-raise unexpected OSError in subprocess Popen._internal_poll#153964
fedonman wants to merge 3 commits into
python:mainfrom
fedonman:fix-gh-153962-internal-poll-oserror

Conversation

@fedonman

@fedonman fedonman commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

On POSIX, Popen.poll() caught every OSError from os.waitpid() but only did something useful with two of them: ECHILD, and the case where the call comes from __del__. Any other error, like EINVAL, was caught and dropped, which left returncode as None and made poll() look like the child was still running.

This adds an else: raise so those unexpected errors reach the caller instead of vanishing.

The new raise only runs when the call isn't from __del__ (that case is handled first, since it passes a deadstate value), so __del__ still never raises. The ECHILD behavior is unchanged.

I added a test that patches subprocess._del_safe.waitpid to raise EINVAL and checks that poll() re-raises it. It fails without the change and passes with it, and the rest of test_subprocess still passes. The patch goes through subprocess._del_safe because that's the copy of os.waitpid this code actually calls.

Found as item 8 in devdanzin's standard library audit: https://gist.github.com/devdanzin/3198710e3c0128fda5e0a7b4e0768e5f

Fixes #153962.

…ernal_poll

On POSIX, Popen._internal_poll() caught every OSError from os.waitpid()
and, unless it was ECHILD or the call came from __del__ (a non-None
_deadstate), silently discarded it, leaving returncode as None and
masking a real failure.

Add an else branch that re-raises such unexpected errors. The re-raise is
only reachable when _deadstate is None; __del__ and _cleanup() always
pass a non-None _deadstate, so __del__ still never raises. ECHILD
handling is unchanged.
@fedonman

Copy link
Copy Markdown
Contributor Author

@zware part of EuroPython sprint.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Todo

Development

Successfully merging this pull request may close these issues.

subprocess: Popen._internal_poll silently swallows unexpected OSError from waitpid()

2 participants