Enable abspath(__file__) removal (#336)

This commit is contained in:
Charlie Marsh 2022-10-06 22:49:06 -04:00 committed by GitHub
parent 4eac7a07f5
commit 6e19539e28
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 101 additions and 5 deletions

View File

@ -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 | | 🛠 |

15
resources/test/fixtures/U002.py vendored Normal file
View File

@ -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__)

View 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"
}

View File

@ -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

View File

@ -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

View File

@ -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(())
}
}

View File

@ -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;

View File

@ -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);
}
}