Skip to content

[6.0.x] Merge pull request #7749 from bluetech/fix-get_source-crash #7771

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 19, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions changelog/4984.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Fixed an internal error crash with ``IndexError: list index out of range`` when
collecting a module which starts with a decorated function, the decorator
raises, and assertion rewriting is enabled.
13 changes: 9 additions & 4 deletions src/_pytest/assertion/rewrite.py
Original file line number Diff line number Diff line change
Expand Up @@ -694,13 +694,18 @@ def run(self, mod: ast.Module) -> None:
return
expect_docstring = False
elif (
not isinstance(item, ast.ImportFrom)
or item.level > 0
or item.module != "__future__"
isinstance(item, ast.ImportFrom)
and item.level == 0
and item.module == "__future__"
):
lineno = item.lineno
pass
else:
break
pos += 1
# Special case: for a decorated function, set the lineno to that of the
# first decorator, not the `def`. Issue #4984.
if isinstance(item, ast.FunctionDef) and item.decorator_list:
lineno = item.decorator_list[0].lineno
else:
lineno = item.lineno
imports = [
Expand Down
14 changes: 14 additions & 0 deletions testing/test_collection.py
Original file line number Diff line number Diff line change
Expand Up @@ -1427,3 +1427,17 @@ def test_modules_not_importable_as_side_effect(self, testdir):
"* 1 failed in *",
]
)


def test_does_not_crash_on_error_from_decorated_function(testdir: Testdir) -> None:
"""Regression test for an issue around bad exception formatting due to
assertion rewriting mangling lineno's (#4984)."""
testdir.makepyfile(
"""
@pytest.fixture
def a(): return 4
"""
)
result = testdir.runpytest()
# Not INTERNAL_ERROR
assert result.ret == ExitCode.INTERRUPTED