-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update bugbear #2954
Comments
(Good rules if anyone's looking for a first issue :)) |
B029 implemented in #3068. |
B032 implemented in #3085. |
Would it be possible to add B901 to the checklist above? (I'm not sure I understand the original caveat about it in the description.) I haven't contributed to ruff before (or used Rust), but might be interested in trying. That rule is the only one keeping me from migrating to ruff from flake8/flake8-bugbear. Thanks! |
B901 is really a Python 2 compatibly rule, so I'd assume it is really low priority (and when Python 2 is gone, there's no need to outlaw perfectly valid Python 3 syntax for compatibility with Python 2 anymore). |
@henryiii Hm, I don't think that fully captures the utility of the rule. It's valid syntax in Python 3 as you say, but like most of the B9 opinionated rules in bugbear, the point is that the syntax ( from collections.abc import Iterable
from pathlib import Path
def get_file_paths(file_types: Iterable[str] | None = None) -> Iterable[Path]:
dir_path = Path('.')
if file_types is None:
return dir_path.glob("*")
for file_type in file_types:
yield from dir_path.glob(f"*.{file_type}") While one might assume that the above will give an iterable of all paths in the directory if >>> list(get_file_paths(file_types=["cfg", "toml"]))
[PosixPath('.bumpversion.cfg'),
PosixPath('setup.cfg'),
PosixPath('pyproject.toml')]
>>> list(get_file_paths())
[] B901 catches this, since the syntax/behavior that the author of the code likely intended was: def get_file_paths_fixed(file_types: Iterable[str] | None = None) -> Iterable[Path]:
dir_path = Path('.')
if file_types is None:
yield from dir_path.glob("*")
else:
for file_type in file_types:
yield from dir_path.glob(f"*.{file_type}") which works: >>> list(get_file_paths_fixed())
[PosixPath('.pylintrc'),
PosixPath('.DS_Store'),
PosixPath('pyproject.toml'),
PosixPath('.bumpversion.cfg'),
PosixPath('tests'),
PosixPath('README.md'),
...] |
Thanks for the explanation - then the original explanation for B001 isn't ideal. I've added the opinionated rules above, including B001. B007 would actually be nice too if Ruff was smart enough to only include it if the target Python version was high enough - flake8 & bugbear can't do this, as they don't have a target Python setting like Ruff has. |
Thanks for discussing; agreed that the bugbear README's B901 explanation isn't great. One note: looks like you meant B901-B907 in your latest comment and edits to the checklist (rather than B001-B007, which are actually already implemented in Ruff). |
Not sure where best to discuss it, but I've been looking at B030. How closely do we need to implement the solution from the base package? I looked over bugbear's code for B030 and maybe found a bug in it(?), so not sure whether to implement the bug or try to make ruff a little smarter than that (with big emphasis on little smarter). |
These opinionated bugbear rules are not implemented in Ruff yet: - B950 (line too long), using equivalent: E501. - B902 (invalid first arg for method), using equivalent: N804, N805 See: astral-sh/ruff#2954 These pycodestyle rules are not implemented in Ruff yet and have no equivalent rules: - E303 (too many blank lines), - E302 (Expected 2 blank lines, found 0) - E301 (Expected 1 blank line, found 0) Previously ignored for "pydavinci/wrappers/settings/components.py". Since they don't exist, we don't need to ignore them, but this will apply package wide. Black should handle formatting these correctly anyway.
I'll take up the last rule (B031) 🚀 |
@charliermarsh it looks like this issue was closed prematurely with the merging of the B031 rule PR. There are still 4 opinionated rules listed in the description which haven't yet been implemented. |
Let's open a new issue for those. To me the goal here was to regain parity based on bugbear updates. I will mention that the challenge with including opinionated rules is that they'll be enabled by default by any users that have For me, right now that means potentially being a bit more picky about which of the opinionated rules we include... |
Sounds good, and that makes sense 👍 I opened a separate issue to track the opinionated rules here #3758 |
IIUC, Flake8 makes all X9** opt-in only, so you have to do |
## Summary This PR implements the rule B901, which is part of the opinionated rules of `flake8-bugbear`. This rule seems to be desired in `ruff` as per #3758 and #2954 (comment). ## Test Plan As this PR was made closely following the [CONTRIBUTING.md](https://github.com/astral-sh/ruff/blob/8a25531a7144fd4a6b62c54efde1ef28e2dc18c4/CONTRIBUTING.md), it tests using the snapshot approach, that is described there. ## Sources The implementation is inspired by [the original implementation in the `flake8-bugbear` repository](https://github.com/PyCQA/flake8-bugbear/blob/d1aec4cbef7c4a49147c428b7e4a97e497b5d163/bugbear.py#L1092). The error message and [test file](https://github.com/PyCQA/flake8-bugbear/blob/d1aec4cbef7c4a49147c428b7e4a97e497b5d163/tests/b901.py) where also copied from there. The documentation I came up with on my own and needs improvement. Maybe the example given in #2954 (comment) could be used, but maybe they are too complex, I'm not sure. ## Open Questions - [ ] Documentation. (See above.) - [x] Can I access the parent in a visitor? The [original implementation](https://github.com/PyCQA/flake8-bugbear/blob/d1aec4cbef7c4a49147c428b7e4a97e497b5d163/bugbear.py#L1100) references the `yield` statement's parent to check if it is an expression statement. I didn't find a way to do this in `ruff` and used the `is_expresssion_statement` field on the visitor instead. What are your thoughts on this? Is it possible and / or desired to access the parent node here? - [x] Is `Option::is_some(...)` -> `...unwrap()` the right thing to do? Referring to [this piece of code](https://github.com/tobb10001/ruff/blob/9d5a280f71103ef33df5676d00a6c68c601261ac/crates/ruff_linter/src/rules/flake8_bugbear/rules/return_x_in_generator.rs?plain=1#L91-L96). From my understanding, the `.unwrap()` is safe, because it is checked that `return_` is not `None`. However, I feel like I missed a more elegant solution that does both in one. ## Other I don't know a lot about this rule, I just implemented it because I found it in a https://github.com/astral-sh/ruff/labels/good%20first%20issue. I'm new to Rust, so any constructive critisism is appreciated. --------- Co-authored-by: Charlie Marsh <[email protected]>
Looks like bugbear has new rules:
Also, some of the B9 rules are nice if opted into explicitly and seem to be missing (B90x except
B901 (Python 2 related)& B907 which is nice but poorly implemented in bugbear) - only B904 is present.I don't actually need these for something specific, just noticed this due to an incorrect noqa and thought a tracking issue would be useful.
Opinionated checks:
return x
in a generator function. (Somewhat bad reasoning in description, talks about Python 2, see comments below.)dataclasses
nowadays.)visit_
function with no further call to avisit
function.The text was updated successfully, but these errors were encountered: