From 8e54a40a20c9aab3cc51f8e1cfd9f57e5d799307 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Fri, 21 Feb 2020 14:35:16 +0100 Subject: [PATCH 1/3] capture: factor out _get_multicapture Ref: https://github.com/pytest-dev/pytest/pull/6671#issuecomment-588408992 --- src/_pytest/capture.py | 25 +++++++++++++------------ testing/test_capture.py | 9 +++++++++ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index 3643d782dd9..c7f3f30017e 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -66,6 +66,18 @@ def pytest_load_initial_conftests(early_config: Config): sys.stderr.write(err) +def _get_multicapture(method: str) -> "MultiCapture": + if method == "fd": + return MultiCapture(out=True, err=True, Capture=FDCapture) + elif method == "sys": + return MultiCapture(out=True, err=True, Capture=SysCapture) + elif method == "no": + return MultiCapture(out=False, err=False, in_=False) + elif method == "tee-sys": + return MultiCapture(out=True, err=True, in_=False, Capture=TeeSysCapture) + raise ValueError("unknown capturing method: {!r}".format(method)) + + class CaptureManager: """ Capture plugin, manages that the appropriate capture method is enabled/disabled during collection and each @@ -89,17 +101,6 @@ def __repr__(self): self._method, self._global_capturing, self._capture_fixture ) - def _getcapture(self, method): - if method == "fd": - return MultiCapture(out=True, err=True, Capture=FDCapture) - elif method == "sys": - return MultiCapture(out=True, err=True, Capture=SysCapture) - elif method == "no": - return MultiCapture(out=False, err=False, in_=False) - elif method == "tee-sys": - return MultiCapture(out=True, err=True, in_=False, Capture=TeeSysCapture) - raise ValueError("unknown capturing method: %r" % method) # pragma: no cover - def is_capturing(self): if self.is_globally_capturing(): return "global" @@ -114,7 +115,7 @@ def is_globally_capturing(self): def start_global_capturing(self): assert self._global_capturing is None - self._global_capturing = self._getcapture(self._method) + self._global_capturing = _get_multicapture(self._method) self._global_capturing.start_capturing() def stop_global_capturing(self): diff --git a/testing/test_capture.py b/testing/test_capture.py index e8e09ae73aa..b5f044e1541 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -14,7 +14,9 @@ import pytest from _pytest import capture +from _pytest.capture import _get_multicapture from _pytest.capture import CaptureManager +from _pytest.capture import MultiCapture from _pytest.config import ExitCode # note: py.io capture tests where copied from @@ -1563,3 +1565,10 @@ def test_encodedfile_writelines(tmpfile: BinaryIO) -> None: tmpfile.close() with pytest.raises(ValueError): ef.read() + + +def test__get_multicapture(): + assert isinstance(_get_multicapture("fd"), MultiCapture) + pytest.raises(ValueError, _get_multicapture, "unknown").match( + r"^unknown capturing method: 'unknown'" + ) From e1b6033765443741e1c9000a6306c1b0758a1995 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 22 Feb 2020 13:51:47 +0100 Subject: [PATCH 2/3] _CaptureMethod --- src/_pytest/capture.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/_pytest/capture.py b/src/_pytest/capture.py index c7f3f30017e..a1335d654f0 100644 --- a/src/_pytest/capture.py +++ b/src/_pytest/capture.py @@ -17,9 +17,15 @@ 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 +if TYPE_CHECKING: + from typing_extensions import Literal + + _CaptureMethod = Literal["fd", "sys", "no", "tee-sys"] + patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"} @@ -66,7 +72,7 @@ def pytest_load_initial_conftests(early_config: Config): sys.stderr.write(err) -def _get_multicapture(method: str) -> "MultiCapture": +def _get_multicapture(method: "_CaptureMethod") -> "MultiCapture": if method == "fd": return MultiCapture(out=True, err=True, Capture=FDCapture) elif method == "sys": @@ -91,7 +97,7 @@ class CaptureManager: case special handling is needed to ensure the fixtures take precedence over the global capture. """ - def __init__(self, method) -> None: + def __init__(self, method: "_CaptureMethod") -> None: self._method = method self._global_capturing = None self._capture_fixture = None # type: Optional[CaptureFixture] From 71a69876d1dba7fcc99e36c81b4fc305fa422973 Mon Sep 17 00:00:00 2001 From: Daniel Hahler Date: Sat, 22 Feb 2020 23:34:07 +0100 Subject: [PATCH 3/3] typing with test --- testing/test_capture.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/testing/test_capture.py b/testing/test_capture.py index b5f044e1541..7396fd26076 100644 --- a/testing/test_capture.py +++ b/testing/test_capture.py @@ -1567,7 +1567,7 @@ def test_encodedfile_writelines(tmpfile: BinaryIO) -> None: ef.read() -def test__get_multicapture(): +def test__get_multicapture() -> None: assert isinstance(_get_multicapture("fd"), MultiCapture) pytest.raises(ValueError, _get_multicapture, "unknown").match( r"^unknown capturing method: 'unknown'"