mirror of
https://github.com/astral-sh/ruff.git
synced 2025-10-01 06:11:43 +00:00
Implement flake8-super
check (#291)
This commit is contained in:
parent
5a1b6c32eb
commit
20989e12ba
7 changed files with 104 additions and 3 deletions
|
@ -263,6 +263,10 @@ Beyond rule-set parity, ruff suffers from the following limitations vis-à-vis F
|
|||
| R001 | UselessObjectInheritance | Class `...` inherits from object |
|
||||
| R002 | NoAssertEquals | `assertEquals` is deprecated, use `assertEqual` instead |
|
||||
| M001 | UnusedNOQA | Unused `noqa` directive |
|
||||
| A001 | BuiltinVariableShadowing | Variable `...` is shadowing a python builtin |
|
||||
| A002 | BuiltinArgumentShadowing | Argument `...` is shadowing a python builtin |
|
||||
| A003 | BuiltinAttributeShadowing | class attribute `...` is shadowing a python builtin |
|
||||
| SPR001 | SuperCallWithParameters | Use `super()` instead of `super(__class__, self)` |
|
||||
|
||||
## Integrations
|
||||
|
||||
|
|
22
resources/test/fixtures/SPR001.py
vendored
Normal file
22
resources/test/fixtures/SPR001.py
vendored
Normal file
|
@ -0,0 +1,22 @@
|
|||
class Parent:
|
||||
def method(self):
|
||||
pass
|
||||
|
||||
def wrong(self):
|
||||
pass
|
||||
|
||||
|
||||
class Child(Parent):
|
||||
def method(self):
|
||||
parent = super() # ok
|
||||
super().method() # ok
|
||||
Parent.method(self) # ok
|
||||
Parent.super(1, 2) # ok
|
||||
|
||||
def wrong(self):
|
||||
parent = super(Child, self) # wrong
|
||||
super(Child, self).method # wrong
|
||||
super(
|
||||
Child,
|
||||
self,
|
||||
).method() # wrong
|
|
@ -680,3 +680,18 @@ pub fn check_builtin_shadowing(
|
|||
None
|
||||
}
|
||||
}
|
||||
|
||||
// flake8-super
|
||||
/// Check that `super()` has no args
|
||||
pub fn check_super_args(expr: &Expr, args: &Vec<Expr>) -> Option<Check> {
|
||||
if let ExprKind::Name { id, .. } = &expr.node {
|
||||
if id == "super" && !args.is_empty() {
|
||||
return Some(Check::new(
|
||||
CheckKind::SuperCallWithParameters,
|
||||
expr.location,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
|
|
@ -689,13 +689,20 @@ where
|
|||
}
|
||||
ExprContext::Del => self.handle_node_delete(expr),
|
||||
},
|
||||
ExprKind::Call { func, .. } => {
|
||||
ExprKind::Call { func, args, .. } => {
|
||||
if self.settings.select.contains(&CheckCode::R002) {
|
||||
if let Some(check) = checks::check_assert_equals(func, self.autofix) {
|
||||
self.checks.push(check)
|
||||
}
|
||||
}
|
||||
|
||||
// flake8-super
|
||||
if self.settings.select.contains(&CheckCode::SPR001) {
|
||||
if let Some(check) = checks::check_super_args(func, args) {
|
||||
self.checks.push(check)
|
||||
}
|
||||
}
|
||||
|
||||
if let ExprKind::Name { id, ctx } = &func.node {
|
||||
if id == "locals" && matches!(ctx, ExprContext::Load) {
|
||||
let scope = &mut self.scopes[*(self
|
||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
|||
use rustpython_parser::ast::Location;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
pub const DEFAULT_CHECK_CODES: [CheckCode; 45] = [
|
||||
pub const DEFAULT_CHECK_CODES: [CheckCode; 46] = [
|
||||
CheckCode::E402,
|
||||
CheckCode::E501,
|
||||
CheckCode::E711,
|
||||
|
@ -51,9 +51,11 @@ pub const DEFAULT_CHECK_CODES: [CheckCode; 45] = [
|
|||
CheckCode::A001,
|
||||
CheckCode::A002,
|
||||
CheckCode::A003,
|
||||
// flake8-super
|
||||
CheckCode::SPR001,
|
||||
];
|
||||
|
||||
pub const ALL_CHECK_CODES: [CheckCode; 48] = [
|
||||
pub const ALL_CHECK_CODES: [CheckCode; 49] = [
|
||||
CheckCode::E402,
|
||||
CheckCode::E501,
|
||||
CheckCode::E711,
|
||||
|
@ -103,6 +105,8 @@ pub const ALL_CHECK_CODES: [CheckCode; 48] = [
|
|||
CheckCode::A001,
|
||||
CheckCode::A002,
|
||||
CheckCode::A003,
|
||||
// flake8-super
|
||||
CheckCode::SPR001,
|
||||
];
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash, PartialOrd, Ord)]
|
||||
|
@ -156,6 +160,8 @@ pub enum CheckCode {
|
|||
A001,
|
||||
A002,
|
||||
A003,
|
||||
// flake8-super
|
||||
SPR001,
|
||||
}
|
||||
|
||||
impl FromStr for CheckCode {
|
||||
|
@ -212,6 +218,8 @@ impl FromStr for CheckCode {
|
|||
"A001" => Ok(CheckCode::A001),
|
||||
"A002" => Ok(CheckCode::A002),
|
||||
"A003" => Ok(CheckCode::A003),
|
||||
// flake8-super
|
||||
"SPR001" => Ok(CheckCode::SPR001),
|
||||
_ => Err(anyhow::anyhow!("Unknown check code: {s}")),
|
||||
}
|
||||
}
|
||||
|
@ -269,6 +277,8 @@ impl CheckCode {
|
|||
CheckCode::A001 => "A001",
|
||||
CheckCode::A002 => "A002",
|
||||
CheckCode::A003 => "A003",
|
||||
// flake8-super
|
||||
CheckCode::SPR001 => "SPR001",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,6 +343,8 @@ impl CheckCode {
|
|||
CheckCode::A001 => CheckKind::BuiltinVariableShadowing("...".to_string()),
|
||||
CheckCode::A002 => CheckKind::BuiltinArgumentShadowing("...".to_string()),
|
||||
CheckCode::A003 => CheckKind::BuiltinAttributeShadowing("...".to_string()),
|
||||
// flake8-super
|
||||
CheckCode::SPR001 => CheckKind::SuperCallWithParameters,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -401,6 +413,8 @@ pub enum CheckKind {
|
|||
BuiltinVariableShadowing(String),
|
||||
BuiltinArgumentShadowing(String),
|
||||
BuiltinAttributeShadowing(String),
|
||||
// flake8-super
|
||||
SuperCallWithParameters,
|
||||
}
|
||||
|
||||
impl CheckKind {
|
||||
|
@ -458,6 +472,8 @@ impl CheckKind {
|
|||
CheckKind::BuiltinVariableShadowing(_) => "BuiltinVariableShadowing",
|
||||
CheckKind::BuiltinArgumentShadowing(_) => "BuiltinArgumentShadowing",
|
||||
CheckKind::BuiltinAttributeShadowing(_) => "BuiltinAttributeShadowing",
|
||||
// flake8-super
|
||||
CheckKind::SuperCallWithParameters => "SuperCallWithParameters",
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,6 +529,8 @@ impl CheckKind {
|
|||
CheckKind::BuiltinVariableShadowing(_) => &CheckCode::A001,
|
||||
CheckKind::BuiltinArgumentShadowing(_) => &CheckCode::A002,
|
||||
CheckKind::BuiltinAttributeShadowing(_) => &CheckCode::A003,
|
||||
// flake8-super
|
||||
CheckKind::SuperCallWithParameters => &CheckCode::SPR001,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -657,6 +675,10 @@ impl CheckKind {
|
|||
CheckKind::BuiltinAttributeShadowing(name) => {
|
||||
format!("class attribute `{name}` is shadowing a python builtin")
|
||||
}
|
||||
// flake8-super
|
||||
CheckKind::SuperCallWithParameters => {
|
||||
"Use `super()` instead of `super(__class__, self)`".to_string()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -762,4 +762,16 @@ mod tests {
|
|||
insta::assert_yaml_snapshot!(checks);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spr001() -> Result<()> {
|
||||
let mut checks = check_path(
|
||||
Path::new("./resources/test/fixtures/SPR001.py"),
|
||||
&settings::Settings::for_rule(CheckCode::SPR001),
|
||||
&fixer::Mode::Generate,
|
||||
)?;
|
||||
checks.sort_by_key(|check| check.location);
|
||||
insta::assert_yaml_snapshot!(checks);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
19
src/snapshots/ruff__linter__tests__spr001.snap
Normal file
19
src/snapshots/ruff__linter__tests__spr001.snap
Normal file
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: SuperCallWithParameters
|
||||
location:
|
||||
row: 17
|
||||
column: 18
|
||||
fix: ~
|
||||
- kind: SuperCallWithParameters
|
||||
location:
|
||||
row: 18
|
||||
column: 9
|
||||
fix: ~
|
||||
- kind: SuperCallWithParameters
|
||||
location:
|
||||
row: 19
|
||||
column: 9
|
||||
fix: ~
|
Loading…
Add table
Add a link
Reference in a new issue