[flake8-pytest-style] Mark autofix for PT001 and PT023 as unsafe if there's comments in the decorator (#18792)

This commit is contained in:
Victor Hugo Gomes 2025-06-20 03:23:59 -03:00 committed by GitHub
parent 22177e6915
commit 97819f8a37
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 128 additions and 3 deletions

View file

@ -76,3 +76,10 @@ def aliased_parentheses_with_params():
)
def aliased_parentheses_no_params_multiline():
return 42
# https://github.com/astral-sh/ruff/issues/18770
@pytest.fixture(
# TODO: use module scope
# scope="module"
)
def my_fixture(): ...

View file

@ -77,3 +77,14 @@ class TestClass:
@pytest.mark.foo()
def test_something():
pass
# https://github.com/astral-sh/ruff/issues/18770
@pytest.mark.parametrize(
# TODO: fix later
# ("param1", "param2"),
# (
# (1, 2),
# (3, 4),
# ),
)
def test_bar(param1, param2): ...

View file

@ -1,3 +1,4 @@
use ruff_diagnostics::Applicability;
use ruff_macros::{ViolationMetadata, derive_message_formats};
use ruff_python_ast::Decorator;
use ruff_python_ast::helpers::map_callable;
@ -57,6 +58,22 @@ use super::helpers::{
/// def my_fixture(): ...
/// ```
///
/// ## Fix safety
/// This rule's fix is marked as unsafe if there's comments in the
/// `pytest.fixture` decorator.
///
/// For example, the fix would be marked as unsafe in the following case:
/// ```python
/// import pytest
///
///
/// @pytest.fixture(
/// # comment
/// # scope = "module"
/// )
/// def my_fixture(): ...
/// ```
///
/// ## Options
/// - `lint.flake8-pytest-style.fixture-parentheses`
///
@ -701,7 +718,17 @@ fn check_fixture_decorator(checker: &Checker, func_name: &str, decorator: &Decor
&& arguments.args.is_empty()
&& arguments.keywords.is_empty()
{
let fix = Fix::safe_edit(Edit::deletion(func.end(), decorator.end()));
let fix = Fix::applicable_edit(
Edit::deletion(func.end(), decorator.end()),
if checker
.comment_ranges()
.intersects(TextRange::new(func.end(), decorator.end()))
{
Applicability::Unsafe
} else {
Applicability::Safe
},
);
pytest_fixture_parentheses(
checker,
decorator,

View file

@ -1,7 +1,8 @@
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;
use ruff_text_size::{Ranged, TextRange};
use crate::checkers::ast::Checker;
use crate::registry::Rule;
@ -44,6 +45,19 @@ use super::helpers::{Parentheses, get_mark_decorators};
/// def test_something(): ...
/// ```
///
/// ## Fix safety
/// This rule's fix is marked as unsafe if there's comments in the
/// `pytest.mark.<marker>` decorator.
/// ```python
/// import pytest
///
///
/// @pytest.mark.foo(
/// # comment
/// )
/// def test_something(): ...
/// ```
///
/// ## Options
/// - `lint.flake8-pytest-style.mark-parentheses`
///
@ -155,7 +169,17 @@ fn check_mark_parentheses(checker: &Checker, decorator: &Decorator, marker: &str
&& args.is_empty()
&& keywords.is_empty()
{
let fix = Fix::safe_edit(Edit::deletion(func.end(), decorator.end()));
let fix = Fix::applicable_edit(
Edit::deletion(func.end(), decorator.end()),
if checker
.comment_ranges()
.intersects(TextRange::new(func.end(), decorator.end()))
{
Applicability::Unsafe
} else {
Applicability::Safe
},
);
pytest_mark_parentheses(
checker,
decorator,

View file

@ -125,3 +125,27 @@ PT001.py:74:1: PT001 [*] Use `@pytest.fixture` over `@pytest.fixture()`
74 |+@aliased
77 75 | def aliased_parentheses_no_params_multiline():
78 76 | return 42
79 77 |
PT001.py:81:1: PT001 [*] Use `@pytest.fixture` over `@pytest.fixture()`
|
80 | # https://github.com/astral-sh/ruff/issues/18770
81 | / @pytest.fixture(
82 | | # TODO: use module scope
83 | | # scope="module"
84 | | )
| |_^ PT001
85 | def my_fixture(): ...
|
= help: Remove parentheses
Unsafe fix
78 78 | return 42
79 79 |
80 80 | # https://github.com/astral-sh/ruff/issues/18770
81 |-@pytest.fixture(
82 |- # TODO: use module scope
83 |- # scope="module"
84 |-)
81 |+@pytest.fixture
85 82 | def my_fixture(): ...

View file

@ -98,3 +98,35 @@ PT023.py:77:9: PT023 [*] Use `@pytest.mark.foo` over `@pytest.mark.foo()`
77 |+ @pytest.mark.foo
78 78 | def test_something():
79 79 | pass
80 80 |
PT023.py:82:1: PT023 [*] Use `@pytest.mark.parametrize` over `@pytest.mark.parametrize()`
|
81 | # https://github.com/astral-sh/ruff/issues/18770
82 | / @pytest.mark.parametrize(
83 | | # TODO: fix later
84 | | # ("param1", "param2"),
85 | | # (
86 | | # (1, 2),
87 | | # (3, 4),
88 | | # ),
89 | | )
| |_^ PT023
90 | def test_bar(param1, param2): ...
|
= help: Remove parentheses
Unsafe fix
79 79 | pass
80 80 |
81 81 | # https://github.com/astral-sh/ruff/issues/18770
82 |-@pytest.mark.parametrize(
83 |- # TODO: fix later
84 |- # ("param1", "param2"),
85 |- # (
86 |- # (1, 2),
87 |- # (3, 4),
88 |- # ),
89 |-)
82 |+@pytest.mark.parametrize
90 83 | def test_bar(param1, param2): ...