mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 20:10:09 +00:00
Add flake8-pie PIE796: prefer-unique-enum (#1923)
I accept any suggestion. By the way, I have a doubt, I have checked and all flake8-pie plugins can be fixed by ruff, but is it necessary that this one is also fixed automatically ? rel #1543
This commit is contained in:
parent
2ed1f78873
commit
6e88c60c46
9 changed files with 192 additions and 0 deletions
|
@ -1141,6 +1141,7 @@ For more, see [flake8-pie](https://pypi.org/project/flake8-pie/0.16.0/) on PyPI.
|
||||||
| ---- | ---- | ------- | --- |
|
| ---- | ---- | ------- | --- |
|
||||||
| PIE790 | NoUnnecessaryPass | Unnecessary `pass` statement | 🛠 |
|
| PIE790 | NoUnnecessaryPass | Unnecessary `pass` statement | 🛠 |
|
||||||
| PIE794 | DupeClassFieldDefinitions | Class field `...` is defined multiple times | 🛠 |
|
| PIE794 | DupeClassFieldDefinitions | Class field `...` is defined multiple times | 🛠 |
|
||||||
|
| PIE796 | PreferUniqueEnums | Enum contains duplicate value: `...` | |
|
||||||
| PIE807 | PreferListBuiltin | Prefer `list()` over useless lambda | 🛠 |
|
| PIE807 | PreferListBuiltin | Prefer `list()` over useless lambda | 🛠 |
|
||||||
|
|
||||||
### flake8-commas (COM)
|
### flake8-commas (COM)
|
||||||
|
|
54
resources/test/fixtures/flake8_pie/PIE796.py
vendored
Normal file
54
resources/test/fixtures/flake8_pie/PIE796.py
vendored
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
class FakeEnum(enum.Enum):
|
||||||
|
A = "A"
|
||||||
|
B = "B"
|
||||||
|
C = "B" # PIE796
|
||||||
|
|
||||||
|
|
||||||
|
class FakeEnum2(Enum):
|
||||||
|
A = 1
|
||||||
|
B = 2
|
||||||
|
C = 2 # PIE796
|
||||||
|
|
||||||
|
|
||||||
|
class FakeEnum3(str, Enum):
|
||||||
|
A = "1"
|
||||||
|
B = "2"
|
||||||
|
C = "2" # PIE796
|
||||||
|
|
||||||
|
class FakeEnum4(Enum):
|
||||||
|
A = 1.0
|
||||||
|
B = 2.5
|
||||||
|
C = 2.5 # PIE796
|
||||||
|
|
||||||
|
|
||||||
|
class FakeEnum5(Enum):
|
||||||
|
A = 1.0
|
||||||
|
B = True
|
||||||
|
C = False
|
||||||
|
D = False # PIE796
|
||||||
|
|
||||||
|
|
||||||
|
class FakeEnum6(Enum):
|
||||||
|
A = 1
|
||||||
|
B = 2
|
||||||
|
C = None
|
||||||
|
D = None # PIE796
|
||||||
|
|
||||||
|
|
||||||
|
@enum.unique
|
||||||
|
class FakeEnum7(enum.Enum):
|
||||||
|
A = "A"
|
||||||
|
B = "B"
|
||||||
|
C = "C"
|
||||||
|
|
||||||
|
@unique
|
||||||
|
class FakeEnum8(Enum):
|
||||||
|
A = 1
|
||||||
|
B = 2
|
||||||
|
C = 2 # PIE796
|
||||||
|
|
||||||
|
class FakeEnum9(enum.Enum):
|
||||||
|
A = "A"
|
||||||
|
B = "B"
|
||||||
|
C = "C"
|
||||||
|
|
|
@ -1431,6 +1431,7 @@
|
||||||
"PIE79",
|
"PIE79",
|
||||||
"PIE790",
|
"PIE790",
|
||||||
"PIE794",
|
"PIE794",
|
||||||
|
"PIE796",
|
||||||
"PIE8",
|
"PIE8",
|
||||||
"PIE80",
|
"PIE80",
|
||||||
"PIE807",
|
"PIE807",
|
||||||
|
|
|
@ -701,6 +701,10 @@ where
|
||||||
flake8_pie::rules::dupe_class_field_definitions(self, stmt, body);
|
flake8_pie::rules::dupe_class_field_definitions(self, stmt, body);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if self.settings.enabled.contains(&RuleCode::PIE796) {
|
||||||
|
flake8_pie::rules::prefer_unique_enums(self, stmt, body);
|
||||||
|
}
|
||||||
|
|
||||||
self.check_builtin_shadowing(name, stmt, false);
|
self.check_builtin_shadowing(name, stmt, false);
|
||||||
|
|
||||||
for expr in bases {
|
for expr in bases {
|
||||||
|
|
|
@ -410,6 +410,7 @@ ruff_macros::define_rule_mapping!(
|
||||||
// flake8-pie
|
// flake8-pie
|
||||||
PIE790 => violations::NoUnnecessaryPass,
|
PIE790 => violations::NoUnnecessaryPass,
|
||||||
PIE794 => violations::DupeClassFieldDefinitions,
|
PIE794 => violations::DupeClassFieldDefinitions,
|
||||||
|
PIE796 => violations::PreferUniqueEnums,
|
||||||
PIE807 => violations::PreferListBuiltin,
|
PIE807 => violations::PreferListBuiltin,
|
||||||
// flake8-commas
|
// flake8-commas
|
||||||
COM812 => violations::TrailingCommaMissing,
|
COM812 => violations::TrailingCommaMissing,
|
||||||
|
|
|
@ -14,6 +14,7 @@ mod tests {
|
||||||
|
|
||||||
#[test_case(RuleCode::PIE790, Path::new("PIE790.py"); "PIE790")]
|
#[test_case(RuleCode::PIE790, Path::new("PIE790.py"); "PIE790")]
|
||||||
#[test_case(RuleCode::PIE794, Path::new("PIE794.py"); "PIE794")]
|
#[test_case(RuleCode::PIE794, Path::new("PIE794.py"); "PIE794")]
|
||||||
|
#[test_case(RuleCode::PIE796, Path::new("PIE796.py"); "PIE796")]
|
||||||
#[test_case(RuleCode::PIE807, Path::new("PIE807.py"); "PIE807")]
|
#[test_case(RuleCode::PIE807, Path::new("PIE807.py"); "PIE807")]
|
||||||
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
|
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
|
||||||
let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
|
let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
|
||||||
|
|
|
@ -2,6 +2,8 @@ use log::error;
|
||||||
use rustc_hash::FxHashSet;
|
use rustc_hash::FxHashSet;
|
||||||
use rustpython_ast::{Constant, Expr, ExprKind, Stmt, StmtKind};
|
use rustpython_ast::{Constant, Expr, ExprKind, Stmt, StmtKind};
|
||||||
|
|
||||||
|
use crate::ast::comparable::ComparableExpr;
|
||||||
|
use crate::ast::helpers::unparse_expr;
|
||||||
use crate::ast::types::{Range, RefEquality};
|
use crate::ast::types::{Range, RefEquality};
|
||||||
use crate::autofix::helpers::delete_stmt;
|
use crate::autofix::helpers::delete_stmt;
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
@ -106,6 +108,41 @@ pub fn dupe_class_field_definitions<'a, 'b>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// PIE796
|
||||||
|
pub fn prefer_unique_enums<'a, 'b>(checker: &mut Checker<'a>, parent: &'b Stmt, body: &'b [Stmt])
|
||||||
|
where
|
||||||
|
'b: 'a,
|
||||||
|
{
|
||||||
|
let StmtKind::ClassDef { bases, .. } = &parent.node else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
if !bases.iter().any(|expr| {
|
||||||
|
checker
|
||||||
|
.resolve_call_path(expr)
|
||||||
|
.map_or(false, |call_path| call_path == ["enum", "Enum"])
|
||||||
|
}) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut seen_targets: FxHashSet<ComparableExpr> = FxHashSet::default();
|
||||||
|
for stmt in body {
|
||||||
|
let StmtKind::Assign { value, .. } = &stmt.node else {
|
||||||
|
continue;
|
||||||
|
};
|
||||||
|
|
||||||
|
if !seen_targets.insert(ComparableExpr::from(value)) {
|
||||||
|
let diagnostic = Diagnostic::new(
|
||||||
|
violations::PreferUniqueEnums {
|
||||||
|
value: unparse_expr(value, checker.stylist),
|
||||||
|
},
|
||||||
|
Range::from_located(stmt),
|
||||||
|
);
|
||||||
|
checker.diagnostics.push(diagnostic);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// PIE807
|
/// PIE807
|
||||||
pub fn prefer_list_builtin(checker: &mut Checker, expr: &Expr) {
|
pub fn prefer_list_builtin(checker: &mut Checker, expr: &Expr) {
|
||||||
let ExprKind::Lambda { args, body } = &expr.node else {
|
let ExprKind::Lambda { args, body } = &expr.node else {
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
---
|
||||||
|
source: src/rules/flake8_pie/mod.rs
|
||||||
|
expression: diagnostics
|
||||||
|
---
|
||||||
|
- kind:
|
||||||
|
PreferUniqueEnums: "\"B\""
|
||||||
|
location:
|
||||||
|
row: 4
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 4
|
||||||
|
column: 11
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
PreferUniqueEnums: "2"
|
||||||
|
location:
|
||||||
|
row: 10
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 10
|
||||||
|
column: 9
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
PreferUniqueEnums: "\"2\""
|
||||||
|
location:
|
||||||
|
row: 16
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 16
|
||||||
|
column: 11
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
PreferUniqueEnums: "2.5"
|
||||||
|
location:
|
||||||
|
row: 21
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 21
|
||||||
|
column: 11
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
PreferUniqueEnums: "False"
|
||||||
|
location:
|
||||||
|
row: 28
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 28
|
||||||
|
column: 13
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
PreferUniqueEnums: None
|
||||||
|
location:
|
||||||
|
row: 35
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 35
|
||||||
|
column: 12
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
- kind:
|
||||||
|
PreferUniqueEnums: "2"
|
||||||
|
location:
|
||||||
|
row: 48
|
||||||
|
column: 4
|
||||||
|
end_location:
|
||||||
|
row: 48
|
||||||
|
column: 9
|
||||||
|
fix: ~
|
||||||
|
parent: ~
|
||||||
|
|
|
@ -5970,6 +5970,24 @@ impl AlwaysAutofixableViolation for DupeClassFieldDefinitions {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
define_violation!(
|
||||||
|
pub struct PreferUniqueEnums {
|
||||||
|
pub value: String,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
impl Violation for PreferUniqueEnums {
|
||||||
|
fn message(&self) -> String {
|
||||||
|
let PreferUniqueEnums { value } = self;
|
||||||
|
format!("Enum contains duplicate value: `{value}`")
|
||||||
|
}
|
||||||
|
|
||||||
|
fn placeholder() -> Self {
|
||||||
|
PreferUniqueEnums {
|
||||||
|
value: "...".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
define_violation!(
|
define_violation!(
|
||||||
pub struct PreferListBuiltin;
|
pub struct PreferListBuiltin;
|
||||||
);
|
);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue