diff --git a/AUTHORS b/AUTHORS index b49405bf757..821bd2a6d65 100644 --- a/AUTHORS +++ b/AUTHORS @@ -113,6 +113,7 @@ Nicolas Delaby Oleg Pidsadnyi Oliver Bestwalter Omar Kohl +Omer Hadari Patrick Hayes Pieter Mulder Piotr Banaszkiewicz diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 32726274f4e..2168914849d 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -22,7 +22,8 @@ * Replace ``raise StopIteration`` usages in the code by simple ``returns`` to finish generators, in accordance to `PEP-479`_ (`#2160`_). Thanks `@tgoodlet`_ for the report and `@nicoddemus`_ for the PR. -* +* Fix internal errors when an unprintable ``AssertionError`` is raised inside a test. + Thanks `@omerhadari`_ for the PR. * Skipping plugin now also works with test items generated by custom collectors (`#2231`_). Thanks to `@vidartf`_. @@ -42,6 +43,7 @@ .. _@sirex: https://github.com/sirex .. _@vidartf: https://github.com/vidartf .. _@kkoukiou: https://github.com/KKoukiou +.. _@omerhadari: https://github.com/omerhadari .. _#2248: https://github.com/pytest-dev/pytest/issues/2248 .. _#2137: https://github.com/pytest-dev/pytest/issues/2137 diff --git a/_pytest/_code/code.py b/_pytest/_code/code.py index 616d5c43138..6eceb0c7f3d 100644 --- a/_pytest/_code/code.py +++ b/_pytest/_code/code.py @@ -352,6 +352,8 @@ class ExceptionInfo(object): help for navigating the traceback. """ _striptext = '' + _assert_start_repr = "AssertionError(u\'assert " if sys.version_info[0] < 3 else "AssertionError(\'assert " + def __init__(self, tup=None, exprinfo=None): import _pytest._code if tup is None: @@ -359,8 +361,8 @@ def __init__(self, tup=None, exprinfo=None): if exprinfo is None and isinstance(tup[1], AssertionError): exprinfo = getattr(tup[1], 'msg', None) if exprinfo is None: - exprinfo = py._builtin._totext(tup[1]) - if exprinfo and exprinfo.startswith('assert '): + exprinfo = py.io.saferepr(tup[1]) + if exprinfo and exprinfo.startswith(self._assert_start_repr): self._striptext = 'AssertionError: ' self._excinfo = tup #: the exception class diff --git a/testing/test_assertion.py b/testing/test_assertion.py index dfc9f60fb65..bc814590ad8 100644 --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -916,6 +916,25 @@ def test_unicode(): result = testdir.runpytest() result.stdout.fnmatch_lines(['*AssertionError*']) +def test_raise_unprintable_assertion_error(testdir): + testdir.makepyfile(r""" + def test_raise_assertion_error(): + raise AssertionError('\xff') + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines([r"> raise AssertionError('\xff')", 'E AssertionError: *']) + +def test_raise_assertion_error_raisin_repr(testdir): + testdir.makepyfile(u""" + class RaisingRepr(object): + def __repr__(self): + raise Exception() + def test_raising_repr(): + raise AssertionError(RaisingRepr()) + """) + result = testdir.runpytest() + result.stdout.fnmatch_lines(['E AssertionError: ']) + def test_issue_1944(testdir): testdir.makepyfile(""" def f():