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.dup2(targetfd_save, self.targetfd)
|
||||||
os.close(targetfd_save)
|
os.close(targetfd_save)
|
||||||
self.syscapture.done()
|
self.syscapture.done()
|
||||||
self.tmpfile.close()
|
_attempt_to_close_capture_file(self.tmpfile)
|
||||||
|
|
||||||
def suspend(self):
|
def suspend(self):
|
||||||
self.syscapture.suspend()
|
self.syscapture.suspend()
|
||||||
|
@ -530,7 +530,7 @@ class SysCapture(object):
|
||||||
def done(self):
|
def done(self):
|
||||||
setattr(sys, self.name, self._old)
|
setattr(sys, self.name, self._old)
|
||||||
del self._old
|
del self._old
|
||||||
self.tmpfile.close()
|
_attempt_to_close_capture_file(self.tmpfile)
|
||||||
|
|
||||||
def suspend(self):
|
def suspend(self):
|
||||||
setattr(sys, self.name, self._old)
|
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.__stdin__ = sys.stdin = _reopen_stdio(sys.stdin, 'rb')
|
||||||
sys.__stdout__ = sys.stdout = _reopen_stdio(sys.stdout, 'wb')
|
sys.__stdout__ = sys.stdout = _reopen_stdio(sys.stdout, 'wb')
|
||||||
sys.__stderr__ = sys.stderr = _reopen_stdio(sys.stderr, '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)
|
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():
|
def test_pickling_and_unpickling_encoded_file():
|
||||||
# See https://bitbucket.org/pytest-dev/pytest/pull-request/194
|
# See https://bitbucket.org/pytest-dev/pytest/pull-request/194
|
||||||
# pickle.loads() raises infinite recursion if
|
# pickle.loads() raises infinite recursion if
|
||||||
|
|
Loading…
Reference in New Issue