Skip to content

Commit f02d843

Browse files
committed
Fix situation where a traceback entry "path" returns a str object
Fix #1133
1 parent 3b11995 commit f02d843

File tree

3 files changed

+47
-16
lines changed

3 files changed

+47
-16
lines changed

CHANGELOG

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
- fix #331: don't collect tests if their failure cannot be reported correctly
88
e.g. they are a callable instance of a class.
99

10+
- fix #1133: fixed internal error when filtering tracebacks where one entry
11+
belongs to a file which is no longer available.
12+
Thanks Bruno Oliveira for the PR.
13+
1014
2.8.2
1115
-----
1216

@@ -50,9 +54,9 @@
5054
"pytest-xdist" plugin, with test reports being assigned to the wrong tests.
5155
Thanks Daniel Grunwald for the report and Bruno Oliveira for the PR.
5256

53-
- (experimental) adapt more SEMVER style versioning and change meaning of
54-
master branch in git repo: "master" branch now keeps the bugfixes, changes
55-
aimed for micro releases. "features" branch will only be be released
57+
- (experimental) adapt more SEMVER style versioning and change meaning of
58+
master branch in git repo: "master" branch now keeps the bugfixes, changes
59+
aimed for micro releases. "features" branch will only be be released
5660
with minor or major pytest releases.
5761

5862
- Fix issue #766 by removing documentation references to distutils.
@@ -77,7 +81,7 @@
7781
-----------------------------
7882

7983
- new ``--lf`` and ``-ff`` options to run only the last failing tests or
80-
"failing tests first" from the last run. This functionality is provided
84+
"failing tests first" from the last run. This functionality is provided
8185
through porting the formerly external pytest-cache plugin into pytest core.
8286
BACKWARD INCOMPAT: if you used pytest-cache's functionality to persist
8387
data between test runs be aware that we don't serialize sets anymore.
@@ -183,17 +187,17 @@
183187

184188
- fix issue735: assertion failures on debug versions of Python 3.4+
185189

186-
- new option ``--import-mode`` to allow to change test module importing
187-
behaviour to append to sys.path instead of prepending. This better allows
188-
to run test modules against installated versions of a package even if the
190+
- new option ``--import-mode`` to allow to change test module importing
191+
behaviour to append to sys.path instead of prepending. This better allows
192+
to run test modules against installated versions of a package even if the
189193
package under test has the same import root. In this example::
190194

191195
testing/__init__.py
192196
testing/test_pkg_under_test.py
193197
pkg_under_test/
194198

195199
the tests will run against the installed version
196-
of pkg_under_test when ``--import-mode=append`` is used whereas
200+
of pkg_under_test when ``--import-mode=append`` is used whereas
197201
by default they would always pick up the local version. Thanks Holger Krekel.
198202

199203
- pytester: add method ``TmpTestdir.delete_loaded_modules()``, and call it

_pytest/python.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,14 +58,17 @@ def _has_positional_arg(func):
5858

5959

6060
def filter_traceback(entry):
61-
# entry.path might sometimes return a str() object when the entry
61+
# entry.path might sometimes return a str object when the entry
6262
# points to dynamically generated code
6363
# see https://bitbucket.org/pytest-dev/py/issues/71
6464
raw_filename = entry.frame.code.raw.co_filename
6565
is_generated = '<' in raw_filename and '>' in raw_filename
6666
if is_generated:
6767
return False
68-
return entry.path != cutdir1 and not entry.path.relto(cutdir2)
68+
# entry.path might point to an inexisting file, in which case it will
69+
# alsso return a str object. see #1133
70+
p = py.path.local(entry.path)
71+
return p != cutdir1 and not p.relto(cutdir2)
6972

7073

7174
def get_real_func(obj):

testing/python/collect.py

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -771,10 +771,12 @@ def test_failing_fixture(fail_fixture):
771771
"* 1 error in *",
772772
])
773773

774-
def test_filter_traceback_accepts_non_paths(self):
775-
"""test that filter_traceback() works around py.code.Code bug
776-
where sometimes its "path" attribute is not a py.path.local object:
777-
https://bitbucket.org/pytest-dev/py/issues/71
774+
def test_filter_traceback_generated_code(self):
775+
"""test that filter_traceback() works with the fact that
776+
py.code.Code.path attribute might return an str object.
777+
In this case, one of the entries on the traceback was produced by
778+
dynamically generated code.
779+
See: https://bitbucket.org/pytest-dev/py/issues/71
778780
This fixes #995.
779781
"""
780782
from _pytest.python import filter_traceback
@@ -783,13 +785,35 @@ def test_filter_traceback_accepts_non_paths(self):
783785
exec('def foo(): raise ValueError', ns)
784786
ns['foo']()
785787
except ValueError:
786-
import sys
787788
_, _, tb = sys.exc_info()
788789

789790
tb = py.code.Traceback(tb)
790-
assert isinstance(tb[-1].path, str) # symptom of the py.code bug
791+
assert isinstance(tb[-1].path, str)
791792
assert not filter_traceback(tb[-1])
792793

794+
def test_filter_traceback_paths_no_longer_valid(self, testdir):
795+
"""test that filter_traceback() works with the fact that
796+
py.code.Code.path attribute might return an str object.
797+
In this case, one of the files in the traceback no longer exists.
798+
This fixes #1133.
799+
"""
800+
from _pytest.python import filter_traceback
801+
testdir.syspathinsert()
802+
testdir.makepyfile(filter_traceback_entry_as_str='''
803+
def foo():
804+
raise ValueError
805+
''')
806+
try:
807+
import filter_traceback_entry_as_str
808+
filter_traceback_entry_as_str.foo()
809+
except ValueError:
810+
_, _, tb = sys.exc_info()
811+
812+
testdir.tmpdir.join('filter_traceback_entry_as_str.py').remove()
813+
tb = py.code.Traceback(tb)
814+
assert isinstance(tb[-1].path, str)
815+
assert filter_traceback(tb[-1])
816+
793817

794818
class TestReportInfo:
795819
def test_itemreport_reportinfo(self, testdir, linecomp):

0 commit comments

Comments
 (0)