Merge pull request #1414 from rygwdn/indexerror
catch IndexError exceptions when getting exception source location
This commit is contained in:
commit
c9927bb66f
1
AUTHORS
1
AUTHORS
|
@ -69,6 +69,7 @@ Ralf Schmitt
|
||||||
Raphael Pierzina
|
Raphael Pierzina
|
||||||
Ronny Pfannschmidt
|
Ronny Pfannschmidt
|
||||||
Ross Lawley
|
Ross Lawley
|
||||||
|
Ryan Wooden
|
||||||
Samuele Pedroni
|
Samuele Pedroni
|
||||||
Tom Viner
|
Tom Viner
|
||||||
Trevor Bekolay
|
Trevor Bekolay
|
||||||
|
|
|
@ -30,7 +30,9 @@
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
*
|
* catch IndexError exceptions when getting exception source location. This fixes
|
||||||
|
pytest internal error for dynamically generated code (fixtures and tests)
|
||||||
|
where source lines are fake by intention
|
||||||
|
|
||||||
*
|
*
|
||||||
|
|
||||||
|
|
|
@ -1774,7 +1774,7 @@ class FixtureLookupError(LookupError):
|
||||||
fspath, lineno = getfslineno(function)
|
fspath, lineno = getfslineno(function)
|
||||||
try:
|
try:
|
||||||
lines, _ = inspect.getsourcelines(get_real_func(function))
|
lines, _ = inspect.getsourcelines(get_real_func(function))
|
||||||
except IOError:
|
except (IOError, IndexError):
|
||||||
error_msg = "file %s, line %s: source code not available"
|
error_msg = "file %s, line %s: source code not available"
|
||||||
addline(error_msg % (fspath, lineno+1))
|
addline(error_msg % (fspath, lineno+1))
|
||||||
else:
|
else:
|
||||||
|
|
|
@ -568,6 +568,32 @@ def test_makereport_getsource(testdir):
|
||||||
result.stdout.fnmatch_lines(['*else: assert False*'])
|
result.stdout.fnmatch_lines(['*else: assert False*'])
|
||||||
|
|
||||||
|
|
||||||
|
def test_makereport_getsource_dynamic_code(testdir, monkeypatch):
|
||||||
|
"""Test that exception in dynamically generated code doesn't break getting the source line."""
|
||||||
|
import inspect
|
||||||
|
original_findsource = inspect.findsource
|
||||||
|
def findsource(obj, *args, **kwargs):
|
||||||
|
# Can be triggered by dynamically created functions
|
||||||
|
if obj.__name__ == 'foo':
|
||||||
|
raise IndexError()
|
||||||
|
return original_findsource(obj, *args, **kwargs)
|
||||||
|
monkeypatch.setattr(inspect, 'findsource', findsource)
|
||||||
|
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def foo(missing):
|
||||||
|
pass
|
||||||
|
|
||||||
|
def test_fix(foo):
|
||||||
|
assert False
|
||||||
|
""")
|
||||||
|
result = testdir.runpytest('-vv')
|
||||||
|
assert 'INTERNALERROR' not in result.stdout.str()
|
||||||
|
result.stdout.fnmatch_lines(["*test_fix*", "*fixture*'missing'*not found*"])
|
||||||
|
|
||||||
|
|
||||||
def test_store_except_info_on_eror():
|
def test_store_except_info_on_eror():
|
||||||
""" Test that upon test failure, the exception info is stored on
|
""" Test that upon test failure, the exception info is stored on
|
||||||
sys.last_traceback and friends.
|
sys.last_traceback and friends.
|
||||||
|
|
Loading…
Reference in New Issue