Merge remote-tracking branch 'upstream/master' into param-ids-fix
This commit is contained in:
commit
f3cee8f0b5
|
@ -9,6 +9,11 @@
|
|||
pytest.parametrize in Python 3.
|
||||
Thanks Paul Kehrer for the report and Bruno Oliveira for the PR.
|
||||
|
||||
- fix #995: fixed internal error when filtering tracebacks where one entry
|
||||
was generated by an exec() statement.
|
||||
Thanks Daniel Hahler, Ashley C Straw, Philippe Gauthier and Pavel Savchenko
|
||||
for contributing and Bruno Oliveira for the PR.
|
||||
|
||||
2.8.1
|
||||
-----
|
||||
|
||||
|
|
|
@ -192,8 +192,8 @@ def cache(request):
|
|||
cache.get(key, default)
|
||||
cache.set(key, value)
|
||||
|
||||
Keys must be strings not containing a "/" separator. Add a unique identifier
|
||||
(such as plugin/app name) to avoid clashes with other cache users.
|
||||
Keys must be a ``/`` separated value, where the first part is usually the
|
||||
name of your plugin or application to avoid clashes with other cache users.
|
||||
|
||||
Values can be any object handled by the json stdlib module.
|
||||
"""
|
||||
|
|
|
@ -49,6 +49,13 @@ def _has_positional_arg(func):
|
|||
|
||||
|
||||
def filter_traceback(entry):
|
||||
# entry.path might sometimes return a str() object when the entry
|
||||
# points to dynamically generated code
|
||||
# see https://bitbucket.org/pytest-dev/py/issues/71
|
||||
raw_filename = entry.frame.code.raw.co_filename
|
||||
is_generated = '<' in raw_filename and '>' in raw_filename
|
||||
if is_generated:
|
||||
return False
|
||||
return entry.path != cutdir1 and not entry.path.relto(cutdir2)
|
||||
|
||||
|
||||
|
|
|
@ -332,17 +332,17 @@ after others, i.e. the position in the ``N``-sized list of functions:
|
|||
.. code-block:: python
|
||||
|
||||
# Plugin 1
|
||||
@pytest.hookimpl_spec(tryfirst=True)
|
||||
@pytest.hookimpl(tryfirst=True)
|
||||
def pytest_collection_modifyitems(items):
|
||||
# will execute as early as possible
|
||||
|
||||
# Plugin 2
|
||||
@pytest.hookimpl_spec(trylast=True)
|
||||
@pytest.hookimpl(trylast=True)
|
||||
def pytest_collection_modifyitems(items):
|
||||
# will execute as late as possible
|
||||
|
||||
# Plugin 3
|
||||
@pytest.hookimpl_spec(hookwrapper=True)
|
||||
@pytest.hookimpl(hookwrapper=True)
|
||||
def pytest_collection_modifyitems(items):
|
||||
# will execute even before the tryfirst one above!
|
||||
outcome = yield
|
||||
|
|
|
@ -733,6 +733,54 @@ class TestTracebackCutting:
|
|||
"E*NameError*",
|
||||
])
|
||||
|
||||
def test_traceback_filter_error_during_fixture_collection(self, testdir):
|
||||
"""integration test for issue #995.
|
||||
"""
|
||||
testdir.makepyfile("""
|
||||
import pytest
|
||||
|
||||
def fail_me(func):
|
||||
ns = {}
|
||||
exec('def w(): raise ValueError("fail me")', ns)
|
||||
return ns['w']
|
||||
|
||||
@pytest.fixture(scope='class')
|
||||
@fail_me
|
||||
def fail_fixture():
|
||||
pass
|
||||
|
||||
def test_failing_fixture(fail_fixture):
|
||||
pass
|
||||
""")
|
||||
result = testdir.runpytest()
|
||||
assert result.ret != 0
|
||||
out = result.stdout.str()
|
||||
assert "INTERNALERROR>" not in out
|
||||
result.stdout.fnmatch_lines([
|
||||
"*ValueError: fail me*",
|
||||
"* 1 error in *",
|
||||
])
|
||||
|
||||
def test_filter_traceback_accepts_non_paths(self):
|
||||
"""test that filter_traceback() works around py.code.Code bug
|
||||
where sometimes its "path" attribute is not a py.path.local object:
|
||||
https://bitbucket.org/pytest-dev/py/issues/71
|
||||
This fixes #995.
|
||||
"""
|
||||
from _pytest.python import filter_traceback
|
||||
try:
|
||||
ns = {}
|
||||
exec('def foo(): raise ValueError', ns)
|
||||
ns['foo']()
|
||||
except ValueError:
|
||||
import sys
|
||||
_, _, tb = sys.exc_info()
|
||||
|
||||
tb = py.code.Traceback(tb)
|
||||
assert isinstance(tb[-1].path, str) # symptom of the py.code bug
|
||||
assert not filter_traceback(tb[-1])
|
||||
|
||||
|
||||
class TestReportInfo:
|
||||
def test_itemreport_reportinfo(self, testdir, linecomp):
|
||||
testdir.makeconftest("""
|
||||
|
|
Loading…
Reference in New Issue