Skip to content

Commit d7d0894

Browse files
authored
Merge pull request #7771 from nicoddemus/backport-7749
[6.0.x] Merge pull request #7749 from bluetech/fix-get_source-crash
2 parents 819fef8 + 6933bf6 commit d7d0894

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

changelog/4984.bugfix.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Fixed an internal error crash with ``IndexError: list index out of range`` when
2+
collecting a module which starts with a decorated function, the decorator
3+
raises, and assertion rewriting is enabled.

src/_pytest/assertion/rewrite.py

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -694,13 +694,18 @@ def run(self, mod: ast.Module) -> None:
694694
return
695695
expect_docstring = False
696696
elif (
697-
not isinstance(item, ast.ImportFrom)
698-
or item.level > 0
699-
or item.module != "__future__"
697+
isinstance(item, ast.ImportFrom)
698+
and item.level == 0
699+
and item.module == "__future__"
700700
):
701-
lineno = item.lineno
701+
pass
702+
else:
702703
break
703704
pos += 1
705+
# Special case: for a decorated function, set the lineno to that of the
706+
# first decorator, not the `def`. Issue #4984.
707+
if isinstance(item, ast.FunctionDef) and item.decorator_list:
708+
lineno = item.decorator_list[0].lineno
704709
else:
705710
lineno = item.lineno
706711
imports = [

testing/test_collection.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1427,3 +1427,17 @@ def test_modules_not_importable_as_side_effect(self, testdir):
14271427
"* 1 failed in *",
14281428
]
14291429
)
1430+
1431+
1432+
def test_does_not_crash_on_error_from_decorated_function(testdir: Testdir) -> None:
1433+
"""Regression test for an issue around bad exception formatting due to
1434+
assertion rewriting mangling lineno's (#4984)."""
1435+
testdir.makepyfile(
1436+
"""
1437+
@pytest.fixture
1438+
def a(): return 4
1439+
"""
1440+
)
1441+
result = testdir.runpytest()
1442+
# Not INTERNAL_ERROR
1443+
assert result.ret == ExitCode.INTERRUPTED

0 commit comments

Comments
 (0)