Skip to content

Conversation

@PieterCK
Copy link
Contributor

@PieterCK PieterCK commented Sep 5, 2025

Summary

Adds a new rule to find and report use of os.path or pathlib.Path in
async functions.

Issue: #8451

Test Plan

Using cargo insta test

@PieterCK PieterCK force-pushed the add-rule-async-240-blocking-path-usage branch from bc9d2a8 to a16ea55 Compare September 5, 2025 10:18
@PieterCK PieterCK marked this pull request as ready for review September 5, 2025 10:24
@PieterCK PieterCK mentioned this pull request Sep 5, 2025
37 tasks
@ntBre
Copy link
Contributor

ntBre commented Sep 5, 2025

Thanks! We're pretty focused on the minor release this week, so I may not get a chance to review until next week. But this looks really good from a quick skim :)

@ntBre ntBre added rule Implementing or modifying a lint rule preview Related to preview mode features labels Sep 5, 2025
@ntBre ntBre self-requested a review September 5, 2025 12:53
@github-actions
Copy link
Contributor

github-actions bot commented Sep 5, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@PieterCK PieterCK force-pushed the add-rule-async-240-blocking-path-usage branch 4 times, most recently from 19b3ea6 to be73d44 Compare September 5, 2025 14:02
@PieterCK PieterCK marked this pull request as draft September 8, 2025 15:46
@PieterCK PieterCK force-pushed the add-rule-async-240-blocking-path-usage branch 3 times, most recently from 0950d6e to 20b5b46 Compare September 9, 2025 09:01
@PieterCK PieterCK changed the title [flake8-async] Implement blocking-path-method (ASYNC240). wip [flake8-async] Implement blocking-path-method (ASYNC240). Sep 9, 2025
Adds a new rule to find and report use of `os.path` or `pathlib.Path` in
async functions.
@PieterCK PieterCK force-pushed the add-rule-async-240-blocking-path-usage branch from 20b5b46 to c5b5f27 Compare September 9, 2025 12:46
@PieterCK PieterCK marked this pull request as ready for review September 9, 2025 13:04
@PieterCK

This comment was marked as outdated.

@PieterCK PieterCK changed the title wip [flake8-async] Implement blocking-path-method (ASYNC240). [flake8-async] Implement blocking-path-method (ASYNC240). Sep 9, 2025
@PieterCK PieterCK requested a review from amyreese September 10, 2025 06:19
@PieterCK
Copy link
Contributor Author

Bumping this PR for review again.

@ntBre
Copy link
Contributor

ntBre commented Sep 17, 2025

What's the best way to show new PR changes here?

I usually just push additional commits. That works better with GitHub's "Changes since your last review" button than comparing rebased commits. We always squash and merge PRs anyway. But it's not too big of a deal either way :)

I'll give this another look now!

Copy link
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you! This looks great to me overall, I just had a few minor comments. I especially liked the tests. They were really easy to read and review 😄

};

if check_type::<PathlibPathChecker>(binding, semantic) {
if maybe_calling_io_operation(attr.id.as_str()) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same attr as above right? I think we could do this check once before both the constructor and check_type checks, returning early if it's not one of the known attributes.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aha, good catch. I moved this a few checks above to just before the constructor check.

Comment on lines 921 to 929
traverse_union_and_optional(
&mut |inner_expr, _| {
if Self::is_pathlib_path_constructor(semantic, inner_expr) {
found = true;
}
},
semantic,
annotation,
);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do like having this check like in #20091, but I'm a little bit hesitant to add it here since it will affect other rules too. I would probably either revert this and accept that we miss option/union annotations for now, until we possibly update the TypeChecker infrastructure more generally in the future, or move this check into the rule itself, as @amyreese did for ASYNC212.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, for now I added a copy of PathlibPathChecker that has the traversing logic to this rule.

This also reverts back the changes made to `PathlibPathChecker` in the
previous commit.
@PieterCK PieterCK marked this pull request as draft September 18, 2025 11:41
@PieterCK PieterCK changed the title [flake8-async] Implement blocking-path-method (ASYNC240). [wip] [flake8-async] Implement blocking-path-method (ASYNC240). Sep 18, 2025
@PieterCK
Copy link
Contributor Author

PieterCK commented Sep 18, 2025

Thank you for doing another pass on this! Will post another comment once this is ready for review again.

@PieterCK PieterCK force-pushed the add-rule-async-240-blocking-path-usage branch from caedfa8 to c594fb8 Compare September 22, 2025 15:22
This commit contains changes addressing some code reviews:

- The `Violation::message` implementation doesn't mention that the
linter only look for blocking path methods and non-blocking methods are
allowed. I've tweaked the comments and added another code example of
async function using non-blocking os/pathlib path methods.

- The `is_calling_os_path_method` function could be simpler. I've used
the suggested implementation and pulled it out from the function since
it's only one line now.

- The logic to see if an expression is calling a method form the
pathlib.Path module could be simpler if it calls
`PathlibPathChecker::match_initializer` directly.

- The rule function can return early if `maybe_calling_io_operation`
returns false when checking the expressions attribute.
This commit contains changes addressing some code reviews:

- Updated `maybe_calling_io_operation` to have a more complete allow
list.

- ASYNC230 already handles `path.open()` case, so it is added to the
allow list. There is a new test for that.

- Fix typo.
Move the main rule implementation to just below the
`BlockingPathMethodInAsyncFunction` implementation.
@PieterCK PieterCK force-pushed the add-rule-async-240-blocking-path-usage branch from c594fb8 to f31d0b6 Compare September 22, 2025 15:26
@PieterCK PieterCK changed the title [wip] [flake8-async] Implement blocking-path-method (ASYNC240). [flake8-async] Implement blocking-path-method (ASYNC240). Sep 22, 2025
@PieterCK PieterCK marked this pull request as ready for review September 22, 2025 15:34
@PieterCK
Copy link
Contributor Author

@ntBre -- Marking this as ready for you to take a look again!

Copy link
Member

@amyreese amyreese left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

looks good to me!

Copy link
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, this looks good to me too! I just had one comment about moving the todo comment to a separate issue for a follow-up discussion.

Comment on lines 915 to 919
// match_annotation doesn't check `Path` in union
// or `Optional`.
// TODO: Once we have updated it to handle those
// cases, update `blocking_path_method.rs`(ASYNC240)
// to use this version of `PathlibPathChecker`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's good to record this TODO somewhere, but I'm kind of leaning toward opening a separate issue and deleting this comment. I feel like we should probably either always traverse unions or never traverse unions and apply that decision to all of our TypeCheckers rather than keep a mix of them.

Copy link
Contributor Author

@PieterCK PieterCK Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. This commit removes the comment, Remove comment on PathlibPathChecker.

Copy link
Contributor Author

@PieterCK PieterCK Sep 23, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And opened #20529 to keep track of this.

Copy link
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@ntBre ntBre changed the title [flake8-async] Implement blocking-path-method (ASYNC240). [flake8-async] Implement blocking-path-method (ASYNC240) Sep 23, 2025
@ntBre ntBre merged commit edb920b into astral-sh:main Sep 23, 2025
36 checks passed
@PieterCK
Copy link
Contributor Author

Awesome! Thank you

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

preview Related to preview mode features rule Implementing or modifying a lint rule

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants