Skip to content

[flake8-use-pathlib] Make PTH100 fix unsafe because it can change behavior#20100

Merged
ntBre merged 3 commits intoastral-sh:mainfrom
chirizxc:pth100
Aug 26, 2025
Merged

[flake8-use-pathlib] Make PTH100 fix unsafe because it can change behavior#20100
ntBre merged 3 commits intoastral-sh:mainfrom
chirizxc:pth100

Conversation

@chirizxc
Copy link
Contributor

@chirizxc chirizxc commented Aug 26, 2025

Summary

Fixes #20088

Test Plan

cargo nextest run flake8_use_pathlib

@github-actions
Copy link
Contributor

github-actions bot commented Aug 26, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

ℹ️ ecosystem check detected linter changes. (+0 -0 violations, +0 -208 fixes in 6 projects; 49 projects unchanged)

apache/airflow (+0 -0 violations, +0 -56 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview --select ALL

- airflow-core/docs/conf.py:330:29: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ airflow-core/docs/conf.py:330:29: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- airflow-core/src/airflow/config_templates/default_webserver_config.py:32:11: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ airflow-core/src/airflow/config_templates/default_webserver_config.py:32:11: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- airflow-core/src/airflow/utils/cli.py:224:18: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ airflow-core/src/airflow/utils/cli.py:224:18: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- airflow-core/src/airflow/utils/cli.py:363:15: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ airflow-core/src/airflow/utils/cli.py:363:15: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- airflow-core/src/airflow/utils/log/file_processor_handler.py:145:25: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ airflow-core/src/airflow/utils/log/file_processor_handler.py:145:25: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- airflow-core/tests/integration/otel/dags/otel_test_dag_with_pause_between_tasks.py:114:34: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ airflow-core/tests/integration/otel/dags/otel_test_dag_with_pause_between_tasks.py:114:34: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- airflow-core/tests/integration/otel/dags/otel_test_dag_with_pause_in_task.py:50:34: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
... 43 additional changes omitted for project

apache/superset (+0 -0 violations, +0 -10 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview --select ALL

- docker/pythonpath_dev/superset_config.py:124:21: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ docker/pythonpath_dev/superset_config.py:124:21: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/cypress_run.py:135:34: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/cypress_run.py:135:34: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- setup.py:23:12: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ setup.py:23:12: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- superset/cli/update.py:76:20: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ superset/cli/update.py:76:20: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- superset/translations/utils.py:27:23: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ superset/translations/utils.py:27:23: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`

bokeh/bokeh (+0 -0 violations, +0 -44 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview --select ALL

- scripts/sri.py:9:7: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/sri.py:9:7: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- src/bokeh/application/handlers/code_runner.py:182:39: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ src/bokeh/application/handlers/code_runner.py:182:39: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- src/bokeh/command/subcommands/serve.py:924:20: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ src/bokeh/command/subcommands/serve.py:924:20: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- src/bokeh/command/util.py:117:12: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ src/bokeh/command/util.py:117:12: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- src/bokeh/embed/bundle.py:277:21: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ src/bokeh/embed/bundle.py:277:21: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
... 34 additional changes omitted for project

latchbio/latch (+0 -0 violations, +0 -2 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview

- docs/source/conf.py:18:20: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ docs/source/conf.py:18:20: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`

milvus-io/pymilvus (+0 -0 violations, +0 -2 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview

- docs/source/conf.py:15:20: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ docs/source/conf.py:15:20: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`

zulip/zulip (+0 -0 violations, +0 -94 fixes)

ruff check --no-cache --exit-zero --ignore RUF9 --no-fix --output-format concise --preview --select ALL

- docs/conf.py:11:20: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ docs/conf.py:11:20: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- manage.py:7:28: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ manage.py:7:28: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/lib/check_rabbitmq_queue.py:10:62: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/lib/check_rabbitmq_queue.py:10:62: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/lib/clean_emoji_cache.py:6:62: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/lib/clean_emoji_cache.py:6:62: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/lib/clean_unused_caches.py:7:62: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/lib/clean_unused_caches.py:7:62: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/lib/puppet_cache.py:13:62: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/lib/puppet_cache.py:13:62: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/lib/queue_workers.py:5:60: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/lib/queue_workers.py:5:60: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/lib/setup_path.py:10:64: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/lib/setup_path.py:10:64: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/lib/setup_venv.py:5:62: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/lib/setup_venv.py:5:62: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/lib/sharding.py:9:60: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/lib/sharding.py:9:60: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
- scripts/lib/zulip_tools.py:562:19: PTH100 [*] `os.path.abspath()` should be replaced by `Path.resolve()`
+ scripts/lib/zulip_tools.py:562:19: PTH100 `os.path.abspath()` should be replaced by `Path.resolve()`
... 72 additional changes omitted for project

Changes by rule (1 rules affected)

code total + violation - violation + fix - fix
PTH100 208 0 0 0 208

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! Just a couple of small suggestions.

Comment on lines 43 to 47
/// This rule's fix is marked as unsafe if the replacement would remove comments attached to the original expression.
///
/// `Path.resolve()` resolves symlinks, while `os.path.abspath()` does not.
/// If preserving symlinks is important, you may need to use `Path.absolute()`.
/// The suggested autofix is marked as unsafe because it can change behavior.
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't think it's so important to mention the comment issue now that the rule is always unsafe. I'd probably say something like:

This rule's fix is always marked as unsafe because Path.resolve() resolves symlinks, while os.path.abspath() does not. If resolving symlinks is important, you may need to use Path.absolute(). However, Path.absolute() also does not remove any .. components in a path, unlike os.path.abspath() and Path.resolve(), so if that specific combination of behaviors is required, there's no existing pathlib alternative. See CPython issue #69200.

That's a bit wordy, so it could be nice to include @dscorbett's nice table from the issue instead, up to you.

Copy link
Contributor

Choose a reason for hiding this comment

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

I can't comment on the line below, but as I mentioned on the issue, we should also update the Correspondence between os and pathlib link below (#20088 (comment)). The new link is https://docs.python.org/3/library/pathlib.html#corresponding-tools

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It seems to me that if a fix is going to change behavior in any way, it's better to leave it as a unsafe

@ntBre ntBre added fixes Related to suggested fixes for violations preview Related to preview mode features labels Aug 26, 2025
@chirizxc
Copy link
Contributor Author

Should I change links in this PR in the same way in all PTH rules?

@chirizxc
Copy link
Contributor Author

I also see that there are many more functions in the table for which there are no rules and fixes, can we start adding them?

@ntBre
Copy link
Contributor

ntBre commented Aug 26, 2025

Should I change links in this PR in the same way in all PTH rules?

Sure, but let's do that in a follow-up documentation PR. I think this one is good to go now.

I also see that there are many more functions in the table for which there are no rules and fixes, can we start adding them?

I think we've implemented all of the rules in the upstream flake8-use-pathlib, and it's not a high priority to add more rules right now, so I don't think we need to exhaustively cover the table. You could open an issue to track interest in any of the ones we're missing, though, if you want!

@ntBre ntBre enabled auto-merge (squash) August 26, 2025 18:56
@ntBre ntBre merged commit f558bf7 into astral-sh:main Aug 26, 2025
34 checks passed
@chirizxc chirizxc deleted the pth100 branch August 26, 2025 19:09
ntBre pushed a commit that referenced this pull request Aug 26, 2025
…ndence between `os` and `pathlib` (#20103)

<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

Part of #20100 |
#20100 (comment)
carljm added a commit to leandrobbraga/ruff that referenced this pull request Aug 27, 2025
* main:
  [`ruff`] Preserve relative whitespace in multi-line expressions (`RUF033`) (astral-sh#19647)
  [ty] Optimize TDD atom ordering (astral-sh#20098)
  [`airflow`] Extend `AIR311` and `AIR312` rules (astral-sh#20082)
  [ty] Preserve qualifiers when accessing attributes on unions/intersections (astral-sh#20114)
  [ty] Fix the inferred interface of specialized generic protocols (astral-sh#19866)
  [ty] Infer slightly more precise types for comprehensions (astral-sh#20111)
  [ty] Add more tests for protocols (astral-sh#20095)
  [ty] don't eagerly unpack aliases in user-authored unions (astral-sh#20055)
  [`flake8-use-pathlib`] Update links to the table showing the correspondence between `os` and `pathlib` (astral-sh#20103)
  [`flake8-use-pathlib`] Make `PTH100` fix unsafe because it can change behavior (astral-sh#20100)
  [`flake8-use-pathlib`] Delete unused `Rule::OsSymlink` enabled check (astral-sh#20099)
  [ty] Add search paths info to unresolved import diagnostics (astral-sh#20040)
  [`flake8-logging-format`] Add auto-fix for f-string logging calls (`G004`) (astral-sh#19303)
  Add a `ScopeKind` for the `__class__` cell (astral-sh#20048)
  Fix incorrect D413 links in docstrings convention FAQ (astral-sh#20089)
  [ty] Refactor inlay hints structure to use separate parts (astral-sh#20052)
second-ed pushed a commit to second-ed/ruff that referenced this pull request Sep 9, 2025
… behavior (astral-sh#20100)

<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary
Fixes astral-sh#20088
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan

`cargo nextest run flake8_use_pathlib`

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
second-ed pushed a commit to second-ed/ruff that referenced this pull request Sep 9, 2025
…ndence between `os` and `pathlib` (astral-sh#20103)

<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title? (Please prefix
with `[ty]` for ty pull
  requests.)
- Does this pull request include references to any relevant issues?
-->

## Summary

Part of astral-sh#20100 |
astral-sh#20100 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fixes Related to suggested fixes for violations preview Related to preview mode features

Projects

None yet

Development

Successfully merging this pull request may close these issues.

PTH100 unsafely converts os.path.abspath to pathlib.Path.resolve

2 participants