mirror of https://github.com/python/cpython
Refactor test_preexec_errpipe to not create an uncollectable reference cycle.
This commit is contained in:
commit
859035d2ef
|
@ -1189,22 +1189,15 @@ class POSIXProcessTestCase(BaseTestCase):
|
||||||
self.fail("Exception raised by preexec_fn did not make it "
|
self.fail("Exception raised by preexec_fn did not make it "
|
||||||
"to the parent process.")
|
"to the parent process.")
|
||||||
|
|
||||||
@unittest.skipIf(not os.path.exists("/dev/zero"), "/dev/zero required.")
|
class _TestExecuteChildPopen(subprocess.Popen):
|
||||||
def test_preexec_errpipe_does_not_double_close_pipes(self):
|
"""Used to test behavior at the end of _execute_child."""
|
||||||
"""Issue16140: Don't double close pipes on preexec error."""
|
def __init__(self, testcase, *args, **kwargs):
|
||||||
class SafeConstructorPopen(subprocess.Popen):
|
self._testcase = testcase
|
||||||
def __init__(self):
|
|
||||||
pass # Do nothing so we can modify the instance for testing.
|
|
||||||
def RealPopen(self, *args, **kwargs):
|
|
||||||
subprocess.Popen.__init__(self, *args, **kwargs)
|
subprocess.Popen.__init__(self, *args, **kwargs)
|
||||||
def raise_it():
|
|
||||||
raise RuntimeError("force the _execute_child() errpipe_data path.")
|
|
||||||
|
|
||||||
p = SafeConstructorPopen()
|
def _execute_child(self, *args, **kwargs):
|
||||||
|
|
||||||
def _test_fds_execute_child_wrapper(*args, **kwargs):
|
|
||||||
try:
|
try:
|
||||||
subprocess.Popen._execute_child(p, *args, **kwargs)
|
subprocess.Popen._execute_child(self, *args, **kwargs)
|
||||||
finally:
|
finally:
|
||||||
# Open a bunch of file descriptors and verify that
|
# Open a bunch of file descriptors and verify that
|
||||||
# none of them are the same as the ones the Popen
|
# none of them are the same as the ones the Popen
|
||||||
|
@ -1213,17 +1206,23 @@ class POSIXProcessTestCase(BaseTestCase):
|
||||||
for _ in range(8)]
|
for _ in range(8)]
|
||||||
try:
|
try:
|
||||||
for fd in devzero_fds:
|
for fd in devzero_fds:
|
||||||
self.assertNotIn(fd, (
|
self._testcase.assertNotIn(
|
||||||
p.stdin.fileno(), p.stdout.fileno(),
|
fd, (self.stdin.fileno(), self.stdout.fileno(),
|
||||||
p.stderr.fileno()),
|
self.stderr.fileno()),
|
||||||
msg="At least one fd was closed early.")
|
msg="At least one fd was closed early.")
|
||||||
finally:
|
finally:
|
||||||
map(os.close, devzero_fds)
|
map(os.close, devzero_fds)
|
||||||
|
|
||||||
p._execute_child = _test_fds_execute_child_wrapper
|
@unittest.skipIf(not os.path.exists("/dev/zero"), "/dev/zero required.")
|
||||||
|
def test_preexec_errpipe_does_not_double_close_pipes(self):
|
||||||
|
"""Issue16140: Don't double close pipes on preexec error."""
|
||||||
|
|
||||||
|
def raise_it():
|
||||||
|
raise RuntimeError("force the _execute_child() errpipe_data path.")
|
||||||
|
|
||||||
with self.assertRaises(RuntimeError):
|
with self.assertRaises(RuntimeError):
|
||||||
p.RealPopen([sys.executable, "-c", "pass"],
|
self._TestExecuteChildPopen(
|
||||||
|
self, [sys.executable, "-c", "pass"],
|
||||||
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
stdin=subprocess.PIPE, stdout=subprocess.PIPE,
|
||||||
stderr=subprocess.PIPE, preexec_fn=raise_it)
|
stderr=subprocess.PIPE, preexec_fn=raise_it)
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue