Skip to content

Commit b7fd3f0

Browse files
Merge pull request #1093 from nicoddemus/relto-bug
Fix internal error when filtering tracebacks where one entry was generated by an exec() statement Fixes #995
2 parents 639ae0c + d1e00f6 commit b7fd3f0

File tree

3 files changed

+59
-0
lines changed

3 files changed

+59
-0
lines changed

CHANGELOG

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
2.8.2.dev
22
---------
33

4+
- fix #995: fixed internal error when filtering tracebacks where one entry
5+
was generated by an exec() statement.
6+
Thanks Daniel Hahler, Ashley C Straw, Philippe Gauthier and Pavel Savchenko
7+
for contributing and Bruno Oliveira for the PR.
48

59
2.8.1
610
-----

_pytest/python.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,13 @@ def _has_positional_arg(func):
4949

5050

5151
def filter_traceback(entry):
52+
# entry.path might sometimes return a str() object when the entry
53+
# points to dynamically generated code
54+
# see https://bitbucket.org/pytest-dev/py/issues/71
55+
raw_filename = entry.frame.code.raw.co_filename
56+
is_generated = '<' in raw_filename and '>' in raw_filename
57+
if is_generated:
58+
return False
5259
return entry.path != cutdir1 and not entry.path.relto(cutdir2)
5360

5461

testing/python/collect.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -733,6 +733,54 @@ def test_traceback_error_during_import(self, testdir):
733733
"E*NameError*",
734734
])
735735

736+
def test_traceback_filter_error_during_fixture_collection(self, testdir):
737+
"""integration test for issue #995.
738+
"""
739+
testdir.makepyfile("""
740+
import pytest
741+
742+
def fail_me(func):
743+
ns = {}
744+
exec('def w(): raise ValueError("fail me")', ns)
745+
return ns['w']
746+
747+
@pytest.fixture(scope='class')
748+
@fail_me
749+
def fail_fixture():
750+
pass
751+
752+
def test_failing_fixture(fail_fixture):
753+
pass
754+
""")
755+
result = testdir.runpytest()
756+
assert result.ret != 0
757+
out = result.stdout.str()
758+
assert "INTERNALERROR>" not in out
759+
result.stdout.fnmatch_lines([
760+
"*ValueError: fail me*",
761+
"* 1 error in *",
762+
])
763+
764+
def test_filter_traceback_accepts_non_paths(self):
765+
"""test that filter_traceback() works around py.code.Code bug
766+
where sometimes its "path" attribute is not a py.path.local object:
767+
https://bitbucket.org/pytest-dev/py/issues/71
768+
This fixes #995.
769+
"""
770+
from _pytest.python import filter_traceback
771+
try:
772+
ns = {}
773+
exec('def foo(): raise ValueError', ns)
774+
ns['foo']()
775+
except ValueError:
776+
import sys
777+
_, _, tb = sys.exc_info()
778+
779+
tb = py.code.Traceback(tb)
780+
assert isinstance(tb[-1].path, str) # symptom of the py.code bug
781+
assert not filter_traceback(tb[-1])
782+
783+
736784
class TestReportInfo:
737785
def test_itemreport_reportinfo(self, testdir, linecomp):
738786
testdir.makeconftest("""

0 commit comments

Comments
 (0)