[flake8-pytest-style] PT001/PT023 fix makes syntax error on parenthesized decorator (#18782)

Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
Dan Parizher 2025-06-23 07:46:15 -04:00 committed by GitHub
parent 907c291877
commit 7ec7853cec
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 110 additions and 22 deletions

View file

@ -83,3 +83,13 @@ def aliased_parentheses_no_params_multiline():
# scope="module"
)
def my_fixture(): ...
@(pytest.fixture())
def outer_paren_fixture_no_params():
return 42
@(fixture())
def outer_paren_imported_fixture_no_params():
return 42

View file

@ -88,3 +88,14 @@ class TestClass:
# ),
)
def test_bar(param1, param2): ...
@(pytest.mark.foo())
def test_outer_paren_mark_function():
pass
class TestClass:
@(pytest.mark.foo())
def test_method_outer_paren():
pass

View file

@ -708,7 +708,7 @@ fn pytest_fixture_parentheses(
fn check_fixture_decorator(checker: &Checker, func_name: &str, decorator: &Decorator) {
match &decorator.expression {
Expr::Call(ast::ExprCall {
func,
func: _,
arguments,
range: _,
node_index: _,
@ -719,11 +719,8 @@ fn check_fixture_decorator(checker: &Checker, func_name: &str, decorator: &Decor
&& arguments.keywords.is_empty()
{
let fix = Fix::applicable_edit(
Edit::deletion(func.end(), decorator.end()),
if checker
.comment_ranges()
.intersects(TextRange::new(func.end(), decorator.end()))
{
Edit::range_deletion(arguments.range()),
if checker.comment_ranges().intersects(arguments.range()) {
Applicability::Unsafe
} else {
Applicability::Safe

View file

@ -2,7 +2,7 @@ use ruff_diagnostics::Applicability;
use ruff_python_ast::{self as ast, Arguments, Decorator, Expr};
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_text_size::{Ranged, TextRange};
use ruff_text_size::Ranged;
use crate::checkers::ast::Checker;
use crate::registry::Rule;
@ -154,27 +154,18 @@ fn pytest_mark_parentheses(
fn check_mark_parentheses(checker: &Checker, decorator: &Decorator, marker: &str) {
match &decorator.expression {
Expr::Call(ast::ExprCall {
func,
arguments:
Arguments {
args,
keywords,
range: _,
node_index: _,
},
func: _,
arguments,
range: _,
node_index: _,
}) => {
if !checker.settings().flake8_pytest_style.mark_parentheses
&& args.is_empty()
&& keywords.is_empty()
&& arguments.args.is_empty()
&& arguments.keywords.is_empty()
{
let fix = Fix::applicable_edit(
Edit::deletion(func.end(), decorator.end()),
if checker
.comment_ranges()
.intersects(TextRange::new(func.end(), decorator.end()))
{
Edit::range_deletion(arguments.range()),
if checker.comment_ranges().intersects(arguments.range()) {
Applicability::Unsafe
} else {
Applicability::Safe

View file

@ -149,3 +149,42 @@ PT001.py:81:1: PT001 [*] Use `@pytest.fixture` over `@pytest.fixture()`
84 |-)
81 |+@pytest.fixture
85 82 | def my_fixture(): ...
86 83 |
87 84 |
PT001.py:88:1: PT001 [*] Use `@pytest.fixture` over `@pytest.fixture()`
|
88 | @(pytest.fixture())
| ^^^^^^^^^^^^^^^^^^^ PT001
89 | def outer_paren_fixture_no_params():
90 | return 42
|
= help: Remove parentheses
Safe fix
85 85 | def my_fixture(): ...
86 86 |
87 87 |
88 |-@(pytest.fixture())
88 |+@(pytest.fixture)
89 89 | def outer_paren_fixture_no_params():
90 90 | return 42
91 91 |
PT001.py:93:1: PT001 [*] Use `@pytest.fixture` over `@pytest.fixture()`
|
93 | @(fixture())
| ^^^^^^^^^^^^ PT001
94 | def outer_paren_imported_fixture_no_params():
95 | return 42
|
= help: Remove parentheses
Safe fix
90 90 | return 42
91 91 |
92 92 |
93 |-@(fixture())
93 |+@(fixture)
94 94 | def outer_paren_imported_fixture_no_params():
95 95 | return 42

View file

@ -130,3 +130,43 @@ PT023.py:82:1: PT023 [*] Use `@pytest.mark.parametrize` over `@pytest.mark.param
89 |-)
82 |+@pytest.mark.parametrize
90 83 | def test_bar(param1, param2): ...
91 84 |
92 85 |
PT023.py:93:1: PT023 [*] Use `@pytest.mark.foo` over `@pytest.mark.foo()`
|
93 | @(pytest.mark.foo())
| ^^^^^^^^^^^^^^^^^^^^ PT023
94 | def test_outer_paren_mark_function():
95 | pass
|
= help: Remove parentheses
Safe fix
90 90 | def test_bar(param1, param2): ...
91 91 |
92 92 |
93 |-@(pytest.mark.foo())
93 |+@(pytest.mark.foo)
94 94 | def test_outer_paren_mark_function():
95 95 | pass
96 96 |
PT023.py:99:5: PT023 [*] Use `@pytest.mark.foo` over `@pytest.mark.foo()`
|
98 | class TestClass:
99 | @(pytest.mark.foo())
| ^^^^^^^^^^^^^^^^^^^^ PT023
100 | def test_method_outer_paren():
101 | pass
|
= help: Remove parentheses
Safe fix
96 96 |
97 97 |
98 98 | class TestClass:
99 |- @(pytest.mark.foo())
99 |+ @(pytest.mark.foo)
100 100 | def test_method_outer_paren():
101 101 | pass