diff --git a/changelog/6871.bugfix.rst b/changelog/6871.bugfix.rst new file mode 100644 index 00000000000..fe69c750915 --- /dev/null +++ b/changelog/6871.bugfix.rst @@ -0,0 +1 @@ +Fix crash with captured output when using the :fixture:`capsysbinary fixture `. diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index 1df4667907c..5e79711c2ca 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -682,7 +682,8 @@ def resume(self): setattr(sys, self.name, self.tmpfile) self._state = "resumed" - def writeorg(self, data): + def writeorg(self, data: str) -> None: + data = data.decode(self._old.encoding) self._old.write(data) self._old.flush() @@ -696,6 +697,10 @@ def snap(self): self.tmpfile.truncate() return res + def writeorg(self, data: str) -> None: + self._old.write(data) + self._old.flush() + class TeeSysCapture(SysCapture): def __init__(self, fd, tmpfile=None): diff --git a/testing/test_capture.py b/testing/test_capture.py index d30d796d0c2..2303fd2cac0 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -542,18 +542,33 @@ def test_hello(capfdbinary): reprec.assertoutcome(passed=1) def test_capsysbinary(self, testdir): - reprec = testdir.inline_runsource( + p1 = testdir.makepyfile( """\ def test_hello(capsysbinary): import sys + # some likely un-decodable bytes sys.stdout.buffer.write(b'\\xfe\\x98\\x20') + out, err = capsysbinary.readouterr() assert out == b'\\xfe\\x98\\x20' assert err == b'' + + # handles writing strings + print("hello") + print("hello stderr", file=sys.stderr) """ ) - reprec.assertoutcome(passed=1) + result = testdir.runpytest(str(p1), "-rA") + result.stdout.fnmatch_lines( + [ + "*- Captured stdout call -*", + "hello", + "*- Captured stderr call -*", + "hello stderr", + "*= 1 passed in *", + ] + ) def test_partial_setup_failure(self, testdir): p = testdir.makepyfile(