Skip to content

Conversation

danparizher
Copy link
Contributor

Summary

Fixes #19437

Copy link
Contributor

github-actions bot commented Jul 20, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@ntBre ntBre added the rule Implementing or modifying a lint rule label Jul 20, 2025
@ntBre ntBre self-requested a review July 20, 2025 23:04
@ntBre ntBre changed the title [flake8_use_pathlib] Expand PTH201 to check all PurePath subclasses [flake8-use-pathlib] Expand PTH201 to check all PurePath subclasses Jul 20, 2025
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.

Thanks! I had one nit about the tests that will make this much easier to review, and then a suggestion about code reuse. I think factoring this out into a helper function would be fine for now, and then we could create a follow-up issue to check the other PTH rules.

Comment on lines 72 to 79
let is_pathlib = matches!(
segments,
[
"pathlib",
"Path" | "PurePath" | "PosixPath" | "PurePosixPath" | "WindowsPath" | "PureWindowsPath"
]
);
let is_packagepath = matches!(segments, ["importlib", "metadata", "PackagePath"]);
Copy link
Contributor

Choose a reason for hiding this comment

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

It seems we have a couple of different existing checks that are similar to this:

pub fn is_pathlib_path(binding: &Binding, semantic: &SemanticModel) -> bool {
check_type::<PathlibPathChecker>(binding, semantic)
}

which will check Bindings and includes all of these except PackagePath, and

pub(crate) fn is_pathlib_path_call(checker: &Checker, expr: &Expr) -> bool {
expr.as_call_expr().is_some_and(|expr_call| {
checker
.semantic()
.resolve_qualified_name(&expr_call.func)
.is_some_and(|name| matches!(name.segments(), ["pathlib", "Path"]))
})
}

which only checks for pathlib.Path. I don't think we can switch all of the current calls to one or the other, but we might at least want to factor this code into a helper function (is_pure_path_subclass maybe) so that we can use it in the other PTH rules, if appropriate.

cc @chirizxc who has been working on PTH autofixes

Comment on lines 10 to 14
_ = PosixPath(".")
_ = PurePosixPath(".")
_ = WindowsPath(".")
_ = PureWindowsPath(".")
_ = PackagePath(".")
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we move these and the new imports to the bottom of the file? Adding them here has created quite a large diff for a file that should mostly be the same.

@danparizher danparizher requested a review from ntBre July 30, 2025 00:52
@danparizher
Copy link
Contributor Author

It looks like the overall snapshot diff is still rather large because of the additional line from importing PackagePath. Would it be best to squish that onto one line in this case?

@ntBre
Copy link
Contributor

ntBre commented Jul 30, 2025

I would just move the new imports to the bottom too, with the new code. It's obviously not good Python style in general, but it works well for our tests :) Or we could split out a separate test file, that works too.

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.

Thanks!

@ntBre
Copy link
Contributor

ntBre commented Jul 30, 2025

It's a bit annoying, but I'm wondering if we need to preview-gate this. There aren't any new ecosystem hits, but it's still a pretty big expansion to the rule. I guess we should put it in preview, just to be safe.

@danparizher danparizher requested a review from ntBre July 31, 2025 00:48
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.

Looks good, just one nit about the test location.

@danparizher danparizher requested a review from ntBre July 31, 2025 23:13
@ntBre ntBre added the preview Related to preview mode features label Aug 1, 2025
@ntBre ntBre merged commit b3a26a5 into astral-sh:main Aug 1, 2025
36 checks passed
@danparizher danparizher deleted the fix-19437 branch August 1, 2025 02:37
dcreager added a commit that referenced this pull request Aug 1, 2025
* main: (39 commits)
  [ty] Initial test suite for `TypedDict` (#19686)
  [ty] Improve debuggability of protocol types (#19662)
  [ty] Simplify lifetime requirements for `PySlice` trait (#19687)
  [ty] Improve `isinstance()` truthiness analysis for generic types (#19668)
  [`refurb`] Make example error out-of-the-box (`FURB164`) (#19673)
  Fix link: unused_import.rs (#19648)
  [ty] Remove `Specialization::display` (full) (#19682)
  [ty] Remove `KnownModule::is_enum` (#19681)
  [ty] Support `__setitem__` and improve `__getitem__` related diagnostics (#19578)
  [ty] Sync vendored typeshed stubs (#19676)
  [`flake8-use-pathlib`] Expand `PTH201` to check all `PurePath` subclasses (#19440)
  [`refurb`] Make example error out-of-the-box (`FURB180`) (#19672)
  [`pyupgrade`] Prevent infinite loop with `I002` (`UP010`, `UP035`) (#19413)
  [ty] Improve the `Display` for generic `type[]` types (#19667)
  [ty] Refactor `TypeInferenceBuilder::infer_subscript_expression_types` (#19658)
  Fix tests on 32-bit architectures (#19652)
  [ty] Move `pandas-stubs` to bad.txt (#19659)
  [ty] Remove special casing for string-literal-in-tuple `__contains__` (#19642)
  Update pre-commit's `ruff` id (#19654)
  Update salsa (#19449)
  ...
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.

PTH201 should check all subclasses of PurePath
2 participants