mirror of
https://github.com/astral-sh/ruff.git
synced 2025-09-26 11:59:35 +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 | 🛠 |
|
||||
| PIE794 | DupeClassFieldDefinitions | Class field `...` is defined multiple times | 🛠 |
|
||||
| PIE796 | PreferUniqueEnums | Enum contains duplicate value: `...` | |
|
||||
| PIE807 | PreferListBuiltin | Prefer `list()` over useless lambda | 🛠 |
|
||||
|
||||
### 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",
|
||||
"PIE790",
|
||||
"PIE794",
|
||||
"PIE796",
|
||||
"PIE8",
|
||||
"PIE80",
|
||||
"PIE807",
|
||||
|
|
|
@ -701,6 +701,10 @@ where
|
|||
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);
|
||||
|
||||
for expr in bases {
|
||||
|
|
|
@ -410,6 +410,7 @@ ruff_macros::define_rule_mapping!(
|
|||
// flake8-pie
|
||||
PIE790 => violations::NoUnnecessaryPass,
|
||||
PIE794 => violations::DupeClassFieldDefinitions,
|
||||
PIE796 => violations::PreferUniqueEnums,
|
||||
PIE807 => violations::PreferListBuiltin,
|
||||
// flake8-commas
|
||||
COM812 => violations::TrailingCommaMissing,
|
||||
|
|
|
@ -14,6 +14,7 @@ mod tests {
|
|||
|
||||
#[test_case(RuleCode::PIE790, Path::new("PIE790.py"); "PIE790")]
|
||||
#[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")]
|
||||
fn rules(rule_code: RuleCode, path: &Path) -> Result<()> {
|
||||
let snapshot = format!("{}_{}", rule_code.as_ref(), path.to_string_lossy());
|
||||
|
|
|
@ -2,6 +2,8 @@ use log::error;
|
|||
use rustc_hash::FxHashSet;
|
||||
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::autofix::helpers::delete_stmt;
|
||||
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
|
||||
pub fn prefer_list_builtin(checker: &mut Checker, expr: &Expr) {
|
||||
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!(
|
||||
pub struct PreferListBuiltin;
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue