[flake8-bugbear] Implement class-as-data-structure (B903)#9601
[flake8-bugbear] Implement class-as-data-structure (B903)#9601dylwil3 merged 18 commits intoastral-sh:mainfrom
flake8-bugbear] Implement class-as-data-structure (B903)#9601Conversation
|
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| B903 | 40 | 40 | 0 | 0 | 0 |
4894b8f to
366bd8e
Compare
02b14f3 to
40bc3c0
Compare
|
Hi! Thanks for implementing this. I'm hesitant to include this rule in Ruff. It looks like "too few methods" is used as a proxy for "this should be a dataclass" — it seems like a rule like "it only has an Separately, there's a false positive here for nested classes used for configuration — perhaps those should be excluded from the rule? |
a4a7b17 to
29ee553
Compare
Tweaked accordingly! Changing up the name of the rule slightly may be in order, I figure? 🤔 Please advise! |
d51d701 to
514affe
Compare
MichaReiser
left a comment
There was a problem hiding this comment.
I left an inline comment with a rule name suggestion. @AlexWaygood do you have ideas/opinions on a name for this rule?
crates/ruff_linter/src/rules/pylint/rules/too_few_public_methods.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/too_few_public_methods.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/too_few_public_methods.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/pylint/rules/too_few_public_methods.rs
Outdated
Show resolved
Hide resolved
Possibly something like I think the current name is okay, albeit a bit verbose, and there is some advantage to it having the same name as the original pylint rule |
I like the name but it, unfortunately, doesn't fit our rule naming convention
We can use the same rule code as pylint, but I would prefer another name that's more explicit about its motivation. Having a different name might also help to set expectations, considering that we're probably changing the semantics of the rule. |
|
Maybe something like |
|
This is interesting #10146 I haven't looked at how the two rules overlap but maybe there's an opportunity. |
That is interesting, indeed... it's flagging a different antipattern, but one that has the same solution |
|
Let me know if there's any action items blocking this PR, not sure what to make of these comments tbh |
|
Note for reviewing: The rule itself is a style rule but we need to find a good name that expresses the motivation to use dataclasses/named tuples instead of enforcing a number of public methods. The name should read as But the intent of the rule itself fits into ruff as a style rule. |
|
@zanieb @MichaReiser Is there any progress on merging this? I think it would be a beneficial rule to add. In addition to suggesting data-classes this also covers the case where people create empty "base" classes, which is an antipattern in my opinion. Ideally, I would also like to have a rule which flags classes with |
Not much other than that we have to come up with a good rule name that captures the motivation. Do you have any suggestions for a good rule name? |
What is the naming convention/naming rules? IMHO, there are three different rules here, they can be named:
|
pylint] - Implement too-few-public-methods rule (PLR0903)flake8-bugbear] Implement class-as-data-structure rule (B903)
flake8-bugbear] Implement class-as-data-structure rule (B903)flake8-bugbear] Implement class-as-data-structure (B903)
|
Just some updates here:
Gonna check out the ecosystem results and possibly update the documentation, but otherwise I think this is close to done unless there are any objections! Update: Ecosystem results look much better to me now! |
crates/ruff_linter/src/rules/flake8_bugbear/rules/class_as_data_structure.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/flake8_bugbear/rules/class_as_data_structure.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/flake8_bugbear/rules/class_as_data_structure.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/flake8_bugbear/rules/class_as_data_structure.rs
Outdated
Show resolved
Hide resolved
crates/ruff_linter/src/rules/flake8_bugbear/rules/class_as_data_structure.rs
Show resolved
Hide resolved
|
Thanks for implementing this @diceroll123 and sorry for the delay on getting it over the line! |
* main: Use uv consistently throughout the documentation (#15302) [red-knot] Eagerly normalize `type[]` types (#15272) [`pyupgrade`] Split `UP007` to two individual rules for `Union` and `Optional` (`UP007`, `UP045`) (#15313) [red-knot] Improve symbol-lookup tracing (#14907) [red-knot] improve type shrinking coverage in red-knot property tests (#15297) [`flake8-return`] Recognize functions returning `Never` as non-returning (`RET503`) (#15298) [`flake8-bugbear`] Implement `class-as-data-structure` (`B903`) (#9601) Avoid treating newline-separated sections as sub-sections (#15311) Remove call when removing final argument from `format` (#15309) Don't enforce `object-without-hash-method` in stubs (#15310) Don't special-case class instances in binary expression inference (#15161) Upgrade zizmor to the latest version in CI (#15300)
Summary
Adds
class-as-data-structurerule (B903).Took some creative liberty with this by allowing the class to have any decorators or base classes. There are years-old issues on pylint that don't approve of the strictness when it comes to these things.
Especially considering that dataclass is a decorator and namedtuple can be a base class. I feel ignoring those explicitly is redundant all things considered, but it's not a hill I'm willing to die on!
See: #970
Test Plan
cargo test