terminalwriter: don't flush implicitly; add explicit flushes

Flushing on every write is somewhat expensive.

Rely on line buffering instead (if line buffering for stdout is
disabled, there must be some reason...), and add explicit flushes when
not outputting lines.

This is how regular `print()` e.g. work so should be familiar.
This commit is contained in:
Ran Benita 2020-04-29 17:58:33 +03:00
parent d9b43647b7
commit 1bc4170e63
5 changed files with 22 additions and 9 deletions

View File

@ -155,7 +155,7 @@ class TerminalWriter:
self.line(line, **kw)
def write(self, msg: str, **kw: bool) -> None:
def write(self, msg: str, *, flush: bool = False, **kw: bool) -> None:
if msg:
current_line = msg.rsplit("\n", 1)[-1]
if "\n" in msg:
@ -170,12 +170,16 @@ class TerminalWriter:
else:
markupmsg = msg
self._file.write(markupmsg)
self._file.flush()
if flush:
self.flush()
def line(self, s: str = "", **kw: bool) -> None:
self.write(s, **kw)
self.write("\n")
def flush(self) -> None:
self._file.flush()
def _write_source(self, lines: Sequence[str], indents: Sequence[str] = ()) -> None:
"""Write lines of source code possibly highlighted.

View File

@ -1424,7 +1424,7 @@ def _showfixtures_main(config, session):
def write_docstring(tw: TerminalWriter, doc: str, indent: str = " ") -> None:
for line in doc.split("\n"):
tw.write(indent + line + "\n")
tw.line(indent + line)
class Function(PyobjMixin, nodes.Item):

View File

@ -120,6 +120,7 @@ def show_test_item(item):
used_fixtures = sorted(getattr(item, "fixturenames", []))
if used_fixtures:
tw.write(" (fixtures used: {})".format(", ".join(used_fixtures)))
tw.flush()
def pytest_runtest_setup(item):

View File

@ -68,6 +68,8 @@ def _show_fixture_action(fixturedef, msg):
if hasattr(fixturedef, "cached_param"):
tw.write("[{}]".format(fixturedef.cached_param))
tw.flush()
if capman:
capman.resume_global_capture()

View File

@ -343,7 +343,7 @@ class TerminalReporter:
fspath = self.startdir.bestrelpath(fspath)
self._tw.line()
self._tw.write(fspath + " ")
self._tw.write(res, **markup)
self._tw.write(res, flush=True, **markup)
def write_ensure_prefix(self, prefix, extra="", **kwargs):
if self.currentfspath != prefix:
@ -359,8 +359,11 @@ class TerminalReporter:
self._tw.line()
self.currentfspath = None
def write(self, content, **markup):
self._tw.write(content, **markup)
def write(self, content: str, *, flush: bool = False, **markup: bool) -> None:
self._tw.write(content, flush=flush, **markup)
def flush(self) -> None:
self._tw.flush()
def write_line(self, line, **markup):
if not isinstance(line, str):
@ -437,9 +440,11 @@ class TerminalReporter:
if self.showlongtestinfo:
line = self._locationline(nodeid, *location)
self.write_ensure_prefix(line, "")
self.flush()
elif self.showfspath:
fsid = nodeid.split("::")[0]
self.write_fspath_result(fsid, "")
self.flush()
def pytest_runtest_logreport(self, report: TestReport) -> None:
self._tests_ran = True
@ -491,6 +496,7 @@ class TerminalReporter:
self._tw.write(word, **markup)
self._tw.write(" " + line)
self.currentfspath = -2
self.flush()
@property
def _is_last_item(self):
@ -539,7 +545,7 @@ class TerminalReporter:
msg = self._get_progress_information_message()
w = self._width_of_current_line
fill = self._tw.fullwidth - w - 1
self.write(msg.rjust(fill), **{color: True})
self.write(msg.rjust(fill), flush=True, **{color: True})
@property
def _width_of_current_line(self):
@ -553,10 +559,10 @@ class TerminalReporter:
def pytest_collection(self) -> None:
if self.isatty:
if self.config.option.verbose >= 0:
self.write("collecting ... ", bold=True)
self.write("collecting ... ", flush=True, bold=True)
self._collect_report_last_write = time.time()
elif self.config.option.verbose >= 1:
self.write("collecting ... ", bold=True)
self.write("collecting ... ", flush=True, bold=True)
def pytest_collectreport(self, report: CollectReport) -> None:
if report.failed: