feat: add autofix for PLR0402 (#2504)

This commit is contained in:
Florian Best 2023-02-03 05:25:16 +01:00 committed by GitHub
parent d4cef9305a
commit 7e9b9cc7b3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 95 additions and 34 deletions

View File

@ -1344,7 +1344,7 @@ For more, see [Pylint](https://pypi.org/project/pylint/) on PyPI.
| ---- | ---- | ------- | --- |
| PLR0133 | constant-comparison | Two constants compared in a comparison, consider replacing `{left_constant} {op} {right_constant}` | |
| PLR0206 | property-with-parameters | Cannot have defined parameters for properties | |
| PLR0402 | consider-using-from-import | Use `from {module} import {name}` in lieu of alias | |
| PLR0402 | consider-using-from-import | Use `from {module} import {name}` in lieu of alias | 🛠 |
| PLR0913 | too-many-args | Too many arguments to function call ({c_args}/{max_args}) | |
| PLR0915 | too-many-statements | Too many statements ({statements}/{max_statements}) | |
| PLR1701 | consider-merging-isinstance | Merge these isinstance calls: `isinstance({obj}, ({types}))` | |

View File

@ -9,6 +9,7 @@ from collections import OrderedDict as o_dict
import os.path as path # [consider-using-from-import]
import os.path as p
import foo.bar.foobar as foobar # [consider-using-from-import]
import foo.bar.foobar as foobar, sys # [consider-using-from-import]
import os
import os as OS
from sys import version

View File

@ -922,7 +922,7 @@ where
pylint::rules::useless_import_alias(self, alias);
}
if self.settings.rules.enabled(&Rule::ConsiderUsingFromImport) {
pylint::rules::use_from_import(self, alias);
pylint::rules::use_from_import(self, stmt, alias, names);
}
if let Some(asname) = &alias.node.asname {

View File

@ -1,27 +1,45 @@
use rustpython_ast::Alias;
use rustpython_parser::ast::Stmt;
use ruff_macros::derive_message_formats;
use crate::ast::types::Range;
use crate::checkers::ast::Checker;
use crate::define_violation;
use crate::fix::Fix;
use crate::registry::Diagnostic;
use crate::violation::Violation;
use ruff_macros::derive_message_formats;
use crate::violation::{Availability, Violation};
use crate::{define_violation, AutofixKind};
define_violation!(
pub struct ConsiderUsingFromImport {
pub module: String,
pub name: String,
pub fixable: bool,
}
);
impl Violation for ConsiderUsingFromImport {
const AUTOFIX: Option<AutofixKind> = Some(AutofixKind::new(Availability::Always));
#[derive_message_formats]
fn message(&self) -> String {
let ConsiderUsingFromImport { module, name } = self;
let ConsiderUsingFromImport { module, name, .. } = self;
format!("Use `from {module} import {name}` in lieu of alias")
}
fn autofix_title_formatter(&self) -> Option<fn(&Self) -> String> {
let ConsiderUsingFromImport { fixable, .. } = self;
if *fixable {
Some(|ConsiderUsingFromImport { module, name, .. }| {
format!("Replace with `from {module} import {name}`")
})
} else {
None
}
}
}
/// PLR0402
pub fn use_from_import(checker: &mut Checker, alias: &Alias) {
pub fn use_from_import(checker: &mut Checker, stmt: &Stmt, alias: &Alias, names: &[Alias]) {
let Some(asname) = &alias.node.asname else {
return;
};
@ -31,11 +49,22 @@ pub fn use_from_import(checker: &mut Checker, alias: &Alias) {
if name != asname {
return;
}
checker.diagnostics.push(Diagnostic::new(
let fixable = names.len() == 1;
let mut diagnostic = Diagnostic::new(
ConsiderUsingFromImport {
module: module.to_string(),
name: name.to_string(),
fixable,
},
Range::from_located(alias),
));
);
if fixable && checker.patch(diagnostic.kind.rule()) {
diagnostic.amend(Fix::replacement(
format!("from {module} import {asname}"),
stmt.location,
stmt.end_location.unwrap(),
));
}
checker.diagnostics.push(diagnostic);
}

View File

@ -41,109 +41,109 @@ expression: diagnostics
- kind:
UselessImportAlias: ~
location:
row: 15
row: 16
column: 14
end_location:
row: 15
row: 16
column: 24
fix:
content:
- bar
location:
row: 15
row: 16
column: 14
end_location:
row: 15
row: 16
column: 24
parent: ~
- kind:
UselessImportAlias: ~
location:
row: 18
row: 19
column: 18
end_location:
row: 18
row: 19
column: 28
fix:
content:
- bar
location:
row: 18
row: 19
column: 18
end_location:
row: 18
row: 19
column: 28
parent: ~
- kind:
UselessImportAlias: ~
location:
row: 19
row: 20
column: 22
end_location:
row: 19
row: 20
column: 38
fix:
content:
- foobar
location:
row: 19
row: 20
column: 22
end_location:
row: 19
row: 20
column: 38
parent: ~
- kind:
UselessImportAlias: ~
location:
row: 21
row: 22
column: 14
end_location:
row: 21
row: 22
column: 24
fix:
content:
- foo
location:
row: 21
row: 22
column: 14
end_location:
row: 21
row: 22
column: 24
parent: ~
- kind:
UselessImportAlias: ~
location:
row: 22
row: 23
column: 26
end_location:
row: 22
row: 23
column: 38
fix:
content:
- foo2
location:
row: 22
row: 23
column: 26
end_location:
row: 22
row: 23
column: 38
parent: ~
- kind:
UselessImportAlias: ~
location:
row: 24
row: 25
column: 20
end_location:
row: 24
row: 25
column: 36
fix:
content:
- foobar
location:
row: 24
row: 25
column: 20
end_location:
row: 24
row: 25
column: 36
parent: ~

View File

@ -6,24 +6,55 @@ expression: diagnostics
ConsiderUsingFromImport:
module: os
name: path
fixable: true
location:
row: 9
column: 7
end_location:
row: 9
column: 22
fix: ~
fix:
content:
- from os import path
location:
row: 9
column: 0
end_location:
row: 9
column: 22
parent: ~
- kind:
ConsiderUsingFromImport:
module: foo.bar
name: foobar
fixable: true
location:
row: 11
column: 7
end_location:
row: 11
column: 31
fix:
content:
- from foo.bar import foobar
location:
row: 11
column: 0
end_location:
row: 11
column: 31
parent: ~
- kind:
ConsiderUsingFromImport:
module: foo.bar
name: foobar
fixable: false
location:
row: 12
column: 7
end_location:
row: 12
column: 31
fix: ~
parent: ~