Deprecate TerminalReporter._tw

Fix #2803
This commit is contained in:
Bruno Oliveira 2017-09-27 16:00:55 -03:00
parent de0d19ca09
commit 3b30c93f73
7 changed files with 71 additions and 56 deletions

View File

@ -931,7 +931,7 @@ class Config(object):
fslocation=fslocation, nodeid=nodeid)) fslocation=fslocation, nodeid=nodeid))
def get_terminal_writer(self): def get_terminal_writer(self):
return self.pluginmanager.get_plugin("terminalreporter")._tw return self.pluginmanager.get_plugin("terminalreporter").writer
def pytest_cmdline_parse(self, pluginmanager, args): def pytest_cmdline_parse(self, pluginmanager, args):
# REF1 assert self == pluginmanager.config, (self, pluginmanager.config) # REF1 assert self == pluginmanager.config, (self, pluginmanager.config)

View File

@ -83,7 +83,7 @@ def _enter_pdb(node, excinfo, rep):
# XXX we re-use the TerminalReporter's terminalwriter # XXX we re-use the TerminalReporter's terminalwriter
# because this seems to avoid some encoding related troubles # because this seems to avoid some encoding related troubles
# for not completely clear reasons. # for not completely clear reasons.
tw = node.config.pluginmanager.getplugin("terminalreporter")._tw tw = node.config.pluginmanager.getplugin("terminalreporter").writer
tw.line() tw.line()
tw.sep(">", "traceback") tw.sep(">", "traceback")
rep.toterminal(tw) rep.toterminal(tw)

View File

@ -107,7 +107,7 @@ def pytest_cmdline_main(config):
def showhelp(config): def showhelp(config):
reporter = config.pluginmanager.get_plugin('terminalreporter') reporter = config.pluginmanager.get_plugin('terminalreporter')
tw = reporter._tw tw = reporter.writer
tw.write(config._parser.optparser.format_help()) tw.write(config._parser.optparser.format_help())
tw.line() tw.line()
tw.line() tw.line()

View File

@ -25,7 +25,7 @@ def pytest_configure(config):
if tr is not None: if tr is not None:
# pastebin file will be utf-8 encoded binary file # pastebin file will be utf-8 encoded binary file
config._pastebinfile = tempfile.TemporaryFile('w+b') config._pastebinfile = tempfile.TemporaryFile('w+b')
oldwrite = tr._tw.write oldwrite = tr.writer.write
def tee_write(s, **kwargs): def tee_write(s, **kwargs):
oldwrite(s, **kwargs) oldwrite(s, **kwargs)
@ -33,7 +33,7 @@ def pytest_configure(config):
s = s.encode('utf-8') s = s.encode('utf-8')
config._pastebinfile.write(s) config._pastebinfile.write(s)
tr._tw.write = tee_write tr.writer.write = tee_write
def pytest_unconfigure(config): def pytest_unconfigure(config):
@ -45,7 +45,7 @@ def pytest_unconfigure(config):
del config._pastebinfile del config._pastebinfile
# undo our patching in the terminal reporter # undo our patching in the terminal reporter
tr = config.pluginmanager.getplugin('terminalreporter') tr = config.pluginmanager.getplugin('terminalreporter')
del tr._tw.__dict__['write'] del tr.writer.__dict__['write']
# write summary # write summary
tr.write_sep("=", "Sending information to Paste Service") tr.write_sep("=", "Sending information to Paste Service")
pastebinurl = create_new_paste(sessionlog) pastebinurl = create_new_paste(sessionlog)

View File

@ -295,9 +295,9 @@ def pytest_terminal_summary(terminalreporter):
show_simple(terminalreporter, lines, 'passed', "PASSED %s") show_simple(terminalreporter, lines, 'passed', "PASSED %s")
if lines: if lines:
tr._tw.sep("=", "short test summary info") tr.writer.sep("=", "short test summary info")
for line in lines: for line in lines:
tr._tw.line(line) tr.writer.line(line)
def show_simple(terminalreporter, lines, stat, format): def show_simple(terminalreporter, lines, stat, format):

View File

