1 new commit in pytest: https://bitbucket.org/hpk42/pytest/commits/a1f920be1e33/ Changeset: a1f920be1e33 User: flub Date: 2014-04-02 18:35:22 Summary: Escape newlines in result from assertrepr hook
The result from the pytest_assertrepr_compare hook should not include any newlines since that will confuse the mini-formatting language used by assertion.util.format_explanation. So simply escape the included newlines, this way hook writers do not have to worry about this at all. Fixes issue 453. Affected #: 2 files diff -r 66efe3231c7bdb6316d9e0fcd9f76f36d1063d06 -r a1f920be1e33b3ad8c2f0549d482119b52d7f4e1 _pytest/assertion/__init__.py --- a/_pytest/assertion/__init__.py +++ b/_pytest/assertion/__init__.py @@ -88,22 +88,38 @@ def pytest_runtest_setup(item): + """Setup the pytest_assertrepr_compare hook + + The newinterpret and rewrite modules will use util._reprcompare if + it exists to use custom reporting via the + pytest_assertrepr_compare hook. This sets up this custom + comparison for the test. + """ def callbinrepr(op, left, right): + """Call the pytest_assertrepr_compare hook and prepare the result + + This uses the first result from the hook and then ensures the + following: + * Overly verbose explanations are dropped unles -vv was used. + * Embedded newlines are escaped to help util.format_explanation() + later. + * If the rewrite mode is used embedded %-characters are replaced + to protect later % formatting. + + The result can be formatted by util.format_explanation() for + pretty printing. + """ hook_result = item.ihook.pytest_assertrepr_compare( config=item.config, op=op, left=left, right=right) for new_expl in hook_result: if new_expl: - # Don't include pageloads of data unless we are very - # verbose (-vv) if (sum(len(p) for p in new_expl[1:]) > 80*8 and item.config.option.verbose < 2): new_expl[1:] = [py.builtin._totext( 'Detailed information truncated, use "-vv" to show')] + new_expl = [line.replace("\n", "\\n") for line in new_expl] res = py.builtin._totext("\n~").join(new_expl) if item.config.getvalue("assertmode") == "rewrite": - # The result will be fed back a python % formatting - # operation, which will fail if there are extraneous - # '%'s in the string. Escape them here. res = res.replace("%", "%%") return res util._reprcompare = callbinrepr @@ -145,4 +161,5 @@ "(are you using python -O?)\n") +# Expose this plugin's implementation for the pytest_assertrepr_compare hook pytest_assertrepr_compare = util.assertrepr_compare diff -r 66efe3231c7bdb6316d9e0fcd9f76f36d1063d06 -r a1f920be1e33b3ad8c2f0549d482119b52d7f4e1 testing/test_assertion.py --- a/testing/test_assertion.py +++ b/testing/test_assertion.py @@ -4,6 +4,7 @@ import py, pytest import _pytest.assertion as plugin from _pytest.assertion import reinterpret +from _pytest.assertion import util needsnewassert = pytest.mark.skipif("sys.version_info < (2,6)") @@ -199,6 +200,21 @@ assert msg +class TestFormatExplanation: + + def test_speical_chars_full(self, testdir): + # Issue 453, for the bug this would raise IndexError + testdir.makepyfile(""" + def test_foo(): + assert u'\\n}' == u'' + """) + result = testdir.runpytest() + assert result.ret == 1 + result.stdout.fnmatch_lines([ + "*AssertionError*", + ]) + + def test_python25_compile_issue257(testdir): testdir.makepyfile(""" def test_rewritten(): Repository URL: https://bitbucket.org/hpk42/pytest/ -- This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email. _______________________________________________ pytest-commit mailing list pytest-commit@python.org https://mail.python.org/mailman/listinfo/pytest-commit