[flake8-async] Extend ASYNC230 to detect blocking pathlib I/O methods#19619
[flake8-async] Extend ASYNC230 to detect blocking pathlib I/O methods#19619aidandj wants to merge 5 commits intoastral-sh:mainfrom
flake8-async] Extend ASYNC230 to detect blocking pathlib I/O methods#19619Conversation
Add detection for pathlib's blocking I/O methods (read_text, read_bytes, write_text, write_bytes) in async functions, beyond just the open() method. Signed-off-by: Aidan Jensen <[email protected]>
ntBre
left a comment
There was a problem hiding this comment.
Thanks! This change makes sense to me, but I think we should preview-gate it since the rule itself is stable.
Otherwise I just had a couple of small nits.
| if attr.as_str() != "open" | ||
| && attr.as_str() != "read_text" | ||
| && attr.as_str() != "read_bytes" | ||
| && attr.as_str() != "write_text" | ||
| && attr.as_str() != "write_bytes" | ||
| { |
There was a problem hiding this comment.
I think we could use matches! here:
| if attr.as_str() != "open" | |
| && attr.as_str() != "read_text" | |
| && attr.as_str() != "read_bytes" | |
| && attr.as_str() != "write_text" | |
| && attr.as_str() != "write_bytes" | |
| { | |
| if !matches!(attr.as_str(), "open" | |
| | "read_text" | |
| | "read_bytes" | |
| | "write_text" | |
| | "write_bytes") | |
| { |
However, we will need two checks here for now because I think we should gate this behind preview since it's an expansion of a stable rule. You can see examples of these in preview.rs:
ruff/crates/ruff_linter/src/preview.rs
Lines 224 to 227 in d449c54
and references to those functions.
There was a problem hiding this comment.
Thanks for the matches suggestion. Rust newbie here, still learning.
I'll look into the preview stuff.
| def foo_sync(): | ||
| open("") | ||
|
|
||
|
|
There was a problem hiding this comment.
Can you revert this? It will make the snapshots a bit easier to review since it won't shift everything down :)
There was a problem hiding this comment.
Sorry, I kept trying to revert this but my formatter kept adding it back. I'll revert it again.
There was a problem hiding this comment.
No worries, I habitually hit my formatter binding and always have to hold back when modifying snapshots too.
flake8-async] Extend ASYNC230 to detect blocking pathlib I/O methods
Signed-off-by: Aidan Jensen <[email protected]>
Signed-off-by: Aidan Jensen <[email protected]>
Signed-off-by: Aidan Jensen <[email protected]>
|
I did a double check in the pathlib library and found I found a pattern of enabling preview tests in another file and copied that over, if there is a better method for preview tests let me know. It would be nice to tie them to those helper methods so that when you deleted the helper method you would know to move the test out of the preview call. Maybe that could be as simple as calling the helper function in the preview test to bring attention to it. Also, who's responsibility is it to take it out of preview? The PR author? Or the ruff team? |
Signed-off-by: Aidan Jensen <[email protected]>
We'll take it out of preview, following our versioning policy. Is this change in line with the upstream ASYNC rule? |
I should have mentioned this somewhere, but I looked into the upstream rule yesterday, and it looks like they only flag |
| 62 | async def func() -> None: | ||
| 63 | p = Path("foo").read_text() # ASYNC230 | ||
| | ^^^^^^^^^^^^^^^^^^^^^ ASYNC230 | ||
| | |
There was a problem hiding this comment.
The diagnostics here are fairly confusing as it's not clear to me where I'm calling open. Can we add a help text saying that read_text calls open internally`. We may also want to update the rule's documentation to mention the new (preview only behavior)
There was a problem hiding this comment.
Another option would be to simplify and just remove the mention of open. And just say blocking methods.
Considering Unlike other rules, the upstream async linter is very actively maintained. That makes it more likely that we'll run into conflicting rules. I tried to find a related issue or PR upstream but wasn't successful. @Zac-HD: Is this something that has come up with the async rules before? Is this a change you would be open to also make in |
|
I think this'd be the first time ruff was ahead of flake8-async, nice! How about we move this new logic to a new ASYNC233 code, and open an upstream issue to implement it / reserve the number? I think this is a much better experience for users updating their linter too, since they can use some temporary ignores without missing the current 230 issues. |
This seems reasonable. Let me know if there is consensus and I could take a stab at that as well |
|
Upstream issue opened! Practically speaking, if you're interested in implementing more rules I'd pretty strongly prefer pulling more into |
|
Thanks @Zac-HD
We're interested, it's just hard to prioritize with everything else going but we could mark some of those as help wanted (CC: @ntBre wdty?) A new code sounds good to me. But this may justify removing the exsting pathlib check from |
I don't think we have any preference between adding |
Sounds good to me! Thank y'all! |
|
Thanks again for working on this! I'll go ahead and close this PR for now as it's gotten stale, but feel free to open another one implementing a new ASYNC233 rule as discussed above. |
Summary
Add detection for pathlib's blocking I/O methods (
read_text,read_bytes,write_text,write_bytes) in async functions, beyond just theopen()method. Under the hood, these methods callopen, so they have the same issue thatopendoes.Test Plan
Added test cases to the existing ASYNC230 test suite and updated the snapshot.