[5.4.x] Fix crash when printing while capsysbinary is active (#7002)
Backport of 1fda861190
from master.
This commit is contained in:
parent
f7327759e8
commit
e3a3c90d94
|
@ -0,0 +1 @@
|
|||
Fix crash with captured output when using the :fixture:`capsysbinary fixture <capsysbinary>`.
|
|
@ -610,8 +610,6 @@ class FDCaptureBinary:
|
|||
|
||||
def writeorg(self, data):
|
||||
""" write to original file descriptor. """
|
||||
if isinstance(data, str):
|
||||
data = data.encode("utf8") # XXX use encoding of original stream
|
||||
os.write(self.targetfd_save, data)
|
||||
|
||||
|
||||
|
@ -631,6 +629,11 @@ class FDCapture(FDCaptureBinary):
|
|||
res = str(res, enc, "replace")
|
||||
return res
|
||||
|
||||
def writeorg(self, data):
|
||||
""" write to original file descriptor. """
|
||||
data = data.encode("utf-8") # XXX use encoding of original stream
|
||||
os.write(self.targetfd_save, data)
|
||||
|
||||
|
||||
class SysCaptureBinary:
|
||||
|
||||
|
@ -682,8 +685,9 @@ class SysCaptureBinary:
|
|||
self._state = "resumed"
|
||||
|
||||
def writeorg(self, data):
|
||||
self._old.write(data)
|
||||
self._old.flush()
|
||||
self._old.buffer.write(data)
|
||||
self._old.buffer.flush()
|
||||
|
||||
|
||||
class SysCapture(SysCaptureBinary):
|
||||
|
@ -695,6 +699,10 @@ class SysCapture(SysCaptureBinary):
|
|||
self.tmpfile.truncate()
|
||||
return res
|
||||
|
||||
def writeorg(self, data):
|
||||
self._old.write(data)
|
||||
self._old.flush()
|
||||
|
||||
|
||||
class TeeSysCapture(SysCapture):
|
||||
def __init__(self, fd, tmpfile=None):
|
||||
|
|
|
@ -542,18 +542,40 @@ class TestCaptureFixture:
|
|||
reprec.assertoutcome(passed=1)
|
||||
|
||||
def test_capsysbinary(self, testdir):
|
||||
reprec = testdir.inline_runsource(
|
||||
"""\
|
||||
p1 = testdir.makepyfile(
|
||||
r"""
|
||||
def test_hello(capsysbinary):
|
||||
import sys
|
||||
# some likely un-decodable bytes
|
||||
sys.stdout.buffer.write(b'\\xfe\\x98\\x20')
|
||||
|
||||
sys.stdout.buffer.write(b'hello')
|
||||
|
||||
# Some likely un-decodable bytes.
|
||||
sys.stdout.buffer.write(b'\xfe\x98\x20')
|
||||
|
||||
sys.stdout.buffer.flush()
|
||||
|
||||
# Ensure writing in text mode still works and is captured.
|
||||
# https://github.com/pytest-dev/pytest/issues/6871
|
||||
print("world", flush=True)
|
||||
|
||||
out, err = capsysbinary.readouterr()
|
||||
assert out == b'\\xfe\\x98\\x20'
|
||||
assert out == b'hello\xfe\x98\x20world\n'
|
||||
assert err == b''
|
||||
|
||||
print("stdout after")
|
||||
print("stderr after", file=sys.stderr)
|
||||
"""
|
||||
)
|
||||
reprec.assertoutcome(passed=1)
|
||||
result = testdir.runpytest(str(p1), "-rA")
|
||||
result.stdout.fnmatch_lines(
|
||||
[
|
||||
"*- Captured stdout call -*",
|
||||
"stdout after",
|
||||
"*- Captured stderr call -*",
|
||||
"stderr after",
|
||||
"*= 1 passed in *",
|
||||
]
|
||||
)
|
||||
|
||||
def test_partial_setup_failure(self, testdir):
|
||||
p = testdir.makepyfile(
|
||||
|
@ -977,7 +999,7 @@ class TestFDCapture:
|
|||
cap.start()
|
||||
tmpfile.write(data1)
|
||||
tmpfile.flush()
|
||||
cap.writeorg(data2)
|
||||
cap.writeorg(data2.decode("ascii"))
|
||||
scap = cap.snap()
|
||||
cap.done()
|
||||
assert scap == data1.decode("ascii")
|
||||
|
|
Loading…
Reference in New Issue