|
11 | 11 | from tempfile import TemporaryFile |
12 | 12 | from typing import BinaryIO |
13 | 13 | from typing import Generator |
| 14 | +from typing import IO |
14 | 15 | from typing import Iterable |
15 | 16 | from typing import Optional |
16 | 17 |
|
17 | 18 | import pytest |
18 | | -from _pytest.compat import CaptureAndPassthroughIO |
19 | | -from _pytest.compat import CaptureIO |
20 | 19 | from _pytest.config import Config |
21 | 20 | from _pytest.fixtures import FixtureRequest |
22 | 21 |
|
@@ -98,7 +97,8 @@ def _getcapture(self, method): |
98 | 97 | return MultiCapture(out=False, err=False, in_=False) |
99 | 98 | elif method == "tee-sys": |
100 | 99 | return MultiCapture(out=True, err=True, in_=False, Capture=TeeSysCapture) |
101 | | - raise ValueError("unknown capturing method: %r" % method) # pragma: no cover |
| 100 | + else: |
| 101 | + assert False, "unknown capturing method: {}".format(method) |
102 | 102 |
|
103 | 103 | def is_capturing(self): |
104 | 104 | if self.is_globally_capturing(): |
@@ -323,6 +323,25 @@ def capfdbinary(request): |
323 | 323 | yield fixture |
324 | 324 |
|
325 | 325 |
|
| 326 | +class CaptureIO(io.TextIOWrapper): |
| 327 | + def __init__(self) -> None: |
| 328 | + super().__init__(io.BytesIO(), encoding="UTF-8", newline="", write_through=True) |
| 329 | + |
| 330 | + def getvalue(self) -> str: |
| 331 | + assert isinstance(self.buffer, io.BytesIO) |
| 332 | + return self.buffer.getvalue().decode("UTF-8") |
| 333 | + |
| 334 | + |
| 335 | +class PassthroughCaptureIO(CaptureIO): |
| 336 | + def __init__(self, other: IO) -> None: |
| 337 | + self._other = other |
| 338 | + super().__init__() |
| 339 | + |
| 340 | + def write(self, s) -> int: |
| 341 | + super().write(s) |
| 342 | + return self._other.write(s) |
| 343 | + |
| 344 | + |
326 | 345 | class CaptureFixture: |
327 | 346 | """ |
328 | 347 | Object returned by :py:func:`capsys`, :py:func:`capsysbinary`, :py:func:`capfd` and :py:func:`capfdbinary` |
@@ -686,16 +705,13 @@ def snap(self): |
686 | 705 |
|
687 | 706 |
|
688 | 707 | class TeeSysCapture(SysCapture): |
689 | | - def __init__(self, fd, tmpfile=None): |
690 | | - name = patchsysdict[fd] |
691 | | - self._old = getattr(sys, name) |
692 | | - self.name = name |
693 | | - if tmpfile is None: |
694 | | - if name == "stdin": |
695 | | - tmpfile = DontReadFromInput() |
696 | | - else: |
697 | | - tmpfile = CaptureAndPassthroughIO(self._old) |
698 | | - self.tmpfile = tmpfile |
| 708 | + def __init__(self, fd: int) -> None: |
| 709 | + old = getattr(sys, patchsysdict[fd]) |
| 710 | + if fd == 0: |
| 711 | + super().__init__(fd) |
| 712 | + else: |
| 713 | + super().__init__(fd, PassthroughCaptureIO(old)) |
| 714 | + assert self._old == old, (self._old, old) |
699 | 715 |
|
700 | 716 |
|
701 | 717 | map_fixname_class = { |
|
0 commit comments