Skip to content

Commit

Permalink
PLR0902: add support for annotated assignments and ...
Browse files Browse the repository at this point in the history
... attributes declared outside class methods
  • Loading branch information
liushuyu committed Feb 26, 2024
1 parent ac45ec1 commit 5e3ebe9
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 19 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
class Fruit:
# max of 7 attributes by default, can be configured
self.attr0: int = 0
self.attr0 = 1
self.attr1, self.attr2 = 1, 2

def __init__(self):
# max of 7 attributes by default, can be configured
self.worm_name = "Jimmy"
self.worm_type = "Codling Moths"
self.worm_color = "light brown"
Expand All @@ -11,3 +15,6 @@ def __init__(self):
self.secondary_worm_name = "Kim"
self.secondary_worm_type = "Apple maggot"
self.secondary_worm_color = "Whitish"
# typed assignments
self.a_string: str = "String"
self.a_number: float = 3.1415926
52 changes: 37 additions & 15 deletions crates/ruff_linter/src/rules/pylint/rules/too_many_attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,22 @@ fn collect_attributes<'a>(attributes: &mut HashSet<&'a str>, expr: &'a ExprAttri
}
}

fn extract_assigned_attributes<'a>(attributes: &mut HashSet<&'a str>, target: &'a Expr) {
match target {
Expr::Attribute(expr) => {
collect_attributes(attributes, expr);
}
Expr::Tuple(tuple) => {
for expr in &tuple.elts {
if let Some(expr) = expr.as_attribute_expr() {
collect_attributes(attributes, expr);
}
}
}
_ => (),
}
}

/// PLR0902
pub(crate) fn too_many_attributes(
checker: &Checker,
Expand All @@ -52,27 +68,33 @@ pub(crate) fn too_many_attributes(
diagnostics: &mut Vec<Diagnostic>,
) {
let mut attributes = HashSet::new();
// collect attributes defined in `__init__`
for body in &class_def.body {
if let Stmt::FunctionDef(func_def) = body {
for stmt in &func_def.body {
if let Stmt::Assign(assign) = stmt {
for target in &assign.targets {
match target {
Expr::Attribute(expr) => {
collect_attributes(&mut attributes, expr);
}
Expr::Tuple(tuple) => {
for expr in &tuple.elts {
if let Some(expr) = expr.as_attribute_expr() {
collect_attributes(&mut attributes, expr);
}
}
match body {
Stmt::FunctionDef(func_def) => {
for stmt in &func_def.body {
match stmt {
Stmt::Assign(assign) => {
for target in &assign.targets {
extract_assigned_attributes(&mut attributes, target);
}
_ => (),
}
Stmt::AnnAssign(assign) => {
extract_assigned_attributes(&mut attributes, &assign.target);
}
_ => (),
}
}
}
Stmt::Assign(assign) => {
for target in &assign.targets {
extract_assigned_attributes(&mut attributes, target);
}
}
Stmt::AnnAssign(assign) => {
extract_assigned_attributes(&mut attributes, &assign.target);
}
_ => (),
}
}
let num_attributes = attributes.len();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
---
source: crates/ruff_linter/src/rules/pylint/mod.rs
---
too_many_attributes.py:1:7: PLR0902 Too many instance attributes (10/7)
too_many_attributes.py:1:7: PLR0902 Too many instance attributes (15/7)
|
1 | class Fruit:
| ^^^^^ PLR0902
2 | def __init__(self):
3 | # max of 7 attributes by default, can be configured
2 | # max of 7 attributes by default, can be configured
3 | self.attr0: int = 0
|


0 comments on commit 5e3ebe9

Please sign in to comment.