From a51dc0c7ce3b4964dc78c52c47c8210ae8e57553 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 1 Mar 2019 10:08:39 +0100 Subject: [PATCH 1/2] Validate type with writing to captured output like without Fixes https://github.com/pytest-dev/pytest/issues/4861. --- changelog/4861.bugfix.rst | 1 + src/_pytest/capture.py | 5 +++++ testing/test_capture.py | 24 ++++++++++++++++++++++++ 3 files changed, 30 insertions(+) create mode 100644 changelog/4861.bugfix.rst diff --git a/changelog/4861.bugfix.rst b/changelog/4861.bugfix.rst new file mode 100644 index 000000000..5b3a89aa2 --- /dev/null +++ b/changelog/4861.bugfix.rst @@ -0,0 +1 @@ +Validate type with writing to captured output like without. diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index 533690949..7bd319b1a 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -17,6 +17,7 @@ from tempfile import TemporaryFile import six import pytest +from _pytest.compat import _PY3 from _pytest.compat import CaptureIO patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"} @@ -412,6 +413,10 @@ class EncodedFile(object): def write(self, obj): if isinstance(obj, six.text_type): obj = obj.encode(self.encoding, "replace") + elif _PY3: + raise TypeError( + "write() argument must be str, not {}".format(type(obj).__name__) + ) self.buffer.write(obj) def writelines(self, linelist): diff --git a/testing/test_capture.py b/testing/test_capture.py index 81ab4e8a8..546738f28 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -18,6 +18,7 @@ from six import text_type import pytest from _pytest import capture from _pytest.capture import CaptureManager +from _pytest.compat import _PY3 from _pytest.main import EXIT_NOTESTSCOLLECTED # note: py.io capture tests where copied from @@ -1526,3 +1527,26 @@ def test_capture_with_live_logging(testdir, capture_fixture): result = testdir.runpytest_subprocess("--log-cli-level=INFO") assert result.ret == 0 + + +def test_typeerror_encodedfile_write(testdir): + """It should behave the same with and without output capturing (#4861).""" + p = testdir.makepyfile( + """ + def test_fails(): + import sys + sys.stdout.write(b"foo") + """ + ) + result_without_capture = testdir.runpytest("-s", str(p)) + + result_with_capture = testdir.runpytest(str(p)) + + assert result_with_capture.ret == result_without_capture.ret + + if _PY3: + result_with_capture.stdout.fnmatch_lines( + ["E TypeError: write() argument must be str, not bytes"] + ) + else: + assert result_with_capture.ret == 0 From 33db5e081d5eedc9e64f3b501ac4c0ce2a497178 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Fri, 1 Mar 2019 10:09:29 -0300 Subject: [PATCH 2/2] Tweak changelog --- changelog/4861.bugfix.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog/4861.bugfix.rst b/changelog/4861.bugfix.rst index 5b3a89aa2..b4bf125d1 100644 --- a/changelog/4861.bugfix.rst +++ b/changelog/4861.bugfix.rst @@ -1 +1 @@ -Validate type with writing to captured output like without. +Improve validation of contents written to captured output so it behaves the same as when capture is disabled.