diff --git a/Lib/test/test_subprocess.py b/Lib/test/test_subprocess.py index d152826213ebdb..1d2d15c7a24c3b 100644 --- a/Lib/test/test_subprocess.py +++ b/Lib/test/test_subprocess.py @@ -29,6 +29,11 @@ except ImportError: threading = None +try: + import _testcapi +except ImportError: + _testcapi = None + if support.PGO: raise unittest.SkipTest("test is not helpful for PGO") @@ -2565,42 +2570,24 @@ def test_communicate_BrokenPipeError_stdin_close_with_timeout(self): proc.communicate(timeout=999) mock_proc_stdin.close.assert_called_once_with() - @unittest.skipIf(not ctypes, 'ctypes module required') - @unittest.skipIf(not sys.executable, 'Test requires sys.executable') - def test_child_terminated_in_stopped_state(self): + @unittest.skipUnless(_testcapi is not None + and hasattr(_testcapi, 'W_STOPCODE'), + 'need _testcapi.W_STOPCODE') + def test_stopped(self): """Test wait() behavior when waitpid returns WIFSTOPPED; issue29335.""" - PTRACE_TRACEME = 0 # From glibc and MacOS (PT_TRACE_ME). - libc_name = ctypes.util.find_library('c') - libc = ctypes.CDLL(libc_name) - if not hasattr(libc, 'ptrace'): - raise unittest.SkipTest('ptrace() required') - - code = textwrap.dedent(f""" - import ctypes - import faulthandler - from test.support import SuppressCrashReport - - libc = ctypes.CDLL({libc_name!r}) - libc.ptrace({PTRACE_TRACEME}, 0, 0) - """) - - child = subprocess.Popen([sys.executable, '-c', code]) - if child.wait() != 0: - raise unittest.SkipTest('ptrace() failed - unable to test') - - code += textwrap.dedent(f""" - with SuppressCrashReport(): - # Crash the process - faulthandler._sigsegv() - """) - child = subprocess.Popen([sys.executable, '-c', code]) - try: - returncode = child.wait() - except: - child.kill() # Clean up the hung stopped process. - raise - self.assertNotEqual(0, returncode) - self.assertLess(returncode, 0) # signal death, likely SIGSEGV. + args = [sys.executable, '-c', 'pass'] + proc = subprocess.Popen(args) + + # Wait until the real process completes to avoid zombie process + pid = proc.pid + pid, status = os.waitpid(pid, 0) + self.assertEqual(status, 0) + + status = _testcapi.W_STOPCODE(3) + with mock.patch('subprocess.os.waitpid', return_value=(pid, status)): + returncode = proc.wait() + + self.assertEqual(returncode, -3) @unittest.skipUnless(mswindows, "Windows specific tests") diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 655669050dd222..95c10184159808 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -18,6 +18,10 @@ # include /* struct timeval */ #endif +#ifdef HAVE_SYS_WAIT_H +#include /* For W_STOPCODE */ +#endif + #ifdef WITH_THREAD #include "pythread.h" #endif /* WITH_THREAD */ @@ -4272,6 +4276,7 @@ test_pyobject_fastcallkeywords(PyObject *self, PyObject *args) return _PyObject_FastCallKeywords(func, stack, nargs, kwnames); } + static PyObject* stack_pointer(PyObject *self, PyObject *args) { @@ -4280,6 +4285,20 @@ stack_pointer(PyObject *self, PyObject *args) } +#ifdef W_STOPCODE +static PyObject* +py_w_stopcode(PyObject *self, PyObject *args) +{ + int sig, status; + if (!PyArg_ParseTuple(args, "i", &sig)) { + return NULL; + } + status = W_STOPCODE(sig); + return PyLong_FromLong(status); +} +#endif + + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", (PyCFunction)raise_memoryerror, METH_NOARGS}, @@ -4493,6 +4512,9 @@ static PyMethodDef TestMethods[] = { {"pyobject_fastcalldict", test_pyobject_fastcalldict, METH_VARARGS}, {"pyobject_fastcallkeywords", test_pyobject_fastcallkeywords, METH_VARARGS}, {"stack_pointer", stack_pointer, METH_NOARGS}, +#ifdef W_STOPCODE + {"W_STOPCODE", py_w_stopcode, METH_VARARGS}, +#endif {NULL, NULL} /* sentinel */ }; pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy