mirror of https://github.com/astral-sh/ruff
Enable abspath(__file__) removal (#336)
This commit is contained in:
parent
4eac7a07f5
commit
6e19539e28
|
|
@ -280,6 +280,7 @@ The 🛠 emoji indicates that a rule is automatically fixable by the `--fix` com
|
|||
| T201 | PrintFound | `print` found | | 🛠 |
|
||||
| T203 | PPrintFound | `pprint` found | | 🛠 |
|
||||
| U001 | UselessMetaclassType | `__metaclass__ = type` is implied | | 🛠 |
|
||||
| U002 | UnnecessaryAbspath | `abspath(__file__)` is unnecessary in Python 3.9 and later | | 🛠 |
|
||||
| R001 | UselessObjectInheritance | Class `...` inherits from object | | 🛠 |
|
||||
| R002 | NoAssertEquals | `assertEquals` is deprecated, use `assertEqual` instead | | 🛠 |
|
||||
| M001 | UnusedNOQA | Unused `noqa` directive | | 🛠 |
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
from os.path import abspath
|
||||
|
||||
x = abspath(__file__)
|
||||
|
||||
|
||||
import os
|
||||
|
||||
|
||||
y = os.path.abspath(__file__)
|
||||
|
||||
|
||||
from os import path
|
||||
|
||||
|
||||
z = path.abspath(__file__)
|
||||
|
|
@ -134,6 +134,27 @@ pub fn check_useless_metaclass_type(
|
|||
None
|
||||
}
|
||||
|
||||
/// Check UnnecessaryAbspath compliance.
|
||||
pub fn check_unnecessary_abspath(func: &Expr, args: &Vec<Expr>, location: Range) -> Option<Check> {
|
||||
// Validate the arguments.
|
||||
if args.len() == 1 {
|
||||
if let ExprKind::Name { id, .. } = &args[0].node {
|
||||
if id == "__file__" {
|
||||
match &func.node {
|
||||
ExprKind::Attribute { attr: id, .. } | ExprKind::Name { id, .. } => {
|
||||
if id == "abspath" {
|
||||
return Some(Check::new(CheckKind::UnnecessaryAbspath, location));
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
fn is_ambiguous_name(name: &str) -> bool {
|
||||
name == "l" || name == "I" || name == "O"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -772,6 +772,11 @@ where
|
|||
};
|
||||
}
|
||||
|
||||
// pyupgrade
|
||||
if self.settings.enabled.contains(&CheckCode::U002) {
|
||||
plugins::unnecessary_abspath(self, expr, func, args);
|
||||
}
|
||||
|
||||
if let ExprKind::Name { id, ctx } = &func.node {
|
||||
if id == "locals" && matches!(ctx, ExprContext::Load) {
|
||||
let scope = &mut self.scopes[*(self
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ pub const DEFAULT_CHECK_CODES: [CheckCode; 42] = [
|
|||
CheckCode::F901,
|
||||
];
|
||||
|
||||
pub const ALL_CHECK_CODES: [CheckCode; 53] = [
|
||||
pub const ALL_CHECK_CODES: [CheckCode; 54] = [
|
||||
// pycodestyle
|
||||
CheckCode::E402,
|
||||
CheckCode::E501,
|
||||
|
|
@ -111,6 +111,7 @@ pub const ALL_CHECK_CODES: [CheckCode; 53] = [
|
|||
CheckCode::T203,
|
||||
// pyupgrade
|
||||
CheckCode::U001,
|
||||
CheckCode::U002,
|
||||
// Refactor
|
||||
CheckCode::R001,
|
||||
CheckCode::R002,
|
||||
|
|
@ -177,6 +178,7 @@ pub enum CheckCode {
|
|||
T203,
|
||||
// pyupgrade
|
||||
U001,
|
||||
U002,
|
||||
// Refactor
|
||||
R001,
|
||||
R002,
|
||||
|
|
@ -246,6 +248,7 @@ impl FromStr for CheckCode {
|
|||
"T203" => Ok(CheckCode::T203),
|
||||
// pyupgrade
|
||||
"U001" => Ok(CheckCode::U001),
|
||||
"U002" => Ok(CheckCode::U002),
|
||||
// Refactor
|
||||
"R001" => Ok(CheckCode::R001),
|
||||
"R002" => Ok(CheckCode::R002),
|
||||
|
|
@ -316,6 +319,7 @@ impl CheckCode {
|
|||
CheckCode::T203 => "T203",
|
||||
// pyupgrade
|
||||
CheckCode::U001 => "U001",
|
||||
CheckCode::U002 => "U002",
|
||||
// Refactor
|
||||
CheckCode::R001 => "R001",
|
||||
CheckCode::R002 => "R002",
|
||||
|
|
@ -395,6 +399,7 @@ impl CheckCode {
|
|||
CheckCode::T203 => CheckKind::PPrintFound,
|
||||
// pyupgrade
|
||||
CheckCode::U001 => CheckKind::UselessMetaclassType,
|
||||
CheckCode::U002 => CheckKind::UnnecessaryAbspath,
|
||||
// Refactor
|
||||
CheckCode::R001 => CheckKind::UselessObjectInheritance("...".to_string()),
|
||||
CheckCode::R002 => CheckKind::NoAssertEquals,
|
||||
|
|
@ -446,7 +451,6 @@ pub enum CheckKind {
|
|||
ModuleImportNotAtTopOfFile,
|
||||
MultiValueRepeatedKeyLiteral,
|
||||
MultiValueRepeatedKeyVariable(String),
|
||||
NoAssertEquals,
|
||||
NoneComparison(RejectedCmpop),
|
||||
NotInTest,
|
||||
NotIsTest,
|
||||
|
|
@ -460,10 +464,7 @@ pub enum CheckKind {
|
|||
UndefinedLocal(String),
|
||||
UndefinedName(String),
|
||||
UnusedImport(String),
|
||||
UnusedNOQA(Option<String>),
|
||||
UnusedVariable(String),
|
||||
UselessMetaclassType,
|
||||
UselessObjectInheritance(String),
|
||||
YieldOutsideFunction,
|
||||
// flake8-builtin
|
||||
BuiltinVariableShadowing(String),
|
||||
|
|
@ -476,6 +477,14 @@ pub enum CheckKind {
|
|||
// flake8-print
|
||||
PrintFound,
|
||||
PPrintFound,
|
||||
// pyupgrade
|
||||
UnnecessaryAbspath,
|
||||
UselessMetaclassType,
|
||||
// Refactor
|
||||
NoAssertEquals,
|
||||
UselessObjectInheritance(String),
|
||||
// Meta
|
||||
UnusedNOQA(Option<String>),
|
||||
}
|
||||
|
||||
impl CheckKind {
|
||||
|
|
@ -536,6 +545,7 @@ impl CheckKind {
|
|||
CheckKind::PrintFound => "PrintFound",
|
||||
CheckKind::PPrintFound => "PPrintFound",
|
||||
// pyupgrade
|
||||
CheckKind::UnnecessaryAbspath => "UnnecessaryAbspath",
|
||||
CheckKind::UselessMetaclassType => "UselessMetaclassType",
|
||||
// Refactor
|
||||
CheckKind::NoAssertEquals => "NoAssertEquals",
|
||||
|
|
@ -602,6 +612,7 @@ impl CheckKind {
|
|||
CheckKind::PrintFound => &CheckCode::T201,
|
||||
CheckKind::PPrintFound => &CheckCode::T203,
|
||||
// pyupgrade
|
||||
CheckKind::UnnecessaryAbspath => &CheckCode::U002,
|
||||
CheckKind::UselessMetaclassType => &CheckCode::U001,
|
||||
// Refactor
|
||||
CheckKind::NoAssertEquals => &CheckCode::R002,
|
||||
|
|
@ -761,6 +772,9 @@ impl CheckKind {
|
|||
CheckKind::PrintFound => "`print` found".to_string(),
|
||||
CheckKind::PPrintFound => "`pprint` found".to_string(),
|
||||
// pyupgrade
|
||||
CheckKind::UnnecessaryAbspath => {
|
||||
"`abspath(__file__)` is unnecessary in Python 3.9 and later".to_string()
|
||||
}
|
||||
CheckKind::UselessMetaclassType => "`__metaclass__ = type` is implied".to_string(),
|
||||
// Refactor
|
||||
CheckKind::NoAssertEquals => {
|
||||
|
|
@ -785,6 +799,7 @@ impl CheckKind {
|
|||
| CheckKind::PPrintFound
|
||||
| CheckKind::PrintFound
|
||||
| CheckKind::SuperCallWithParameters
|
||||
| CheckKind::UnnecessaryAbspath
|
||||
| CheckKind::UnusedImport(_)
|
||||
| CheckKind::UnusedNOQA(_)
|
||||
| CheckKind::UselessMetaclassType
|
||||
|
|
|
|||
|
|
@ -845,4 +845,16 @@ mod tests {
|
|||
insta::assert_yaml_snapshot!(checks);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn u002() -> Result<()> {
|
||||
let mut checks = check_path(
|
||||
Path::new("./resources/test/fixtures/U002.py"),
|
||||
&settings::Settings::for_rule(CheckCode::U002),
|
||||
&fixer::Mode::Generate,
|
||||
)?;
|
||||
checks.sort_by_key(|check| check.location);
|
||||
insta::assert_yaml_snapshot!(checks);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ mod if_tuple;
|
|||
mod invalid_print_syntax;
|
||||
mod print_call;
|
||||
mod super_call_with_parameters;
|
||||
mod unnecessary_abspath;
|
||||
mod useless_metaclass_type;
|
||||
mod useless_object_inheritance;
|
||||
|
||||
|
|
@ -13,5 +14,6 @@ pub use if_tuple::if_tuple;
|
|||
pub use invalid_print_syntax::invalid_print_syntax;
|
||||
pub use print_call::print_call;
|
||||
pub use super_call_with_parameters::super_call_with_parameters;
|
||||
pub use unnecessary_abspath::unnecessary_abspath;
|
||||
pub use useless_metaclass_type::useless_metaclass_type;
|
||||
pub use useless_object_inheritance::useless_object_inheritance;
|
||||
|
|
|
|||
|
|
@ -0,0 +1,25 @@
|
|||
use rustpython_ast::Expr;
|
||||
|
||||
use crate::ast::checks;
|
||||
use crate::ast::types::{CheckLocator, Range};
|
||||
use crate::autofix::fixer;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::checks::Fix;
|
||||
|
||||
pub fn unnecessary_abspath(checker: &mut Checker, expr: &Expr, func: &Expr, args: &Vec<Expr>) {
|
||||
if let Some(mut check) = checks::check_unnecessary_abspath(
|
||||
func,
|
||||
args,
|
||||
checker.locate_check(Range::from_located(expr)),
|
||||
) {
|
||||
if matches!(checker.autofix, fixer::Mode::Generate | fixer::Mode::Apply) {
|
||||
check.amend(Fix {
|
||||
content: "__file__".to_string(),
|
||||
location: expr.location,
|
||||
end_location: expr.end_location,
|
||||
applied: false,
|
||||
});
|
||||
}
|
||||
checker.add_check(check);
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue