From 053c052190ef757a660c715c110e88a8e053ef04 Mon Sep 17 00:00:00 2001 From: Tyler Goodlet Date: Fri, 1 Apr 2016 01:20:22 -0400 Subject: [PATCH 1/3] Always lstrip() keyword expression --- _pytest/mark.py | 2 +- testing/acceptance_test.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/_pytest/mark.py b/_pytest/mark.py index 1a7635402..d8b60def3 100644 --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -58,7 +58,7 @@ pytest_cmdline_main.tryfirst = True def pytest_collection_modifyitems(items, config): - keywordexpr = config.option.keyword + keywordexpr = config.option.keyword.lstrip() matchexpr = config.option.markexpr if not keywordexpr and not matchexpr: return diff --git a/testing/acceptance_test.py b/testing/acceptance_test.py index 9bc3a191a..4e9645037 100644 --- a/testing/acceptance_test.py +++ b/testing/acceptance_test.py @@ -670,6 +670,11 @@ class TestDurations: "*call*test_1*", ]) + def test_with_not(self, testdir): + testdir.makepyfile(self.source) + result = testdir.runpytest("-k not 1") + assert result.ret == 0 + class TestDurationWithFixture: source = """ From fb45f8284041faacb05d0cb2d2046a49d9db493a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20G=C3=BCttler?= Date: Tue, 5 Apr 2016 14:08:30 +0200 Subject: [PATCH 2/3] Hudson -> Jenkins --- doc/en/usage.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/en/usage.rst b/doc/en/usage.rst index a3d56deff..fba699849 100644 --- a/doc/en/usage.rst +++ b/doc/en/usage.rst @@ -158,7 +158,7 @@ To get a list of the slowest 10 test durations:: Creating JUnitXML format files ---------------------------------------------------- -To create result files which can be read by Hudson_ or other Continuous +To create result files which can be read by Jenkins_ or other Continuous integration servers, use this invocation:: py.test --junitxml=path From 7ce5873da23ea0dc6f796c4d608731e25191d756 Mon Sep 17 00:00:00 2001 From: Martin Prusse Date: Fri, 8 Apr 2016 11:24:12 -0300 Subject: [PATCH 3/3] Perform a "unicode aware" check for maximum recursion depth error Avoid errors `UnicodeErrosr`s due non maximum recursion depth errors when checking for those errors. --- AUTHORS | 1 + CHANGELOG.rst | 9 +++++++++ _pytest/_code/code.py | 16 +++++++++++++--- testing/code/test_excinfo.py | 18 +++++++++++++++++- 4 files changed, 40 insertions(+), 4 deletions(-) diff --git a/AUTHORS b/AUTHORS index 92750acc3..14bb4e3c1 100644 --- a/AUTHORS +++ b/AUTHORS @@ -61,6 +61,7 @@ Marc Schlaich Mark Abramowitz Markus Unterwaditzer Martijn Faassen +Martin Prusse Matt Bachmann Michael Aquilina Michael Birtwell diff --git a/CHANGELOG.rst b/CHANGELOG.rst index a64d64a12..2b6780ad8 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -7,6 +7,10 @@ * +* Fix maximum recursion depth detection when raised error class is not aware + of unicode/encoded bytes. + Thanks `@prusse-martin`_ for the PR (`#1506`_). + * Fix ``pytest.mark.skip`` mark when used in strict mode. Thanks `@pquentin`_ for the PR and `@RonnyPfannschmidt`_ for showing how to fix the bug. @@ -15,6 +19,11 @@ Thanks `@omarkohl`_ for the PR. +.. _#1506: https://github.com/pytest-dev/pytest/pull/1506 + +.. _@prusse-martin: https://github.com/prusse-martin + + 2.9.1 ===== diff --git a/_pytest/_code/code.py b/_pytest/_code/code.py index bc68aac55..31a3eda2d 100644 --- a/_pytest/_code/code.py +++ b/_pytest/_code/code.py @@ -579,9 +579,8 @@ class FormattedExcinfo(object): if self.tbfilter: traceback = traceback.filter() recursionindex = None - if excinfo.errisinstance(RuntimeError): - if "maximum recursion depth exceeded" in str(excinfo.value): - recursionindex = traceback.recursionindex() + if is_recursion_error(excinfo): + recursionindex = traceback.recursionindex() last = traceback[-1] entries = [] extraline = None @@ -793,3 +792,14 @@ def getrawcode(obj, trycall=True): return x return obj +if sys.version_info[:2] >= (3, 5): # RecursionError introduced in 3.5 + def is_recursion_error(excinfo): + return excinfo.errisinstance(RecursionError) # noqa +else: + def is_recursion_error(excinfo): + if not excinfo.errisinstance(RuntimeError): + return False + try: + return "maximum recursion depth exceeded" in str(excinfo.value) + except UnicodeError: + return False diff --git a/testing/code/test_excinfo.py b/testing/code/test_excinfo.py index 2defa3103..47ad50b06 100644 --- a/testing/code/test_excinfo.py +++ b/testing/code/test_excinfo.py @@ -3,7 +3,7 @@ import _pytest import py import pytest -from _pytest._code.code import FormattedExcinfo, ReprExceptionInfo +from _pytest._code.code import ExceptionInfo, FormattedExcinfo, ReprExceptionInfo queue = py.builtin._tryimport('queue', 'Queue') @@ -909,3 +909,19 @@ raise ValueError() assert tw.lines[14] == "E ValueError" assert tw.lines[15] == "" assert tw.lines[16].endswith("mod.py:9: ValueError") + + +@pytest.mark.parametrize("style", ["short", "long"]) +@pytest.mark.parametrize("encoding", [None, "utf8", "utf16"]) +def test_repr_traceback_with_unicode(style, encoding): + msg = u'☹' + if encoding is not None: + msg = msg.encode(encoding) + try: + raise RuntimeError(msg) + except RuntimeError: + e_info = ExceptionInfo() + formatter = FormattedExcinfo(style=style) + repr_traceback = formatter.repr_traceback(e_info) + assert repr_traceback is not None +