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 |
|
| R001 | UselessObjectInheritance | Class `...` inherits from object |
|
||||||
| R002 | NoAssertEquals | `assertEquals` is deprecated, use `assertEqual` instead |
|
| R002 | NoAssertEquals | `assertEquals` is deprecated, use `assertEqual` instead |
|
||||||
| M001 | UnusedNOQA | Unused `noqa` directive |
|
| 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
|
## 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
|
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),
|
ExprContext::Del => self.handle_node_delete(expr),
|
||||||
},
|
},
|
||||||
ExprKind::Call { func, .. } => {
|
ExprKind::Call { func, args, .. } => {
|
||||||
if self.settings.select.contains(&CheckCode::R002) {
|
if self.settings.select.contains(&CheckCode::R002) {
|
||||||
if let Some(check) = checks::check_assert_equals(func, self.autofix) {
|
if let Some(check) = checks::check_assert_equals(func, self.autofix) {
|
||||||
self.checks.push(check)
|
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 let ExprKind::Name { id, ctx } = &func.node {
|
||||||
if id == "locals" && matches!(ctx, ExprContext::Load) {
|
if id == "locals" && matches!(ctx, ExprContext::Load) {
|
||||||
let scope = &mut self.scopes[*(self
|
let scope = &mut self.scopes[*(self
|
||||||
|
|
|
@ -4,7 +4,7 @@ use anyhow::Result;
|
||||||
use rustpython_parser::ast::Location;
|
use rustpython_parser::ast::Location;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
pub const DEFAULT_CHECK_CODES: [CheckCode; 45] = [
|
pub const DEFAULT_CHECK_CODES: [CheckCode; 46] = [
|
||||||
CheckCode::E402,
|
CheckCode::E402,
|
||||||
CheckCode::E501,
|
CheckCode::E501,
|
||||||
CheckCode::E711,
|
CheckCode::E711,
|
||||||
|
@ -51,9 +51,11 @@ pub const DEFAULT_CHECK_CODES: [CheckCode; 45] = [
|
||||||
CheckCode::A001,
|
CheckCode::A001,
|
||||||
CheckCode::A002,
|
CheckCode::A002,
|
||||||
CheckCode::A003,
|
CheckCode::A003,
|
||||||
|
// flake8-super
|
||||||
|
CheckCode::SPR001,
|
||||||
];
|
];
|
||||||
|
|
||||||
pub const ALL_CHECK_CODES: [CheckCode; 48] = [
|
pub const ALL_CHECK_CODES: [CheckCode; 49] = [
|
||||||
CheckCode::E402,
|
CheckCode::E402,
|
||||||
CheckCode::E501,
|
CheckCode::E501,
|
||||||
CheckCode::E711,
|
CheckCode::E711,
|
||||||
|
@ -103,6 +105,8 @@ pub const ALL_CHECK_CODES: [CheckCode; 48] = [
|
||||||
CheckCode::A001,
|
CheckCode::A001,
|
||||||
CheckCode::A002,
|
CheckCode::A002,
|
||||||
CheckCode::A003,
|
CheckCode::A003,
|
||||||
|
// flake8-super
|
||||||
|
CheckCode::SPR001,
|
||||||
];
|
];
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash, PartialOrd, Ord)]
|
#[derive(Debug, PartialEq, Eq, Clone, Serialize, Deserialize, Hash, PartialOrd, Ord)]
|
||||||
|
@ -156,6 +160,8 @@ pub enum CheckCode {
|
||||||
A001,
|
A001,
|
||||||
A002,
|
A002,
|
||||||
A003,
|
A003,
|
||||||
|
// flake8-super
|
||||||
|
SPR001,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl FromStr for CheckCode {
|
impl FromStr for CheckCode {
|
||||||
|
@ -212,6 +218,8 @@ impl FromStr for CheckCode {
|
||||||
"A001" => Ok(CheckCode::A001),
|
"A001" => Ok(CheckCode::A001),
|
||||||
"A002" => Ok(CheckCode::A002),
|
"A002" => Ok(CheckCode::A002),
|
||||||
"A003" => Ok(CheckCode::A003),
|
"A003" => Ok(CheckCode::A003),
|
||||||
|
// flake8-super
|
||||||
|
"SPR001" => Ok(CheckCode::SPR001),
|
||||||
_ => Err(anyhow::anyhow!("Unknown check code: {s}")),
|
_ => Err(anyhow::anyhow!("Unknown check code: {s}")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -269,6 +277,8 @@ impl CheckCode {
|
||||||
CheckCode::A001 => "A001",
|
CheckCode::A001 => "A001",
|
||||||
CheckCode::A002 => "A002",
|
CheckCode::A002 => "A002",
|
||||||
CheckCode::A003 => "A003",
|
CheckCode::A003 => "A003",
|
||||||
|
// flake8-super
|
||||||
|
CheckCode::SPR001 => "SPR001",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -333,6 +343,8 @@ impl CheckCode {
|
||||||
CheckCode::A001 => CheckKind::BuiltinVariableShadowing("...".to_string()),
|
CheckCode::A001 => CheckKind::BuiltinVariableShadowing("...".to_string()),
|
||||||
CheckCode::A002 => CheckKind::BuiltinArgumentShadowing("...".to_string()),
|
CheckCode::A002 => CheckKind::BuiltinArgumentShadowing("...".to_string()),
|
||||||
CheckCode::A003 => CheckKind::BuiltinAttributeShadowing("...".to_string()),
|
CheckCode::A003 => CheckKind::BuiltinAttributeShadowing("...".to_string()),
|
||||||
|
// flake8-super
|
||||||
|
CheckCode::SPR001 => CheckKind::SuperCallWithParameters,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -401,6 +413,8 @@ pub enum CheckKind {
|
||||||
BuiltinVariableShadowing(String),
|
BuiltinVariableShadowing(String),
|
||||||
BuiltinArgumentShadowing(String),
|
BuiltinArgumentShadowing(String),
|
||||||
BuiltinAttributeShadowing(String),
|
BuiltinAttributeShadowing(String),
|
||||||
|
// flake8-super
|
||||||
|
SuperCallWithParameters,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CheckKind {
|
impl CheckKind {
|
||||||
|
@ -458,6 +472,8 @@ impl CheckKind {
|
||||||
CheckKind::BuiltinVariableShadowing(_) => "BuiltinVariableShadowing",
|
CheckKind::BuiltinVariableShadowing(_) => "BuiltinVariableShadowing",
|
||||||
CheckKind::BuiltinArgumentShadowing(_) => "BuiltinArgumentShadowing",
|
CheckKind::BuiltinArgumentShadowing(_) => "BuiltinArgumentShadowing",
|
||||||
CheckKind::BuiltinAttributeShadowing(_) => "BuiltinAttributeShadowing",
|
CheckKind::BuiltinAttributeShadowing(_) => "BuiltinAttributeShadowing",
|
||||||
|
// flake8-super
|
||||||
|
CheckKind::SuperCallWithParameters => "SuperCallWithParameters",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -513,6 +529,8 @@ impl CheckKind {
|
||||||
CheckKind::BuiltinVariableShadowing(_) => &CheckCode::A001,
|
CheckKind::BuiltinVariableShadowing(_) => &CheckCode::A001,
|
||||||
CheckKind::BuiltinArgumentShadowing(_) => &CheckCode::A002,
|
CheckKind::BuiltinArgumentShadowing(_) => &CheckCode::A002,
|
||||||
CheckKind::BuiltinAttributeShadowing(_) => &CheckCode::A003,
|
CheckKind::BuiltinAttributeShadowing(_) => &CheckCode::A003,
|
||||||
|
// flake8-super
|
||||||
|
CheckKind::SuperCallWithParameters => &CheckCode::SPR001,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -657,6 +675,10 @@ impl CheckKind {
|
||||||
CheckKind::BuiltinAttributeShadowing(name) => {
|
CheckKind::BuiltinAttributeShadowing(name) => {
|
||||||
format!("class attribute `{name}` is shadowing a python builtin")
|
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);
|
insta::assert_yaml_snapshot!(checks);
|
||||||
Ok(())
|
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