Suppress ``IOError`` when closing the temporary file used for capturing streams in Python 2.7.
Fix #2370
This commit is contained in:
		
							parent
							
								
									2612d967f8
								
							
						
					
					
						commit
						9517c3a2aa
					
				| 
						 | 
				
			
			@ -476,7 +476,7 @@ class FDCaptureBinary(object):
 | 
			
		|||
        os.dup2(targetfd_save, self.targetfd)
 | 
			
		||||
        os.close(targetfd_save)
 | 
			
		||||
        self.syscapture.done()
 | 
			
		||||
        self.tmpfile.close()
 | 
			
		||||
        _attempt_to_close_capture_file(self.tmpfile)
 | 
			
		||||
 | 
			
		||||
    def suspend(self):
 | 
			
		||||
        self.syscapture.suspend()
 | 
			
		||||
| 
						 | 
				
			
			@ -530,7 +530,7 @@ class SysCapture(object):
 | 
			
		|||
    def done(self):
 | 
			
		||||
        setattr(sys, self.name, self._old)
 | 
			
		||||
        del self._old
 | 
			
		||||
        self.tmpfile.close()
 | 
			
		||||
        _attempt_to_close_capture_file(self.tmpfile)
 | 
			
		||||
 | 
			
		||||
    def suspend(self):
 | 
			
		||||
        setattr(sys, self.name, self._old)
 | 
			
		||||
| 
						 | 
				
			
			@ -681,3 +681,14 @@ def _py36_windowsconsoleio_workaround(stream):
 | 
			
		|||
    sys.__stdin__ = sys.stdin = _reopen_stdio(sys.stdin, 'rb')
 | 
			
		||||
    sys.__stdout__ = sys.stdout = _reopen_stdio(sys.stdout, 'wb')
 | 
			
		||||
    sys.__stderr__ = sys.stderr = _reopen_stdio(sys.stderr, 'wb')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def _attempt_to_close_capture_file(f):
 | 
			
		||||
    """Suppress IOError when closing the temporary file used for capturing streams in py27 (#2370)"""
 | 
			
		||||
    if six.PY2:
 | 
			
		||||
        try:
 | 
			
		||||
            f.close()
 | 
			
		||||
        except IOError:
 | 
			
		||||
            pass
 | 
			
		||||
    else:
 | 
			
		||||
        f.close()
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -0,0 +1 @@
 | 
			
		|||
Suppress ``IOError`` when closing the temporary file used for capturing streams in Python 2.7.
 | 
			
		||||
| 
						 | 
				
			
			@ -1265,6 +1265,30 @@ def test_dontreadfrominput_has_encoding(testdir):
 | 
			
		|||
    reprec.assertoutcome(passed=1)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_crash_on_closing_tmpfile_py27(testdir):
 | 
			
		||||
    testdir.makepyfile('''
 | 
			
		||||
        from __future__ import print_function
 | 
			
		||||
        import time
 | 
			
		||||
        import threading
 | 
			
		||||
        import sys
 | 
			
		||||
 | 
			
		||||
        def spam():
 | 
			
		||||
            f = sys.stderr
 | 
			
		||||
            while True:
 | 
			
		||||
                print('.', end='', file=f)
 | 
			
		||||
 | 
			
		||||
        def test_silly():
 | 
			
		||||
            t = threading.Thread(target=spam)
 | 
			
		||||
            t.daemon = True
 | 
			
		||||
            t.start()
 | 
			
		||||
            time.sleep(0.5)
 | 
			
		||||
 | 
			
		||||
    ''')
 | 
			
		||||
    result = testdir.runpytest_subprocess()
 | 
			
		||||
    assert result.ret == 0
 | 
			
		||||
    assert 'IOError' not in result.stdout.str()
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
def test_pickling_and_unpickling_encoded_file():
 | 
			
		||||
    # See https://bitbucket.org/pytest-dev/pytest/pull-request/194
 | 
			
		||||
    # pickle.loads() raises infinite recursion if
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue