Autofix PT004, PT005, PT024, and PT025 (#1740)

This commit is contained in:
Harutaka Kawamura
2023-01-09 12:41:00 +09:00
committed by GitHub
parent 161ab05533
commit fe4eb13601
7 changed files with 151 additions and 32 deletions

View File

@@ -4,7 +4,7 @@ use super::helpers::{
get_mark_decorators, get_mark_name, is_abstractmethod_decorator, is_pytest_fixture,
is_pytest_yield_fixture, keyword_is_literal,
};
use crate::ast::helpers::{collect_arg_names, collect_call_paths};
use crate::ast::helpers::{collect_arg_names, collect_call_paths, identifier_range};
use crate::ast::types::Range;
use crate::ast::visitor;
use crate::ast::visitor::Visitor;
@@ -156,19 +156,33 @@ fn check_fixture_returns(checker: &mut Checker, func: &Stmt, func_name: &str, bo
&& visitor.has_return_with_value
&& func_name.starts_with('_')
{
checker.diagnostics.push(Diagnostic::new(
let mut diagnostic = Diagnostic::new(
violations::IncorrectFixtureNameUnderscore(func_name.to_string()),
Range::from_located(func),
));
);
if checker.patch(diagnostic.kind.code()) {
let func_name_range = identifier_range(func, checker.locator);
let num_underscores = func_name.len() - func_name.trim_start_matches('_').len();
diagnostic.amend(Fix::deletion(
func_name_range.location,
func_name_range.location.with_col_offset(num_underscores),
));
}
checker.diagnostics.push(diagnostic);
} else if checker.settings.enabled.contains(&RuleCode::PT004)
&& !visitor.has_return_with_value
&& !visitor.has_yield_from
&& !func_name.starts_with('_')
{
checker.diagnostics.push(Diagnostic::new(
let mut diagnostic = Diagnostic::new(
violations::MissingFixtureNameUnderscore(func_name.to_string()),
Range::from_located(func),
));
);
if checker.patch(diagnostic.kind.code()) {
let func_name_range = identifier_range(func, checker.locator);
diagnostic.amend(Fix::insertion("_".to_string(), func_name_range.location));
}
checker.diagnostics.push(diagnostic);
}
if checker.settings.enabled.contains(&RuleCode::PT022) {
@@ -248,19 +262,31 @@ fn check_fixture_marks(checker: &mut Checker, decorators: &[Expr]) {
if checker.settings.enabled.contains(&RuleCode::PT024) {
if name == "asyncio" {
checker.diagnostics.push(Diagnostic::new(
let mut diagnostic = Diagnostic::new(
violations::UnnecessaryAsyncioMarkOnFixture,
Range::from_located(mark),
));
);
if checker.patch(diagnostic.kind.code()) {
let start = Location::new(mark.location.row(), 0);
let end = Location::new(mark.end_location.unwrap().row() + 1, 0);
diagnostic.amend(Fix::deletion(start, end));
}
checker.diagnostics.push(diagnostic);
}
}
if checker.settings.enabled.contains(&RuleCode::PT025) {
if name == "usefixtures" {
checker.diagnostics.push(Diagnostic::new(
let mut diagnostic = Diagnostic::new(
violations::ErroneousUseFixturesOnFixture,
Range::from_located(mark),
));
);
if checker.patch(diagnostic.kind.code()) {
let start = Location::new(mark.location.row(), 0);
let end = Location::new(mark.end_location.unwrap().row() + 1, 0);
diagnostic.amend(Fix::deletion(start, end));
}
checker.diagnostics.push(diagnostic);
}
}
}

View File

@@ -1,6 +1,6 @@
---
source: src/flake8_pytest_style/mod.rs
expression: checks
expression: diagnostics
---
- kind:
MissingFixtureNameUnderscore: patch_something
@@ -10,7 +10,14 @@ expression: checks
end_location:
row: 52
column: 30
fix: ~
fix:
content: _
location:
row: 51
column: 4
end_location:
row: 51
column: 4
parent: ~
- kind:
MissingFixtureNameUnderscore: activate_context
@@ -20,6 +27,13 @@ expression: checks
end_location:
row: 58
column: 13
fix: ~
fix:
content: _
location:
row: 56
column: 4
end_location:
row: 56
column: 4
parent: ~

View File

@@ -1,6 +1,6 @@
---
source: src/flake8_pytest_style/mod.rs
expression: checks
expression: diagnostics
---
- kind:
IncorrectFixtureNameUnderscore: _my_fixture
@@ -10,7 +10,14 @@ expression: checks
end_location:
row: 42
column: 12
fix: ~
fix:
content: ""
location:
row: 41
column: 4
end_location:
row: 41
column: 5
parent: ~
- kind:
IncorrectFixtureNameUnderscore: _activate_context
@@ -20,7 +27,14 @@ expression: checks
end_location:
row: 48
column: 21
fix: ~
fix:
content: ""
location:
row: 46
column: 4
end_location:
row: 46
column: 5
parent: ~
- kind:
IncorrectFixtureNameUnderscore: _activate_context
@@ -30,6 +44,13 @@ expression: checks
end_location:
row: 57
column: 34
fix: ~
fix:
content: ""
location:
row: 52
column: 4
end_location:
row: 52
column: 5
parent: ~

View File

@@ -1,6 +1,6 @@
---
source: src/flake8_pytest_style/mod.rs
expression: checks
expression: diagnostics
---
- kind:
UnnecessaryAsyncioMarkOnFixture: ~
@@ -10,7 +10,14 @@ expression: checks
end_location:
row: 14
column: 22
fix: ~
fix:
content: ""
location:
row: 14
column: 0
end_location:
row: 15
column: 0
parent: ~
- kind:
UnnecessaryAsyncioMarkOnFixture: ~
@@ -20,7 +27,14 @@ expression: checks
end_location:
row: 20
column: 20
fix: ~
fix:
content: ""
location:
row: 20
column: 0
end_location:
row: 21
column: 0
parent: ~
- kind:
UnnecessaryAsyncioMarkOnFixture: ~
@@ -30,7 +44,14 @@ expression: checks
end_location:
row: 27
column: 22
fix: ~
fix:
content: ""
location:
row: 27
column: 0
end_location:
row: 28
column: 0
parent: ~
- kind:
UnnecessaryAsyncioMarkOnFixture: ~
@@ -40,6 +61,13 @@ expression: checks
end_location:
row: 33
column: 20
fix: ~
fix:
content: ""
location:
row: 33
column: 0
end_location:
row: 34
column: 0
parent: ~

View File

@@ -1,6 +1,6 @@
---
source: src/flake8_pytest_style/mod.rs
expression: checks
expression: diagnostics
---
- kind:
ErroneousUseFixturesOnFixture: ~
@@ -10,7 +10,14 @@ expression: checks
end_location:
row: 9
column: 29
fix: ~
fix:
content: ""
location:
row: 9
column: 0
end_location:
row: 10
column: 0
parent: ~
- kind:
ErroneousUseFixturesOnFixture: ~
@@ -20,6 +27,13 @@ expression: checks
end_location:
row: 16
column: 29
fix: ~
fix:
content: ""
location:
row: 16
column: 0
end_location:
row: 17
column: 0
parent: ~

View File

@@ -5358,12 +5358,16 @@ impl Violation for ExtraneousScopeFunction {
define_violation!(
pub struct MissingFixtureNameUnderscore(pub String);
);
impl Violation for MissingFixtureNameUnderscore {
impl AlwaysAutofixableViolation for MissingFixtureNameUnderscore {
fn message(&self) -> String {
let MissingFixtureNameUnderscore(function) = self;
format!("Fixture `{function}` does not return anything, add leading underscore")
}
fn autofix_title(&self) -> String {
"Add leading underscore".to_string()
}
fn placeholder() -> Self {
MissingFixtureNameUnderscore("...".to_string())
}
@@ -5372,12 +5376,16 @@ impl Violation for MissingFixtureNameUnderscore {
define_violation!(
pub struct IncorrectFixtureNameUnderscore(pub String);
);
impl Violation for IncorrectFixtureNameUnderscore {
impl AlwaysAutofixableViolation for IncorrectFixtureNameUnderscore {
fn message(&self) -> String {
let IncorrectFixtureNameUnderscore(function) = self;
format!("Fixture `{function}` returns a value, remove leading underscore")
}
fn autofix_title(&self) -> String {
"Remove leading underscore".to_string()
}
fn placeholder() -> Self {
IncorrectFixtureNameUnderscore("...".to_string())
}
@@ -5644,11 +5652,15 @@ impl AlwaysAutofixableViolation for IncorrectMarkParenthesesStyle {
define_violation!(
pub struct UnnecessaryAsyncioMarkOnFixture;
);
impl Violation for UnnecessaryAsyncioMarkOnFixture {
impl AlwaysAutofixableViolation for UnnecessaryAsyncioMarkOnFixture {
fn message(&self) -> String {
"`pytest.mark.asyncio` is unnecessary for fixtures".to_string()
}
fn autofix_title(&self) -> String {
"Remove `pytest.mark.asyncio`".to_string()
}
fn placeholder() -> Self {
UnnecessaryAsyncioMarkOnFixture
}
@@ -5657,11 +5669,15 @@ impl Violation for UnnecessaryAsyncioMarkOnFixture {
define_violation!(
pub struct ErroneousUseFixturesOnFixture;
);
impl Violation for ErroneousUseFixturesOnFixture {
impl AlwaysAutofixableViolation for ErroneousUseFixturesOnFixture {
fn message(&self) -> String {
"`pytest.mark.usefixtures` has no effect on fixtures".to_string()
}
fn autofix_title(&self) -> String {
"Remove `pytest.mark.usefixtures`".to_string()
}
fn placeholder() -> Self {
ErroneousUseFixturesOnFixture
}