Implement E742

This commit is contained in:
harupy 2022-09-12 08:47:33 +09:00
parent 5f4a62aa40
commit 1b90d40a9d
10 changed files with 86 additions and 0 deletions

View File

@ -154,6 +154,7 @@ Beyond rule-set parity, ruff suffers from the following limitations vis-à-vis F
| E714 | NotIsTest | Test for object identity should be `is not` | | E714 | NotIsTest | Test for object identity should be `is not` |
| E731 | DoNotAssignLambda | Do not assign a lambda expression, use a def | | E731 | DoNotAssignLambda | Do not assign a lambda expression, use a def |
| E741 | AmbiguousVariableName | ambiguous variable name '...' | | E741 | AmbiguousVariableName | ambiguous variable name '...' |
| E742 | AmbiguousClassName | ambiguous class name '...' |
| E902 | IOError | No such file or directory: `...` | | E902 | IOError | No such file or directory: `...` |
| F401 | UnusedImport | `...` imported but unused | | F401 | UnusedImport | `...` imported but unused |
| F403 | ImportStarUsage | Unable to detect undefined names | | F403 | ImportStarUsage | Unable to detect undefined names |

View File

@ -4,6 +4,7 @@ use ruff::checks::{CheckKind, RejectedCmpop};
fn main() { fn main() {
let mut check_kinds: Vec<CheckKind> = vec![ let mut check_kinds: Vec<CheckKind> = vec![
CheckKind::AmbiguousVariableName("...".to_string()), CheckKind::AmbiguousVariableName("...".to_string()),
CheckKind::AmbiguousClassName("...".to_string()),
CheckKind::AssertTuple, CheckKind::AssertTuple,
CheckKind::DefaultExceptNotLast, CheckKind::DefaultExceptNotLast,
CheckKind::DoNotAssignLambda, CheckKind::DoNotAssignLambda,

14
resources/test/fixtures/E742.py vendored Normal file
View File

@ -0,0 +1,14 @@
class l:
pass
class I:
pass
class O:
pass
class X:
pass

View File

@ -10,6 +10,7 @@ select = [
"E714", "E714",
"E731", "E731",
"E741", "E741",
"E742",
"E902", "E902",
"F401", "F401",
"F403", "F403",

View File

@ -109,6 +109,18 @@ pub fn check_ambiguous_variable_name(name: &str, location: Location) -> Option<C
} }
} }
/// Check AmbiguousClassName compliance.
pub fn check_ambiguous_class_name(name: &str, location: Location) -> Option<Check> {
if is_ambiguous_name(name) {
Some(Check::new(
CheckKind::AmbiguousClassName(name.to_string()),
location,
))
} else {
None
}
}
/// Check UselessObjectInheritance compliance. /// Check UselessObjectInheritance compliance.
pub fn check_useless_object_inheritance( pub fn check_useless_object_inheritance(
stmt: &Stmt, stmt: &Stmt,

View File

@ -296,6 +296,12 @@ where
} }
} }
if self.settings.select.contains(&CheckCode::E742) {
if let Some(check) = checks::check_ambiguous_class_name(name, stmt.location) {
self.checks.push(check);
}
}
for expr in bases { for expr in bases {
self.visit_expr(expr) self.visit_expr(expr)
} }

View File

