@@ -70,7 +70,9 @@ def run_test_in_subprocess(testname: str, ns: Namespace) -> subprocess.Popen:
7070 kw ['start_new_session' ] = True
7171 return subprocess .Popen (cmd ,
7272 stdout = subprocess .PIPE ,
73- stderr = subprocess .PIPE ,
73+ # bpo-45410: Write stderr into stdout to keep
74+ # messages order
75+ stderr = subprocess .STDOUT ,
7476 universal_newlines = True ,
7577 close_fds = (os .name != 'nt' ),
7678 cwd = os_helper .SAVEDCWD ,
@@ -114,8 +116,8 @@ def stop(self):
114116
115117class MultiprocessResult (NamedTuple ):
116118 result : TestResult
119+ # bpo-45410: stderr is written into stdout to keep messages order
117120 stdout : str
118- stderr : str
119121 error_msg : str
120122
121123
@@ -195,11 +197,10 @@ def mp_result_error(
195197 self ,
196198 test_result : TestResult ,
197199 stdout : str = '' ,
198- stderr : str = '' ,
199200 err_msg = None
200201 ) -> MultiprocessResult :
201202 test_result .duration_sec = time .monotonic () - self .start_time
202- return MultiprocessResult (test_result , stdout , stderr , err_msg )
203+ return MultiprocessResult (test_result , stdout , err_msg )
203204
204205 def _run_process (self , test_name : str ) -> tuple [int , str , str ]:
205206 self .start_time = time .monotonic ()
@@ -223,13 +224,14 @@ def _run_process(self, test_name: str) -> tuple[int, str, str]:
223224 raise ExitThread
224225
225226 try :
226- stdout , stderr = popen .communicate (timeout = self .timeout )
227+ # bpo-45410: stderr is written into stdout
228+ stdout , _ = popen .communicate (timeout = self .timeout )
227229 retcode = popen .returncode
228230 assert retcode is not None
229231 except subprocess .TimeoutExpired :
230232 if self ._stopped :
231- # kill() has been called: communicate() fails
232- # on reading closed stdout/stderr
233+ # kill() has been called: communicate() fails on reading
234+ # closed stdout
233235 raise ExitThread
234236
235237 # On timeout, kill the process
@@ -238,20 +240,19 @@ def _run_process(self, test_name: str) -> tuple[int, str, str]:
238240 # None means TIMEOUT for the caller
239241 retcode = None
240242 # bpo-38207: Don't attempt to call communicate() again: on it
241- # can hang until all child processes using stdout and stderr
243+ # can hang until all child processes using stdout
242244 # pipes completes.
243- stdout = stderr = ''
245+ stdout = ''
244246 except OSError :
245247 if self ._stopped :
246248 # kill() has been called: communicate() fails
247- # on reading closed stdout/stderr
249+ # on reading closed stdout
248250 raise ExitThread
249251 raise
250252 else :
251253 stdout = stdout .strip ()
252- stderr = stderr .rstrip ()
253254
254- return (retcode , stdout , stderr )
255+ return (retcode , stdout )
255256 except :
256257 self ._kill ()
257258 raise
@@ -261,10 +262,10 @@ def _run_process(self, test_name: str) -> tuple[int, str, str]:
261262 self .current_test_name = None
262263
263264 def _runtest (self , test_name : str ) -> MultiprocessResult :
264- retcode , stdout , stderr = self ._run_process (test_name )
265+ retcode , stdout = self ._run_process (test_name )
265266
266267 if retcode is None :
267- return self .mp_result_error (Timeout (test_name ), stdout , stderr )
268+ return self .mp_result_error (Timeout (test_name ), stdout )
268269
269270 err_msg = None
270271 if retcode != 0 :
@@ -282,10 +283,9 @@ def _runtest(self, test_name: str) -> MultiprocessResult:
282283 err_msg = "Failed to parse worker JSON: %s" % exc
283284
284285 if err_msg is not None :
285- return self .mp_result_error (ChildError (test_name ),
286- stdout , stderr , err_msg )
286+ return self .mp_result_error (ChildError (test_name ), stdout , err_msg )
287287
288- return MultiprocessResult (result , stdout , stderr , err_msg )
288+ return MultiprocessResult (result , stdout , err_msg )
289289
290290 def run (self ) -> None :
291291 while not self ._stopped :
@@ -309,10 +309,8 @@ def run(self) -> None:
309309 def _wait_completed (self ) -> None :
310310 popen = self ._popen
311311
312- # stdout and stderr must be closed to ensure that communicate()
313- # does not hang
312+ # stdout must be closed to ensure that communicate() does not hang
314313 popen .stdout .close ()
315- popen .stderr .close ()
316314
317315 try :
318316 popen .wait (JOIN_TIMEOUT )
@@ -449,8 +447,6 @@ def _process_result(self, item: QueueOutput) -> bool:
449447
450448 if mp_result .stdout :
451449 print (mp_result .stdout , flush = True )
452- if mp_result .stderr and not self .ns .pgo :
453- print (mp_result .stderr , file = sys .stderr , flush = True )
454450
455451 if must_stop (mp_result .result , self .ns ):
456452 return True
0 commit comments