Skip to content

Commit 0dd4cb0

Browse files
authored
Merge pull request #4862 from blueyed/encodedfile-write-typerror
Validate type with writing to captured output like without
2 parents 276ffa8 + 33db5e0 commit 0dd4cb0

File tree

3 files changed

+30
-0
lines changed

3 files changed

+30
-0
lines changed

changelog/4861.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Improve validation of contents written to captured output so it behaves the same as when capture is disabled.

src/_pytest/capture.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import six
1818

1919
import pytest
20+
from _pytest.compat import _PY3
2021
from _pytest.compat import CaptureIO
2122

2223
patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"}
@@ -412,6 +413,10 @@ def __init__(self, buffer, encoding):
412413
def write(self, obj):
413414
if isinstance(obj, six.text_type):
414415
obj = obj.encode(self.encoding, "replace")
416+
elif _PY3:
417+
raise TypeError(
418+
"write() argument must be str, not {}".format(type(obj).__name__)
419+
)
415420
self.buffer.write(obj)
416421

417422
def writelines(self, linelist):

testing/test_capture.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import pytest
1919
from _pytest import capture
2020
from _pytest.capture import CaptureManager
21+
from _pytest.compat import _PY3
2122
from _pytest.main import EXIT_NOTESTSCOLLECTED
2223

2324
# note: py.io capture tests where copied from
@@ -1526,3 +1527,26 @@ def test_capture({0}):
15261527

15271528
result = testdir.runpytest_subprocess("--log-cli-level=INFO")
15281529
assert result.ret == 0
1530+
1531+
1532+
def test_typeerror_encodedfile_write(testdir):
1533+
"""It should behave the same with and without output capturing (#4861)."""
1534+
p = testdir.makepyfile(
1535+
"""
1536+
def test_fails():
1537+
import sys
1538+
sys.stdout.write(b"foo")
1539+
"""
1540+
)
1541+
result_without_capture = testdir.runpytest("-s", str(p))
1542+
1543+
result_with_capture = testdir.runpytest(str(p))
1544+
1545+
assert result_with_capture.ret == result_without_capture.ret
1546+
1547+
if _PY3:
1548+
result_with_capture.stdout.fnmatch_lines(
1549+
["E TypeError: write() argument must be str, not bytes"]
1550+
)
1551+
else:
1552+
assert result_with_capture.ret == 0

0 commit comments

Comments
 (0)