Skip to content

Commit 0c10eca

Browse files
polyfills: os.waitstatus_to_exitcode() for <3.9
Move the open-coded waitstatus_to_exitcode() logic from transports.py into polyfills.py as suggested by Martin. We adjust the code a little bit to match the actual stdlib implementation which means we have to catch ValueError at the call site. Closes #22915
1 parent 373846f commit 0c10eca

File tree

2 files changed

+18
-7
lines changed

2 files changed

+18
-7
lines changed

src/cockpit/polyfills.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55

66
import contextlib
7+
import os
78
import socket
89

910

@@ -25,6 +26,18 @@ def recv_fds(sock, bufsize, maxfds, flags=0):
2526

2627
socket.recv_fds = recv_fds
2728

29+
# introduced in 3.9
30+
if not hasattr(os, 'waitstatus_to_exitcode'):
31+
def waitstatus_to_exitcode(status: int) -> int:
32+
if os.WIFEXITED(status):
33+
return os.WEXITSTATUS(status)
34+
elif os.WIFSIGNALED(status):
35+
return -os.WTERMSIG(status)
36+
else:
37+
raise ValueError(f'Invalid wait status: {status}')
38+
39+
os.waitstatus_to_exitcode = waitstatus_to_exitcode
40+
2841
# introduced in 3.7
2942
if not hasattr(contextlib, 'AsyncExitStack'):
3043
class AsyncExitStack:

src/cockpit/transports.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -310,15 +310,13 @@ def get_stderr(self, *, reset: bool = False) -> str:
310310
def watch_exit(self, process: 'subprocess.Popen[bytes]') -> None:
311311
def child_exited(pid: int, status: int) -> None:
312312
assert pid == process.pid
313-
# os.waitstatus_to_exitcode() is only available since Python 3.9
314-
if os.WIFEXITED(status):
315-
self._returncode = os.WEXITSTATUS(status)
316-
elif os.WIFSIGNALED(status):
317-
self._returncode = -os.WTERMSIG(status)
318-
else:
313+
assert isinstance(self._protocol, SubprocessProtocol)
314+
315+
try:
316+
self._returncode = os.waitstatus_to_exitcode(status)
317+
except ValueError:
319318
self._returncode = status
320319

321-
assert isinstance(self._protocol, SubprocessProtocol)
322320
logger.debug('Process exited with status %d', self._returncode)
323321
if not self._closing:
324322
self._protocol.process_exited()

0 commit comments

Comments
 (0)