@ -5,15 +5,18 @@ This is a good source for looking at the various reporting hooks.
from __future__ import absolute_import, division, print_function from __future__ import absolute_import, division, print_function
import itertools import itertools
from _pytest.main import EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, \ import platform
EXIT_USAGEERROR, EXIT_NOTESTSCOLLECTED
import pytest
import py
import six
import sys import sys
import time import time
import platform import warnings
import py
import six
import pluggy import pluggy
import pytest
from _pytest.main import EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, \
EXIT_USAGEERROR, EXIT_NOTESTSCOLLECTED
def pytest_addoption(parser): def pytest_addoption(parser):
@ -136,13 +139,22 @@ class TerminalReporter:
self.startdir = py.path.local() self.startdir = py.path.local()
if file is None: if file is None:
file = sys.stdout file = sys.stdout
self._tw = self.writer = _pytest.config.create_terminal_writer(config, self._writer = _pytest.config.create_terminal_writer(config, file)
file)
self.currentfspath = None self.currentfspath = None
self.reportchars = getreportopt(config) self.reportchars = getreportopt(config)
self.hasmarkup = self._tw.hasmarkup self.hasmarkup = self.writer.hasmarkup
self.isatty = file.isatty() self.isatty = file.isatty()
@property
def writer(self):
return self._writer
@property
def _tw(self):
warnings.warn(DeprecationWarning('TerminalReporter._tw is deprecated, use TerminalReporter.writer instead'),
stacklevel=2)
return self.writer
def hasopt(self, char): def hasopt(self, char):
char = {'xfailed': 'x', 'skipped': 's'}.get(char, char) char = {'xfailed': 'x', 'skipped': 's'}.get(char, char)
return char in self.reportchars return char in self.reportchars
@ -152,32 +164,32 @@ class TerminalReporter:
if fspath != self.currentfspath: if fspath != self.currentfspath:
self.currentfspath = fspath self.currentfspath = fspath
fspath = self.startdir.bestrelpath(fspath) fspath = self.startdir.bestrelpath(fspath)
self._tw.line() self.writer.line()
self._tw.write(fspath + " ") self.writer.write(fspath + " ")
self._tw.write(res) self.writer.write(res)
def write_ensure_prefix(self, prefix, extra="", **kwargs): def write_ensure_prefix(self, prefix, extra="", **kwargs):
if self.currentfspath != prefix: if self.currentfspath != prefix:
self._tw.line() self.writer.line()
self.currentfspath = prefix self.currentfspath = prefix
self._tw.write(prefix) self.writer.write(prefix)
if extra: if extra:
self._tw.write(extra, **kwargs) self.writer.write(extra, **kwargs)
self.currentfspath = -2 self.currentfspath = -2
def ensure_newline(self): def ensure_newline(self):
if self.currentfspath: if self.currentfspath:
self._tw.line() self.writer.line()
self.currentfspath = None self.currentfspath = None
def write(self, content, **markup): def write(self, content, **markup):
self._tw.write(content, **markup) self.writer.write(content, **markup)
def write_line(self, line, **markup): def write_line(self, line, **markup):
if not isinstance(line, six.text_type): if not isinstance(line, six.text_type):
line = six.text_type(line, errors="replace") line = six.text_type(line, errors="replace")
self.ensure_newline() self.ensure_newline()
self._tw.line(line, **markup) self.writer.line(line, **markup)
def rewrite(self, line, **markup): def rewrite(self, line, **markup):
""" """
@ -190,22 +202,22 @@ class TerminalReporter:
""" """
erase = markup.pop('erase', False) erase = markup.pop('erase', False)
if erase: if erase:
fill_count = self._tw.fullwidth - len(line) fill_count = self.writer.fullwidth - len(line)
fill = ' ' * fill_count fill = ' ' * fill_count
else: else:
fill = '' fill = ''
line = str(line) line = str(line)
self._tw.write("\r" + line + fill, **markup) self.writer.write("\r" + line + fill, **markup)
def write_sep(self, sep, title=None, **markup): def write_sep(self, sep, title=None, **markup):
self.ensure_newline() self.ensure_newline()
self._tw.sep(sep, title, **markup) self.writer.sep(sep, title, **markup)
def section(self, title, sep="=", **kw): def section(self, title, sep="=", **kw):
self._tw.sep(sep, title, **kw) self.writer.sep(sep, title, **kw)
def line(self, msg, **kw): def line(self, msg, **kw):
self._tw.line(msg, **kw) self.writer.line(msg, **kw)
def pytest_internalerror(self, excrepr): def pytest_internalerror(self, excrepr):
for line in six.text_type(excrepr).split("\n"): for line in six.text_type(excrepr).split("\n"):
@ -252,7 +264,7 @@ class TerminalReporter:
if not hasattr(rep, 'node') and self.showfspath: if not hasattr(rep, 'node') and self.showfspath:
self.write_fspath_result(rep.nodeid, letter) self.write_fspath_result(rep.nodeid, letter)
else: else:
self._tw.write(letter) self.writer.write(letter)
else: else:
if isinstance(word, tuple): if isinstance(word, tuple):
word, markup = word word, markup = word
@ -263,16 +275,18 @@ class TerminalReporter:
markup = {'red': True} markup = {'red': True}
elif rep.skipped: elif rep.skipped:
markup = {'yellow': True} markup = {'yellow': True}
else:
markup = {}
line = self._locationline(rep.nodeid, *rep.location) line = self._locationline(rep.nodeid, *rep.location)
if not hasattr(rep, 'node'): if not hasattr(rep, 'node'):
self.write_ensure_prefix(line, word, **markup) self.write_ensure_prefix(line, word, **markup)
# self._tw.write(word, **markup) # self.writer.write(word, **markup)
else: else:
self.ensure_newline() self.ensure_newline()
if hasattr(rep, 'node'): if hasattr(rep, 'node'):
self._tw.write("[%s] " % rep.node.gateway.id) self.writer.write("[%s] " % rep.node.gateway.id)
self._tw.write(word, **markup) self.writer.write(word, **markup)
self._tw.write(" " + line) self.writer.write(" " + line)
self.currentfspath = -2 self.currentfspath = -2
def pytest_collection(self): def pytest_collection(self):
@ -358,9 +372,9 @@ class TerminalReporter:
if self.config.option.collectonly: if self.config.option.collectonly:
self._printcollecteditems(session.items) self._printcollecteditems(session.items)
if self.stats.get('failed'): if self.stats.get('failed'):
self._tw.sep("!", "collection failures") self.writer.sep("!", "collection failures")
for rep in self.stats.get('failed'): for rep in self.stats.get('failed'):
rep.toterminal(self._tw) rep.toterminal(self.writer)
return 1 return 1
return 0 return 0
lines = self.config.hook.pytest_report_collectionfinish( lines = self.config.hook.pytest_report_collectionfinish(
@ -378,12 +392,12 @@ class TerminalReporter:
name = item.nodeid.split('::', 1)[0] name = item.nodeid.split('::', 1)[0]
counts[name] = counts.get(name, 0) + 1 counts[name] = counts.get(name, 0) + 1
for name, count in sorted(counts.items()): for name, count in sorted(counts.items()):
self._tw.line("%s: %d" % (name, count)) self.writer.line("%s: %d" % (name, count))
else: else:
for item in items: for item in items:
nodeid = item.nodeid nodeid = item.nodeid
nodeid = nodeid.replace("::()::", "::") nodeid = nodeid.replace("::()::", "::")
self._tw.line(nodeid) self.writer.line(nodeid)
return return
stack = [] stack = []
indent = "" indent = ""
@ -398,13 +412,13 @@ class TerminalReporter:
# if col.name == "()": # if col.name == "()":
# continue # continue
indent = (len(stack) - 1) * " " indent = (len(stack) - 1) * " "
self._tw.line("%s%s" % (indent, col)) self.writer.line("%s%s" % (indent, col))
@pytest.hookimpl(hookwrapper=True) @pytest.hookimpl(hookwrapper=True)
def pytest_sessionfinish(self, exitstatus): def pytest_sessionfinish(self, exitstatus):
outcome = yield outcome = yield
outcome.get_result() outcome.get_result()
self._tw.line("") self.writer.line("")
summary_exit_codes = ( summary_exit_codes = (
EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, EXIT_USAGEERROR, EXIT_OK, EXIT_TESTSFAILED, EXIT_INTERRUPTED, EXIT_USAGEERROR,
EXIT_NOTESTSCOLLECTED) EXIT_NOTESTSCOLLECTED)
@ -434,10 +448,10 @@ class TerminalReporter:
self.write_sep("!", msg) self.write_sep("!", msg)
if "KeyboardInterrupt" in msg: if "KeyboardInterrupt" in msg:
if self.config.option.fulltrace: if self.config.option.fulltrace:
excrepr.toterminal(self._tw) excrepr.toterminal(self.writer)
else: else:
self._tw.line("to show a full traceback on KeyboardInterrupt use --fulltrace", yellow=True) self.writer.line("to show a full traceback on KeyboardInterrupt use --fulltrace", yellow=True)
excrepr.reprcrash.toterminal(self._tw) excrepr.reprcrash.toterminal(self.writer)
def _locationline(self, nodeid, fspath, lineno, domain): def _locationline(self, nodeid, fspath, lineno, domain):
def mkrel(nodeid): def mkrel(nodeid):
@ -493,14 +507,14 @@ class TerminalReporter:
grouped = itertools.groupby(all_warnings, key=lambda wr: wr.get_location(self.config)) grouped = itertools.groupby(all_warnings, key=lambda wr: wr.get_location(self.config))
self.write_sep("=", "warnings summary", yellow=True, bold=False) self.write_sep("=", "warnings summary", yellow=True, bold=False)
for location, warnings in grouped: for location, warning_records in grouped:
self._tw.line(str(location) or '<undetermined location>') self.writer.line(str(location) or '<undetermined location>')
for w in warnings: for w in warning_records:
lines = w.message.splitlines() lines = w.message.splitlines()
indented = '\n'.join(' ' + x for x in lines) indented = '\n'.join(' ' + x for x in lines)
self._tw.line(indented) self.writer.line(indented)
self._tw.line() self.writer.line()
self._tw.line('-- Docs: http://doc.pytest.org/en/latest/warnings.html') self.writer.line('-- Docs: http://doc.pytest.org/en/latest/warnings.html')
def summary_passes(self): def summary_passes(self):
if self.config.option.tbstyle != "no": if self.config.option.tbstyle != "no":
@ -517,10 +531,10 @@ class TerminalReporter:
def print_teardown_sections(self, rep): def print_teardown_sections(self, rep):
for secname, content in rep.sections: for secname, content in rep.sections:
if 'teardown' in secname: if 'teardown' in secname:
self._tw.sep('-', secname) self.writer.sep('-', secname)
if content[-1:] == "\n": if content[-1:] == "\n":
content = content[:-1] content = content[:-1]
self._tw.line(content) self.writer.line(content)
def summary_failures(self): def summary_failures(self):
if self.config.option.tbstyle != "no": if self.config.option.tbstyle != "no":
@ -560,12 +574,12 @@ class TerminalReporter:
self._outrep_summary(rep) self._outrep_summary(rep)
def _outrep_summary(self, rep): def _outrep_summary(self, rep):
rep.toterminal(self._tw) rep.toterminal(self.writer)
for secname, content in rep.sections: for secname, content in rep.sections:
self._tw.sep("-", secname) self.writer.sep("-", secname)
if content[-1:] == "\n": if content[-1:] == "\n":
content = content[:-1] content = content[:-1]
self._tw.line(content) self.writer.line(content)
def summary_stats(self): def summary_stats(self):
session_duration = time.time() - self._sessionstarttime session_duration = time.time() - self._sessionstarttime

1
changelog/2803.removal Normal file
View File

@ -0,0 +1 @@
``TerminalReporter._tw`` has been deprecated in favor of ``TerminalReporter.writer`` and will be removed in a future version. Also, ``TerminalReporter.writer`` is now read-only.