Merge pull request #6545 from blueyed/terminalwriter
config: typing for create_terminal_writer, re-export TerminalWriter
This commit is contained in:
commit
8ca8d25202
|
@ -64,7 +64,7 @@ repos:
|
||||||
_code\.|
|
_code\.|
|
||||||
builtin\.|
|
builtin\.|
|
||||||
code\.|
|
code\.|
|
||||||
io\.(BytesIO|saferepr)|
|
io\.(BytesIO|saferepr|TerminalWriter)|
|
||||||
path\.local\.sysfind|
|
path\.local\.sysfind|
|
||||||
process\.|
|
process\.|
|
||||||
std\.
|
std\.
|
||||||
|
|
|
@ -29,6 +29,7 @@ import pluggy
|
||||||
import py
|
import py
|
||||||
|
|
||||||
import _pytest
|
import _pytest
|
||||||
|
from _pytest._io import TerminalWriter
|
||||||
from _pytest._io.saferepr import safeformat
|
from _pytest._io.saferepr import safeformat
|
||||||
from _pytest._io.saferepr import saferepr
|
from _pytest._io.saferepr import saferepr
|
||||||
from _pytest.compat import overload
|
from _pytest.compat import overload
|
||||||
|
@ -915,14 +916,14 @@ class TerminalRepr:
|
||||||
# FYI this is called from pytest-xdist's serialization of exception
|
# FYI this is called from pytest-xdist's serialization of exception
|
||||||
# information.
|
# information.
|
||||||
io = StringIO()
|
io = StringIO()
|
||||||
tw = py.io.TerminalWriter(file=io)
|
tw = TerminalWriter(file=io)
|
||||||
self.toterminal(tw)
|
self.toterminal(tw)
|
||||||
return io.getvalue().strip()
|
return io.getvalue().strip()
|
||||||
|
|
||||||
def __repr__(self) -> str:
|
def __repr__(self) -> str:
|
||||||
return "<{} instance at {:0x}>".format(self.__class__, id(self))
|
return "<{} instance at {:0x}>".format(self.__class__, id(self))
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
|
||||||
|
@ -933,7 +934,7 @@ class ExceptionRepr(TerminalRepr):
|
||||||
def addsection(self, name: str, content: str, sep: str = "-") -> None:
|
def addsection(self, name: str, content: str, sep: str = "-") -> None:
|
||||||
self.sections.append((name, content, sep))
|
self.sections.append((name, content, sep))
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
for name, content, sep in self.sections:
|
for name, content, sep in self.sections:
|
||||||
tw.sep(sep, name)
|
tw.sep(sep, name)
|
||||||
tw.line(content)
|
tw.line(content)
|
||||||
|
@ -953,7 +954,7 @@ class ExceptionChainRepr(ExceptionRepr):
|
||||||
self.reprtraceback = chain[-1][0]
|
self.reprtraceback = chain[-1][0]
|
||||||
self.reprcrash = chain[-1][1]
|
self.reprcrash = chain[-1][1]
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
for element in self.chain:
|
for element in self.chain:
|
||||||
element[0].toterminal(tw)
|
element[0].toterminal(tw)
|
||||||
if element[2] is not None:
|
if element[2] is not None:
|
||||||
|
@ -970,7 +971,7 @@ class ReprExceptionInfo(ExceptionRepr):
|
||||||
self.reprtraceback = reprtraceback
|
self.reprtraceback = reprtraceback
|
||||||
self.reprcrash = reprcrash
|
self.reprcrash = reprcrash
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
self.reprtraceback.toterminal(tw)
|
self.reprtraceback.toterminal(tw)
|
||||||
super().toterminal(tw)
|
super().toterminal(tw)
|
||||||
|
|
||||||
|
@ -988,7 +989,7 @@ class ReprTraceback(TerminalRepr):
|
||||||
self.extraline = extraline
|
self.extraline = extraline
|
||||||
self.style = style
|
self.style = style
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
# the entries might have different styles
|
# the entries might have different styles
|
||||||
for i, entry in enumerate(self.reprentries):
|
for i, entry in enumerate(self.reprentries):
|
||||||
if entry.style == "long":
|
if entry.style == "long":
|
||||||
|
@ -1020,7 +1021,7 @@ class ReprEntryNative(TerminalRepr):
|
||||||
def __init__(self, tblines: Sequence[str]) -> None:
|
def __init__(self, tblines: Sequence[str]) -> None:
|
||||||
self.lines = tblines
|
self.lines = tblines
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
tw.write("".join(self.lines))
|
tw.write("".join(self.lines))
|
||||||
|
|
||||||
|
|
||||||
|
@ -1039,7 +1040,7 @@ class ReprEntry(TerminalRepr):
|
||||||
self.reprfileloc = filelocrepr
|
self.reprfileloc = filelocrepr
|
||||||
self.style = style
|
self.style = style
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
if self.style == "short":
|
if self.style == "short":
|
||||||
assert self.reprfileloc is not None
|
assert self.reprfileloc is not None
|
||||||
self.reprfileloc.toterminal(tw)
|
self.reprfileloc.toterminal(tw)
|
||||||
|
@ -1072,7 +1073,7 @@ class ReprFileLocation(TerminalRepr):
|
||||||
self.lineno = lineno
|
self.lineno = lineno
|
||||||
self.message = message
|
self.message = message
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
# filename and lineno output for each entry,
|
# filename and lineno output for each entry,
|
||||||
# using an output format that most editors understand
|
# using an output format that most editors understand
|
||||||
msg = self.message
|
msg = self.message
|
||||||
|
@ -1087,7 +1088,7 @@ class ReprLocals(TerminalRepr):
|
||||||
def __init__(self, lines: Sequence[str]) -> None:
|
def __init__(self, lines: Sequence[str]) -> None:
|
||||||
self.lines = lines
|
self.lines = lines
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
for line in self.lines:
|
for line in self.lines:
|
||||||
tw.line(line)
|
tw.line(line)
|
||||||
|
|
||||||
|
@ -1096,7 +1097,7 @@ class ReprFuncArgs(TerminalRepr):
|
||||||
def __init__(self, args: Sequence[Tuple[str, object]]) -> None:
|
def __init__(self, args: Sequence[Tuple[str, object]]) -> None:
|
||||||
self.args = args
|
self.args = args
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
if self.args:
|
if self.args:
|
||||||
linesofar = ""
|
linesofar = ""
|
||||||
for name, value in self.args:
|
for name, value in self.args:
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
# Reexport TerminalWriter from here instead of py, to make it easier to
|
||||||
|
# extend or swap our own implementation in the future.
|
||||||
|
from py.io import TerminalWriter as TerminalWriter # noqa: F401
|
|
@ -17,6 +17,7 @@ from .pathlib import Path
|
||||||
from .pathlib import resolve_from_str
|
from .pathlib import resolve_from_str
|
||||||
from .pathlib import rm_rf
|
from .pathlib import rm_rf
|
||||||
from _pytest import nodes
|
from _pytest import nodes
|
||||||
|
from _pytest._io import TerminalWriter
|
||||||
from _pytest.config import Config
|
from _pytest.config import Config
|
||||||
from _pytest.main import Session
|
from _pytest.main import Session
|
||||||
|
|
||||||
|
@ -418,7 +419,7 @@ def pytest_report_header(config):
|
||||||
def cacheshow(config, session):
|
def cacheshow(config, session):
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
|
|
||||||
tw = py.io.TerminalWriter()
|
tw = TerminalWriter()
|
||||||
tw.line("cachedir: " + str(config.cache._cachedir))
|
tw.line("cachedir: " + str(config.cache._cachedir))
|
||||||
if not config.cache._cachedir.is_dir():
|
if not config.cache._cachedir.is_dir():
|
||||||
tw.line("cache is empty")
|
tw.line("cache is empty")
|
||||||
|
|
|
@ -36,6 +36,7 @@ from .findpaths import determine_setup
|
||||||
from .findpaths import exists
|
from .findpaths import exists
|
||||||
from _pytest._code import ExceptionInfo
|
from _pytest._code import ExceptionInfo
|
||||||
from _pytest._code import filter_traceback
|
from _pytest._code import filter_traceback
|
||||||
|
from _pytest._io import TerminalWriter
|
||||||
from _pytest.compat import importlib_metadata
|
from _pytest.compat import importlib_metadata
|
||||||
from _pytest.compat import TYPE_CHECKING
|
from _pytest.compat import TYPE_CHECKING
|
||||||
from _pytest.outcomes import fail
|
from _pytest.outcomes import fail
|
||||||
|
@ -73,7 +74,7 @@ def main(args=None, plugins=None) -> "Union[int, _pytest.main.ExitCode]":
|
||||||
config = _prepareconfig(args, plugins)
|
config = _prepareconfig(args, plugins)
|
||||||
except ConftestImportFailure as e:
|
except ConftestImportFailure as e:
|
||||||
exc_info = ExceptionInfo(e.excinfo)
|
exc_info = ExceptionInfo(e.excinfo)
|
||||||
tw = py.io.TerminalWriter(sys.stderr)
|
tw = TerminalWriter(sys.stderr)
|
||||||
tw.line(
|
tw.line(
|
||||||
"ImportError while loading conftest '{e.path}'.".format(e=e), red=True
|
"ImportError while loading conftest '{e.path}'.".format(e=e), red=True
|
||||||
)
|
)
|
||||||
|
@ -99,7 +100,7 @@ def main(args=None, plugins=None) -> "Union[int, _pytest.main.ExitCode]":
|
||||||
finally:
|
finally:
|
||||||
config._ensure_unconfigure()
|
config._ensure_unconfigure()
|
||||||
except UsageError as e:
|
except UsageError as e:
|
||||||
tw = py.io.TerminalWriter(sys.stderr)
|
tw = TerminalWriter(sys.stderr)
|
||||||
for msg in e.args:
|
for msg in e.args:
|
||||||
tw.line("ERROR: {}\n".format(msg), red=True)
|
tw.line("ERROR: {}\n".format(msg), red=True)
|
||||||
return ExitCode.USAGE_ERROR
|
return ExitCode.USAGE_ERROR
|
||||||
|
@ -1175,12 +1176,12 @@ def setns(obj, dic):
|
||||||
setattr(pytest, name, value)
|
setattr(pytest, name, value)
|
||||||
|
|
||||||
|
|
||||||
def create_terminal_writer(config, *args, **kwargs):
|
def create_terminal_writer(config: Config, *args, **kwargs) -> TerminalWriter:
|
||||||
"""Create a TerminalWriter instance configured according to the options
|
"""Create a TerminalWriter instance configured according to the options
|
||||||
in the config object. Every code which requires a TerminalWriter object
|
in the config object. Every code which requires a TerminalWriter object
|
||||||
and has access to a config object should use this function.
|
and has access to a config object should use this function.
|
||||||
"""
|
"""
|
||||||
tw = py.io.TerminalWriter(*args, **kwargs)
|
tw = TerminalWriter(*args, **kwargs)
|
||||||
if config.option.color == "yes":
|
if config.option.color == "yes":
|
||||||
tw.hasmarkup = True
|
tw.hasmarkup = True
|
||||||
if config.option.color == "no":
|
if config.option.color == "no":
|
||||||
|
|
|
@ -13,13 +13,14 @@ from typing import Sequence
|
||||||
from typing import Tuple
|
from typing import Tuple
|
||||||
from typing import Union
|
from typing import Union
|
||||||
|
|
||||||
import py
|
import py.path
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from _pytest import outcomes
|
from _pytest import outcomes
|
||||||
from _pytest._code.code import ExceptionInfo
|
from _pytest._code.code import ExceptionInfo
|
||||||
from _pytest._code.code import ReprFileLocation
|
from _pytest._code.code import ReprFileLocation
|
||||||
from _pytest._code.code import TerminalRepr
|
from _pytest._code.code import TerminalRepr
|
||||||
|
from _pytest._io import TerminalWriter
|
||||||
from _pytest.compat import safe_getattr
|
from _pytest.compat import safe_getattr
|
||||||
from _pytest.compat import TYPE_CHECKING
|
from _pytest.compat import TYPE_CHECKING
|
||||||
from _pytest.fixtures import FixtureRequest
|
from _pytest.fixtures import FixtureRequest
|
||||||
|
@ -139,7 +140,7 @@ class ReprFailDoctest(TerminalRepr):
|
||||||
):
|
):
|
||||||
self.reprlocation_lines = reprlocation_lines
|
self.reprlocation_lines = reprlocation_lines
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
for reprlocation, lines in self.reprlocation_lines:
|
for reprlocation, lines in self.reprlocation_lines:
|
||||||
for line in lines:
|
for line in lines:
|
||||||
tw.line(line)
|
tw.line(line)
|
||||||
|
|
|
@ -16,6 +16,7 @@ import py
|
||||||
import _pytest
|
import _pytest
|
||||||
from _pytest._code.code import FormattedExcinfo
|
from _pytest._code.code import FormattedExcinfo
|
||||||
from _pytest._code.code import TerminalRepr
|
from _pytest._code.code import TerminalRepr
|
||||||
|
from _pytest._io import TerminalWriter
|
||||||
from _pytest.compat import _format_args
|
from _pytest.compat import _format_args
|
||||||
from _pytest.compat import _PytestWrapper
|
from _pytest.compat import _PytestWrapper
|
||||||
from _pytest.compat import get_real_func
|
from _pytest.compat import get_real_func
|
||||||
|
@ -754,7 +755,7 @@ class FixtureLookupErrorRepr(TerminalRepr):
|
||||||
self.firstlineno = firstlineno
|
self.firstlineno = firstlineno
|
||||||
self.argname = argname
|
self.argname = argname
|
||||||
|
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
# tw.line("FixtureLookupError: %s" %(self.argname), red=True)
|
# tw.line("FixtureLookupError: %s" %(self.argname), red=True)
|
||||||
for tbline in self.tblines:
|
for tbline in self.tblines:
|
||||||
tw.line(tbline.rstrip())
|
tw.line(tbline.rstrip())
|
||||||
|
|
|
@ -18,6 +18,7 @@ from _pytest._code.code import ReprFuncArgs
|
||||||
from _pytest._code.code import ReprLocals
|
from _pytest._code.code import ReprLocals
|
||||||
from _pytest._code.code import ReprTraceback
|
from _pytest._code.code import ReprTraceback
|
||||||
from _pytest._code.code import TerminalRepr
|
from _pytest._code.code import TerminalRepr
|
||||||
|
from _pytest._io import TerminalWriter
|
||||||
from _pytest.compat import TYPE_CHECKING
|
from _pytest.compat import TYPE_CHECKING
|
||||||
from _pytest.nodes import Node
|
from _pytest.nodes import Node
|
||||||
from _pytest.outcomes import skip
|
from _pytest.outcomes import skip
|
||||||
|
@ -80,7 +81,7 @@ class BaseReport:
|
||||||
|
|
||||||
.. versionadded:: 3.0
|
.. versionadded:: 3.0
|
||||||
"""
|
"""
|
||||||
tw = py.io.TerminalWriter(stringio=True)
|
tw = TerminalWriter(stringio=True)
|
||||||
tw.hasmarkup = False
|
tw.hasmarkup = False
|
||||||
self.toterminal(tw)
|
self.toterminal(tw)
|
||||||
exc = tw.stringio.getvalue()
|
exc = tw.stringio.getvalue()
|
||||||
|
|
|
@ -12,6 +12,7 @@ import pytest
|
||||||
from _pytest._code.code import ExceptionChainRepr
|
from _pytest._code.code import ExceptionChainRepr
|
||||||
from _pytest._code.code import ExceptionInfo
|
from _pytest._code.code import ExceptionInfo
|
||||||
from _pytest._code.code import FormattedExcinfo
|
from _pytest._code.code import FormattedExcinfo
|
||||||
|
from _pytest._io import TerminalWriter
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -855,7 +856,7 @@ raise ValueError()
|
||||||
from _pytest._code.code import TerminalRepr
|
from _pytest._code.code import TerminalRepr
|
||||||
|
|
||||||
class MyRepr(TerminalRepr):
|
class MyRepr(TerminalRepr):
|
||||||
def toterminal(self, tw: py.io.TerminalWriter) -> None:
|
def toterminal(self, tw: TerminalWriter) -> None:
|
||||||
tw.line("я")
|
tw.line("я")
|
||||||
|
|
||||||
x = str(MyRepr())
|
x = str(MyRepr())
|
||||||
|
@ -1005,7 +1006,7 @@ raise ValueError()
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
excinfo = pytest.raises(ValueError, mod.f)
|
excinfo = pytest.raises(ValueError, mod.f)
|
||||||
tw = py.io.TerminalWriter(stringio=True)
|
tw = TerminalWriter(stringio=True)
|
||||||
repr = excinfo.getrepr(**reproptions)
|
repr = excinfo.getrepr(**reproptions)
|
||||||
repr.toterminal(tw)
|
repr.toterminal(tw)
|
||||||
assert tw.stringio.getvalue()
|
assert tw.stringio.getvalue()
|
||||||
|
@ -1225,7 +1226,7 @@ raise ValueError()
|
||||||
getattr(excinfo.value, attr).__traceback__ = None
|
getattr(excinfo.value, attr).__traceback__ = None
|
||||||
|
|
||||||
r = excinfo.getrepr()
|
r = excinfo.getrepr()
|
||||||
tw = py.io.TerminalWriter(stringio=True)
|
tw = TerminalWriter(stringio=True)
|
||||||
tw.hasmarkup = False
|
tw.hasmarkup = False
|
||||||
r.toterminal(tw)
|
r.toterminal(tw)
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import py.io
|
from _pytest._io import TerminalWriter
|
||||||
|
|
||||||
from _pytest.logging import ColoredLevelFormatter
|
from _pytest.logging import ColoredLevelFormatter
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,7 +21,7 @@ def test_coloredlogformatter():
|
||||||
class option:
|
class option:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
tw = py.io.TerminalWriter()
|
tw = TerminalWriter()
|
||||||
tw.hasmarkup = True
|
tw.hasmarkup = True
|
||||||
formatter = ColoredLevelFormatter(tw, logfmt)
|
formatter = ColoredLevelFormatter(tw, logfmt)
|
||||||
output = formatter.format(record)
|
output = formatter.format(record)
|
||||||
|
@ -142,7 +141,7 @@ def test_colored_short_level():
|
||||||
class option:
|
class option:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
tw = py.io.TerminalWriter()
|
tw = TerminalWriter()
|
||||||
tw.hasmarkup = True
|
tw.hasmarkup = True
|
||||||
formatter = ColoredLevelFormatter(tw, logfmt)
|
formatter = ColoredLevelFormatter(tw, logfmt)
|
||||||
output = formatter.format(record)
|
output = formatter.format(record)
|
||||||
|
|
Loading…
Reference in New Issue