bpo-40138: Fix Windows os.waitpid() for large exit code (GH-19654) · python/cpython@de5dcfa

@@ -2417,12 +2417,37 @@ def test_getppid(self):

24172417

# We are the parent of our subprocess

24182418

self.assertEqual(int(stdout), os.getpid())

241924192420+

def check_waitpid(self, code, exitcode):

2421+

if sys.platform == 'win32':

2422+

# On Windows, os.spawnv() simply joins arguments with spaces:

2423+

# arguments need to be quoted

2424+

args = [f'"{sys.executable}"', '-c', f'"{code}"']

2425+

else:

2426+

args = [sys.executable, '-c', code]

2427+

pid = os.spawnv(os.P_NOWAIT, sys.executable, args)

2428+2429+

pid2, status = os.waitpid(pid, 0)

2430+

if sys.platform == 'win32':

2431+

self.assertEqual(status, exitcode << 8)

2432+

else:

2433+

self.assertTrue(os.WIFEXITED(status), status)

2434+

self.assertEqual(os.WEXITSTATUS(status), exitcode)

2435+

self.assertEqual(pid2, pid)

2436+24202437

def test_waitpid(self):

2421-

args = [sys.executable, '-c', 'pass']

2422-

# Add an implicit test for PyUnicode_FSConverter().

2423-

pid = os.spawnv(os.P_NOWAIT, FakePath(args[0]), args)

2424-

status = os.waitpid(pid, 0)

2425-

self.assertEqual(status, (pid, 0))

2438+

self.check_waitpid(code='pass', exitcode=0)

2439+2440+

def test_waitpid_exitcode(self):

2441+

exitcode = 23

2442+

code = f'import sys; sys.exit({exitcode})'

2443+

self.check_waitpid(code, exitcode=exitcode)

2444+2445+

@unittest.skipUnless(sys.platform == 'win32', 'win32-specific test')

2446+

def test_waitpid_windows(self):

2447+

# bpo-40138: test os.waitpid() with exit code larger than INT_MAX.

2448+

STATUS_CONTROL_C_EXIT = 0xC000013A

2449+

code = f'import _winapi; _winapi.ExitProcess({STATUS_CONTROL_C_EXIT})'

2450+

self.check_waitpid(code, exitcode=STATUS_CONTROL_C_EXIT)

242624512427245224282453

class SpawnTests(unittest.TestCase):