@ -16,6 +16,7 @@ pub enum CheckCode {
E714, E714,
E731, E731,
E741, E741,
E742,
E902, E902,
F401, F401,
F403, F403,
@ -54,6 +55,7 @@ impl FromStr for CheckCode {
"E714" => Ok(CheckCode::E714), "E714" => Ok(CheckCode::E714),
"E731" => Ok(CheckCode::E731), "E731" => Ok(CheckCode::E731),
"E741" => Ok(CheckCode::E741), "E741" => Ok(CheckCode::E741),
"E742" => Ok(CheckCode::E742),
"E902" => Ok(CheckCode::E902), "E902" => Ok(CheckCode::E902),
"F401" => Ok(CheckCode::F401), "F401" => Ok(CheckCode::F401),
"F403" => Ok(CheckCode::F403), "F403" => Ok(CheckCode::F403),
@ -93,6 +95,7 @@ impl CheckCode {
CheckCode::E714 => "E714", CheckCode::E714 => "E714",
CheckCode::E731 => "E731", CheckCode::E731 => "E731",
CheckCode::E741 => "E741", CheckCode::E741 => "E741",
CheckCode::E742 => "E742",
CheckCode::E902 => "E902", CheckCode::E902 => "E902",
CheckCode::F401 => "F401", CheckCode::F401 => "F401",
CheckCode::F403 => "F403", CheckCode::F403 => "F403",
@ -130,6 +133,7 @@ impl CheckCode {
CheckCode::E714 => &LintSource::AST, CheckCode::E714 => &LintSource::AST,
CheckCode::E731 => &LintSource::AST, CheckCode::E731 => &LintSource::AST,
CheckCode::E741 => &LintSource::AST, CheckCode::E741 => &LintSource::AST,
CheckCode::E742 => &LintSource::AST,
CheckCode::E902 => &LintSource::FileSystem, CheckCode::E902 => &LintSource::FileSystem,
CheckCode::F401 => &LintSource::AST, CheckCode::F401 => &LintSource::AST,
CheckCode::F403 => &LintSource::AST, CheckCode::F403 => &LintSource::AST,
@ -174,6 +178,7 @@ pub enum RejectedCmpop {
pub enum CheckKind { pub enum CheckKind {
AssertTuple, AssertTuple,
AmbiguousVariableName(String), AmbiguousVariableName(String),
AmbiguousClassName(String),
DefaultExceptNotLast, DefaultExceptNotLast,
DoNotAssignLambda, DoNotAssignLambda,
DuplicateArgumentName, DuplicateArgumentName,
@ -211,6 +216,7 @@ impl CheckKind {
match self { match self {
CheckKind::AssertTuple => "AssertTuple", CheckKind::AssertTuple => "AssertTuple",
CheckKind::AmbiguousVariableName(_) => "AmbiguousVariableName", CheckKind::AmbiguousVariableName(_) => "AmbiguousVariableName",
CheckKind::AmbiguousClassName(_) => "AmbiguousClassName",
CheckKind::DefaultExceptNotLast => "DefaultExceptNotLast", CheckKind::DefaultExceptNotLast => "DefaultExceptNotLast",
CheckKind::DuplicateArgumentName => "DuplicateArgumentName", CheckKind::DuplicateArgumentName => "DuplicateArgumentName",
CheckKind::FStringMissingPlaceholders => "FStringMissingPlaceholders", CheckKind::FStringMissingPlaceholders => "FStringMissingPlaceholders",
@ -260,6 +266,7 @@ impl CheckKind {
CheckKind::LineTooLong => &CheckCode::E501, CheckKind::LineTooLong => &CheckCode::E501,
CheckKind::DoNotAssignLambda => &CheckCode::E731, CheckKind::DoNotAssignLambda => &CheckCode::E731,
CheckKind::AmbiguousVariableName(_) => &CheckCode::E741, CheckKind::AmbiguousVariableName(_) => &CheckCode::E741,
CheckKind::AmbiguousClassName(_) => &CheckCode::E742,
CheckKind::ModuleImportNotAtTopOfFile => &CheckCode::E402, CheckKind::ModuleImportNotAtTopOfFile => &CheckCode::E402,
CheckKind::MultiValueRepeatedKeyLiteral => &CheckCode::F601, CheckKind::MultiValueRepeatedKeyLiteral => &CheckCode::F601,
CheckKind::MultiValueRepeatedKeyVariable(_) => &CheckCode::F602, CheckKind::MultiValueRepeatedKeyVariable(_) => &CheckCode::F602,
@ -312,6 +319,9 @@ impl CheckKind {
CheckKind::DoNotAssignLambda => { CheckKind::DoNotAssignLambda => {
"Do not assign a lambda expression, use a def".to_string() "Do not assign a lambda expression, use a def".to_string()
} }
CheckKind::AmbiguousClassName(name) => {
format!("ambiguous class name '{}'", name)
}
CheckKind::AmbiguousVariableName(name) => { CheckKind::AmbiguousVariableName(name) => {
format!("ambiguous variable name '{}'", name) format!("ambiguous variable name '{}'", name)
} }
@ -388,6 +398,7 @@ impl CheckKind {
/// Whether the check kind is (potentially) fixable. /// Whether the check kind is (potentially) fixable.
pub fn fixable(&self) -> bool { pub fn fixable(&self) -> bool {
match self { match self {
CheckKind::AmbiguousClassName(_) => true,
CheckKind::AmbiguousVariableName(_) => false, CheckKind::AmbiguousVariableName(_) => false,
CheckKind::AssertTuple => false, CheckKind::AssertTuple => false,
CheckKind::DefaultExceptNotLast => false, CheckKind::DefaultExceptNotLast => false,

View File

@ -441,6 +441,44 @@ mod tests {
Ok(()) Ok(())
} }
#[test]
fn e742() -> Result<()> {
let mut actual = check_path(
Path::new("./resources/test/fixtures/E742.py"),
&settings::Settings {
line_length: 88,
exclude: vec![],
select: BTreeSet::from([CheckCode::E742]),
},
&fixer::Mode::Generate,
)?;
actual.sort_by_key(|check| check.location);
let expected = vec![
Check {
kind: CheckKind::AmbiguousClassName("l".to_string()),
location: Location::new(1, 1),
fix: None,
},
Check {
kind: CheckKind::AmbiguousClassName("I".to_string()),
location: Location::new(5, 1),
fix: None,
},
Check {
kind: CheckKind::AmbiguousClassName("O".to_string()),
location: Location::new(9, 1),
fix: None,
},
];
assert_eq!(actual.len(), expected.len());
for i in 0..actual.len() {
assert_eq!(actual[i], expected[i]);
}
Ok(())
}
#[test] #[test]
fn f401() -> Result<()> { fn f401() -> Result<()> {
let mut actual = check_path( let mut actual = check_path(

View File

@ -267,6 +267,7 @@ other-attribute = 1
CheckCode::E714, CheckCode::E714,
CheckCode::E731, CheckCode::E731,
CheckCode::E741, CheckCode::E741,
CheckCode::E742,
CheckCode::E902, CheckCode::E902,
CheckCode::F401, CheckCode::F401,
CheckCode::F403, CheckCode::F403,

View File

@ -52,6 +52,7 @@ impl Settings {
CheckCode::E714, CheckCode::E714,
CheckCode::E731, CheckCode::E731,
CheckCode::E741, CheckCode::E741,
CheckCode::E742,
CheckCode::E902, CheckCode::E902,
CheckCode::F401, CheckCode::F401,
CheckCode::F403, CheckCode::F403,