From 24d3e015481434657a71d9b5403cc7331e936fea Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 5 Mar 2016 16:09:01 -0300 Subject: [PATCH 1/2] pytest.fail with non-ascii characters raises an internal pytest error Fix #1178 --- CHANGELOG.rst | 4 ++++ _pytest/python.py | 2 +- _pytest/runner.py | 2 +- testing/test_runner.py | 19 +++++++++++++++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 625c7edc5..bddd392d6 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -5,6 +5,10 @@ * +* Fix (`#1178 `_): + ``pytest.fail`` with non-ascii characters raises an internal pytest error. + Thanks `@nicoddemus`_ for the PR. + * Fix (`#469`_): junit parses report.nodeid incorrectly, when params IDs contain ``::``. Thanks `@tomviner`_ for the PR (`#1431`_). diff --git a/_pytest/python.py b/_pytest/python.py index ec346f587..48e4ebf5f 100644 --- a/_pytest/python.py +++ b/_pytest/python.py @@ -740,7 +740,7 @@ class FunctionMixin(PyobjMixin): def _repr_failure_py(self, excinfo, style="long"): if excinfo.errisinstance(pytest.fail.Exception): if not excinfo.value.pytrace: - return str(excinfo.value) + return py._builtin._totext(excinfo.value) return super(FunctionMixin, self)._repr_failure_py(excinfo, style=style) diff --git a/_pytest/runner.py b/_pytest/runner.py index a50c2d738..4f66aa97d 100644 --- a/_pytest/runner.py +++ b/_pytest/runner.py @@ -435,7 +435,7 @@ class OutcomeException(Exception): def __repr__(self): if self.msg: - return str(self.msg) + return py._builtin._totext(self.msg) return "<%s instance>" %(self.__class__.__name__,) __str__ = __repr__ diff --git a/testing/test_runner.py b/testing/test_runner.py index c3c415e0f..bfa8fc77f 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -1,3 +1,4 @@ +# -*- coding: utf-8 -*- from __future__ import with_statement import _pytest._code @@ -439,6 +440,24 @@ def test_pytest_fail_notrace(testdir): assert 'def teardown_function' not in result.stdout.str() +def test_pytest_fail_notrace_unicode(testdir): + """Fix pytest.fail with pytrace=False with non-ascii characters (#1178). + """ + testdir.makepyfile(u""" + # coding: utf-8 + import pytest + + def test_hello(): + pytest.fail(u'oh oh: ☺', pytrace=False) + """) + result = testdir.runpytest() + if sys.version_info[0] >= 3: + result.stdout.fnmatch_lines(['*test_hello*', "oh oh: ☺"]) + else: + result.stdout.fnmatch_lines(['*test_hello*', "oh oh: *"]) + assert 'def test_hello' not in result.stdout.str() + + def test_pytest_no_tests_collected_exit_status(testdir): result = testdir.runpytest() result.stdout.fnmatch_lines('*collected 0 items*') From 5d4703852e0acd7430b57c0485879349c20518d3 Mon Sep 17 00:00:00 2001 From: Bruno Oliveira Date: Sat, 5 Mar 2016 19:34:15 -0300 Subject: [PATCH 2/2] Add test when using native strings with non-ascii chars --- _pytest/runner.py | 5 ++++- testing/test_runner.py | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/_pytest/runner.py b/_pytest/runner.py index 4f66aa97d..cde94c8c8 100644 --- a/_pytest/runner.py +++ b/_pytest/runner.py @@ -435,7 +435,10 @@ class OutcomeException(Exception): def __repr__(self): if self.msg: - return py._builtin._totext(self.msg) + val = self.msg + if isinstance(val, bytes): + val = py._builtin._totext(val, errors='replace') + return val return "<%s instance>" %(self.__class__.__name__,) __str__ = __repr__ diff --git a/testing/test_runner.py b/testing/test_runner.py index bfa8fc77f..4421c5d0d 100644 --- a/testing/test_runner.py +++ b/testing/test_runner.py @@ -440,16 +440,19 @@ def test_pytest_fail_notrace(testdir): assert 'def teardown_function' not in result.stdout.str() -def test_pytest_fail_notrace_unicode(testdir): +@pytest.mark.parametrize('str_prefix', ['u', '']) +def test_pytest_fail_notrace_non_ascii(testdir, str_prefix): """Fix pytest.fail with pytrace=False with non-ascii characters (#1178). + + This tests with native and unicode strings containing non-ascii chars. """ testdir.makepyfile(u""" # coding: utf-8 import pytest def test_hello(): - pytest.fail(u'oh oh: ☺', pytrace=False) - """) + pytest.fail(%s'oh oh: ☺', pytrace=False) + """ % str_prefix) result = testdir.runpytest() if sys.version_info[0] >= 3: result.stdout.fnmatch_lines(['*test_hello*', "oh oh: ☺"])