capture: factor out _get_multicapture (#6788)

Ref: https://github.com/pytest-dev/pytest/pull/6671#issuecomment-588408992
This commit is contained in:
Daniel Hahler 2020-02-22 23:39:20 +01:00 committed by GitHub
parent 1d5a0ef284
commit 706ea86bba
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 29 additions and 13 deletions

View File

@ -17,9 +17,15 @@ from typing import Optional
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,6 +72,18 @@ def pytest_load_initial_conftests(early_config: Config):
sys.stderr.write(err)
def _get_multicapture(method: "_CaptureMethod") -> "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
@ -79,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]
@ -89,17 +107,6 @@ class CaptureManager:
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 +121,7 @@ class CaptureManager:
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):

View File

@ -14,7 +14,9 @@ from typing import TextIO
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() -> None:
assert isinstance(_get_multicapture("fd"), MultiCapture)
pytest.raises(ValueError, _get_multicapture, "unknown").match(
r"^unknown capturing method: 'unknown'"
)