Skip to content

Commit 706ea86

Browse files
authored
capture: factor out _get_multicapture (#6788)
Ref: #6671 (comment)
1 parent 1d5a0ef commit 706ea86

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

src/_pytest/capture.py

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,15 @@
1717
import pytest
1818
from _pytest.compat import CaptureAndPassthroughIO
1919
from _pytest.compat import CaptureIO
20+
from _pytest.compat import TYPE_CHECKING
2021
from _pytest.config import Config
2122
from _pytest.fixtures import FixtureRequest
2223

24+
if TYPE_CHECKING:
25+
from typing_extensions import Literal
26+
27+
_CaptureMethod = Literal["fd", "sys", "no", "tee-sys"]
28+
2329
patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"}
2430

2531

@@ -66,6 +72,18 @@ def pytest_load_initial_conftests(early_config: Config):
6672
sys.stderr.write(err)
6773

6874

75+
def _get_multicapture(method: "_CaptureMethod") -> "MultiCapture":
76+
if method == "fd":
77+
return MultiCapture(out=True, err=True, Capture=FDCapture)
78+
elif method == "sys":
79+
return MultiCapture(out=True, err=True, Capture=SysCapture)
80+
elif method == "no":
81+
return MultiCapture(out=False, err=False, in_=False)
82+
elif method == "tee-sys":
83+
return MultiCapture(out=True, err=True, in_=False, Capture=TeeSysCapture)
84+
raise ValueError("unknown capturing method: {!r}".format(method))
85+
86+
6987
class CaptureManager:
7088
"""
7189
Capture plugin, manages that the appropriate capture method is enabled/disabled during collection and each
@@ -79,7 +97,7 @@ class CaptureManager:
7997
case special handling is needed to ensure the fixtures take precedence over the global capture.
8098
"""
8199

82-
def __init__(self, method) -> None:
100+
def __init__(self, method: "_CaptureMethod") -> None:
83101
self._method = method
84102
self._global_capturing = None
85103
self._capture_fixture = None # type: Optional[CaptureFixture]
@@ -89,17 +107,6 @@ def __repr__(self):
89107
self._method, self._global_capturing, self._capture_fixture
90108
)
91109

92-
def _getcapture(self, method):
93-
if method == "fd":
94-
return MultiCapture(out=True, err=True, Capture=FDCapture)
95-
elif method == "sys":
96-
return MultiCapture(out=True, err=True, Capture=SysCapture)
97-
elif method == "no":
98-
return MultiCapture(out=False, err=False, in_=False)
99-
elif method == "tee-sys":
100-
return MultiCapture(out=True, err=True, in_=False, Capture=TeeSysCapture)
101-
raise ValueError("unknown capturing method: %r" % method) # pragma: no cover
102-
103110
def is_capturing(self):
104111
if self.is_globally_capturing():
105112
return "global"
@@ -114,7 +121,7 @@ def is_globally_capturing(self):
114121

115122
def start_global_capturing(self):
116123
assert self._global_capturing is None
117-
self._global_capturing = self._getcapture(self._method)
124+
self._global_capturing = _get_multicapture(self._method)
118125
self._global_capturing.start_capturing()
119126

120127
def stop_global_capturing(self):

testing/test_capture.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
import pytest
1616
from _pytest import capture
17+
from _pytest.capture import _get_multicapture
1718
from _pytest.capture import CaptureManager
19+
from _pytest.capture import MultiCapture
1820
from _pytest.config import ExitCode
1921

2022
# note: py.io capture tests where copied from
@@ -1563,3 +1565,10 @@ def test_encodedfile_writelines(tmpfile: BinaryIO) -> None:
15631565
tmpfile.close()
15641566
with pytest.raises(ValueError):
15651567
ef.read()
1568+
1569+
1570+
def test__get_multicapture() -> None:
1571+
assert isinstance(_get_multicapture("fd"), MultiCapture)
1572+
pytest.raises(ValueError, _get_multicapture, "unknown").match(
1573+
r"^unknown capturing method: 'unknown'"
1574+
)

0 commit comments

Comments
 (0)