-
Notifications
You must be signed in to change notification settings - Fork 1.6k
[refurb] Implement readlines_in_for lint (FURB129)
#9880
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
Merged
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Contributor
|
| code | total | + violation | - violation | + fix | - fix |
|---|---|---|---|---|---|
| FURB129 | 7 | 7 | 0 | 0 | 0 |
39871a2 to
b73a722
Compare
charliermarsh
approved these changes
Feb 13, 2024
Member
charliermarsh
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks! I added some extensions to our (basic) type inference system to support this.
66faaab to
eb5d049
Compare
eb5d049 to
0bd61b1
Compare
nkxxll
pushed a commit
to nkxxll/ruff
that referenced
this pull request
Mar 10, 2024
## Summary Implement [implicit readlines (FURB129)](https://github.com/dosisod/refurb/blob/master/refurb/checks/iterable/implicit_readlines.py) lint. ## Notes I need a help/an opinion about suggested implementations. This implementation differs from the original one from `refurb` in the following way. This implementation checks syntactically the call of the method with the name `readlines()` inside `for` {loop|generator expression}. The implementation from refurb also [checks](https://github.com/dosisod/refurb/blob/master/refurb/checks/iterable/implicit_readlines.py#L43) that callee is a variable with a type `io.TextIOWrapper` or `io.BufferedReader`. - I do not see a simple way to implement the same logic. - The best I can have is something like ```rust checker.semantic().binding(checker.semantic().resolve_name(attr_expr.value.as_name_expr()?)?).statement(checker.semantic()) ``` and analyze cases. But this will be not about types, but about guessing the type by assignment (or with) expression. - Also this logic has several false negatives, when the callee is not a variable, but the result of function call (e.g. `open(...)`). - On the other side, maybe it is good to lint this on other things, where this suggestion is not safe, and push the developers to change their interfaces to be less surprising, comparing with the standard library. - Anyway while the current implementation has false-positives (I mentioned some of them in the test) I marked the fixes to be unsafe.
dylwil3
added a commit
that referenced
this pull request
Apr 28, 2025
This PR promotes the fix applicability of [readlines-in-for (FURB129)](https://docs.astral.sh/ruff/rules/readlines-in-for/#readlines-in-for-furb129) to always safe. In the original PR (#9880), the author marked the rule as unsafe because Ruff's type inference couldn't quite guarantee that we had an `IOBase` object in hand. Some false positives were recorded in the test fixture. However, before the PR was merged, Charlie added the necessary type inference and the false positives went away. According to the [Python documentation](https://docs.python.org/3/library/io.html#io.IOBase), I believe this fix is safe for any proper implementation of `IOBase`: >[IOBase](https://docs.python.org/3/library/io.html#io.IOBase) (and its subclasses) supports the iterator protocol, meaning that an [IOBase](https://docs.python.org/3/library/io.html#io.IOBase) object can be iterated over yielding the lines in a stream. Lines are defined slightly differently depending on whether the stream is a binary stream (yielding bytes), or a text stream (yielding character strings). See [readline()](https://docs.python.org/3/library/io.html#io.IOBase.readline) below. and then in the [documentation for `readlines`](https://docs.python.org/3/library/io.html#io.IOBase.readlines): >Read and return a list of lines from the stream. hint can be specified to control the number of lines read: no more lines will be read if the total size (in bytes/characters) of all lines so far exceeds hint. [...] >Note that it’s already possible to iterate on file objects using for line in file: ... without calling file.readlines(). I believe that a careful reading of our [versioning policy](https://docs.astral.sh/ruff/versioning/#version-changes) requires that this change be deferred to a minor release - but please correct me if I'm wrong!
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Implement implicit readlines (FURB129) lint.
Notes
I need a help/an opinion about suggested implementations.
This implementation differs from the original one from
refurbin the following way. This implementation checks syntactically the call of the method with the namereadlines()insidefor{loop|generator expression}. The implementation from refurb also checks that callee is a variable with a typeio.TextIOWrapperorio.BufferedReader.and analyze cases. But this will be not about types, but about guessing the type by assignment (or with) expression.
open(...)).Test Plan
cargo test