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 import pytest
from _pytest.compat import CaptureAndPassthroughIO from _pytest.compat import CaptureAndPassthroughIO
from _pytest.compat import CaptureIO from _pytest.compat import CaptureIO
from _pytest.compat import TYPE_CHECKING
from _pytest.config import Config from _pytest.config import Config
from _pytest.fixtures import FixtureRequest 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"} patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"}
@ -66,6 +72,18 @@ def pytest_load_initial_conftests(early_config: Config):
sys.stderr.write(err) 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: class CaptureManager:
""" """
Capture plugin, manages that the appropriate capture method is enabled/disabled during collection and each 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. 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._method = method
self._global_capturing = None self._global_capturing = None
self._capture_fixture = None # type: Optional[CaptureFixture] self._capture_fixture = None # type: Optional[CaptureFixture]
@ -89,17 +107,6 @@ class CaptureManager:
self._method, self._global_capturing, self._capture_fixture 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): def is_capturing(self):
if self.is_globally_capturing(): if self.is_globally_capturing():
return "global" return "global"
@ -114,7 +121,7 @@ class CaptureManager:
def start_global_capturing(self): def start_global_capturing(self):
assert self._global_capturing is None 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() self._global_capturing.start_capturing()
def stop_global_capturing(self): def stop_global_capturing(self):

View File

@ -14,7 +14,9 @@ from typing import TextIO
import pytest import pytest
from _pytest import capture from _pytest import capture
from _pytest.capture import _get_multicapture
from _pytest.capture import CaptureManager from _pytest.capture import CaptureManager
from _pytest.capture import MultiCapture
from _pytest.config import ExitCode from _pytest.config import ExitCode
# note: py.io capture tests where copied from # note: py.io capture tests where copied from
@ -1563,3 +1565,10 @@ def test_encodedfile_writelines(tmpfile: BinaryIO) -> None:
tmpfile.close() tmpfile.close()
with pytest.raises(ValueError): with pytest.raises(ValueError):
ef.read() 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'"
)