Skip to content
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

Fixed error message prints function decorators when using assert in Python 3.9 and above. #9359

Merged
merged 3 commits into from Dec 7, 2021
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Expand Up @@ -347,6 +347,7 @@ Xixi Zhao
Xuan Luong
Xuecong Liao
Yoav Caspi
Yuval Shimon
Zac Hatfield-Dodds
Zachary Kneupper
Zoltán Máté
Expand Down
1 change: 1 addition & 0 deletions changelog/9355.bugfix.rst
@@ -0,0 +1 @@
Fixed error message prints function decorators when using assert in Python 3.9 and above.
5 changes: 5 additions & 0 deletions src/_pytest/_code/source.py
Expand Up @@ -149,6 +149,11 @@ def get_statement_startend2(lineno: int, node: ast.AST) -> Tuple[int, Optional[i
values: List[int] = []
for x in ast.walk(node):
if isinstance(x, (ast.stmt, ast.ExceptHandler)):
# Before Python 3.8, the lineno of a decorated class or function pointed at the decorator.
# Since Python 3.8, the lineno points to the class/def, so need to include the decorators.
if isinstance(x, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)):
nicoddemus marked this conversation as resolved.
Show resolved Hide resolved
for d in x.decorator_list:
values.append(d.lineno - 1)
values.append(x.lineno - 1)
for name in ("finalbody", "orelse"):
val: Optional[List[ast.stmt]] = getattr(x, name, None)
Expand Down
13 changes: 13 additions & 0 deletions testing/code/test_source.py
Expand Up @@ -618,6 +618,19 @@ def something():
assert str(source) == "def func(): raise ValueError(42)"


def test_decorator() -> None:
s = """\
def foo(f):
pass

@foo
def bar():
pass
"""
source = getstatement(3, s)
assert "@foo" in str(source)


def XXX_test_expression_multiline() -> None:
source = """\
something
Expand Down