File tree Expand file tree Collapse file tree 3 files changed +38
-2
lines changed Expand file tree Collapse file tree 3 files changed +38
-2
lines changed Original file line number Diff line number Diff line change @@ -476,7 +476,7 @@ def done(self):
476476 os .dup2 (targetfd_save , self .targetfd )
477477 os .close (targetfd_save )
478478 self .syscapture .done ()
479- self .tmpfile . close ( )
479+ _attempt_to_close_capture_file ( self .tmpfile )
480480
481481 def suspend (self ):
482482 self .syscapture .suspend ()
@@ -530,7 +530,7 @@ def snap(self):
530530 def done (self ):
531531 setattr (sys , self .name , self ._old )
532532 del self ._old
533- self .tmpfile . close ( )
533+ _attempt_to_close_capture_file ( self .tmpfile )
534534
535535 def suspend (self ):
536536 setattr (sys , self .name , self ._old )
@@ -681,3 +681,14 @@ def _reopen_stdio(f, mode):
681681 sys .__stdin__ = sys .stdin = _reopen_stdio (sys .stdin , 'rb' )
682682 sys .__stdout__ = sys .stdout = _reopen_stdio (sys .stdout , 'wb' )
683683 sys .__stderr__ = sys .stderr = _reopen_stdio (sys .stderr , 'wb' )
684+
685+
686+ def _attempt_to_close_capture_file (f ):
687+ """Suppress IOError when closing the temporary file used for capturing streams in py27 (#2370)"""
688+ if six .PY2 :
689+ try :
690+ f .close ()
691+ except IOError :
692+ pass
693+ else :
694+ f .close ()
Original file line number Diff line number Diff line change 1+ Suppress ``IOError `` when closing the temporary file used for capturing streams in Python 2.7.
Original file line number Diff line number Diff line change @@ -1265,6 +1265,30 @@ def test_capattr():
12651265 reprec .assertoutcome (passed = 1 )
12661266
12671267
1268+ def test_crash_on_closing_tmpfile_py27 (testdir ):
1269+ testdir .makepyfile ('''
1270+ from __future__ import print_function
1271+ import time
1272+ import threading
1273+ import sys
1274+
1275+ def spam():
1276+ f = sys.stderr
1277+ while True:
1278+ print('.', end='', file=f)
1279+
1280+ def test_silly():
1281+ t = threading.Thread(target=spam)
1282+ t.daemon = True
1283+ t.start()
1284+ time.sleep(0.5)
1285+
1286+ ''' )
1287+ result = testdir .runpytest_subprocess ()
1288+ assert result .ret == 0
1289+ assert 'IOError' not in result .stdout .str ()
1290+
1291+
12681292def test_pickling_and_unpickling_encoded_file ():
12691293 # See https://bitbucket.org/pytest-dev/pytest/pull-request/194
12701294 # pickle.loads() raises infinite recursion if
You can’t perform that action at this time.
0 commit comments