catch IndexError exceptions when getting exception source location
This commit is contained in:
parent
310bada6f5
commit
cf9a09e988
|
@ -526,6 +526,10 @@
|
||||||
directories created by this fixture (defaults to $TEMP/pytest-$USER).
|
directories created by this fixture (defaults to $TEMP/pytest-$USER).
|
||||||
Thanks Bruno Oliveira for the PR.
|
Thanks Bruno Oliveira for the PR.
|
||||||
|
|
||||||
|
- 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
|
||||||
|
|
||||||
2.7.2 (compared to 2.7.1)
|
2.7.2 (compared to 2.7.1)
|
||||||
=============================
|
=============================
|
||||||
|
|
||||||
|
|
|
@ -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,49 @@ 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):
|
||||||
|
"""Test that exception in dynamically generated code doesn't break getting the source line."""
|
||||||
|
sub = testdir.mkdir("sub")
|
||||||
|
sub.join("__init__.py").write("")
|
||||||
|
sub.join("fixtures.py").write(py.std.textwrap.dedent(
|
||||||
|
"""
|
||||||
|
import sys
|
||||||
|
import pytest
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
def get_caller_module(depth=2):
|
||||||
|
frame = sys._getframe(depth)
|
||||||
|
module = inspect.getmodule(frame)
|
||||||
|
if module is None:
|
||||||
|
return get_caller_module(depth=depth)
|
||||||
|
return module
|
||||||
|
|
||||||
|
def inject():
|
||||||
|
context = {}
|
||||||
|
exec('''
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
@pytest.fixture
|
||||||
|
def foo(request):
|
||||||
|
request.getfuncargvalue('sone')
|
||||||
|
''', context)
|
||||||
|
module = get_caller_module()
|
||||||
|
foo = context['foo']
|
||||||
|
module.foo = foo
|
||||||
|
|
||||||
|
inject()
|
||||||
|
"""))
|
||||||
|
sub.join("conftest.py").write("""from fixtures import foo""")
|
||||||
|
sub.join("test_dynamic.py").write(py.std.textwrap.dedent(
|
||||||
|
"""
|
||||||
|
def test_foo(foo):
|
||||||
|
pass
|
||||||
|
"""))
|
||||||
|
result = testdir.runpytest('-vv')
|
||||||
|
assert 'INTERNALERROR' not in result.stdout.str()
|
||||||
|
result.stdout.fnmatch_lines(['*else: assert False*'])
|
||||||
|
|
||||||
|
|
||||||
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