[3.6] bpo-30121: Fix debug assert in subprocess on Windows (#1224) (#… · python/cpython@e76cb43 (original) (raw)
`@@ -49,6 +49,8 @@
`
49
49
`else:
`
50
50
`SETBINARY = ''
`
51
51
``
``
52
`+
NONEXISTING_CMD = ('nonexisting_i_hope',)
`
``
53
+
52
54
``
53
55
`class BaseTestCase(unittest.TestCase):
`
54
56
`def setUp(self):
`
`@@ -1120,10 +1122,11 @@ def _test_bufsize_equal_one(self, line, expected, universal_newlines):
`
1120
1122
`p.stdin.write(line) # expect that it flushes the line in text mode
`
1121
1123
`os.close(p.stdin.fileno()) # close it without flushing the buffer
`
1122
1124
`read_line = p.stdout.readline()
`
1123
``
`-
try:
`
1124
``
`-
p.stdin.close()
`
1125
``
`-
except OSError:
`
1126
``
`-
pass
`
``
1125
`+
with support.SuppressCrashReport():
`
``
1126
`+
try:
`
``
1127
`+
p.stdin.close()
`
``
1128
`+
except OSError:
`
``
1129
`+
pass
`
1127
1130
`p.stdin = None
`
1128
1131
`self.assertEqual(p.returncode, 0)
`
1129
1132
`self.assertEqual(read_line, expected)
`
`@@ -1148,13 +1151,54 @@ def test_leaking_fds_on_error(self):
`
1148
1151
`# 1024 times (each call leaked two fds).
`
1149
1152
`for i in range(1024):
`
1150
1153
`with self.assertRaises(OSError) as c:
`
1151
``
`-
subprocess.Popen(['nonexisting_i_hope'],
`
``
1154
`+
subprocess.Popen(NONEXISTING_CMD,
`
1152
1155
`stdout=subprocess.PIPE,
`
1153
1156
`stderr=subprocess.PIPE)
`
1154
1157
`# ignore errors that indicate the command was not found
`
1155
1158
`if c.exception.errno not in (errno.ENOENT, errno.EACCES):
`
1156
1159
`raise c.exception
`
1157
1160
``
``
1161
`+
def test_nonexisting_with_pipes(self):
`
``
1162
`+
bpo-30121: Popen with pipes must close properly pipes on error.
`
``
1163
`+
Previously, os.close() was called with a Windows handle which is not
`
``
1164
`+
a valid file descriptor.
`
``
1165
`+
`
``
1166
`+
Run the test in a subprocess to control how the CRT reports errors
`
``
1167
`+
and to get stderr content.
`
``
1168
`+
try:
`
``
1169
`+
import msvcrt
`
``
1170
`+
msvcrt.CrtSetReportMode
`
``
1171
`+
except (AttributeError, ImportError):
`
``
1172
`+
self.skipTest("need msvcrt.CrtSetReportMode")
`
``
1173
+
``
1174
`+
code = textwrap.dedent(f"""
`
``
1175
`+
import msvcrt
`
``
1176
`+
import subprocess
`
``
1177
+
``
1178
`+
cmd = {NONEXISTING_CMD!r}
`
``
1179
+
``
1180
`+
for report_type in [msvcrt.CRT_WARN,
`
``
1181
`+
msvcrt.CRT_ERROR,
`
``
1182
`+
msvcrt.CRT_ASSERT]:
`
``
1183
`+
msvcrt.CrtSetReportMode(report_type, msvcrt.CRTDBG_MODE_FILE)
`
``
1184
`+
msvcrt.CrtSetReportFile(report_type, msvcrt.CRTDBG_FILE_STDERR)
`
``
1185
+
``
1186
`+
try:
`
``
1187
`+
subprocess.Popen([cmd],
`
``
1188
`+
stdout=subprocess.PIPE,
`
``
1189
`+
stderr=subprocess.PIPE)
`
``
1190
`+
except OSError:
`
``
1191
`+
pass
`
``
1192
`+
""")
`
``
1193
`+
cmd = [sys.executable, "-c", code]
`
``
1194
`+
proc = subprocess.Popen(cmd,
`
``
1195
`+
stderr=subprocess.PIPE,
`
``
1196
`+
universal_newlines=True)
`
``
1197
`+
with proc:
`
``
1198
`+
stderr = proc.communicate()[1]
`
``
1199
`+
self.assertEqual(stderr, "")
`
``
1200
`+
self.assertEqual(proc.returncode, 0)
`
``
1201
+
1158
1202
`@unittest.skipIf(threading is None, "threading required")
`
1159
1203
`def test_double_close_on_error(self):
`
1160
1204
`# Issue #18851
`
`@@ -1167,7 +1211,7 @@ def open_fds():
`
1167
1211
`t.start()
`
1168
1212
`try:
`
1169
1213
`with self.assertRaises(EnvironmentError):
`
1170
``
`-
subprocess.Popen(['nonexisting_i_hope'],
`
``
1214
`+
subprocess.Popen(NONEXISTING_CMD,
`
1171
1215
`stdin=subprocess.PIPE,
`
1172
1216
`stdout=subprocess.PIPE,
`
1173
1217
`stderr=subprocess.PIPE)
`
`@@ -2433,7 +2477,7 @@ def test_leak_fast_process_del_killed(self):
`
2433
2477
`# should trigger the wait() of p
`
2434
2478
`time.sleep(0.2)
`
2435
2479
`with self.assertRaises(OSError) as c:
`
2436
``
`-
with subprocess.Popen(['nonexisting_i_hope'],
`
``
2480
`+
with subprocess.Popen(NONEXISTING_CMD,
`
2437
2481
`stdout=subprocess.PIPE,
`
2438
2482
`stderr=subprocess.PIPE) as proc:
`
2439
2483
`pass
`
`@@ -2863,7 +2907,7 @@ def test_communicate_stdin(self):
`
2863
2907
``
2864
2908
`def test_invalid_args(self):
`
2865
2909
`with self.assertRaises((FileNotFoundError, PermissionError)) as c:
`
2866
``
`-
with subprocess.Popen(['nonexisting_i_hope'],
`
``
2910
`+
with subprocess.Popen(NONEXISTING_CMD,
`
2867
2911
`stdout=subprocess.PIPE,
`
2868
2912
`stderr=subprocess.PIPE) as proc:
`
2869
2913
`pass
`