Skip to content

Commit daeefd2

Browse files
authored
bpo-28326: Fix multiprocessing.Process when stdout and/or stderr is closed or None. (#4073)
1 parent 73c4708 commit daeefd2

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

Lib/multiprocessing/popen_fork.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,14 @@ class Popen(object):
1414
method = 'fork'
1515

1616
def __init__(self, process_obj):
17-
sys.stdout.flush()
18-
sys.stderr.flush()
17+
try:
18+
sys.stdout.flush()
19+
except (AttributeError, ValueError):
20+
pass
21+
try:
22+
sys.stderr.flush()
23+
except (AttributeError, ValueError):
24+
pass
1925
self.returncode = None
2026
self.finalizer = None
2127
self._launch(process_obj)

Lib/test/_test_multiprocessing.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,27 @@ def test_wait_for_threads(self):
582582
proc.join()
583583
self.assertTrue(evt.is_set())
584584

585+
@classmethod
586+
def _test_error_on_stdio_flush(self, evt):
587+
evt.set()
588+
589+
def test_error_on_stdio_flush(self):
590+
streams = [io.StringIO(), None]
591+
streams[0].close()
592+
for stream_name in ('stdout', 'stderr'):
593+
for stream in streams:
594+
old_stream = getattr(sys, stream_name)
595+
setattr(sys, stream_name, stream)
596+
try:
597+
evt = self.Event()
598+
proc = self.Process(target=self._test_error_on_stdio_flush,
599+
args=(evt,))
600+
proc.start()
601+
proc.join()
602+
self.assertTrue(evt.is_set())
603+
finally:
604+
setattr(sys, stream_name, old_stream)
605+
585606

586607
#
587608
#
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix multiprocessing.Process when stdout and/or stderr is closed or None.

0 commit comments

Comments
 (0)