fix problem with unicode in writing failure representations to terminal, thanks ThomasWaldmann

This commit is contained in:
holger krekel 2012-06-24 16:42:31 +02:00
parent 6e0c30d67d
commit 227d847216
4 changed files with 31 additions and 7 deletions

View File

@ -1,12 +1,14 @@
Changes between 2.2.4 and 2.2.5.dev Changes between 2.2.4 and 2.2.5.dev
----------------------------------- -----------------------------------
- catch unicode-issues when writing failure representations
to terminal to prevent the whole session from crashing
- fix xfail/skip confusion: a skip-mark or an imperative pytest.skip - fix xfail/skip confusion: a skip-mark or an imperative pytest.skip
will now take precedence before xfail-markers because we will now take precedence before xfail-markers because we
can't determine xfail/xpass status in case of a skip. see also: can't determine xfail/xpass status in case of a skip. see also:
http://stackoverflow.com/questions/11105828/in-py-test-when-i-explicitly-skip-a-test-that-is-marked-as-xfail-how-can-i-get http://stackoverflow.com/questions/11105828/in-py-test-when-i-explicitly-skip-a-test-that-is-marked-as-xfail-how-can-i-get
- always report installed 3rd party plugins - always report installed 3rd party plugins in the header of a test run
- fix issue160: a failing setup of an xfail-marked tests should - fix issue160: a failing setup of an xfail-marked tests should
be reported as xfail (not xpass) be reported as xfail (not xpass)

View File

@ -154,7 +154,10 @@ class BaseReport(object):
if hasattr(longrepr, 'toterminal'): if hasattr(longrepr, 'toterminal'):
longrepr.toterminal(out) longrepr.toterminal(out)
else: else:
out.line(str(longrepr)) try:
out.line(longrepr)
except UnicodeEncodeError:
out.line("<unprintable longrepr>")
passed = property(lambda x: x.outcome == "passed") passed = property(lambda x: x.outcome == "passed")
failed = property(lambda x: x.outcome == "failed") failed = property(lambda x: x.outcome == "failed")
@ -279,7 +282,7 @@ class CollectErrorRepr(TerminalRepr):
def __init__(self, msg): def __init__(self, msg):
self.longrepr = msg self.longrepr = msg
def toterminal(self, out): def toterminal(self, out):
out.line(str(self.longrepr), red=True) out.line(self.longrepr, red=True)
class SetupState(object): class SetupState(object):
""" shared state for setting up/tearing down test items or collectors. """ """ shared state for setting up/tearing down test items or collectors. """

View File

@ -38,13 +38,14 @@ def pytest_configure(config):
stdout = py.std.sys.stdout stdout = py.std.sys.stdout
if hasattr(os, 'dup') and hasattr(stdout, 'fileno'): if hasattr(os, 'dup') and hasattr(stdout, 'fileno'):
try: try:
newfd = os.dup(stdout.fileno()) newstdout = py.io.dupfile(stdout, buffering=1,
#print "got newfd", newfd encoding=stdout.encoding)
except ValueError: except ValueError:
pass pass
else: else:
stdout = os.fdopen(newfd, stdout.mode, 1) config._cleanup.append(lambda: newstdout.close())
config._cleanup.append(lambda: stdout.close()) assert stdout.encoding == newstdout.encoding
stdout = newstdout
reporter = TerminalReporter(config, stdout) reporter = TerminalReporter(config, stdout)
config.pluginmanager.register(reporter, 'terminalreporter') config.pluginmanager.register(reporter, 'terminalreporter')

View File

@ -456,3 +456,21 @@ def test_pytest_cmdline_main(testdir):
ret = popen.wait() ret = popen.wait()
assert ret == 0 assert ret == 0
def test_unicode_in_longrepr(testdir):
testdir.makeconftest("""
import py
def pytest_runtest_makereport(__multicall__):
rep = __multicall__.execute()
if rep.when == "call":
rep.longrepr = py.builtin._totext("\\xc3\\xa4", "utf8")
return rep
""")
testdir.makepyfile("""
def test_out():
assert 0
""")
result = testdir.runpytest()
assert result.ret == 1
assert "UnicodeEncodeError" not in result.stderr.str()