diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index 2798a24b4..d34bf23f8 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -11,10 +11,9 @@ from io import UnsupportedOperation from tempfile import TemporaryFile from typing import Generator from typing import Optional +from typing import TextIO import pytest -from _pytest.compat import CaptureAndPassthroughIO -from _pytest.compat import CaptureIO from _pytest.compat import TYPE_CHECKING from _pytest.config import Config from _pytest.fixtures import FixtureRequest @@ -320,6 +319,25 @@ def capfdbinary(request): yield fixture +class CaptureIO(io.TextIOWrapper): + def __init__(self) -> None: + super().__init__(io.BytesIO(), encoding="UTF-8", newline="", write_through=True) + + def getvalue(self) -> str: + assert isinstance(self.buffer, io.BytesIO) + return self.buffer.getvalue().decode("UTF-8") + + +class TeeCaptureIO(CaptureIO): + def __init__(self, other: TextIO) -> None: + self._other = other + super().__init__() + + def write(self, s: str) -> int: + super().write(s) + return self._other.write(s) + + class CaptureFixture: """ Object returned by :py:func:`capsys`, :py:func:`capsysbinary`, :py:func:`capfd` and :py:func:`capfdbinary` @@ -673,7 +691,7 @@ class TeeSysCapture(SysCapture): if name == "stdin": tmpfile = DontReadFromInput() else: - tmpfile = CaptureAndPassthroughIO(self._old) + tmpfile = TeeCaptureIO(self._old) self.tmpfile = tmpfile diff --git a/src/_pytest/compat.py b/src/_pytest/compat.py index cf051182f..ba225eb8f 100644 --- a/src/_pytest/compat.py +++ b/src/_pytest/compat.py @@ -3,7 +3,6 @@ python version compatibility code """ import functools import inspect -import io import os import re import sys @@ -13,7 +12,6 @@ from inspect import signature from typing import Any from typing import Callable from typing import Generic -from typing import IO from typing import Optional from typing import overload from typing import Tuple @@ -343,25 +341,6 @@ def safe_isclass(obj: object) -> bool: return False -class CaptureIO(io.TextIOWrapper): - def __init__(self) -> None: - super().__init__(io.BytesIO(), encoding="UTF-8", newline="", write_through=True) - - def getvalue(self) -> str: - assert isinstance(self.buffer, io.BytesIO) - return self.buffer.getvalue().decode("UTF-8") - - -class CaptureAndPassthroughIO(CaptureIO): - def __init__(self, other: IO) -> None: - self._other = other - super().__init__() - - def write(self, s) -> int: - super().write(s) - return self._other.write(s) - - if sys.version_info < (3, 5, 2): def overload(f): # noqa: F811 diff --git a/testing/test_capture.py b/testing/test_capture.py index b059073b5..233143193 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -804,10 +804,10 @@ class TestCaptureIO: assert f.getvalue() == "foo\r\n" -class TestCaptureAndPassthroughIO(TestCaptureIO): +class TestTeeCaptureIO(TestCaptureIO): def test_text(self): sio = io.StringIO() - f = capture.CaptureAndPassthroughIO(sio) + f = capture.TeeCaptureIO(sio) f.write("hello") s1 = f.getvalue() assert s1 == "hello" @@ -818,7 +818,7 @@ class TestCaptureAndPassthroughIO(TestCaptureIO): def test_unicode_and_str_mixture(self): sio = io.StringIO() - f = capture.CaptureAndPassthroughIO(sio) + f = capture.TeeCaptureIO(sio) f.write("\u00f6") pytest.raises(TypeError, f.write, b"hello")