mirror of
https://github.com/python/cpython.git
synced 2025-09-26 18:29:57 +00:00
Raise our own SubprocessError rather than a RuntimeError in when dealing with
odd rare errors coming from the subprocess module.
This commit is contained in:
parent
82fdadeba1
commit
8d07c264e4
4 changed files with 13 additions and 10 deletions
|
@ -1042,9 +1042,9 @@ class Popen(object):
|
||||||
w9xpopen = os.path.join(os.path.dirname(sys.base_exec_prefix),
|
w9xpopen = os.path.join(os.path.dirname(sys.base_exec_prefix),
|
||||||
"w9xpopen.exe")
|
"w9xpopen.exe")
|
||||||
if not os.path.exists(w9xpopen):
|
if not os.path.exists(w9xpopen):
|
||||||
raise RuntimeError("Cannot locate w9xpopen.exe, which is "
|
raise SubprocessError(
|
||||||
"needed for Popen to work with your "
|
"Cannot locate w9xpopen.exe, which is needed for "
|
||||||
"shell or platform.")
|
"Popen to work with your shell or platform.")
|
||||||
return w9xpopen
|
return w9xpopen
|
||||||
|
|
||||||
|
|
||||||
|
@ -1414,12 +1414,12 @@ class Popen(object):
|
||||||
except ValueError:
|
except ValueError:
|
||||||
warnings.warn(RuntimeWarning(
|
warnings.warn(RuntimeWarning(
|
||||||
'Bad exception data: %r' % errpipe_data))
|
'Bad exception data: %r' % errpipe_data))
|
||||||
exception_name = b'RuntimeError'
|
exception_name = b'SubprocessError'
|
||||||
hex_errno = b'0'
|
hex_errno = b'0'
|
||||||
err_msg = b'Unknown'
|
err_msg = b'Unknown'
|
||||||
child_exception_type = getattr(
|
child_exception_type = getattr(
|
||||||
builtins, exception_name.decode('ascii'),
|
builtins, exception_name.decode('ascii'),
|
||||||
RuntimeError)
|
SubprocessError)
|
||||||
for fd in (p2cwrite, c2pread, errread):
|
for fd in (p2cwrite, c2pread, errread):
|
||||||
if fd != -1:
|
if fd != -1:
|
||||||
os.close(fd)
|
os.close(fd)
|
||||||
|
@ -1452,7 +1452,7 @@ class Popen(object):
|
||||||
self.returncode = _WEXITSTATUS(sts)
|
self.returncode = _WEXITSTATUS(sts)
|
||||||
else:
|
else:
|
||||||
# Should never happen
|
# Should never happen
|
||||||
raise RuntimeError("Unknown child exit status!")
|
raise SubprocessError("Unknown child exit status!")
|
||||||
|
|
||||||
|
|
||||||
def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid,
|
def _internal_poll(self, _deadstate=None, _waitpid=os.waitpid,
|
||||||
|
|
|
@ -1179,7 +1179,7 @@ class POSIXProcessTestCase(BaseTestCase):
|
||||||
try:
|
try:
|
||||||
p = subprocess.Popen([sys.executable, "-c", ""],
|
p = subprocess.Popen([sys.executable, "-c", ""],
|
||||||
preexec_fn=raise_it)
|
preexec_fn=raise_it)
|
||||||
except RuntimeError as e:
|
except subprocess.SubprocessError as e:
|
||||||
self.assertTrue(
|
self.assertTrue(
|
||||||
subprocess._posixsubprocess,
|
subprocess._posixsubprocess,
|
||||||
"Expected a ValueError from the preexec_fn")
|
"Expected a ValueError from the preexec_fn")
|
||||||
|
@ -1544,12 +1544,12 @@ class POSIXProcessTestCase(BaseTestCase):
|
||||||
# Pure Python implementations keeps the message
|
# Pure Python implementations keeps the message
|
||||||
self.assertIsNone(subprocess._posixsubprocess)
|
self.assertIsNone(subprocess._posixsubprocess)
|
||||||
self.assertEqual(str(err), "surrogate:\uDCff")
|
self.assertEqual(str(err), "surrogate:\uDCff")
|
||||||
except RuntimeError as err:
|
except subprocess.SubprocessError as err:
|
||||||
# _posixsubprocess uses a default message
|
# _posixsubprocess uses a default message
|
||||||
self.assertIsNotNone(subprocess._posixsubprocess)
|
self.assertIsNotNone(subprocess._posixsubprocess)
|
||||||
self.assertEqual(str(err), "Exception occurred in preexec_fn.")
|
self.assertEqual(str(err), "Exception occurred in preexec_fn.")
|
||||||
else:
|
else:
|
||||||
self.fail("Expected ValueError or RuntimeError")
|
self.fail("Expected ValueError or subprocess.SubprocessError")
|
||||||
|
|
||||||
def test_undecodable_env(self):
|
def test_undecodable_env(self):
|
||||||
for key, value in (('test', 'abc\uDCFF'), ('test\uDCFF', '42')):
|
for key, value in (('test', 'abc\uDCFF'), ('test\uDCFF', '42')):
|
||||||
|
|
|
@ -116,6 +116,9 @@ Core and Builtins
|
||||||
Library
|
Library
|
||||||
-------
|
-------
|
||||||
|
|
||||||
|
- The subprocess module now raises its own SubprocessError instead of a
|
||||||
|
RuntimeError in various error situations which should not normally happen.
|
||||||
|
|
||||||
- Issue #16327: The subprocess module no longer leaks file descriptors
|
- Issue #16327: The subprocess module no longer leaks file descriptors
|
||||||
used for stdin/stdout/stderr pipes to the child when fork() fails.
|
used for stdin/stdout/stderr pipes to the child when fork() fails.
|
||||||
|
|
||||||
|
|
|
@ -497,7 +497,7 @@ error:
|
||||||
/* We can't call strerror(saved_errno). It is not async signal safe.
|
/* We can't call strerror(saved_errno). It is not async signal safe.
|
||||||
* The parent process will look the error message up. */
|
* The parent process will look the error message up. */
|
||||||
} else {
|
} else {
|
||||||
unused = write(errpipe_write, "RuntimeError:0:", 15);
|
unused = write(errpipe_write, "SubprocessError:0:", 18);
|
||||||
unused = write(errpipe_write, err_msg, strlen(err_msg));
|
unused = write(errpipe_write, err_msg, strlen(err_msg));
|
||||||
}
|
}
|
||||||
if (unused) return; /* silly? yes! avoids gcc compiler warning. */
|
if (unused) return; /* silly? yes! avoids gcc compiler warning. */
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue