mirror of
https://github.com/pre-commit/pre-commit-hooks.git
synced 2026-04-10 13:24:18 +00:00
[pre-commit.ci] auto fixes from pre-commit.com hooks
for more information, see https://pre-commit.ci
This commit is contained in:
parent
72ad6dc953
commit
f4cd1ba0d6
813 changed files with 66015 additions and 58839 deletions
|
|
@ -1,12 +1,14 @@
|
|||
# mypy: allow-untyped-defs
|
||||
"""Per-test stdout/stderr capturing mechanism."""
|
||||
from __future__ import annotations
|
||||
|
||||
import abc
|
||||
import collections
|
||||
import contextlib
|
||||
import io
|
||||
from io import UnsupportedOperation
|
||||
import os
|
||||
import sys
|
||||
from io import UnsupportedOperation
|
||||
from tempfile import TemporaryFile
|
||||
from types import TracebackType
|
||||
from typing import Any
|
||||
|
|
@ -40,25 +42,25 @@ from _pytest.nodes import Item
|
|||
from _pytest.reports import CollectReport
|
||||
|
||||
|
||||
_CaptureMethod = Literal["fd", "sys", "no", "tee-sys"]
|
||||
_CaptureMethod = Literal['fd', 'sys', 'no', 'tee-sys']
|
||||
|
||||
|
||||
def pytest_addoption(parser: Parser) -> None:
|
||||
group = parser.getgroup("general")
|
||||
group = parser.getgroup('general')
|
||||
group._addoption(
|
||||
"--capture",
|
||||
action="store",
|
||||
default="fd",
|
||||
metavar="method",
|
||||
choices=["fd", "sys", "no", "tee-sys"],
|
||||
help="Per-test capturing method: one of fd|sys|no|tee-sys",
|
||||
'--capture',
|
||||
action='store',
|
||||
default='fd',
|
||||
metavar='method',
|
||||
choices=['fd', 'sys', 'no', 'tee-sys'],
|
||||
help='Per-test capturing method: one of fd|sys|no|tee-sys',
|
||||
)
|
||||
group._addoption(
|
||||
"-s",
|
||||
action="store_const",
|
||||
const="no",
|
||||
dest="capture",
|
||||
help="Shortcut for --capture=no",
|
||||
'-s',
|
||||
action='store_const',
|
||||
const='no',
|
||||
dest='capture',
|
||||
help='Shortcut for --capture=no',
|
||||
)
|
||||
|
||||
|
||||
|
|
@ -70,7 +72,7 @@ def _colorama_workaround() -> None:
|
|||
first import of colorama while I/O capture is active, colorama will
|
||||
fail in various ways.
|
||||
"""
|
||||
if sys.platform.startswith("win32"):
|
||||
if sys.platform.startswith('win32'):
|
||||
try:
|
||||
import colorama # noqa: F401
|
||||
except ImportError:
|
||||
|
|
@ -101,21 +103,21 @@ def _windowsconsoleio_workaround(stream: TextIO) -> None:
|
|||
|
||||
See https://github.com/pytest-dev/py/issues/103.
|
||||
"""
|
||||
if not sys.platform.startswith("win32") or hasattr(sys, "pypy_version_info"):
|
||||
if not sys.platform.startswith('win32') or hasattr(sys, 'pypy_version_info'):
|
||||
return
|
||||
|
||||
# Bail out if ``stream`` doesn't seem like a proper ``io`` stream (#2666).
|
||||
if not hasattr(stream, "buffer"): # type: ignore[unreachable]
|
||||
if not hasattr(stream, 'buffer'): # type: ignore[unreachable]
|
||||
return
|
||||
|
||||
buffered = hasattr(stream.buffer, "raw")
|
||||
buffered = hasattr(stream.buffer, 'raw')
|
||||
raw_stdout = stream.buffer.raw if buffered else stream.buffer # type: ignore[attr-defined]
|
||||
|
||||
if not isinstance(raw_stdout, io._WindowsConsoleIO): # type: ignore[attr-defined]
|
||||
return
|
||||
|
||||
def _reopen_stdio(f, mode):
|
||||
if not buffered and mode[0] == "w":
|
||||
if not buffered and mode[0] == 'w':
|
||||
buffering = 0
|
||||
else:
|
||||
buffering = -1
|
||||
|
|
@ -128,20 +130,20 @@ def _windowsconsoleio_workaround(stream: TextIO) -> None:
|
|||
f.line_buffering,
|
||||
)
|
||||
|
||||
sys.stdin = _reopen_stdio(sys.stdin, "rb")
|
||||
sys.stdout = _reopen_stdio(sys.stdout, "wb")
|
||||
sys.stderr = _reopen_stdio(sys.stderr, "wb")
|
||||
sys.stdin = _reopen_stdio(sys.stdin, 'rb')
|
||||
sys.stdout = _reopen_stdio(sys.stdout, 'wb')
|
||||
sys.stderr = _reopen_stdio(sys.stderr, 'wb')
|
||||
|
||||
|
||||
@hookimpl(wrapper=True)
|
||||
def pytest_load_initial_conftests(early_config: Config) -> Generator[None, None, None]:
|
||||
ns = early_config.known_args_namespace
|
||||
if ns.capture == "fd":
|
||||
if ns.capture == 'fd':
|
||||
_windowsconsoleio_workaround(sys.stdout)
|
||||
_colorama_workaround()
|
||||
pluginmanager = early_config.pluginmanager
|
||||
capman = CaptureManager(ns.capture)
|
||||
pluginmanager.register(capman, "capturemanager")
|
||||
pluginmanager.register(capman, 'capturemanager')
|
||||
|
||||
# Make sure that capturemanager is properly reset at final shutdown.
|
||||
early_config.add_cleanup(capman.stop_global_capturing)
|
||||
|
|
@ -176,16 +178,16 @@ class EncodedFile(io.TextIOWrapper):
|
|||
def mode(self) -> str:
|
||||
# TextIOWrapper doesn't expose a mode, but at least some of our
|
||||
# tests check it.
|
||||
return self.buffer.mode.replace("b", "")
|
||||
return self.buffer.mode.replace('b', '')
|
||||
|
||||
|
||||
class CaptureIO(io.TextIOWrapper):
|
||||
def __init__(self) -> None:
|
||||
super().__init__(io.BytesIO(), encoding="UTF-8", newline="", write_through=True)
|
||||
super().__init__(io.BytesIO(), encoding='UTF-8', newline='', write_through=True)
|
||||
|
||||
def getvalue(self) -> str:
|
||||
assert isinstance(self.buffer, io.BytesIO)
|
||||
return self.buffer.getvalue().decode("UTF-8")
|
||||
return self.buffer.getvalue().decode('UTF-8')
|
||||
|
||||
|
||||
class TeeCaptureIO(CaptureIO):
|
||||
|
|
@ -205,7 +207,7 @@ class DontReadFromInput(TextIO):
|
|||
|
||||
def read(self, size: int = -1) -> str:
|
||||
raise OSError(
|
||||
"pytest: reading from stdin while output is captured! Consider using `-s`."
|
||||
'pytest: reading from stdin while output is captured! Consider using `-s`.',
|
||||
)
|
||||
|
||||
readline = read
|
||||
|
|
@ -213,19 +215,19 @@ class DontReadFromInput(TextIO):
|
|||
def __next__(self) -> str:
|
||||
return self.readline()
|
||||
|
||||
def readlines(self, hint: Optional[int] = -1) -> List[str]:
|
||||
def readlines(self, hint: int | None = -1) -> list[str]:
|
||||
raise OSError(
|
||||
"pytest: reading from stdin while output is captured! Consider using `-s`."
|
||||
'pytest: reading from stdin while output is captured! Consider using `-s`.',
|
||||
)
|
||||
|
||||
def __iter__(self) -> Iterator[str]:
|
||||
return self
|
||||
|
||||
def fileno(self) -> int:
|
||||
raise UnsupportedOperation("redirected stdin is pseudofile, has no fileno()")
|
||||
raise UnsupportedOperation('redirected stdin is pseudofile, has no fileno()')
|
||||
|
||||
def flush(self) -> None:
|
||||
raise UnsupportedOperation("redirected stdin is pseudofile, has no flush()")
|
||||
raise UnsupportedOperation('redirected stdin is pseudofile, has no flush()')
|
||||
|
||||
def isatty(self) -> bool:
|
||||
return False
|
||||
|
|
@ -237,34 +239,34 @@ class DontReadFromInput(TextIO):
|
|||
return False
|
||||
|
||||
def seek(self, offset: int, whence: int = 0) -> int:
|
||||
raise UnsupportedOperation("redirected stdin is pseudofile, has no seek(int)")
|
||||
raise UnsupportedOperation('redirected stdin is pseudofile, has no seek(int)')
|
||||
|
||||
def seekable(self) -> bool:
|
||||
return False
|
||||
|
||||
def tell(self) -> int:
|
||||
raise UnsupportedOperation("redirected stdin is pseudofile, has no tell()")
|
||||
raise UnsupportedOperation('redirected stdin is pseudofile, has no tell()')
|
||||
|
||||
def truncate(self, size: Optional[int] = None) -> int:
|
||||
raise UnsupportedOperation("cannot truncate stdin")
|
||||
def truncate(self, size: int | None = None) -> int:
|
||||
raise UnsupportedOperation('cannot truncate stdin')
|
||||
|
||||
def write(self, data: str) -> int:
|
||||
raise UnsupportedOperation("cannot write to stdin")
|
||||
raise UnsupportedOperation('cannot write to stdin')
|
||||
|
||||
def writelines(self, lines: Iterable[str]) -> None:
|
||||
raise UnsupportedOperation("Cannot write to stdin")
|
||||
raise UnsupportedOperation('Cannot write to stdin')
|
||||
|
||||
def writable(self) -> bool:
|
||||
return False
|
||||
|
||||
def __enter__(self) -> "DontReadFromInput":
|
||||
def __enter__(self) -> DontReadFromInput:
|
||||
return self
|
||||
|
||||
def __exit__(
|
||||
self,
|
||||
type: Optional[Type[BaseException]],
|
||||
value: Optional[BaseException],
|
||||
traceback: Optional[TracebackType],
|
||||
type: type[BaseException] | None,
|
||||
value: BaseException | None,
|
||||
traceback: TracebackType | None,
|
||||
) -> None:
|
||||
pass
|
||||
|
||||
|
|
@ -309,11 +311,11 @@ class CaptureBase(abc.ABC, Generic[AnyStr]):
|
|||
raise NotImplementedError()
|
||||
|
||||
|
||||
patchsysdict = {0: "stdin", 1: "stdout", 2: "stderr"}
|
||||
patchsysdict = {0: 'stdin', 1: 'stdout', 2: 'stderr'}
|
||||
|
||||
|
||||
class NoCapture(CaptureBase[str]):
|
||||
EMPTY_BUFFER = ""
|
||||
EMPTY_BUFFER = ''
|
||||
|
||||
def __init__(self, fd: int) -> None:
|
||||
pass
|
||||
|
|
@ -331,7 +333,7 @@ class NoCapture(CaptureBase[str]):
|
|||
pass
|
||||
|
||||
def snap(self) -> str:
|
||||
return ""
|
||||
return ''
|
||||
|
||||
def writeorg(self, data: str) -> None:
|
||||
pass
|
||||
|
|
@ -339,76 +341,76 @@ class NoCapture(CaptureBase[str]):
|
|||
|
||||
class SysCaptureBase(CaptureBase[AnyStr]):
|
||||
def __init__(
|
||||
self, fd: int, tmpfile: Optional[TextIO] = None, *, tee: bool = False
|
||||
self, fd: int, tmpfile: TextIO | None = None, *, tee: bool = False,
|
||||
) -> None:
|
||||
name = patchsysdict[fd]
|
||||
self._old: TextIO = getattr(sys, name)
|
||||
self.name = name
|
||||
if tmpfile is None:
|
||||
if name == "stdin":
|
||||
if name == 'stdin':
|
||||
tmpfile = DontReadFromInput()
|
||||
else:
|
||||
tmpfile = CaptureIO() if not tee else TeeCaptureIO(self._old)
|
||||
self.tmpfile = tmpfile
|
||||
self._state = "initialized"
|
||||
self._state = 'initialized'
|
||||
|
||||
def repr(self, class_name: str) -> str:
|
||||
return "<{} {} _old={} _state={!r} tmpfile={!r}>".format(
|
||||
return '<{} {} _old={} _state={!r} tmpfile={!r}>'.format(
|
||||
class_name,
|
||||
self.name,
|
||||
hasattr(self, "_old") and repr(self._old) or "<UNSET>",
|
||||
hasattr(self, '_old') and repr(self._old) or '<UNSET>',
|
||||
self._state,
|
||||
self.tmpfile,
|
||||
)
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "<{} {} _old={} _state={!r} tmpfile={!r}>".format(
|
||||
return '<{} {} _old={} _state={!r} tmpfile={!r}>'.format(
|
||||
self.__class__.__name__,
|
||||
self.name,
|
||||
hasattr(self, "_old") and repr(self._old) or "<UNSET>",
|
||||
hasattr(self, '_old') and repr(self._old) or '<UNSET>',
|
||||
self._state,
|
||||
self.tmpfile,
|
||||
)
|
||||
|
||||
def _assert_state(self, op: str, states: Tuple[str, ...]) -> None:
|
||||
def _assert_state(self, op: str, states: tuple[str, ...]) -> None:
|
||||
assert (
|
||||
self._state in states
|
||||
), "cannot {} in state {!r}: expected one of {}".format(
|
||||
op, self._state, ", ".join(states)
|
||||
), 'cannot {} in state {!r}: expected one of {}'.format(
|
||||
op, self._state, ', '.join(states),
|
||||
)
|
||||
|
||||
def start(self) -> None:
|
||||
self._assert_state("start", ("initialized",))
|
||||
self._assert_state('start', ('initialized',))
|
||||
setattr(sys, self.name, self.tmpfile)
|
||||
self._state = "started"
|
||||
self._state = 'started'
|
||||
|
||||
def done(self) -> None:
|
||||
self._assert_state("done", ("initialized", "started", "suspended", "done"))
|
||||
if self._state == "done":
|
||||
self._assert_state('done', ('initialized', 'started', 'suspended', 'done'))
|
||||
if self._state == 'done':
|
||||
return
|
||||
setattr(sys, self.name, self._old)
|
||||
del self._old
|
||||
self.tmpfile.close()
|
||||
self._state = "done"
|
||||
self._state = 'done'
|
||||
|
||||
def suspend(self) -> None:
|
||||
self._assert_state("suspend", ("started", "suspended"))
|
||||
self._assert_state('suspend', ('started', 'suspended'))
|
||||
setattr(sys, self.name, self._old)
|
||||
self._state = "suspended"
|
||||
self._state = 'suspended'
|
||||
|
||||
def resume(self) -> None:
|
||||
self._assert_state("resume", ("started", "suspended"))
|
||||
if self._state == "started":
|
||||
self._assert_state('resume', ('started', 'suspended'))
|
||||
if self._state == 'started':
|
||||
return
|
||||
setattr(sys, self.name, self.tmpfile)
|
||||
self._state = "started"
|
||||
self._state = 'started'
|
||||
|
||||
|
||||
class SysCaptureBinary(SysCaptureBase[bytes]):
|
||||
EMPTY_BUFFER = b""
|
||||
EMPTY_BUFFER = b''
|
||||
|
||||
def snap(self) -> bytes:
|
||||
self._assert_state("snap", ("started", "suspended"))
|
||||
self._assert_state('snap', ('started', 'suspended'))
|
||||
self.tmpfile.seek(0)
|
||||
res = self.tmpfile.buffer.read()
|
||||
self.tmpfile.seek(0)
|
||||
|
|
@ -416,17 +418,17 @@ class SysCaptureBinary(SysCaptureBase[bytes]):
|
|||
return res
|
||||
|
||||
def writeorg(self, data: bytes) -> None:
|
||||
self._assert_state("writeorg", ("started", "suspended"))
|
||||
self._assert_state('writeorg', ('started', 'suspended'))
|
||||
self._old.flush()
|
||||
self._old.buffer.write(data)
|
||||
self._old.buffer.flush()
|
||||
|
||||
|
||||
class SysCapture(SysCaptureBase[str]):
|
||||
EMPTY_BUFFER = ""
|
||||
EMPTY_BUFFER = ''
|
||||
|
||||
def snap(self) -> str:
|
||||
self._assert_state("snap", ("started", "suspended"))
|
||||
self._assert_state('snap', ('started', 'suspended'))
|
||||
assert isinstance(self.tmpfile, CaptureIO)
|
||||
res = self.tmpfile.getvalue()
|
||||
self.tmpfile.seek(0)
|
||||
|
|
@ -434,7 +436,7 @@ class SysCapture(SysCaptureBase[str]):
|
|||
return res
|
||||
|
||||
def writeorg(self, data: str) -> None:
|
||||
self._assert_state("writeorg", ("started", "suspended"))
|
||||
self._assert_state('writeorg', ('started', 'suspended'))
|
||||
self._old.write(data)
|
||||
self._old.flush()
|
||||
|
||||
|
|
@ -457,21 +459,21 @@ class FDCaptureBase(CaptureBase[AnyStr]):
|
|||
# Further complications are the need to support suspend() and the
|
||||
# possibility of FD reuse (e.g. the tmpfile getting the very same
|
||||
# target FD). The following approach is robust, I believe.
|
||||
self.targetfd_invalid: Optional[int] = os.open(os.devnull, os.O_RDWR)
|
||||
self.targetfd_invalid: int | None = os.open(os.devnull, os.O_RDWR)
|
||||
os.dup2(self.targetfd_invalid, targetfd)
|
||||
else:
|
||||
self.targetfd_invalid = None
|
||||
self.targetfd_save = os.dup(targetfd)
|
||||
|
||||
if targetfd == 0:
|
||||
self.tmpfile = open(os.devnull, encoding="utf-8")
|
||||
self.tmpfile = open(os.devnull, encoding='utf-8')
|
||||
self.syscapture: CaptureBase[str] = SysCapture(targetfd)
|
||||
else:
|
||||
self.tmpfile = EncodedFile(
|
||||
TemporaryFile(buffering=0),
|
||||
encoding="utf-8",
|
||||
errors="replace",
|
||||
newline="",
|
||||
encoding='utf-8',
|
||||
errors='replace',
|
||||
newline='',
|
||||
write_through=True,
|
||||
)
|
||||
if targetfd in patchsysdict:
|
||||
|
|
@ -479,10 +481,10 @@ class FDCaptureBase(CaptureBase[AnyStr]):
|
|||
else:
|
||||
self.syscapture = NoCapture(targetfd)
|
||||
|
||||
self._state = "initialized"
|
||||
self._state = 'initialized'
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "<{} {} oldfd={} _state={!r} tmpfile={!r}>".format(
|
||||
return '<{} {} oldfd={} _state={!r} tmpfile={!r}>'.format(
|
||||
self.__class__.__name__,
|
||||
self.targetfd,
|
||||
self.targetfd_save,
|
||||
|
|
@ -490,25 +492,25 @@ class FDCaptureBase(CaptureBase[AnyStr]):
|
|||
self.tmpfile,
|
||||
)
|
||||
|
||||
def _assert_state(self, op: str, states: Tuple[str, ...]) -> None:
|
||||
def _assert_state(self, op: str, states: tuple[str, ...]) -> None:
|
||||
assert (
|
||||
self._state in states
|
||||
), "cannot {} in state {!r}: expected one of {}".format(
|
||||
op, self._state, ", ".join(states)
|
||||
), 'cannot {} in state {!r}: expected one of {}'.format(
|
||||
op, self._state, ', '.join(states),
|
||||
)
|
||||
|
||||
def start(self) -> None:
|
||||
"""Start capturing on targetfd using memorized tmpfile."""
|
||||
self._assert_state("start", ("initialized",))
|
||||
self._assert_state('start', ('initialized',))
|
||||
os.dup2(self.tmpfile.fileno(), self.targetfd)
|
||||
self.syscapture.start()
|
||||
self._state = "started"
|
||||
self._state = 'started'
|
||||
|
||||
def done(self) -> None:
|
||||
"""Stop capturing, restore streams, return original capture file,
|
||||
seeked to position zero."""
|
||||
self._assert_state("done", ("initialized", "started", "suspended", "done"))
|
||||
if self._state == "done":
|
||||
self._assert_state('done', ('initialized', 'started', 'suspended', 'done'))
|
||||
if self._state == 'done':
|
||||
return
|
||||
os.dup2(self.targetfd_save, self.targetfd)
|
||||
os.close(self.targetfd_save)
|
||||
|
|
@ -518,23 +520,23 @@ class FDCaptureBase(CaptureBase[AnyStr]):
|
|||
os.close(self.targetfd_invalid)
|
||||
self.syscapture.done()
|
||||
self.tmpfile.close()
|
||||
self._state = "done"
|
||||
self._state = 'done'
|
||||
|
||||
def suspend(self) -> None:
|
||||
self._assert_state("suspend", ("started", "suspended"))
|
||||
if self._state == "suspended":
|
||||
self._assert_state('suspend', ('started', 'suspended'))
|
||||
if self._state == 'suspended':
|
||||
return
|
||||
self.syscapture.suspend()
|
||||
os.dup2(self.targetfd_save, self.targetfd)
|
||||
self._state = "suspended"
|
||||
self._state = 'suspended'
|
||||
|
||||
def resume(self) -> None:
|
||||
self._assert_state("resume", ("started", "suspended"))
|
||||
if self._state == "started":
|
||||
self._assert_state('resume', ('started', 'suspended'))
|
||||
if self._state == 'started':
|
||||
return
|
||||
self.syscapture.resume()
|
||||
os.dup2(self.tmpfile.fileno(), self.targetfd)
|
||||
self._state = "started"
|
||||
self._state = 'started'
|
||||
|
||||
|
||||
class FDCaptureBinary(FDCaptureBase[bytes]):
|
||||
|
|
@ -543,10 +545,10 @@ class FDCaptureBinary(FDCaptureBase[bytes]):
|
|||
snap() produces `bytes`.
|
||||
"""
|
||||
|
||||
EMPTY_BUFFER = b""
|
||||
EMPTY_BUFFER = b''
|
||||
|
||||
def snap(self) -> bytes:
|
||||
self._assert_state("snap", ("started", "suspended"))
|
||||
self._assert_state('snap', ('started', 'suspended'))
|
||||
self.tmpfile.seek(0)
|
||||
res = self.tmpfile.buffer.read()
|
||||
self.tmpfile.seek(0)
|
||||
|
|
@ -555,7 +557,7 @@ class FDCaptureBinary(FDCaptureBase[bytes]):
|
|||
|
||||
def writeorg(self, data: bytes) -> None:
|
||||
"""Write to original file descriptor."""
|
||||
self._assert_state("writeorg", ("started", "suspended"))
|
||||
self._assert_state('writeorg', ('started', 'suspended'))
|
||||
os.write(self.targetfd_save, data)
|
||||
|
||||
|
||||
|
|
@ -565,10 +567,10 @@ class FDCapture(FDCaptureBase[str]):
|
|||
snap() produces text.
|
||||
"""
|
||||
|
||||
EMPTY_BUFFER = ""
|
||||
EMPTY_BUFFER = ''
|
||||
|
||||
def snap(self) -> str:
|
||||
self._assert_state("snap", ("started", "suspended"))
|
||||
self._assert_state('snap', ('started', 'suspended'))
|
||||
self.tmpfile.seek(0)
|
||||
res = self.tmpfile.read()
|
||||
self.tmpfile.seek(0)
|
||||
|
|
@ -577,9 +579,9 @@ class FDCapture(FDCaptureBase[str]):
|
|||
|
||||
def writeorg(self, data: str) -> None:
|
||||
"""Write to original file descriptor."""
|
||||
self._assert_state("writeorg", ("started", "suspended"))
|
||||
self._assert_state('writeorg', ('started', 'suspended'))
|
||||
# XXX use encoding of original stream
|
||||
os.write(self.targetfd_save, data.encode("utf-8"))
|
||||
os.write(self.targetfd_save, data.encode('utf-8'))
|
||||
|
||||
|
||||
# MultiCapture
|
||||
|
|
@ -598,7 +600,7 @@ if sys.version_info >= (3, 11) or TYPE_CHECKING:
|
|||
else:
|
||||
|
||||
class CaptureResult(
|
||||
collections.namedtuple("CaptureResult", ["out", "err"]), # noqa: PYI024
|
||||
collections.namedtuple('CaptureResult', ['out', 'err']), # noqa: PYI024
|
||||
Generic[AnyStr],
|
||||
):
|
||||
"""The result of :method:`caplog.readouterr() <pytest.CaptureFixture.readouterr>`."""
|
||||
|
|
@ -612,16 +614,16 @@ class MultiCapture(Generic[AnyStr]):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
in_: Optional[CaptureBase[AnyStr]],
|
||||
out: Optional[CaptureBase[AnyStr]],
|
||||
err: Optional[CaptureBase[AnyStr]],
|
||||
in_: CaptureBase[AnyStr] | None,
|
||||
out: CaptureBase[AnyStr] | None,
|
||||
err: CaptureBase[AnyStr] | None,
|
||||
) -> None:
|
||||
self.in_: Optional[CaptureBase[AnyStr]] = in_
|
||||
self.out: Optional[CaptureBase[AnyStr]] = out
|
||||
self.err: Optional[CaptureBase[AnyStr]] = err
|
||||
self.in_: CaptureBase[AnyStr] | None = in_
|
||||
self.out: CaptureBase[AnyStr] | None = out
|
||||
self.err: CaptureBase[AnyStr] | None = err
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "<MultiCapture out={!r} err={!r} in_={!r} _state={!r} _in_suspended={!r}>".format(
|
||||
return '<MultiCapture out={!r} err={!r} in_={!r} _state={!r} _in_suspended={!r}>'.format(
|
||||
self.out,
|
||||
self.err,
|
||||
self.in_,
|
||||
|
|
@ -630,7 +632,7 @@ class MultiCapture(Generic[AnyStr]):
|
|||
)
|
||||
|
||||
def start_capturing(self) -> None:
|
||||
self._state = "started"
|
||||
self._state = 'started'
|
||||
if self.in_:
|
||||
self.in_.start()
|
||||
if self.out:
|
||||
|
|
@ -638,7 +640,7 @@ class MultiCapture(Generic[AnyStr]):
|
|||
if self.err:
|
||||
self.err.start()
|
||||
|
||||
def pop_outerr_to_orig(self) -> Tuple[AnyStr, AnyStr]:
|
||||
def pop_outerr_to_orig(self) -> tuple[AnyStr, AnyStr]:
|
||||
"""Pop current snapshot out/err capture and flush to orig streams."""
|
||||
out, err = self.readouterr()
|
||||
if out:
|
||||
|
|
@ -650,7 +652,7 @@ class MultiCapture(Generic[AnyStr]):
|
|||
return out, err
|
||||
|
||||
def suspend_capturing(self, in_: bool = False) -> None:
|
||||
self._state = "suspended"
|
||||
self._state = 'suspended'
|
||||
if self.out:
|
||||
self.out.suspend()
|
||||
if self.err:
|
||||
|
|
@ -660,7 +662,7 @@ class MultiCapture(Generic[AnyStr]):
|
|||
self._in_suspended = True
|
||||
|
||||
def resume_capturing(self) -> None:
|
||||
self._state = "started"
|
||||
self._state = 'started'
|
||||
if self.out:
|
||||
self.out.resume()
|
||||
if self.err:
|
||||
|
|
@ -672,9 +674,9 @@ class MultiCapture(Generic[AnyStr]):
|
|||
|
||||
def stop_capturing(self) -> None:
|
||||
"""Stop capturing and reset capturing streams."""
|
||||
if self._state == "stopped":
|
||||
raise ValueError("was already stopped")
|
||||
self._state = "stopped"
|
||||
if self._state == 'stopped':
|
||||
raise ValueError('was already stopped')
|
||||
self._state = 'stopped'
|
||||
if self.out:
|
||||
self.out.done()
|
||||
if self.err:
|
||||
|
|
@ -684,27 +686,27 @@ class MultiCapture(Generic[AnyStr]):
|
|||
|
||||
def is_started(self) -> bool:
|
||||
"""Whether actively capturing -- not suspended or stopped."""
|
||||
return self._state == "started"
|
||||
return self._state == 'started'
|
||||
|
||||
def readouterr(self) -> CaptureResult[AnyStr]:
|
||||
out = self.out.snap() if self.out else ""
|
||||
err = self.err.snap() if self.err else ""
|
||||
out = self.out.snap() if self.out else ''
|
||||
err = self.err.snap() if self.err else ''
|
||||
# TODO: This type error is real, need to fix.
|
||||
return CaptureResult(out, err) # type: ignore[arg-type]
|
||||
|
||||
|
||||
def _get_multicapture(method: _CaptureMethod) -> MultiCapture[str]:
|
||||
if method == "fd":
|
||||
if method == 'fd':
|
||||
return MultiCapture(in_=FDCapture(0), out=FDCapture(1), err=FDCapture(2))
|
||||
elif method == "sys":
|
||||
elif method == 'sys':
|
||||
return MultiCapture(in_=SysCapture(0), out=SysCapture(1), err=SysCapture(2))
|
||||
elif method == "no":
|
||||
elif method == 'no':
|
||||
return MultiCapture(in_=None, out=None, err=None)
|
||||
elif method == "tee-sys":
|
||||
elif method == 'tee-sys':
|
||||
return MultiCapture(
|
||||
in_=None, out=SysCapture(1, tee=True), err=SysCapture(2, tee=True)
|
||||
in_=None, out=SysCapture(1, tee=True), err=SysCapture(2, tee=True),
|
||||
)
|
||||
raise ValueError(f"unknown capturing method: {method!r}")
|
||||
raise ValueError(f'unknown capturing method: {method!r}')
|
||||
|
||||
|
||||
# CaptureManager and CaptureFixture
|
||||
|
|
@ -731,25 +733,25 @@ class CaptureManager:
|
|||
|
||||
def __init__(self, method: _CaptureMethod) -> None:
|
||||
self._method: Final = method
|
||||
self._global_capturing: Optional[MultiCapture[str]] = None
|
||||
self._capture_fixture: Optional[CaptureFixture[Any]] = None
|
||||
self._global_capturing: MultiCapture[str] | None = None
|
||||
self._capture_fixture: CaptureFixture[Any] | None = None
|
||||
|
||||
def __repr__(self) -> str:
|
||||
return "<CaptureManager _method={!r} _global_capturing={!r} _capture_fixture={!r}>".format(
|
||||
self._method, self._global_capturing, self._capture_fixture
|
||||
return '<CaptureManager _method={!r} _global_capturing={!r} _capture_fixture={!r}>'.format(
|
||||
self._method, self._global_capturing, self._capture_fixture,
|
||||
)
|
||||
|
||||
def is_capturing(self) -> Union[str, bool]:
|
||||
def is_capturing(self) -> str | bool:
|
||||
if self.is_globally_capturing():
|
||||
return "global"
|
||||
return 'global'
|
||||
if self._capture_fixture:
|
||||
return "fixture %s" % self._capture_fixture.request.fixturename
|
||||
return 'fixture %s' % self._capture_fixture.request.fixturename
|
||||
return False
|
||||
|
||||
# Global capturing control
|
||||
|
||||
def is_globally_capturing(self) -> bool:
|
||||
return self._method != "no"
|
||||
return self._method != 'no'
|
||||
|
||||
def start_global_capturing(self) -> None:
|
||||
assert self._global_capturing is None
|
||||
|
|
@ -787,12 +789,12 @@ class CaptureManager:
|
|||
|
||||
# Fixture Control
|
||||
|
||||
def set_fixture(self, capture_fixture: "CaptureFixture[Any]") -> None:
|
||||
def set_fixture(self, capture_fixture: CaptureFixture[Any]) -> None:
|
||||
if self._capture_fixture:
|
||||
current_fixture = self._capture_fixture.request.fixturename
|
||||
requested_fixture = capture_fixture.request.fixturename
|
||||
capture_fixture.request.raiseerror(
|
||||
f"cannot use {requested_fixture} and {current_fixture} at the same time"
|
||||
f'cannot use {requested_fixture} and {current_fixture} at the same time',
|
||||
)
|
||||
self._capture_fixture = capture_fixture
|
||||
|
||||
|
|
@ -848,14 +850,14 @@ class CaptureManager:
|
|||
self.suspend_global_capture(in_=False)
|
||||
|
||||
out, err = self.read_global_capture()
|
||||
item.add_report_section(when, "stdout", out)
|
||||
item.add_report_section(when, "stderr", err)
|
||||
item.add_report_section(when, 'stdout', out)
|
||||
item.add_report_section(when, 'stderr', err)
|
||||
|
||||
# Hooks
|
||||
|
||||
@hookimpl(wrapper=True)
|
||||
def pytest_make_collect_report(
|
||||
self, collector: Collector
|
||||
self, collector: Collector,
|
||||
) -> Generator[None, CollectReport, CollectReport]:
|
||||
if isinstance(collector, File):
|
||||
self.resume_global_capture()
|
||||
|
|
@ -865,26 +867,26 @@ class CaptureManager:
|
|||
self.suspend_global_capture()
|
||||
out, err = self.read_global_capture()
|
||||
if out:
|
||||
rep.sections.append(("Captured stdout", out))
|
||||
rep.sections.append(('Captured stdout', out))
|
||||
if err:
|
||||
rep.sections.append(("Captured stderr", err))
|
||||
rep.sections.append(('Captured stderr', err))
|
||||
else:
|
||||
rep = yield
|
||||
return rep
|
||||
|
||||
@hookimpl(wrapper=True)
|
||||
def pytest_runtest_setup(self, item: Item) -> Generator[None, None, None]:
|
||||
with self.item_capture("setup", item):
|
||||
with self.item_capture('setup', item):
|
||||
return (yield)
|
||||
|
||||
@hookimpl(wrapper=True)
|
||||
def pytest_runtest_call(self, item: Item) -> Generator[None, None, None]:
|
||||
with self.item_capture("call", item):
|
||||
with self.item_capture('call', item):
|
||||
return (yield)
|
||||
|
||||
@hookimpl(wrapper=True)
|
||||
def pytest_runtest_teardown(self, item: Item) -> Generator[None, None, None]:
|
||||
with self.item_capture("teardown", item):
|
||||
with self.item_capture('teardown', item):
|
||||
return (yield)
|
||||
|
||||
@hookimpl(tryfirst=True)
|
||||
|
|
@ -902,15 +904,15 @@ class CaptureFixture(Generic[AnyStr]):
|
|||
|
||||
def __init__(
|
||||
self,
|
||||
captureclass: Type[CaptureBase[AnyStr]],
|
||||
captureclass: type[CaptureBase[AnyStr]],
|
||||
request: SubRequest,
|
||||
*,
|
||||
_ispytest: bool = False,
|
||||
) -> None:
|
||||
check_ispytest(_ispytest)
|
||||
self.captureclass: Type[CaptureBase[AnyStr]] = captureclass
|
||||
self.captureclass: type[CaptureBase[AnyStr]] = captureclass
|
||||
self.request = request
|
||||
self._capture: Optional[MultiCapture[AnyStr]] = None
|
||||
self._capture: MultiCapture[AnyStr] | None = None
|
||||
self._captured_out: AnyStr = self.captureclass.EMPTY_BUFFER
|
||||
self._captured_err: AnyStr = self.captureclass.EMPTY_BUFFER
|
||||
|
||||
|
|
@ -968,7 +970,7 @@ class CaptureFixture(Generic[AnyStr]):
|
|||
def disabled(self) -> Generator[None, None, None]:
|
||||
"""Temporarily disable capturing while inside the ``with`` block."""
|
||||
capmanager: CaptureManager = self.request.config.pluginmanager.getplugin(
|
||||
"capturemanager"
|
||||
'capturemanager',
|
||||
)
|
||||
with capmanager.global_and_fixture_disabled():
|
||||
yield
|
||||
|
|
@ -995,7 +997,7 @@ def capsys(request: SubRequest) -> Generator[CaptureFixture[str], None, None]:
|
|||
captured = capsys.readouterr()
|
||||
assert captured.out == "hello\n"
|
||||
"""
|
||||
capman: CaptureManager = request.config.pluginmanager.getplugin("capturemanager")
|
||||
capman: CaptureManager = request.config.pluginmanager.getplugin('capturemanager')
|
||||
capture_fixture = CaptureFixture(SysCapture, request, _ispytest=True)
|
||||
capman.set_fixture(capture_fixture)
|
||||
capture_fixture._start()
|
||||
|
|
@ -1022,7 +1024,7 @@ def capsysbinary(request: SubRequest) -> Generator[CaptureFixture[bytes], None,
|
|||
captured = capsysbinary.readouterr()
|
||||
assert captured.out == b"hello\n"
|
||||
"""
|
||||
capman: CaptureManager = request.config.pluginmanager.getplugin("capturemanager")
|
||||
capman: CaptureManager = request.config.pluginmanager.getplugin('capturemanager')
|
||||
capture_fixture = CaptureFixture(SysCaptureBinary, request, _ispytest=True)
|
||||
capman.set_fixture(capture_fixture)
|
||||
capture_fixture._start()
|
||||
|
|
@ -1049,7 +1051,7 @@ def capfd(request: SubRequest) -> Generator[CaptureFixture[str], None, None]:
|
|||
captured = capfd.readouterr()
|
||||
assert captured.out == "hello\n"
|
||||
"""
|
||||
capman: CaptureManager = request.config.pluginmanager.getplugin("capturemanager")
|
||||
capman: CaptureManager = request.config.pluginmanager.getplugin('capturemanager')
|
||||
capture_fixture = CaptureFixture(FDCapture, request, _ispytest=True)
|
||||
capman.set_fixture(capture_fixture)
|
||||
capture_fixture._start()
|
||||
|
|
@ -1077,7 +1079,7 @@ def capfdbinary(request: SubRequest) -> Generator[CaptureFixture[bytes], None, N
|
|||
assert captured.out == b"hello\n"
|
||||
|
||||
"""
|
||||
capman: CaptureManager = request.config.pluginmanager.getplugin("capturemanager")
|
||||
capman: CaptureManager = request.config.pluginmanager.getplugin('capturemanager')
|
||||
capture_fixture = CaptureFixture(FDCaptureBinary, request, _ispytest=True)
|
||||
capman.set_fixture(capture_fixture)
|
||||
capture_fixture._start()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue