Compare commits
63 Commits
alex/renam
...
dcreager/h
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb95e49f96 | ||
|
|
0817a367e1 | ||
|
|
34b463d0a1 | ||
|
|
b438631de2 | ||
|
|
fbc211f344 | ||
|
|
1810b7c7a3 | ||
|
|
39353da108 | ||
|
|
7b88440fc2 | ||
|
|
8426cc6915 | ||
|
|
c08a2d6d65 | ||
|
|
6ddf729864 | ||
|
|
eaba8bc61e | ||
|
|
b18d213869 | ||
|
|
847e5f0c68 | ||
|
|
41772466d5 | ||
|
|
180d9de472 | ||
|
|
adf58b6c19 | ||
|
|
b683da8cde | ||
|
|
6d1c549c4e | ||
|
|
c574dff6b0 | ||
|
|
8c12fcb927 | ||
|
|
a2eaf7ce26 | ||
|
|
c3626a6d74 | ||
|
|
8221450cbc | ||
|
|
93db8833ef | ||
|
|
51d5bc709d | ||
|
|
0198857224 | ||
|
|
35b568dd6b | ||
|
|
35a5fd767d | ||
|
|
ac1b68c56d | ||
|
|
ab261360e4 | ||
|
|
19600ecd51 | ||
|
|
319f5be78c | ||
|
|
6370aea644 | ||
|
|
9d8e35b165 | ||
|
|
5c75e91abe | ||
|
|
6e73b859ef | ||
|
|
11e5ecb91e | ||
|
|
be47fbe0f6 | ||
|
|
37effea8fd | ||
|
|
3771f1567c | ||
|
|
6b94e620fe | ||
|
|
db80febb6b | ||
|
|
f95eb90951 | ||
|
|
1f1542db51 | ||
|
|
abbbe8f3af | ||
|
|
5d3a35e071 | ||
|
|
ff386b4797 | ||
|
|
1bf4969c96 | ||
|
|
2be73e9afb | ||
|
|
7a347c4370 | ||
|
|
70b23a4fd0 | ||
|
|
beea8cdfec | ||
|
|
416e956fe0 | ||
|
|
88c0ce3e38 | ||
|
|
8fb29eafb8 | ||
|
|
23ebfe7777 | ||
|
|
f90d6466e0 | ||
|
|
15af4c0a34 | ||
|
|
76f8e5b755 | ||
|
|
b66a3e7451 | ||
|
|
70f51e9648 | ||
|
|
9a29f7a339 |
24
.github/workflows/ci.yaml
vendored
24
.github/workflows/ci.yaml
vendored
@@ -707,6 +707,24 @@ jobs:
|
||||
- run: cargo binstall --no-confirm cargo-shear
|
||||
- run: cargo shear
|
||||
|
||||
ty-completion-evaluation:
|
||||
name: "ty completion evaluation"
|
||||
runs-on: depot-ubuntu-22.04-16
|
||||
needs: determine_changes
|
||||
if: ${{ needs.determine_changes.outputs.ty == 'true' || github.ref == 'refs/heads/main' }}
|
||||
steps:
|
||||
- uses: actions/checkout@08c6903cd8c0fde910a37f88322edcfb5dd907a8 # v5.0.0
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: astral-sh/setup-uv@d0cc045d04ccac9d8b7881df0226f9e82c39688e # v6.8.0
|
||||
- uses: Swatinem/rust-cache@f13886b937689c021905a6b90929199931d60db1 # v2.8.1
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- name: "Run ty completion evaluation"
|
||||
run: cargo run --release --package ty_completion_eval -- all --threshold 0.1 --tasks /tmp/completion-evaluation-tasks.csv
|
||||
- name: "Ensure there are no changes"
|
||||
run: diff ./crates/ty_completion_eval/completion-evaluation-tasks.csv /tmp/completion-evaluation-tasks.csv
|
||||
|
||||
python-package:
|
||||
name: "python package"
|
||||
runs-on: ubuntu-latest
|
||||
@@ -749,7 +767,7 @@ jobs:
|
||||
with:
|
||||
node-version: 22
|
||||
- name: "Cache pre-commit"
|
||||
uses: actions/cache@0400d5f644dc74513175e3cd8d07132dd4860809 # v4.2.4
|
||||
uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4.3.0
|
||||
with:
|
||||
path: ~/.cache/pre-commit
|
||||
key: pre-commit-${{ hashFiles('.pre-commit-config.yaml') }}
|
||||
@@ -911,7 +929,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: determine_changes
|
||||
if: |
|
||||
github.ref == 'refs/heads/main' ||
|
||||
github.ref == 'refs/heads/main' ||
|
||||
(needs.determine_changes.outputs.formatter == 'true' || needs.determine_changes.outputs.linter == 'true')
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
@@ -946,7 +964,7 @@ jobs:
|
||||
runs-on: ubuntu-24.04
|
||||
needs: determine_changes
|
||||
if: |
|
||||
github.ref == 'refs/heads/main' ||
|
||||
github.ref == 'refs/heads/main' ||
|
||||
needs.determine_changes.outputs.ty == 'true'
|
||||
timeout-minutes: 20
|
||||
steps:
|
||||
|
||||
@@ -16,7 +16,8 @@ exclude: |
|
||||
crates/ruff_python_formatter/resources/.*|
|
||||
crates/ruff_python_formatter/tests/snapshots/.*|
|
||||
crates/ruff_python_resolver/resources/.*|
|
||||
crates/ruff_python_resolver/tests/snapshots/.*
|
||||
crates/ruff_python_resolver/tests/snapshots/.*|
|
||||
crates/ty_completion_eval/truth/.*
|
||||
)$
|
||||
|
||||
repos:
|
||||
|
||||
@@ -1,5 +1,21 @@
|
||||
# Breaking Changes
|
||||
|
||||
## 0.14.0
|
||||
|
||||
- **Default to Python 3.10**
|
||||
|
||||
Ruff now defaults to Python 3.10 instead of 3.9 if no explicit Python
|
||||
version is configured using [`ruff.target-version`](https://docs.astral.sh/ruff/settings/#target-version)
|
||||
or [`project.requires-python`](https://packaging.python.org/en/latest/guides/writing-pyproject-toml/#python-requires)
|
||||
([#20725](https://github.com/astral-sh/ruff/pull/20725))
|
||||
|
||||
- **Default to Python 3.14 for syntax errors**
|
||||
|
||||
Ruff will default to the _latest_ supported Python version (3.14) when
|
||||
checking for syntax errors without a Python version configured. The default
|
||||
in all other cases, like applying lint rules, remains at the minimum
|
||||
supported Python version (3.10).
|
||||
|
||||
## 0.13.0
|
||||
|
||||
- **Several rules can now add `from __future__ import annotations` automatically**
|
||||
|
||||
276
CHANGELOG.md
276
CHANGELOG.md
@@ -1,266 +1,46 @@
|
||||
# Changelog
|
||||
|
||||
## 0.13.3
|
||||
## 0.14.0
|
||||
|
||||
Released on 2025-10-02.
|
||||
|
||||
### Preview features
|
||||
|
||||
- Display diffs for `ruff format --check` and add support for different output formats ([#20443](https://github.com/astral-sh/ruff/pull/20443))
|
||||
- \[`pyflakes`\] Handle some common submodule import situations for `unused-import` (`F401`) ([#20200](https://github.com/astral-sh/ruff/pull/20200))
|
||||
- \[`ruff`\] Do not flag `%r` + `repr()` combinations (`RUF065`) ([#20600](https://github.com/astral-sh/ruff/pull/20600))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- \[`cli`\] Add conflict between `--add-noqa` and `--diff` options ([#20642](https://github.com/astral-sh/ruff/pull/20642))
|
||||
- \[`pylint`\] Exempt required imports from `PLR0402` ([#20381](https://github.com/astral-sh/ruff/pull/20381))
|
||||
- \[`pylint`\] Fix missing `max-nested-blocks` in settings display ([#20574](https://github.com/astral-sh/ruff/pull/20574))
|
||||
- \[`pyupgrade`\] Prevent infinite loop with `I002` and `UP026` ([#20634](https://github.com/astral-sh/ruff/pull/20634))
|
||||
|
||||
### Rule changes
|
||||
|
||||
- \[`flake8-simplify`\] Improve help message clarity (`SIM105`) ([#20548](https://github.com/astral-sh/ruff/pull/20548))
|
||||
|
||||
### Documentation
|
||||
|
||||
- Add the *The Basics* title back to CONTRIBUTING.md ([#20624](https://github.com/astral-sh/ruff/pull/20624))
|
||||
- Fixed documentation for try_consider_else ([#20587](https://github.com/astral-sh/ruff/pull/20587))
|
||||
- \[`isort`\] Clarify dependency between `order-by-type` and `case-sensitive` settings ([#20559](https://github.com/astral-sh/ruff/pull/20559))
|
||||
- \[`pylint`\] Clarify fix safety to include left-hand hashability (`PLR6201`) ([#20518](https://github.com/astral-sh/ruff/pull/20518))
|
||||
|
||||
### Other changes
|
||||
|
||||
- \[`playground`\] Fix quick fixes for empty ranges in playground ([#20599](https://github.com/astral-sh/ruff/pull/20599))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@TaKO8Ki](https://github.com/TaKO8Ki)
|
||||
- [@ntBre](https://github.com/ntBre)
|
||||
- [@dylwil3](https://github.com/dylwil3)
|
||||
- [@MichaReiser](https://github.com/MichaReiser)
|
||||
- [@danparizher](https://github.com/danparizher)
|
||||
- [@LilMonk](https://github.com/LilMonk)
|
||||
- [@mgiovani](https://github.com/mgiovani)
|
||||
- [@IDrokin117](https://github.com/IDrokin117)
|
||||
|
||||
## 0.13.2
|
||||
|
||||
Released on 2025-09-25.
|
||||
|
||||
### Preview features
|
||||
|
||||
- \[`flake8-async`\] Implement `blocking-path-method` (`ASYNC240`) ([#20264](https://github.com/astral-sh/ruff/pull/20264))
|
||||
- \[`flake8-bugbear`\] Implement `map-without-explicit-strict` (`B912`) ([#20429](https://github.com/astral-sh/ruff/pull/20429))
|
||||
- \[`flake8-bultins`\] Detect class-scope builtin shadowing in decorators, default args, and attribute initializers (`A003`) ([#20178](https://github.com/astral-sh/ruff/pull/20178))
|
||||
- \[`ruff`\] Implement `logging-eager-conversion` (`RUF065`) ([#19942](https://github.com/astral-sh/ruff/pull/19942))
|
||||
- Include `.pyw` files by default when linting and formatting ([#20458](https://github.com/astral-sh/ruff/pull/20458))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Deduplicate input paths ([#20105](https://github.com/astral-sh/ruff/pull/20105))
|
||||
- \[`flake8-comprehensions`\] Preserve trailing commas for single-element lists (`C409`) ([#19571](https://github.com/astral-sh/ruff/pull/19571))
|
||||
- \[`flake8-pyi`\] Avoid syntax error from conflict with `PIE790` (`PYI021`) ([#20010](https://github.com/astral-sh/ruff/pull/20010))
|
||||
- \[`flake8-simplify`\] Correct fix for positive `maxsplit` without separator (`SIM905`) ([#20056](https://github.com/astral-sh/ruff/pull/20056))
|
||||
- \[`pyupgrade`\] Fix `UP008` not to apply when `__class__` is a local variable ([#20497](https://github.com/astral-sh/ruff/pull/20497))
|
||||
- \[`ruff`\] Fix `B004` to skip invalid `hasattr`/`getattr` calls ([#20486](https://github.com/astral-sh/ruff/pull/20486))
|
||||
- \[`ruff`\] Replace `-nan` with `nan` when using the value to construct a `Decimal` (`FURB164` ) ([#20391](https://github.com/astral-sh/ruff/pull/20391))
|
||||
|
||||
### Documentation
|
||||
|
||||
- Add 'Finding ways to help' to CONTRIBUTING.md ([#20567](https://github.com/astral-sh/ruff/pull/20567))
|
||||
- Update import path to `ruff-wasm-web` ([#20539](https://github.com/astral-sh/ruff/pull/20539))
|
||||
- \[`flake8-bandit`\] Clarify the supported hashing functions (`S324`) ([#20534](https://github.com/astral-sh/ruff/pull/20534))
|
||||
|
||||
### Other changes
|
||||
|
||||
- \[`playground`\] Allow hover quick fixes to appear for overlapping diagnostics ([#20527](https://github.com/astral-sh/ruff/pull/20527))
|
||||
- \[`playground`\] Fix non‑BMP code point handling in quick fixes and markers ([#20526](https://github.com/astral-sh/ruff/pull/20526))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@BurntSushi](https://github.com/BurntSushi)
|
||||
- [@mtshiba](https://github.com/mtshiba)
|
||||
- [@second-ed](https://github.com/second-ed)
|
||||
- [@danparizher](https://github.com/danparizher)
|
||||
- [@ShikChen](https://github.com/ShikChen)
|
||||
- [@PieterCK](https://github.com/PieterCK)
|
||||
- [@GDYendell](https://github.com/GDYendell)
|
||||
- [@RazerM](https://github.com/RazerM)
|
||||
- [@TaKO8Ki](https://github.com/TaKO8Ki)
|
||||
- [@amyreese](https://github.com/amyreese)
|
||||
- [@ntbre](https://github.com/ntBre)
|
||||
- [@MichaReiser](https://github.com/MichaReiser)
|
||||
|
||||
## 0.13.1
|
||||
|
||||
Released on 2025-09-18.
|
||||
|
||||
### Preview features
|
||||
|
||||
- \[`flake8-simplify`\] Detect unnecessary `None` default for additional key expression types (`SIM910`) ([#20343](https://github.com/astral-sh/ruff/pull/20343))
|
||||
- \[`flake8-use-pathlib`\] Add fix for `PTH123` ([#20169](https://github.com/astral-sh/ruff/pull/20169))
|
||||
- \[`flake8-use-pathlib`\] Fix `PTH101`, `PTH104`, `PTH105`, `PTH121` fixes ([#20143](https://github.com/astral-sh/ruff/pull/20143))
|
||||
- \[`flake8-use-pathlib`\] Make `PTH111` fix unsafe because it can change behavior ([#20215](https://github.com/astral-sh/ruff/pull/20215))
|
||||
- \[`pycodestyle`\] Fix `E301` to only trigger for functions immediately within a class ([#19768](https://github.com/astral-sh/ruff/pull/19768))
|
||||
- \[`refurb`\] Mark `single-item-membership-test` fix as always unsafe (`FURB171`) ([#20279](https://github.com/astral-sh/ruff/pull/20279))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Handle t-strings for token-based rules and suppression comments ([#20357](https://github.com/astral-sh/ruff/pull/20357))
|
||||
- \[`flake8-bandit`\] Fix truthiness: dict-only `**` displays not truthy for `shell` (`S602`, `S604`, `S609`) ([#20177](https://github.com/astral-sh/ruff/pull/20177))
|
||||
- \[`flake8-simplify`\] Fix diagnostic to show correct method name for `str.rsplit` calls (`SIM905`) ([#20459](https://github.com/astral-sh/ruff/pull/20459))
|
||||
- \[`flynt`\] Use triple quotes for joined raw strings with newlines (`FLY002`) ([#20197](https://github.com/astral-sh/ruff/pull/20197))
|
||||
- \[`pyupgrade`\] Fix false positive when class name is shadowed by local variable (`UP008`) ([#20427](https://github.com/astral-sh/ruff/pull/20427))
|
||||
- \[`pyupgrade`\] Prevent infinite loop with `I002` and `UP026` ([#20327](https://github.com/astral-sh/ruff/pull/20327))
|
||||
- \[`ruff`\] Recognize t-strings, generators, and lambdas in `invalid-index-type` (`RUF016`) ([#20213](https://github.com/astral-sh/ruff/pull/20213))
|
||||
|
||||
### Rule changes
|
||||
|
||||
- \[`RUF102`\] Respect rule redirects in invalid rule code detection ([#20245](https://github.com/astral-sh/ruff/pull/20245))
|
||||
- \[`flake8-bugbear`\] Mark the fix for `unreliable-callable-check` as always unsafe (`B004`) ([#20318](https://github.com/astral-sh/ruff/pull/20318))
|
||||
- \[`ruff`\] Allow dataclass attribute value instantiation from nested frozen dataclass (`RUF009`) ([#20352](https://github.com/astral-sh/ruff/pull/20352))
|
||||
|
||||
### CLI
|
||||
|
||||
- Add fixes to `output-format=sarif` ([#20300](https://github.com/astral-sh/ruff/pull/20300))
|
||||
- Treat panics as fatal diagnostics, sort panics last ([#20258](https://github.com/astral-sh/ruff/pull/20258))
|
||||
|
||||
### Documentation
|
||||
|
||||
- \[`ruff`\] Add `analyze.string-imports-min-dots` to settings ([#20375](https://github.com/astral-sh/ruff/pull/20375))
|
||||
- Update README.md with Albumentations new repository URL ([#20415](https://github.com/astral-sh/ruff/pull/20415))
|
||||
|
||||
### Other changes
|
||||
|
||||
- Bump MSRV to Rust 1.88 ([#20470](https://github.com/astral-sh/ruff/pull/20470))
|
||||
- Enable inline noqa for multiline strings in playground ([#20442](https://github.com/astral-sh/ruff/pull/20442))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@chirizxc](https://github.com/chirizxc)
|
||||
- [@danparizher](https://github.com/danparizher)
|
||||
- [@IDrokin117](https://github.com/IDrokin117)
|
||||
- [@amyreese](https://github.com/amyreese)
|
||||
- [@AlexWaygood](https://github.com/AlexWaygood)
|
||||
- [@dylwil3](https://github.com/dylwil3)
|
||||
- [@njhearp](https://github.com/njhearp)
|
||||
- [@woodruffw](https://github.com/woodruffw)
|
||||
- [@dcreager](https://github.com/dcreager)
|
||||
- [@TaKO8Ki](https://github.com/TaKO8Ki)
|
||||
- [@BurntSushi](https://github.com/BurntSushi)
|
||||
- [@salahelfarissi](https://github.com/salahelfarissi)
|
||||
- [@MichaReiser](https://github.com/MichaReiser)
|
||||
|
||||
## 0.13.0
|
||||
|
||||
Check out the [blog post](https://astral.sh/blog/ruff-v0.13.0) for a migration
|
||||
guide and overview of the changes!
|
||||
Released on 2025-10-07.
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- **Several rules can now add `from __future__ import annotations` automatically**
|
||||
|
||||
`TC001`, `TC002`, `TC003`, `RUF013`, and `UP037` now add `from __future__ import annotations` as part of their fixes when the
|
||||
`lint.future-annotations` setting is enabled. This allows the rules to move
|
||||
more imports into `TYPE_CHECKING` blocks (`TC001`, `TC002`, and `TC003`),
|
||||
use PEP 604 union syntax on Python versions before 3.10 (`RUF013`), and
|
||||
unquote more annotations (`UP037`).
|
||||
|
||||
- **Full module paths are now used to verify first-party modules**
|
||||
|
||||
Ruff now checks that the full path to a module exists on disk before
|
||||
categorizing it as a first-party import. This change makes first-party
|
||||
import detection more accurate, helping to avoid false positives on local
|
||||
directories with the same name as a third-party dependency, for example. See
|
||||
the [FAQ
|
||||
section](https://docs.astral.sh/ruff/faq/#how-does-ruff-determine-which-of-my-imports-are-first-party-third-party-etc) on import categorization for more details.
|
||||
|
||||
- **Deprecated rules must now be selected by exact rule code**
|
||||
|
||||
Ruff will no longer activate deprecated rules selected by their group name
|
||||
or prefix. As noted below, the two remaining deprecated rules were also
|
||||
removed in this release, so this won't affect any current rules, but it will
|
||||
still affect any deprecations in the future.
|
||||
|
||||
- **The deprecated macOS configuration directory fallback has been removed**
|
||||
|
||||
Ruff will no longer look for a user-level configuration file at
|
||||
`~/Library/Application Support/ruff/ruff.toml` on macOS. This feature was
|
||||
deprecated in v0.5 in favor of using the [XDG
|
||||
specification](https://specifications.freedesktop.org/basedir-spec/latest/)
|
||||
(usually resolving to `~/.config/ruff/ruff.toml`), like on Linux. The
|
||||
fallback and accompanying deprecation warning have now been removed.
|
||||
|
||||
### Removed Rules
|
||||
|
||||
The following rules have been removed:
|
||||
|
||||
- [`pandas-df-variable-name`](https://docs.astral.sh/ruff/rules/pandas-df-variable-name) (`PD901`)
|
||||
- [`non-pep604-isinstance`](https://docs.astral.sh/ruff/rules/non-pep604-isinstance) (`UP038`)
|
||||
|
||||
### Stabilization
|
||||
|
||||
The following rules have been stabilized and are no longer in preview:
|
||||
|
||||
- [`airflow-dag-no-schedule-argument`](https://docs.astral.sh/ruff/rules/airflow-dag-no-schedule-argument)
|
||||
(`AIR002`)
|
||||
- [`airflow3-removal`](https://docs.astral.sh/ruff/rules/airflow3-removal) (`AIR301`)
|
||||
- [`airflow3-moved-to-provider`](https://docs.astral.sh/ruff/rules/airflow3-moved-to-provider)
|
||||
(`AIR302`)
|
||||
- [`airflow3-suggested-update`](https://docs.astral.sh/ruff/rules/airflow3-suggested-update)
|
||||
(`AIR311`)
|
||||
- [`airflow3-suggested-to-move-to-provider`](https://docs.astral.sh/ruff/rules/airflow3-suggested-to-move-to-provider)
|
||||
(`AIR312`)
|
||||
- [`long-sleep-not-forever`](https://docs.astral.sh/ruff/rules/long-sleep-not-forever) (`ASYNC116`)
|
||||
- [`f-string-number-format`](https://docs.astral.sh/ruff/rules/f-string-number-format) (`FURB116`)
|
||||
- [`os-symlink`](https://docs.astral.sh/ruff/rules/os-symlink) (`PTH211`)
|
||||
- [`generic-not-last-base-class`](https://docs.astral.sh/ruff/rules/generic-not-last-base-class)
|
||||
(`PYI059`)
|
||||
- [`redundant-none-literal`](https://docs.astral.sh/ruff/rules/redundant-none-literal) (`PYI061`)
|
||||
- [`pytest-raises-ambiguous-pattern`](https://docs.astral.sh/ruff/rules/pytest-raises-ambiguous-pattern)
|
||||
(`RUF043`)
|
||||
- [`unused-unpacked-variable`](https://docs.astral.sh/ruff/rules/unused-unpacked-variable)
|
||||
(`RUF059`)
|
||||
- [`useless-class-metaclass-type`](https://docs.astral.sh/ruff/rules/useless-class-metaclass-type)
|
||||
(`UP050`)
|
||||
|
||||
The following behaviors have been stabilized:
|
||||
|
||||
- [`assert-raises-exception`](https://docs.astral.sh/ruff/rules/assert-raises-exception) (`B017`)
|
||||
now checks for direct calls to `unittest.TestCase.assert_raises` and `pytest.raises` instead of
|
||||
only the context manager forms.
|
||||
- [`missing-trailing-comma`](https://docs.astral.sh/ruff/rules/missing-trailing-comma) (`COM812`)
|
||||
and [`prohibited-trailing-comma`](https://docs.astral.sh/ruff/rules/prohibited-trailing-comma)
|
||||
(`COM819`) now check for trailing commas in PEP 695 type parameter lists.
|
||||
- [`raw-string-in-exception`](https://docs.astral.sh/ruff/rules/raw-string-in-exception) (`EM101`)
|
||||
now also checks for byte strings in exception messages.
|
||||
- [`invalid-mock-access`](https://docs.astral.sh/ruff/rules/invalid-mock-access) (`PGH005`) now
|
||||
checks for `AsyncMock` methods like `not_awaited` in addition to the synchronous variants.
|
||||
- [`useless-import-alias`](https://docs.astral.sh/ruff/rules/useless-import-alias) (`PLC0414`) no
|
||||
longer applies to `__init__.py` files, where it conflicted with one of the suggested fixes for
|
||||
[`unused-import`](https://docs.astral.sh/ruff/rules/unused-import) (`F401`).
|
||||
- [`bidirectional-unicode`](https://docs.astral.sh/ruff/rules/bidirectional-unicode) (`PLE2502`) now
|
||||
also checks for U+061C (Arabic Letter Mark).
|
||||
- The fix for
|
||||
[`multiple-with-statements`](https://docs.astral.sh/ruff/rules/multiple-with-statements)
|
||||
(`SIM117`) is now marked as always safe.
|
||||
- Update default and latest Python versions for 3.14 ([#20725](https://github.com/astral-sh/ruff/pull/20725))
|
||||
|
||||
### Preview features
|
||||
|
||||
- \[`pyupgrade`\] Enable `UP043` in stub files ([#20027](https://github.com/astral-sh/ruff/pull/20027))
|
||||
- \[`flake8-bugbear`\] Include certain guaranteed-mutable expressions: tuples, generators, and assignment expressions (`B006`) ([#20024](https://github.com/astral-sh/ruff/pull/20024))
|
||||
- \[`refurb`\] Add fixes for `FURB101` and `FURB103` ([#20520](https://github.com/astral-sh/ruff/pull/20520))
|
||||
- \[`ruff`\] Extend `FA102` with listed PEP 585-compatible APIs ([#20659](https://github.com/astral-sh/ruff/pull/20659))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- \[`pyupgrade`\] Apply `UP008` only when the `__class__` cell exists ([#19424](https://github.com/astral-sh/ruff/pull/19424))
|
||||
- \[`ruff`\] Fix empty f-string detection in `in-empty-collection` (`RUF060`) ([#20249](https://github.com/astral-sh/ruff/pull/20249))
|
||||
|
||||
### Server
|
||||
|
||||
- Add support for using uv as an alternative formatter backend ([#19665](https://github.com/astral-sh/ruff/pull/19665))
|
||||
- \[`flake8-annotations`\] Fix return type annotations to handle shadowed builtin symbols (`ANN201`, `ANN202`, `ANN204`, `ANN205`, `ANN206`) ([#20612](https://github.com/astral-sh/ruff/pull/20612))
|
||||
- \[`flynt`\] Fix f-string quoting for mixed quote joiners (`FLY002`) ([#20662](https://github.com/astral-sh/ruff/pull/20662))
|
||||
- \[`isort`\] Fix inserting required imports before future imports (`I002`) ([#20676](https://github.com/astral-sh/ruff/pull/20676))
|
||||
- \[`ruff`\] Handle argfile expansion errors gracefully ([#20691](https://github.com/astral-sh/ruff/pull/20691))
|
||||
- \[`ruff`\] Skip `RUF051` if `else`/`elif` block is present ([#20705](https://github.com/astral-sh/ruff/pull/20705))
|
||||
- \[`ruff`\] Improve handling of intermixed comments inside from-imports ([#20561](https://github.com/astral-sh/ruff/pull/20561))
|
||||
|
||||
### Documentation
|
||||
|
||||
- \[`pep8-naming`\] Fix formatting of `__all__` (`N816`) ([#20301](https://github.com/astral-sh/ruff/pull/20301))
|
||||
- \[`flake8-comprehensions`\] Clarify fix safety documentation (`C413`) ([#20640](https://github.com/astral-sh/ruff/pull/20640))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@danparizher](https://github.com/danparizher)
|
||||
- [@terror](https://github.com/terror)
|
||||
- [@TaKO8Ki](https://github.com/TaKO8Ki)
|
||||
- [@ntBre](https://github.com/ntBre)
|
||||
- [@njhearp](https://github.com/njhearp)
|
||||
- [@amyreese](https://github.com/amyreese)
|
||||
- [@IDrokin117](https://github.com/IDrokin117)
|
||||
- [@chirizxc](https://github.com/chirizxc)
|
||||
|
||||
## 0.13.x
|
||||
|
||||
See [changelogs/0.13.x](./changelogs/0.13.x.md)
|
||||
|
||||
## 0.12.x
|
||||
|
||||
|
||||
@@ -321,10 +321,16 @@ them to [PyPI](https://pypi.org/project/ruff/).
|
||||
Ruff follows the [semver](https://semver.org/) versioning standard. However, as pre-1.0 software,
|
||||
even patch releases may contain [non-backwards-compatible changes](https://semver.org/#spec-item-4).
|
||||
|
||||
### Creating a new release
|
||||
### Installing tools
|
||||
|
||||
1. Install `uv`: `curl -LsSf https://astral.sh/uv/install.sh | sh`
|
||||
|
||||
1. Install `npm`: `brew install npm` or similar
|
||||
|
||||
### Creating a new release
|
||||
|
||||
Commit each step of this process separately for easier review.
|
||||
|
||||
1. Run `./scripts/release.sh`; this command will:
|
||||
|
||||
- Generate a temporary virtual environment with `rooster`
|
||||
@@ -337,6 +343,7 @@ even patch releases may contain [non-backwards-compatible changes](https://semve
|
||||
|
||||
- Often labels will be missing from pull requests they will need to be manually organized into the proper section
|
||||
- Changes should be edited to be user-facing descriptions, avoiding internal details
|
||||
- Square brackets (eg, `[ruff]` project name) will be automatically escaped by `pre-commit`
|
||||
|
||||
Additionally, for minor releases:
|
||||
|
||||
@@ -376,13 +383,13 @@ even patch releases may contain [non-backwards-compatible changes](https://semve
|
||||
|
||||
1. Verify the GitHub release:
|
||||
|
||||
1. The Changelog should match the content of `CHANGELOG.md`
|
||||
1. Append the contributors from the `scripts/release.sh` script
|
||||
1. The changelog should match the content of `CHANGELOG.md`
|
||||
|
||||
1. If needed, [update the schemastore](https://github.com/astral-sh/ruff/blob/main/scripts/update_schemastore.py).
|
||||
|
||||
1. One can determine if an update is needed when
|
||||
`git diff old-version-tag new-version-tag -- ruff.schema.json` returns a non-empty diff.
|
||||
1. Run `uv run --only-dev --no-sync scripts/update_schemastore.py --proto <https|ssh>`
|
||||
1. Once run successfully, you should follow the link in the output to create a PR.
|
||||
|
||||
1. If needed, update the [`ruff-lsp`](https://github.com/astral-sh/ruff-lsp) and
|
||||
|
||||
49
Cargo.lock
generated
49
Cargo.lock
generated
@@ -818,6 +818,27 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv"
|
||||
version = "1.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
|
||||
dependencies = [
|
||||
"csv-core",
|
||||
"itoa",
|
||||
"ryu",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "csv-core"
|
||||
version = "0.1.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctrlc"
|
||||
version = "3.5.0"
|
||||
@@ -2738,7 +2759,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.13.3"
|
||||
version = "0.14.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"argfile",
|
||||
@@ -2777,6 +2798,7 @@ dependencies = [
|
||||
"ruff_python_ast",
|
||||
"ruff_python_formatter",
|
||||
"ruff_python_parser",
|
||||
"ruff_python_trivia",
|
||||
"ruff_server",
|
||||
"ruff_source_file",
|
||||
"ruff_text_size",
|
||||
@@ -2994,7 +3016,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_linter"
|
||||
version = "0.13.3"
|
||||
version = "0.14.0"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"anyhow",
|
||||
@@ -3348,7 +3370,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_wasm"
|
||||
version = "0.13.3"
|
||||
version = "0.14.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"console_log",
|
||||
@@ -4227,6 +4249,26 @@ dependencies = [
|
||||
"ty_python_semantic",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ty_completion_eval"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bstr",
|
||||
"clap",
|
||||
"csv",
|
||||
"regex",
|
||||
"ruff_db",
|
||||
"ruff_text_size",
|
||||
"serde",
|
||||
"tempfile",
|
||||
"toml",
|
||||
"ty_ide",
|
||||
"ty_project",
|
||||
"ty_python_semantic",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ty_ide"
|
||||
version = "0.0.0"
|
||||
@@ -4418,6 +4460,7 @@ dependencies = [
|
||||
"thiserror 2.0.16",
|
||||
"toml",
|
||||
"tracing",
|
||||
"ty_ide",
|
||||
"ty_python_semantic",
|
||||
"ty_static",
|
||||
"ty_vendored",
|
||||
|
||||
@@ -43,6 +43,7 @@ ruff_workspace = { path = "crates/ruff_workspace" }
|
||||
|
||||
ty = { path = "crates/ty" }
|
||||
ty_combine = { path = "crates/ty_combine" }
|
||||
ty_completion_eval = { path = "crates/ty_completion_eval" }
|
||||
ty_ide = { path = "crates/ty_ide" }
|
||||
ty_project = { path = "crates/ty_project", default-features = false }
|
||||
ty_python_semantic = { path = "crates/ty_python_semantic" }
|
||||
@@ -69,6 +70,7 @@ camino = { version = "1.1.7" }
|
||||
clap = { version = "4.5.3", features = ["derive"] }
|
||||
clap_complete_command = { version = "0.6.0" }
|
||||
clearscreen = { version = "4.0.0" }
|
||||
csv = { version = "1.3.1" }
|
||||
divan = { package = "codspeed-divan-compat", version = "3.0.2" }
|
||||
codspeed-criterion-compat = { version = "3.0.2", default-features = false }
|
||||
colored = { version = "3.0.0" }
|
||||
@@ -203,7 +205,7 @@ wild = { version = "2" }
|
||||
zip = { version = "0.6.6", default-features = false }
|
||||
|
||||
[workspace.metadata.cargo-shear]
|
||||
ignored = ["getrandom", "ruff_options_metadata", "uuid", "get-size2"]
|
||||
ignored = ["getrandom", "ruff_options_metadata", "uuid", "get-size2", "ty_completion_eval"]
|
||||
|
||||
|
||||
[workspace.lints.rust]
|
||||
|
||||
@@ -148,8 +148,8 @@ curl -LsSf https://astral.sh/ruff/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/install.ps1 | iex"
|
||||
|
||||
# For a specific version.
|
||||
curl -LsSf https://astral.sh/ruff/0.13.3/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/0.13.3/install.ps1 | iex"
|
||||
curl -LsSf https://astral.sh/ruff/0.14.0/install.sh | sh
|
||||
powershell -c "irm https://astral.sh/ruff/0.14.0/install.ps1 | iex"
|
||||
```
|
||||
|
||||
You can also install Ruff via [Homebrew](https://formulae.brew.sh/formula/ruff), [Conda](https://anaconda.org/conda-forge/ruff),
|
||||
@@ -182,7 +182,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com/) hook via [`ruff
|
||||
```yaml
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: v0.13.3
|
||||
rev: v0.14.0
|
||||
hooks:
|
||||
# Run the linter.
|
||||
- id: ruff-check
|
||||
|
||||
263
changelogs/0.13.x.md
Normal file
263
changelogs/0.13.x.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# Changelog 0.13.x
|
||||
|
||||
## 0.13.0
|
||||
|
||||
Check out the [blog post](https://astral.sh/blog/ruff-v0.13.0) for a migration
|
||||
guide and overview of the changes!
|
||||
|
||||
### Breaking changes
|
||||
|
||||
- **Several rules can now add `from __future__ import annotations` automatically**
|
||||
|
||||
`TC001`, `TC002`, `TC003`, `RUF013`, and `UP037` now add `from __future__ import annotations` as part of their fixes when the
|
||||
`lint.future-annotations` setting is enabled. This allows the rules to move
|
||||
more imports into `TYPE_CHECKING` blocks (`TC001`, `TC002`, and `TC003`),
|
||||
use PEP 604 union syntax on Python versions before 3.10 (`RUF013`), and
|
||||
unquote more annotations (`UP037`).
|
||||
|
||||
- **Full module paths are now used to verify first-party modules**
|
||||
|
||||
Ruff now checks that the full path to a module exists on disk before
|
||||
categorizing it as a first-party import. This change makes first-party
|
||||
import detection more accurate, helping to avoid false positives on local
|
||||
directories with the same name as a third-party dependency, for example. See
|
||||
the [FAQ
|
||||
section](https://docs.astral.sh/ruff/faq/#how-does-ruff-determine-which-of-my-imports-are-first-party-third-party-etc) on import categorization for more details.
|
||||
|
||||
- **Deprecated rules must now be selected by exact rule code**
|
||||
|
||||
Ruff will no longer activate deprecated rules selected by their group name
|
||||
or prefix. As noted below, the two remaining deprecated rules were also
|
||||
removed in this release, so this won't affect any current rules, but it will
|
||||
still affect any deprecations in the future.
|
||||
|
||||
- **The deprecated macOS configuration directory fallback has been removed**
|
||||
|
||||
Ruff will no longer look for a user-level configuration file at
|
||||
`~/Library/Application Support/ruff/ruff.toml` on macOS. This feature was
|
||||
deprecated in v0.5 in favor of using the [XDG
|
||||
specification](https://specifications.freedesktop.org/basedir-spec/latest/)
|
||||
(usually resolving to `~/.config/ruff/ruff.toml`), like on Linux. The
|
||||
fallback and accompanying deprecation warning have now been removed.
|
||||
|
||||
### Removed Rules
|
||||
|
||||
The following rules have been removed:
|
||||
|
||||
- [`pandas-df-variable-name`](https://docs.astral.sh/ruff/rules/pandas-df-variable-name) (`PD901`)
|
||||
- [`non-pep604-isinstance`](https://docs.astral.sh/ruff/rules/non-pep604-isinstance) (`UP038`)
|
||||
|
||||
### Stabilization
|
||||
|
||||
The following rules have been stabilized and are no longer in preview:
|
||||
|
||||
- [`airflow-dag-no-schedule-argument`](https://docs.astral.sh/ruff/rules/airflow-dag-no-schedule-argument)
|
||||
(`AIR002`)
|
||||
- [`airflow3-removal`](https://docs.astral.sh/ruff/rules/airflow3-removal) (`AIR301`)
|
||||
- [`airflow3-moved-to-provider`](https://docs.astral.sh/ruff/rules/airflow3-moved-to-provider)
|
||||
(`AIR302`)
|
||||
- [`airflow3-suggested-update`](https://docs.astral.sh/ruff/rules/airflow3-suggested-update)
|
||||
(`AIR311`)
|
||||
- [`airflow3-suggested-to-move-to-provider`](https://docs.astral.sh/ruff/rules/airflow3-suggested-to-move-to-provider)
|
||||
(`AIR312`)
|
||||
- [`long-sleep-not-forever`](https://docs.astral.sh/ruff/rules/long-sleep-not-forever) (`ASYNC116`)
|
||||
- [`f-string-number-format`](https://docs.astral.sh/ruff/rules/f-string-number-format) (`FURB116`)
|
||||
- [`os-symlink`](https://docs.astral.sh/ruff/rules/os-symlink) (`PTH211`)
|
||||
- [`generic-not-last-base-class`](https://docs.astral.sh/ruff/rules/generic-not-last-base-class)
|
||||
(`PYI059`)
|
||||
- [`redundant-none-literal`](https://docs.astral.sh/ruff/rules/redundant-none-literal) (`PYI061`)
|
||||
- [`pytest-raises-ambiguous-pattern`](https://docs.astral.sh/ruff/rules/pytest-raises-ambiguous-pattern)
|
||||
(`RUF043`)
|
||||
- [`unused-unpacked-variable`](https://docs.astral.sh/ruff/rules/unused-unpacked-variable)
|
||||
(`RUF059`)
|
||||
- [`useless-class-metaclass-type`](https://docs.astral.sh/ruff/rules/useless-class-metaclass-type)
|
||||
(`UP050`)
|
||||
|
||||
The following behaviors have been stabilized:
|
||||
|
||||
- [`assert-raises-exception`](https://docs.astral.sh/ruff/rules/assert-raises-exception) (`B017`)
|
||||
now checks for direct calls to `unittest.TestCase.assert_raises` and `pytest.raises` instead of
|
||||
only the context manager forms.
|
||||
- [`missing-trailing-comma`](https://docs.astral.sh/ruff/rules/missing-trailing-comma) (`COM812`)
|
||||
and [`prohibited-trailing-comma`](https://docs.astral.sh/ruff/rules/prohibited-trailing-comma)
|
||||
(`COM819`) now check for trailing commas in PEP 695 type parameter lists.
|
||||
- [`raw-string-in-exception`](https://docs.astral.sh/ruff/rules/raw-string-in-exception) (`EM101`)
|
||||
now also checks for byte strings in exception messages.
|
||||
- [`invalid-mock-access`](https://docs.astral.sh/ruff/rules/invalid-mock-access) (`PGH005`) now
|
||||
checks for `AsyncMock` methods like `not_awaited` in addition to the synchronous variants.
|
||||
- [`useless-import-alias`](https://docs.astral.sh/ruff/rules/useless-import-alias) (`PLC0414`) no
|
||||
longer applies to `__init__.py` files, where it conflicted with one of the suggested fixes for
|
||||
[`unused-import`](https://docs.astral.sh/ruff/rules/unused-import) (`F401`).
|
||||
- [`bidirectional-unicode`](https://docs.astral.sh/ruff/rules/bidirectional-unicode) (`PLE2502`) now
|
||||
also checks for U+061C (Arabic Letter Mark).
|
||||
- The fix for
|
||||
[`multiple-with-statements`](https://docs.astral.sh/ruff/rules/multiple-with-statements)
|
||||
(`SIM117`) is now marked as always safe.
|
||||
|
||||
### Preview features
|
||||
|
||||
- \[`pyupgrade`\] Enable `UP043` in stub files ([#20027](https://github.com/astral-sh/ruff/pull/20027))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- \[`pyupgrade`\] Apply `UP008` only when the `__class__` cell exists ([#19424](https://github.com/astral-sh/ruff/pull/19424))
|
||||
- \[`ruff`\] Fix empty f-string detection in `in-empty-collection` (`RUF060`) ([#20249](https://github.com/astral-sh/ruff/pull/20249))
|
||||
|
||||
### Server
|
||||
|
||||
- Add support for using uv as an alternative formatter backend ([#19665](https://github.com/astral-sh/ruff/pull/19665))
|
||||
|
||||
### Documentation
|
||||
|
||||
- \[`pep8-naming`\] Fix formatting of `__all__` (`N816`) ([#20301](https://github.com/astral-sh/ruff/pull/20301))
|
||||
|
||||
## 0.13.1
|
||||
|
||||
Released on 2025-09-18.
|
||||
|
||||
### Preview features
|
||||
|
||||
- \[`flake8-simplify`\] Detect unnecessary `None` default for additional key expression types (`SIM910`) ([#20343](https://github.com/astral-sh/ruff/pull/20343))
|
||||
- \[`flake8-use-pathlib`\] Add fix for `PTH123` ([#20169](https://github.com/astral-sh/ruff/pull/20169))
|
||||
- \[`flake8-use-pathlib`\] Fix `PTH101`, `PTH104`, `PTH105`, `PTH121` fixes ([#20143](https://github.com/astral-sh/ruff/pull/20143))
|
||||
- \[`flake8-use-pathlib`\] Make `PTH111` fix unsafe because it can change behavior ([#20215](https://github.com/astral-sh/ruff/pull/20215))
|
||||
- \[`pycodestyle`\] Fix `E301` to only trigger for functions immediately within a class ([#19768](https://github.com/astral-sh/ruff/pull/19768))
|
||||
- \[`refurb`\] Mark `single-item-membership-test` fix as always unsafe (`FURB171`) ([#20279](https://github.com/astral-sh/ruff/pull/20279))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Handle t-strings for token-based rules and suppression comments ([#20357](https://github.com/astral-sh/ruff/pull/20357))
|
||||
- \[`flake8-bandit`\] Fix truthiness: dict-only `**` displays not truthy for `shell` (`S602`, `S604`, `S609`) ([#20177](https://github.com/astral-sh/ruff/pull/20177))
|
||||
- \[`flake8-simplify`\] Fix diagnostic to show correct method name for `str.rsplit` calls (`SIM905`) ([#20459](https://github.com/astral-sh/ruff/pull/20459))
|
||||
- \[`flynt`\] Use triple quotes for joined raw strings with newlines (`FLY002`) ([#20197](https://github.com/astral-sh/ruff/pull/20197))
|
||||
- \[`pyupgrade`\] Fix false positive when class name is shadowed by local variable (`UP008`) ([#20427](https://github.com/astral-sh/ruff/pull/20427))
|
||||
- \[`pyupgrade`\] Prevent infinite loop with `I002` and `UP026` ([#20327](https://github.com/astral-sh/ruff/pull/20327))
|
||||
- \[`ruff`\] Recognize t-strings, generators, and lambdas in `invalid-index-type` (`RUF016`) ([#20213](https://github.com/astral-sh/ruff/pull/20213))
|
||||
|
||||
### Rule changes
|
||||
|
||||
- \[`RUF102`\] Respect rule redirects in invalid rule code detection ([#20245](https://github.com/astral-sh/ruff/pull/20245))
|
||||
- \[`flake8-bugbear`\] Mark the fix for `unreliable-callable-check` as always unsafe (`B004`) ([#20318](https://github.com/astral-sh/ruff/pull/20318))
|
||||
- \[`ruff`\] Allow dataclass attribute value instantiation from nested frozen dataclass (`RUF009`) ([#20352](https://github.com/astral-sh/ruff/pull/20352))
|
||||
|
||||
### CLI
|
||||
|
||||
- Add fixes to `output-format=sarif` ([#20300](https://github.com/astral-sh/ruff/pull/20300))
|
||||
- Treat panics as fatal diagnostics, sort panics last ([#20258](https://github.com/astral-sh/ruff/pull/20258))
|
||||
|
||||
### Documentation
|
||||
|
||||
- \[`ruff`\] Add `analyze.string-imports-min-dots` to settings ([#20375](https://github.com/astral-sh/ruff/pull/20375))
|
||||
- Update README.md with Albumentations new repository URL ([#20415](https://github.com/astral-sh/ruff/pull/20415))
|
||||
|
||||
### Other changes
|
||||
|
||||
- Bump MSRV to Rust 1.88 ([#20470](https://github.com/astral-sh/ruff/pull/20470))
|
||||
- Enable inline noqa for multiline strings in playground ([#20442](https://github.com/astral-sh/ruff/pull/20442))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@chirizxc](https://github.com/chirizxc)
|
||||
- [@danparizher](https://github.com/danparizher)
|
||||
- [@IDrokin117](https://github.com/IDrokin117)
|
||||
- [@amyreese](https://github.com/amyreese)
|
||||
- [@AlexWaygood](https://github.com/AlexWaygood)
|
||||
- [@dylwil3](https://github.com/dylwil3)
|
||||
- [@njhearp](https://github.com/njhearp)
|
||||
- [@woodruffw](https://github.com/woodruffw)
|
||||
- [@dcreager](https://github.com/dcreager)
|
||||
- [@TaKO8Ki](https://github.com/TaKO8Ki)
|
||||
- [@BurntSushi](https://github.com/BurntSushi)
|
||||
- [@salahelfarissi](https://github.com/salahelfarissi)
|
||||
- [@MichaReiser](https://github.com/MichaReiser)
|
||||
|
||||
## 0.13.2
|
||||
|
||||
Released on 2025-09-25.
|
||||
|
||||
### Preview features
|
||||
|
||||
- \[`flake8-async`\] Implement `blocking-path-method` (`ASYNC240`) ([#20264](https://github.com/astral-sh/ruff/pull/20264))
|
||||
- \[`flake8-bugbear`\] Implement `map-without-explicit-strict` (`B912`) ([#20429](https://github.com/astral-sh/ruff/pull/20429))
|
||||
- \[`flake8-bultins`\] Detect class-scope builtin shadowing in decorators, default args, and attribute initializers (`A003`) ([#20178](https://github.com/astral-sh/ruff/pull/20178))
|
||||
- \[`ruff`\] Implement `logging-eager-conversion` (`RUF065`) ([#19942](https://github.com/astral-sh/ruff/pull/19942))
|
||||
- Include `.pyw` files by default when linting and formatting ([#20458](https://github.com/astral-sh/ruff/pull/20458))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- Deduplicate input paths ([#20105](https://github.com/astral-sh/ruff/pull/20105))
|
||||
- \[`flake8-comprehensions`\] Preserve trailing commas for single-element lists (`C409`) ([#19571](https://github.com/astral-sh/ruff/pull/19571))
|
||||
- \[`flake8-pyi`\] Avoid syntax error from conflict with `PIE790` (`PYI021`) ([#20010](https://github.com/astral-sh/ruff/pull/20010))
|
||||
- \[`flake8-simplify`\] Correct fix for positive `maxsplit` without separator (`SIM905`) ([#20056](https://github.com/astral-sh/ruff/pull/20056))
|
||||
- \[`pyupgrade`\] Fix `UP008` not to apply when `__class__` is a local variable ([#20497](https://github.com/astral-sh/ruff/pull/20497))
|
||||
- \[`ruff`\] Fix `B004` to skip invalid `hasattr`/`getattr` calls ([#20486](https://github.com/astral-sh/ruff/pull/20486))
|
||||
- \[`ruff`\] Replace `-nan` with `nan` when using the value to construct a `Decimal` (`FURB164` ) ([#20391](https://github.com/astral-sh/ruff/pull/20391))
|
||||
|
||||
### Documentation
|
||||
|
||||
- Add 'Finding ways to help' to CONTRIBUTING.md ([#20567](https://github.com/astral-sh/ruff/pull/20567))
|
||||
- Update import path to `ruff-wasm-web` ([#20539](https://github.com/astral-sh/ruff/pull/20539))
|
||||
- \[`flake8-bandit`\] Clarify the supported hashing functions (`S324`) ([#20534](https://github.com/astral-sh/ruff/pull/20534))
|
||||
|
||||
### Other changes
|
||||
|
||||
- \[`playground`\] Allow hover quick fixes to appear for overlapping diagnostics ([#20527](https://github.com/astral-sh/ruff/pull/20527))
|
||||
- \[`playground`\] Fix non‑BMP code point handling in quick fixes and markers ([#20526](https://github.com/astral-sh/ruff/pull/20526))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@BurntSushi](https://github.com/BurntSushi)
|
||||
- [@mtshiba](https://github.com/mtshiba)
|
||||
- [@second-ed](https://github.com/second-ed)
|
||||
- [@danparizher](https://github.com/danparizher)
|
||||
- [@ShikChen](https://github.com/ShikChen)
|
||||
- [@PieterCK](https://github.com/PieterCK)
|
||||
- [@GDYendell](https://github.com/GDYendell)
|
||||
- [@RazerM](https://github.com/RazerM)
|
||||
- [@TaKO8Ki](https://github.com/TaKO8Ki)
|
||||
- [@amyreese](https://github.com/amyreese)
|
||||
- [@ntbre](https://github.com/ntBre)
|
||||
- [@MichaReiser](https://github.com/MichaReiser)
|
||||
|
||||
## 0.13.3
|
||||
|
||||
Released on 2025-10-02.
|
||||
|
||||
### Preview features
|
||||
|
||||
- Display diffs for `ruff format --check` and add support for different output formats ([#20443](https://github.com/astral-sh/ruff/pull/20443))
|
||||
- \[`pyflakes`\] Handle some common submodule import situations for `unused-import` (`F401`) ([#20200](https://github.com/astral-sh/ruff/pull/20200))
|
||||
- \[`ruff`\] Do not flag `%r` + `repr()` combinations (`RUF065`) ([#20600](https://github.com/astral-sh/ruff/pull/20600))
|
||||
|
||||
### Bug fixes
|
||||
|
||||
- \[`cli`\] Add conflict between `--add-noqa` and `--diff` options ([#20642](https://github.com/astral-sh/ruff/pull/20642))
|
||||
- \[`pylint`\] Exempt required imports from `PLR0402` ([#20381](https://github.com/astral-sh/ruff/pull/20381))
|
||||
- \[`pylint`\] Fix missing `max-nested-blocks` in settings display ([#20574](https://github.com/astral-sh/ruff/pull/20574))
|
||||
- \[`pyupgrade`\] Prevent infinite loop with `I002` and `UP026` ([#20634](https://github.com/astral-sh/ruff/pull/20634))
|
||||
|
||||
### Rule changes
|
||||
|
||||
- \[`flake8-simplify`\] Improve help message clarity (`SIM105`) ([#20548](https://github.com/astral-sh/ruff/pull/20548))
|
||||
|
||||
### Documentation
|
||||
|
||||
- Add the *The Basics* title back to CONTRIBUTING.md ([#20624](https://github.com/astral-sh/ruff/pull/20624))
|
||||
- Fixed documentation for try_consider_else ([#20587](https://github.com/astral-sh/ruff/pull/20587))
|
||||
- \[`isort`\] Clarify dependency between `order-by-type` and `case-sensitive` settings ([#20559](https://github.com/astral-sh/ruff/pull/20559))
|
||||
- \[`pylint`\] Clarify fix safety to include left-hand hashability (`PLR6201`) ([#20518](https://github.com/astral-sh/ruff/pull/20518))
|
||||
|
||||
### Other changes
|
||||
|
||||
- \[`playground`\] Fix quick fixes for empty ranges in playground ([#20599](https://github.com/astral-sh/ruff/pull/20599))
|
||||
|
||||
### Contributors
|
||||
|
||||
- [@TaKO8Ki](https://github.com/TaKO8Ki)
|
||||
- [@ntBre](https://github.com/ntBre)
|
||||
- [@dylwil3](https://github.com/dylwil3)
|
||||
- [@MichaReiser](https://github.com/MichaReiser)
|
||||
- [@danparizher](https://github.com/danparizher)
|
||||
- [@LilMonk](https://github.com/LilMonk)
|
||||
- [@mgiovani](https://github.com/mgiovani)
|
||||
- [@IDrokin117](https://github.com/IDrokin117)
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.13.3"
|
||||
version = "0.14.0"
|
||||
publish = true
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
@@ -72,6 +72,7 @@ dunce = { workspace = true }
|
||||
indoc = { workspace = true }
|
||||
insta = { workspace = true, features = ["filters", "json"] }
|
||||
insta-cmd = { workspace = true }
|
||||
ruff_python_trivia = { workspace = true }
|
||||
tempfile = { workspace = true }
|
||||
test-case = { workspace = true }
|
||||
|
||||
|
||||
3654
crates/ruff/tests/cli/lint.rs
Normal file
3654
crates/ruff/tests/cli/lint.rs
Normal file
File diff suppressed because it is too large
Load Diff
177
crates/ruff/tests/cli/main.rs
Normal file
177
crates/ruff/tests/cli/main.rs
Normal file
@@ -0,0 +1,177 @@
|
||||
//! Test fixture utilities for ruff CLI tests
|
||||
//!
|
||||
//! The core concept is borrowed from ty/tests/cli/main.rs and can be extended
|
||||
//! with more functionality from there in the future if needed.
|
||||
|
||||
#![cfg(not(target_family = "wasm"))]
|
||||
|
||||
use anyhow::{Context as _, Result};
|
||||
use insta::internals::SettingsBindDropGuard;
|
||||
use insta_cmd::get_cargo_bin;
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
process::Command,
|
||||
};
|
||||
use tempfile::TempDir;
|
||||
|
||||
mod lint;
|
||||
|
||||
const BIN_NAME: &str = "ruff";
|
||||
|
||||
/// Creates a regex filter for replacing temporary directory paths in snapshots
|
||||
pub(crate) fn tempdir_filter(path: impl AsRef<str>) -> String {
|
||||
format!(r"{}[\\/]?", regex::escape(path.as_ref()))
|
||||
}
|
||||
|
||||
/// A test fixture for running ruff CLI tests with temporary directories and files.
|
||||
///
|
||||
/// This fixture provides:
|
||||
/// - Temporary directory management
|
||||
/// - File creation utilities
|
||||
/// - Proper snapshot filtering for cross-platform compatibility
|
||||
/// - Pre-configured ruff command creation
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// use crate::common::RuffTestFixture;
|
||||
///
|
||||
/// let fixture = RuffTestFixture::with_file("ruff.toml", "select = ['E']")?;
|
||||
/// let output = fixture.command().args(["check", "."]).output()?;
|
||||
/// ```
|
||||
pub(crate) struct CliTest {
|
||||
_temp_dir: TempDir,
|
||||
_settings_scope: SettingsBindDropGuard,
|
||||
project_dir: PathBuf,
|
||||
}
|
||||
|
||||
impl CliTest {
|
||||
/// Creates a new test fixture with an empty temporary directory.
|
||||
///
|
||||
/// This sets up:
|
||||
/// - A temporary directory that's automatically cleaned up
|
||||
/// - Insta snapshot filters for cross-platform path compatibility
|
||||
/// - Environment isolation for consistent test behavior
|
||||
pub(crate) fn new() -> Result<Self> {
|
||||
Self::with_settings(|_, settings| settings)
|
||||
}
|
||||
|
||||
pub(crate) fn with_settings(
|
||||
setup_settings: impl FnOnce(&Path, insta::Settings) -> insta::Settings,
|
||||
) -> Result<Self> {
|
||||
let temp_dir = TempDir::new()?;
|
||||
|
||||
// Canonicalize the tempdir path because macOS uses symlinks for tempdirs
|
||||
// and that doesn't play well with our snapshot filtering.
|
||||
// Simplify with dunce because otherwise we get UNC paths on Windows.
|
||||
let project_dir = dunce::simplified(
|
||||
&temp_dir
|
||||
.path()
|
||||
.canonicalize()
|
||||
.context("Failed to canonicalize project path")?,
|
||||
)
|
||||
.to_path_buf();
|
||||
|
||||
let mut settings = setup_settings(&project_dir, insta::Settings::clone_current());
|
||||
|
||||
settings.add_filter(&tempdir_filter(project_dir.to_str().unwrap()), "[TMP]/");
|
||||
settings.add_filter(r#"\\([\w&&[^nr"]]\w|\s|\.)"#, "/$1");
|
||||
settings.add_filter(r"(Panicked at) [^:]+:\d+:\d+", "$1 <location>");
|
||||
settings.add_filter(ruff_linter::VERSION, "[VERSION]");
|
||||
settings.add_filter(
|
||||
r#"The system cannot find the file specified."#,
|
||||
"No such file or directory",
|
||||
);
|
||||
|
||||
let settings_scope = settings.bind_to_scope();
|
||||
|
||||
Ok(Self {
|
||||
project_dir,
|
||||
_temp_dir: temp_dir,
|
||||
_settings_scope: settings_scope,
|
||||
})
|
||||
}
|
||||
|
||||
/// Creates a test fixture with a single file.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `path` - The relative path for the file
|
||||
/// * `content` - The content to write to the file
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// let fixture = RuffTestFixture::with_file("ruff.toml", "select = ['E']")?;
|
||||
/// ```
|
||||
pub(crate) fn with_file(path: impl AsRef<Path>, content: &str) -> Result<Self> {
|
||||
let fixture = Self::new()?;
|
||||
fixture.write_file(path, content)?;
|
||||
Ok(fixture)
|
||||
}
|
||||
|
||||
/// Ensures that the parent directory of a path exists.
|
||||
fn ensure_parent_directory(path: &Path) -> Result<()> {
|
||||
if let Some(parent) = path.parent() {
|
||||
fs::create_dir_all(parent)
|
||||
.with_context(|| format!("Failed to create directory `{}`", parent.display()))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Writes a file to the test directory.
|
||||
///
|
||||
/// Parent directories are created automatically if they don't exist.
|
||||
/// Content is dedented to remove common leading whitespace for cleaner test code.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `path` - The relative path for the file
|
||||
/// * `content` - The content to write to the file
|
||||
pub(crate) fn write_file(&self, path: impl AsRef<Path>, content: &str) -> Result<()> {
|
||||
let path = path.as_ref();
|
||||
let file_path = self.project_dir.join(path);
|
||||
|
||||
Self::ensure_parent_directory(&file_path)?;
|
||||
|
||||
let content = ruff_python_trivia::textwrap::dedent(content);
|
||||
fs::write(&file_path, content.as_ref())
|
||||
.with_context(|| format!("Failed to write file `{}`", file_path.display()))?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns the path to the test directory root.
|
||||
pub(crate) fn root(&self) -> &Path {
|
||||
&self.project_dir
|
||||
}
|
||||
|
||||
/// Creates a pre-configured ruff command for testing.
|
||||
///
|
||||
/// The command is set up with:
|
||||
/// - The correct ruff binary path
|
||||
/// - Working directory set to the test directory
|
||||
/// - Clean environment variables for consistent behavior
|
||||
///
|
||||
/// You can chain additional arguments and options as needed.
|
||||
///
|
||||
/// # Example
|
||||
///
|
||||
/// ```rust,no_run
|
||||
/// let output = fixture
|
||||
/// .command()
|
||||
/// .args(["check", "--select", "E"])
|
||||
/// .arg(".")
|
||||
/// .output()?;
|
||||
/// ```
|
||||
pub(crate) fn command(&self) -> Command {
|
||||
let mut command = Command::new(get_cargo_bin(BIN_NAME));
|
||||
command.current_dir(&self.project_dir);
|
||||
|
||||
// Unset all environment variables because they can affect test behavior.
|
||||
command.env_clear();
|
||||
|
||||
command
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
source: crates/ruff/tests/lint.rs
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
@@ -12,6 +12,7 @@ info:
|
||||
- "--target-version"
|
||||
- py39
|
||||
- input.py
|
||||
snapshot_kind: text
|
||||
---
|
||||
success: false
|
||||
exit_code: 1
|
||||
@@ -0,0 +1,288 @@
|
||||
---
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- check
|
||||
- "--no-cache"
|
||||
- "--output-format"
|
||||
- concise
|
||||
- "--show-settings"
|
||||
- test.py
|
||||
snapshot_kind: text
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Resolved settings for: "[TMP]/test.py"
|
||||
Settings path: "[TMP]/ruff.toml"
|
||||
|
||||
# General Settings
|
||||
cache_dir = "[TMP]/.ruff_cache"
|
||||
fix = false
|
||||
fix_only = false
|
||||
output_format = concise
|
||||
show_fixes = false
|
||||
unsafe_fixes = hint
|
||||
|
||||
# File Resolver Settings
|
||||
file_resolver.exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
file_resolver.extend_exclude = []
|
||||
file_resolver.force_exclude = false
|
||||
file_resolver.include = [
|
||||
"*.py",
|
||||
"*.pyi",
|
||||
"*.ipynb",
|
||||
"**/pyproject.toml",
|
||||
]
|
||||
file_resolver.extend_include = []
|
||||
file_resolver.respect_gitignore = true
|
||||
file_resolver.project_root = "[TMP]/"
|
||||
|
||||
# Linter Settings
|
||||
linter.exclude = []
|
||||
linter.project_root = "[TMP]/"
|
||||
linter.rules.enabled = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.rules.should_fix = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.per_file_ignores = {}
|
||||
linter.safety_table.forced_safe = []
|
||||
linter.safety_table.forced_unsafe = []
|
||||
linter.unresolved_target_version = 3.10
|
||||
linter.per_file_target_version = {}
|
||||
linter.preview = disabled
|
||||
linter.explicit_preview_rules = false
|
||||
linter.extension = ExtensionMapping({})
|
||||
linter.allowed_confusables = []
|
||||
linter.builtins = []
|
||||
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||
linter.external = []
|
||||
linter.ignore_init_module_imports = true
|
||||
linter.logger_objects = []
|
||||
linter.namespace_packages = []
|
||||
linter.src = [
|
||||
"[TMP]/",
|
||||
"[TMP]/src",
|
||||
]
|
||||
linter.tab_size = 4
|
||||
linter.line_length = 88
|
||||
linter.task_tags = [
|
||||
TODO,
|
||||
FIXME,
|
||||
XXX,
|
||||
]
|
||||
linter.typing_modules = []
|
||||
linter.typing_extensions = true
|
||||
|
||||
# Linter Plugins
|
||||
linter.flake8_annotations.mypy_init_return = false
|
||||
linter.flake8_annotations.suppress_dummy_args = false
|
||||
linter.flake8_annotations.suppress_none_returning = false
|
||||
linter.flake8_annotations.allow_star_arg_any = false
|
||||
linter.flake8_annotations.ignore_fully_untyped = false
|
||||
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/tmp,
|
||||
/var/tmp,
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
linter.flake8_copyright.min_file_size = 0
|
||||
linter.flake8_errmsg.max_string_length = 0
|
||||
linter.flake8_gettext.functions_names = [
|
||||
_,
|
||||
gettext,
|
||||
ngettext,
|
||||
]
|
||||
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||
linter.flake8_import_conventions.aliases = {
|
||||
altair = alt,
|
||||
holoviews = hv,
|
||||
matplotlib = mpl,
|
||||
matplotlib.pyplot = plt,
|
||||
networkx = nx,
|
||||
numpy = np,
|
||||
numpy.typing = npt,
|
||||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
linter.flake8_pytest_style.parametrize_values_type = list
|
||||
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||
linter.flake8_pytest_style.raises_require_match_for = [
|
||||
BaseException,
|
||||
Exception,
|
||||
ValueError,
|
||||
OSError,
|
||||
IOError,
|
||||
EnvironmentError,
|
||||
socket.error,
|
||||
]
|
||||
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||
linter.flake8_pytest_style.mark_parentheses = false
|
||||
linter.flake8_quotes.inline_quotes = double
|
||||
linter.flake8_quotes.multiline_quotes = double
|
||||
linter.flake8_quotes.docstring_quotes = double
|
||||
linter.flake8_quotes.avoid_escape = true
|
||||
linter.flake8_self.ignore_names = [
|
||||
_make,
|
||||
_asdict,
|
||||
_replace,
|
||||
_fields,
|
||||
_field_defaults,
|
||||
_name_,
|
||||
_value_,
|
||||
]
|
||||
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||
linter.flake8_tidy_imports.banned_api = {}
|
||||
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||
linter.flake8_type_checking.strict = false
|
||||
linter.flake8_type_checking.exempt_modules = [
|
||||
typing,
|
||||
typing_extensions,
|
||||
]
|
||||
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||
linter.flake8_type_checking.runtime_required_decorators = []
|
||||
linter.flake8_type_checking.quote_annotations = false
|
||||
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||
linter.isort.required_imports = []
|
||||
linter.isort.combine_as_imports = false
|
||||
linter.isort.force_single_line = false
|
||||
linter.isort.force_sort_within_sections = false
|
||||
linter.isort.detect_same_package = true
|
||||
linter.isort.case_sensitive = false
|
||||
linter.isort.force_wrap_aliases = false
|
||||
linter.isort.force_to_top = []
|
||||
linter.isort.known_modules = {}
|
||||
linter.isort.order_by_type = true
|
||||
linter.isort.relative_imports_order = furthest_to_closest
|
||||
linter.isort.single_line_exclusions = []
|
||||
linter.isort.split_on_trailing_comma = true
|
||||
linter.isort.classes = []
|
||||
linter.isort.constants = []
|
||||
linter.isort.variables = []
|
||||
linter.isort.no_lines_before = []
|
||||
linter.isort.lines_after_imports = -1
|
||||
linter.isort.lines_between_types = 0
|
||||
linter.isort.forced_separate = []
|
||||
linter.isort.section_order = [
|
||||
known { type = future },
|
||||
known { type = standard_library },
|
||||
known { type = third_party },
|
||||
known { type = first_party },
|
||||
known { type = local_folder },
|
||||
]
|
||||
linter.isort.default_section = known { type = third_party }
|
||||
linter.isort.no_sections = false
|
||||
linter.isort.from_first = false
|
||||
linter.isort.length_sort = false
|
||||
linter.isort.length_sort_straight = false
|
||||
linter.mccabe.max_complexity = 10
|
||||
linter.pep8_naming.ignore_names = [
|
||||
setUp,
|
||||
tearDown,
|
||||
setUpClass,
|
||||
tearDownClass,
|
||||
setUpModule,
|
||||
tearDownModule,
|
||||
asyncSetUp,
|
||||
asyncTearDown,
|
||||
setUpTestData,
|
||||
failureException,
|
||||
longMessage,
|
||||
maxDiff,
|
||||
]
|
||||
linter.pep8_naming.classmethod_decorators = []
|
||||
linter.pep8_naming.staticmethod_decorators = []
|
||||
linter.pycodestyle.max_line_length = 88
|
||||
linter.pycodestyle.max_doc_length = none
|
||||
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||
linter.pyflakes.extend_generics = []
|
||||
linter.pyflakes.allowed_unused_imports = []
|
||||
linter.pylint.allow_magic_value_types = [
|
||||
str,
|
||||
bytes,
|
||||
]
|
||||
linter.pylint.allow_dunder_method_names = []
|
||||
linter.pylint.max_args = 5
|
||||
linter.pylint.max_positional_args = 5
|
||||
linter.pylint.max_returns = 6
|
||||
linter.pylint.max_bool_expr = 5
|
||||
linter.pylint.max_branches = 12
|
||||
linter.pylint.max_statements = 50
|
||||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
formatter.unresolved_target_version = 3.10
|
||||
formatter.per_file_target_version = {}
|
||||
formatter.preview = disabled
|
||||
formatter.line_width = 88
|
||||
formatter.line_ending = auto
|
||||
formatter.indent_style = space
|
||||
formatter.indent_width = 4
|
||||
formatter.quote_style = double
|
||||
formatter.magic_trailing_comma = respect
|
||||
formatter.docstring_code_format = disabled
|
||||
formatter.docstring_code_line_width = dynamic
|
||||
|
||||
# Analyze Settings
|
||||
analyze.exclude = []
|
||||
analyze.preview = disabled
|
||||
analyze.target_version = 3.10
|
||||
analyze.string_imports = disabled
|
||||
analyze.extension = ExtensionMapping({})
|
||||
analyze.include_dependencies = {}
|
||||
|
||||
----- stderr -----
|
||||
@@ -0,0 +1,290 @@
|
||||
---
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- check
|
||||
- "--no-cache"
|
||||
- "--output-format"
|
||||
- concise
|
||||
- "--show-settings"
|
||||
- "--select"
|
||||
- UP007
|
||||
- test.py
|
||||
- "-"
|
||||
snapshot_kind: text
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Resolved settings for: "[TMP]/test.py"
|
||||
|
||||
# General Settings
|
||||
cache_dir = "[TMP]/.ruff_cache"
|
||||
fix = false
|
||||
fix_only = false
|
||||
output_format = concise
|
||||
show_fixes = false
|
||||
unsafe_fixes = hint
|
||||
|
||||
# File Resolver Settings
|
||||
file_resolver.exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
file_resolver.extend_exclude = []
|
||||
file_resolver.force_exclude = false
|
||||
file_resolver.include = [
|
||||
"*.py",
|
||||
"*.pyi",
|
||||
"*.ipynb",
|
||||
"**/pyproject.toml",
|
||||
]
|
||||
file_resolver.extend_include = []
|
||||
file_resolver.respect_gitignore = true
|
||||
file_resolver.project_root = "[TMP]/"
|
||||
|
||||
# Linter Settings
|
||||
linter.exclude = []
|
||||
linter.project_root = "[TMP]/"
|
||||
linter.rules.enabled = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.rules.should_fix = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.per_file_ignores = {}
|
||||
linter.safety_table.forced_safe = []
|
||||
linter.safety_table.forced_unsafe = []
|
||||
linter.unresolved_target_version = 3.11
|
||||
linter.per_file_target_version = {}
|
||||
linter.preview = disabled
|
||||
linter.explicit_preview_rules = false
|
||||
linter.extension = ExtensionMapping({})
|
||||
linter.allowed_confusables = []
|
||||
linter.builtins = []
|
||||
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||
linter.external = []
|
||||
linter.ignore_init_module_imports = true
|
||||
linter.logger_objects = []
|
||||
linter.namespace_packages = []
|
||||
linter.src = [
|
||||
"[TMP]/",
|
||||
"[TMP]/src",
|
||||
]
|
||||
linter.tab_size = 4
|
||||
linter.line_length = 88
|
||||
linter.task_tags = [
|
||||
TODO,
|
||||
FIXME,
|
||||
XXX,
|
||||
]
|
||||
linter.typing_modules = []
|
||||
linter.typing_extensions = true
|
||||
|
||||
# Linter Plugins
|
||||
linter.flake8_annotations.mypy_init_return = false
|
||||
linter.flake8_annotations.suppress_dummy_args = false
|
||||
linter.flake8_annotations.suppress_none_returning = false
|
||||
linter.flake8_annotations.allow_star_arg_any = false
|
||||
linter.flake8_annotations.ignore_fully_untyped = false
|
||||
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/tmp,
|
||||
/var/tmp,
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
linter.flake8_copyright.min_file_size = 0
|
||||
linter.flake8_errmsg.max_string_length = 0
|
||||
linter.flake8_gettext.functions_names = [
|
||||
_,
|
||||
gettext,
|
||||
ngettext,
|
||||
]
|
||||
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||
linter.flake8_import_conventions.aliases = {
|
||||
altair = alt,
|
||||
holoviews = hv,
|
||||
matplotlib = mpl,
|
||||
matplotlib.pyplot = plt,
|
||||
networkx = nx,
|
||||
numpy = np,
|
||||
numpy.typing = npt,
|
||||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
linter.flake8_pytest_style.parametrize_values_type = list
|
||||
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||
linter.flake8_pytest_style.raises_require_match_for = [
|
||||
BaseException,
|
||||
Exception,
|
||||
ValueError,
|
||||
OSError,
|
||||
IOError,
|
||||
EnvironmentError,
|
||||
socket.error,
|
||||
]
|
||||
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||
linter.flake8_pytest_style.mark_parentheses = false
|
||||
linter.flake8_quotes.inline_quotes = double
|
||||
linter.flake8_quotes.multiline_quotes = double
|
||||
linter.flake8_quotes.docstring_quotes = double
|
||||
linter.flake8_quotes.avoid_escape = true
|
||||
linter.flake8_self.ignore_names = [
|
||||
_make,
|
||||
_asdict,
|
||||
_replace,
|
||||
_fields,
|
||||
_field_defaults,
|
||||
_name_,
|
||||
_value_,
|
||||
]
|
||||
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||
linter.flake8_tidy_imports.banned_api = {}
|
||||
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||
linter.flake8_type_checking.strict = false
|
||||
linter.flake8_type_checking.exempt_modules = [
|
||||
typing,
|
||||
typing_extensions,
|
||||
]
|
||||
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||
linter.flake8_type_checking.runtime_required_decorators = []
|
||||
linter.flake8_type_checking.quote_annotations = false
|
||||
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||
linter.isort.required_imports = []
|
||||
linter.isort.combine_as_imports = false
|
||||
linter.isort.force_single_line = false
|
||||
linter.isort.force_sort_within_sections = false
|
||||
linter.isort.detect_same_package = true
|
||||
linter.isort.case_sensitive = false
|
||||
linter.isort.force_wrap_aliases = false
|
||||
linter.isort.force_to_top = []
|
||||
linter.isort.known_modules = {}
|
||||
linter.isort.order_by_type = true
|
||||
linter.isort.relative_imports_order = furthest_to_closest
|
||||
linter.isort.single_line_exclusions = []
|
||||
linter.isort.split_on_trailing_comma = true
|
||||
linter.isort.classes = []
|
||||
linter.isort.constants = []
|
||||
linter.isort.variables = []
|
||||
linter.isort.no_lines_before = []
|
||||
linter.isort.lines_after_imports = -1
|
||||
linter.isort.lines_between_types = 0
|
||||
linter.isort.forced_separate = []
|
||||
linter.isort.section_order = [
|
||||
known { type = future },
|
||||
known { type = standard_library },
|
||||
known { type = third_party },
|
||||
known { type = first_party },
|
||||
known { type = local_folder },
|
||||
]
|
||||
linter.isort.default_section = known { type = third_party }
|
||||
linter.isort.no_sections = false
|
||||
linter.isort.from_first = false
|
||||
linter.isort.length_sort = false
|
||||
linter.isort.length_sort_straight = false
|
||||
linter.mccabe.max_complexity = 10
|
||||
linter.pep8_naming.ignore_names = [
|
||||
setUp,
|
||||
tearDown,
|
||||
setUpClass,
|
||||
tearDownClass,
|
||||
setUpModule,
|
||||
tearDownModule,
|
||||
asyncSetUp,
|
||||
asyncTearDown,
|
||||
setUpTestData,
|
||||
failureException,
|
||||
longMessage,
|
||||
maxDiff,
|
||||
]
|
||||
linter.pep8_naming.classmethod_decorators = []
|
||||
linter.pep8_naming.staticmethod_decorators = []
|
||||
linter.pycodestyle.max_line_length = 88
|
||||
linter.pycodestyle.max_doc_length = none
|
||||
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||
linter.pyflakes.extend_generics = []
|
||||
linter.pyflakes.allowed_unused_imports = []
|
||||
linter.pylint.allow_magic_value_types = [
|
||||
str,
|
||||
bytes,
|
||||
]
|
||||
linter.pylint.allow_dunder_method_names = []
|
||||
linter.pylint.max_args = 5
|
||||
linter.pylint.max_positional_args = 5
|
||||
linter.pylint.max_returns = 6
|
||||
linter.pylint.max_bool_expr = 5
|
||||
linter.pylint.max_branches = 12
|
||||
linter.pylint.max_statements = 50
|
||||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
formatter.unresolved_target_version = 3.11
|
||||
formatter.per_file_target_version = {}
|
||||
formatter.preview = disabled
|
||||
formatter.line_width = 88
|
||||
formatter.line_ending = auto
|
||||
formatter.indent_style = space
|
||||
formatter.indent_width = 4
|
||||
formatter.quote_style = double
|
||||
formatter.magic_trailing_comma = respect
|
||||
formatter.docstring_code_format = disabled
|
||||
formatter.docstring_code_line_width = dynamic
|
||||
|
||||
# Analyze Settings
|
||||
analyze.exclude = []
|
||||
analyze.preview = disabled
|
||||
analyze.target_version = 3.11
|
||||
analyze.string_imports = disabled
|
||||
analyze.extension = ExtensionMapping({})
|
||||
analyze.include_dependencies = {}
|
||||
|
||||
----- stderr -----
|
||||
@@ -0,0 +1,292 @@
|
||||
---
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- check
|
||||
- "--no-cache"
|
||||
- "--output-format"
|
||||
- concise
|
||||
- "--preview"
|
||||
- "--show-settings"
|
||||
- "--select"
|
||||
- UP007
|
||||
- test.py
|
||||
- "-"
|
||||
snapshot_kind: text
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Resolved settings for: "[TMP]/test.py"
|
||||
|
||||
# General Settings
|
||||
cache_dir = "[TMP]/.ruff_cache"
|
||||
fix = false
|
||||
fix_only = false
|
||||
output_format = concise
|
||||
show_fixes = false
|
||||
unsafe_fixes = hint
|
||||
|
||||
# File Resolver Settings
|
||||
file_resolver.exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
file_resolver.extend_exclude = []
|
||||
file_resolver.force_exclude = false
|
||||
file_resolver.include = [
|
||||
"*.py",
|
||||
"*.pyi",
|
||||
"*.pyw",
|
||||
"*.ipynb",
|
||||
"**/pyproject.toml",
|
||||
]
|
||||
file_resolver.extend_include = []
|
||||
file_resolver.respect_gitignore = true
|
||||
file_resolver.project_root = "[TMP]/"
|
||||
|
||||
# Linter Settings
|
||||
linter.exclude = []
|
||||
linter.project_root = "[TMP]/"
|
||||
linter.rules.enabled = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.rules.should_fix = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.per_file_ignores = {}
|
||||
linter.safety_table.forced_safe = []
|
||||
linter.safety_table.forced_unsafe = []
|
||||
linter.unresolved_target_version = 3.11
|
||||
linter.per_file_target_version = {}
|
||||
linter.preview = enabled
|
||||
linter.explicit_preview_rules = false
|
||||
linter.extension = ExtensionMapping({})
|
||||
linter.allowed_confusables = []
|
||||
linter.builtins = []
|
||||
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||
linter.external = []
|
||||
linter.ignore_init_module_imports = true
|
||||
linter.logger_objects = []
|
||||
linter.namespace_packages = []
|
||||
linter.src = [
|
||||
"[TMP]/",
|
||||
"[TMP]/src",
|
||||
]
|
||||
linter.tab_size = 4
|
||||
linter.line_length = 88
|
||||
linter.task_tags = [
|
||||
TODO,
|
||||
FIXME,
|
||||
XXX,
|
||||
]
|
||||
linter.typing_modules = []
|
||||
linter.typing_extensions = true
|
||||
|
||||
# Linter Plugins
|
||||
linter.flake8_annotations.mypy_init_return = false
|
||||
linter.flake8_annotations.suppress_dummy_args = false
|
||||
linter.flake8_annotations.suppress_none_returning = false
|
||||
linter.flake8_annotations.allow_star_arg_any = false
|
||||
linter.flake8_annotations.ignore_fully_untyped = false
|
||||
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/tmp,
|
||||
/var/tmp,
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
linter.flake8_copyright.min_file_size = 0
|
||||
linter.flake8_errmsg.max_string_length = 0
|
||||
linter.flake8_gettext.functions_names = [
|
||||
_,
|
||||
gettext,
|
||||
ngettext,
|
||||
]
|
||||
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||
linter.flake8_import_conventions.aliases = {
|
||||
altair = alt,
|
||||
holoviews = hv,
|
||||
matplotlib = mpl,
|
||||
matplotlib.pyplot = plt,
|
||||
networkx = nx,
|
||||
numpy = np,
|
||||
numpy.typing = npt,
|
||||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
linter.flake8_pytest_style.parametrize_values_type = list
|
||||
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||
linter.flake8_pytest_style.raises_require_match_for = [
|
||||
BaseException,
|
||||
Exception,
|
||||
ValueError,
|
||||
OSError,
|
||||
IOError,
|
||||
EnvironmentError,
|
||||
socket.error,
|
||||
]
|
||||
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||
linter.flake8_pytest_style.mark_parentheses = false
|
||||
linter.flake8_quotes.inline_quotes = double
|
||||
linter.flake8_quotes.multiline_quotes = double
|
||||
linter.flake8_quotes.docstring_quotes = double
|
||||
linter.flake8_quotes.avoid_escape = true
|
||||
linter.flake8_self.ignore_names = [
|
||||
_make,
|
||||
_asdict,
|
||||
_replace,
|
||||
_fields,
|
||||
_field_defaults,
|
||||
_name_,
|
||||
_value_,
|
||||
]
|
||||
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||
linter.flake8_tidy_imports.banned_api = {}
|
||||
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||
linter.flake8_type_checking.strict = false
|
||||
linter.flake8_type_checking.exempt_modules = [
|
||||
typing,
|
||||
typing_extensions,
|
||||
]
|
||||
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||
linter.flake8_type_checking.runtime_required_decorators = []
|
||||
linter.flake8_type_checking.quote_annotations = false
|
||||
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||
linter.isort.required_imports = []
|
||||
linter.isort.combine_as_imports = false
|
||||
linter.isort.force_single_line = false
|
||||
linter.isort.force_sort_within_sections = false
|
||||
linter.isort.detect_same_package = true
|
||||
linter.isort.case_sensitive = false
|
||||
linter.isort.force_wrap_aliases = false
|
||||
linter.isort.force_to_top = []
|
||||
linter.isort.known_modules = {}
|
||||
linter.isort.order_by_type = true
|
||||
linter.isort.relative_imports_order = furthest_to_closest
|
||||
linter.isort.single_line_exclusions = []
|
||||
linter.isort.split_on_trailing_comma = true
|
||||
linter.isort.classes = []
|
||||
linter.isort.constants = []
|
||||
linter.isort.variables = []
|
||||
linter.isort.no_lines_before = []
|
||||
linter.isort.lines_after_imports = -1
|
||||
linter.isort.lines_between_types = 0
|
||||
linter.isort.forced_separate = []
|
||||
linter.isort.section_order = [
|
||||
known { type = future },
|
||||
known { type = standard_library },
|
||||
known { type = third_party },
|
||||
known { type = first_party },
|
||||
known { type = local_folder },
|
||||
]
|
||||
linter.isort.default_section = known { type = third_party }
|
||||
linter.isort.no_sections = false
|
||||
linter.isort.from_first = false
|
||||
linter.isort.length_sort = false
|
||||
linter.isort.length_sort_straight = false
|
||||
linter.mccabe.max_complexity = 10
|
||||
linter.pep8_naming.ignore_names = [
|
||||
setUp,
|
||||
tearDown,
|
||||
setUpClass,
|
||||
tearDownClass,
|
||||
setUpModule,
|
||||
tearDownModule,
|
||||
asyncSetUp,
|
||||
asyncTearDown,
|
||||
setUpTestData,
|
||||
failureException,
|
||||
longMessage,
|
||||
maxDiff,
|
||||
]
|
||||
linter.pep8_naming.classmethod_decorators = []
|
||||
linter.pep8_naming.staticmethod_decorators = []
|
||||
linter.pycodestyle.max_line_length = 88
|
||||
linter.pycodestyle.max_doc_length = none
|
||||
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||
linter.pyflakes.extend_generics = []
|
||||
linter.pyflakes.allowed_unused_imports = []
|
||||
linter.pylint.allow_magic_value_types = [
|
||||
str,
|
||||
bytes,
|
||||
]
|
||||
linter.pylint.allow_dunder_method_names = []
|
||||
linter.pylint.max_args = 5
|
||||
linter.pylint.max_positional_args = 5
|
||||
linter.pylint.max_returns = 6
|
||||
linter.pylint.max_bool_expr = 5
|
||||
linter.pylint.max_branches = 12
|
||||
linter.pylint.max_statements = 50
|
||||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
formatter.unresolved_target_version = 3.11
|
||||
formatter.per_file_target_version = {}
|
||||
formatter.preview = enabled
|
||||
formatter.line_width = 88
|
||||
formatter.line_ending = auto
|
||||
formatter.indent_style = space
|
||||
formatter.indent_width = 4
|
||||
formatter.quote_style = double
|
||||
formatter.magic_trailing_comma = respect
|
||||
formatter.docstring_code_format = disabled
|
||||
formatter.docstring_code_line_width = dynamic
|
||||
|
||||
# Analyze Settings
|
||||
analyze.exclude = []
|
||||
analyze.preview = enabled
|
||||
analyze.target_version = 3.11
|
||||
analyze.string_imports = disabled
|
||||
analyze.extension = ExtensionMapping({})
|
||||
analyze.include_dependencies = {}
|
||||
|
||||
----- stderr -----
|
||||
@@ -0,0 +1,292 @@
|
||||
---
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- check
|
||||
- "--no-cache"
|
||||
- "--output-format"
|
||||
- concise
|
||||
- "--show-settings"
|
||||
- "--select"
|
||||
- UP007
|
||||
- "--target-version"
|
||||
- py310
|
||||
- test.py
|
||||
- "-"
|
||||
snapshot_kind: text
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Resolved settings for: "[TMP]/test.py"
|
||||
|
||||
# General Settings
|
||||
cache_dir = "[TMP]/.ruff_cache"
|
||||
fix = false
|
||||
fix_only = false
|
||||
output_format = concise
|
||||
show_fixes = false
|
||||
unsafe_fixes = hint
|
||||
|
||||
# File Resolver Settings
|
||||
file_resolver.exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
file_resolver.extend_exclude = []
|
||||
file_resolver.force_exclude = false
|
||||
file_resolver.include = [
|
||||
"*.py",
|
||||
"*.pyi",
|
||||
"*.ipynb",
|
||||
"**/pyproject.toml",
|
||||
]
|
||||
file_resolver.extend_include = []
|
||||
file_resolver.respect_gitignore = true
|
||||
file_resolver.project_root = "[TMP]/"
|
||||
|
||||
# Linter Settings
|
||||
linter.exclude = []
|
||||
linter.project_root = "[TMP]/"
|
||||
linter.rules.enabled = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.rules.should_fix = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.per_file_ignores = {}
|
||||
linter.safety_table.forced_safe = []
|
||||
linter.safety_table.forced_unsafe = []
|
||||
linter.unresolved_target_version = 3.10
|
||||
linter.per_file_target_version = {}
|
||||
linter.preview = disabled
|
||||
linter.explicit_preview_rules = false
|
||||
linter.extension = ExtensionMapping({})
|
||||
linter.allowed_confusables = []
|
||||
linter.builtins = []
|
||||
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||
linter.external = []
|
||||
linter.ignore_init_module_imports = true
|
||||
linter.logger_objects = []
|
||||
linter.namespace_packages = []
|
||||
linter.src = [
|
||||
"[TMP]/",
|
||||
"[TMP]/src",
|
||||
]
|
||||
linter.tab_size = 4
|
||||
linter.line_length = 88
|
||||
linter.task_tags = [
|
||||
TODO,
|
||||
FIXME,
|
||||
XXX,
|
||||
]
|
||||
linter.typing_modules = []
|
||||
linter.typing_extensions = true
|
||||
|
||||
# Linter Plugins
|
||||
linter.flake8_annotations.mypy_init_return = false
|
||||
linter.flake8_annotations.suppress_dummy_args = false
|
||||
linter.flake8_annotations.suppress_none_returning = false
|
||||
linter.flake8_annotations.allow_star_arg_any = false
|
||||
linter.flake8_annotations.ignore_fully_untyped = false
|
||||
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/tmp,
|
||||
/var/tmp,
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
linter.flake8_copyright.min_file_size = 0
|
||||
linter.flake8_errmsg.max_string_length = 0
|
||||
linter.flake8_gettext.functions_names = [
|
||||
_,
|
||||
gettext,
|
||||
ngettext,
|
||||
]
|
||||
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||
linter.flake8_import_conventions.aliases = {
|
||||
altair = alt,
|
||||
holoviews = hv,
|
||||
matplotlib = mpl,
|
||||
matplotlib.pyplot = plt,
|
||||
networkx = nx,
|
||||
numpy = np,
|
||||
numpy.typing = npt,
|
||||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
linter.flake8_pytest_style.parametrize_values_type = list
|
||||
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||
linter.flake8_pytest_style.raises_require_match_for = [
|
||||
BaseException,
|
||||
Exception,
|
||||
ValueError,
|
||||
OSError,
|
||||
IOError,
|
||||
EnvironmentError,
|
||||
socket.error,
|
||||
]
|
||||
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||
linter.flake8_pytest_style.mark_parentheses = false
|
||||
linter.flake8_quotes.inline_quotes = double
|
||||
linter.flake8_quotes.multiline_quotes = double
|
||||
linter.flake8_quotes.docstring_quotes = double
|
||||
linter.flake8_quotes.avoid_escape = true
|
||||
linter.flake8_self.ignore_names = [
|
||||
_make,
|
||||
_asdict,
|
||||
_replace,
|
||||
_fields,
|
||||
_field_defaults,
|
||||
_name_,
|
||||
_value_,
|
||||
]
|
||||
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||
linter.flake8_tidy_imports.banned_api = {}
|
||||
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||
linter.flake8_type_checking.strict = false
|
||||
linter.flake8_type_checking.exempt_modules = [
|
||||
typing,
|
||||
typing_extensions,
|
||||
]
|
||||
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||
linter.flake8_type_checking.runtime_required_decorators = []
|
||||
linter.flake8_type_checking.quote_annotations = false
|
||||
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||
linter.isort.required_imports = []
|
||||
linter.isort.combine_as_imports = false
|
||||
linter.isort.force_single_line = false
|
||||
linter.isort.force_sort_within_sections = false
|
||||
linter.isort.detect_same_package = true
|
||||
linter.isort.case_sensitive = false
|
||||
linter.isort.force_wrap_aliases = false
|
||||
linter.isort.force_to_top = []
|
||||
linter.isort.known_modules = {}
|
||||
linter.isort.order_by_type = true
|
||||
linter.isort.relative_imports_order = furthest_to_closest
|
||||
linter.isort.single_line_exclusions = []
|
||||
linter.isort.split_on_trailing_comma = true
|
||||
linter.isort.classes = []
|
||||
linter.isort.constants = []
|
||||
linter.isort.variables = []
|
||||
linter.isort.no_lines_before = []
|
||||
linter.isort.lines_after_imports = -1
|
||||
linter.isort.lines_between_types = 0
|
||||
linter.isort.forced_separate = []
|
||||
linter.isort.section_order = [
|
||||
known { type = future },
|
||||
known { type = standard_library },
|
||||
known { type = third_party },
|
||||
known { type = first_party },
|
||||
known { type = local_folder },
|
||||
]
|
||||
linter.isort.default_section = known { type = third_party }
|
||||
linter.isort.no_sections = false
|
||||
linter.isort.from_first = false
|
||||
linter.isort.length_sort = false
|
||||
linter.isort.length_sort_straight = false
|
||||
linter.mccabe.max_complexity = 10
|
||||
linter.pep8_naming.ignore_names = [
|
||||
setUp,
|
||||
tearDown,
|
||||
setUpClass,
|
||||
tearDownClass,
|
||||
setUpModule,
|
||||
tearDownModule,
|
||||
asyncSetUp,
|
||||
asyncTearDown,
|
||||
setUpTestData,
|
||||
failureException,
|
||||
longMessage,
|
||||
maxDiff,
|
||||
]
|
||||
linter.pep8_naming.classmethod_decorators = []
|
||||
linter.pep8_naming.staticmethod_decorators = []
|
||||
linter.pycodestyle.max_line_length = 88
|
||||
linter.pycodestyle.max_doc_length = none
|
||||
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||
linter.pyflakes.extend_generics = []
|
||||
linter.pyflakes.allowed_unused_imports = []
|
||||
linter.pylint.allow_magic_value_types = [
|
||||
str,
|
||||
bytes,
|
||||
]
|
||||
linter.pylint.allow_dunder_method_names = []
|
||||
linter.pylint.max_args = 5
|
||||
linter.pylint.max_positional_args = 5
|
||||
linter.pylint.max_returns = 6
|
||||
linter.pylint.max_bool_expr = 5
|
||||
linter.pylint.max_branches = 12
|
||||
linter.pylint.max_statements = 50
|
||||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
formatter.unresolved_target_version = 3.10
|
||||
formatter.per_file_target_version = {}
|
||||
formatter.preview = disabled
|
||||
formatter.line_width = 88
|
||||
formatter.line_ending = auto
|
||||
formatter.indent_style = space
|
||||
formatter.indent_width = 4
|
||||
formatter.quote_style = double
|
||||
formatter.magic_trailing_comma = respect
|
||||
formatter.docstring_code_format = disabled
|
||||
formatter.docstring_code_line_width = dynamic
|
||||
|
||||
# Analyze Settings
|
||||
analyze.exclude = []
|
||||
analyze.preview = disabled
|
||||
analyze.target_version = 3.10
|
||||
analyze.string_imports = disabled
|
||||
analyze.extension = ExtensionMapping({})
|
||||
analyze.include_dependencies = {}
|
||||
|
||||
----- stderr -----
|
||||
@@ -0,0 +1,289 @@
|
||||
---
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- check
|
||||
- "--no-cache"
|
||||
- "--output-format"
|
||||
- concise
|
||||
- "--show-settings"
|
||||
- "--select"
|
||||
- UP007
|
||||
- foo/test.py
|
||||
snapshot_kind: text
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Resolved settings for: "[TMP]/foo/test.py"
|
||||
|
||||
# General Settings
|
||||
cache_dir = "[TMP]/.ruff_cache"
|
||||
fix = false
|
||||
fix_only = false
|
||||
output_format = concise
|
||||
show_fixes = false
|
||||
unsafe_fixes = hint
|
||||
|
||||
# File Resolver Settings
|
||||
file_resolver.exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
file_resolver.extend_exclude = []
|
||||
file_resolver.force_exclude = false
|
||||
file_resolver.include = [
|
||||
"*.py",
|
||||
"*.pyi",
|
||||
"*.ipynb",
|
||||
"**/pyproject.toml",
|
||||
]
|
||||
file_resolver.extend_include = []
|
||||
file_resolver.respect_gitignore = true
|
||||
file_resolver.project_root = "[TMP]/"
|
||||
|
||||
# Linter Settings
|
||||
linter.exclude = []
|
||||
linter.project_root = "[TMP]/"
|
||||
linter.rules.enabled = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.rules.should_fix = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.per_file_ignores = {}
|
||||
linter.safety_table.forced_safe = []
|
||||
linter.safety_table.forced_unsafe = []
|
||||
linter.unresolved_target_version = 3.11
|
||||
linter.per_file_target_version = {}
|
||||
linter.preview = disabled
|
||||
linter.explicit_preview_rules = false
|
||||
linter.extension = ExtensionMapping({})
|
||||
linter.allowed_confusables = []
|
||||
linter.builtins = []
|
||||
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||
linter.external = []
|
||||
linter.ignore_init_module_imports = true
|
||||
linter.logger_objects = []
|
||||
linter.namespace_packages = []
|
||||
linter.src = [
|
||||
"[TMP]/",
|
||||
"[TMP]/src",
|
||||
]
|
||||
linter.tab_size = 4
|
||||
linter.line_length = 88
|
||||
linter.task_tags = [
|
||||
TODO,
|
||||
FIXME,
|
||||
XXX,
|
||||
]
|
||||
linter.typing_modules = []
|
||||
linter.typing_extensions = true
|
||||
|
||||
# Linter Plugins
|
||||
linter.flake8_annotations.mypy_init_return = false
|
||||
linter.flake8_annotations.suppress_dummy_args = false
|
||||
linter.flake8_annotations.suppress_none_returning = false
|
||||
linter.flake8_annotations.allow_star_arg_any = false
|
||||
linter.flake8_annotations.ignore_fully_untyped = false
|
||||
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/tmp,
|
||||
/var/tmp,
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
linter.flake8_copyright.min_file_size = 0
|
||||
linter.flake8_errmsg.max_string_length = 0
|
||||
linter.flake8_gettext.functions_names = [
|
||||
_,
|
||||
gettext,
|
||||
ngettext,
|
||||
]
|
||||
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||
linter.flake8_import_conventions.aliases = {
|
||||
altair = alt,
|
||||
holoviews = hv,
|
||||
matplotlib = mpl,
|
||||
matplotlib.pyplot = plt,
|
||||
networkx = nx,
|
||||
numpy = np,
|
||||
numpy.typing = npt,
|
||||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
linter.flake8_pytest_style.parametrize_values_type = list
|
||||
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||
linter.flake8_pytest_style.raises_require_match_for = [
|
||||
BaseException,
|
||||
Exception,
|
||||
ValueError,
|
||||
OSError,
|
||||
IOError,
|
||||
EnvironmentError,
|
||||
socket.error,
|
||||
]
|
||||
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||
linter.flake8_pytest_style.mark_parentheses = false
|
||||
linter.flake8_quotes.inline_quotes = double
|
||||
linter.flake8_quotes.multiline_quotes = double
|
||||
linter.flake8_quotes.docstring_quotes = double
|
||||
linter.flake8_quotes.avoid_escape = true
|
||||
linter.flake8_self.ignore_names = [
|
||||
_make,
|
||||
_asdict,
|
||||
_replace,
|
||||
_fields,
|
||||
_field_defaults,
|
||||
_name_,
|
||||
_value_,
|
||||
]
|
||||
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||
linter.flake8_tidy_imports.banned_api = {}
|
||||
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||
linter.flake8_type_checking.strict = false
|
||||
linter.flake8_type_checking.exempt_modules = [
|
||||
typing,
|
||||
typing_extensions,
|
||||
]
|
||||
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||
linter.flake8_type_checking.runtime_required_decorators = []
|
||||
linter.flake8_type_checking.quote_annotations = false
|
||||
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||
linter.isort.required_imports = []
|
||||
linter.isort.combine_as_imports = false
|
||||
linter.isort.force_single_line = false
|
||||
linter.isort.force_sort_within_sections = false
|
||||
linter.isort.detect_same_package = true
|
||||
linter.isort.case_sensitive = false
|
||||
linter.isort.force_wrap_aliases = false
|
||||
linter.isort.force_to_top = []
|
||||
linter.isort.known_modules = {}
|
||||
linter.isort.order_by_type = true
|
||||
linter.isort.relative_imports_order = furthest_to_closest
|
||||
linter.isort.single_line_exclusions = []
|
||||
linter.isort.split_on_trailing_comma = true
|
||||
linter.isort.classes = []
|
||||
linter.isort.constants = []
|
||||
linter.isort.variables = []
|
||||
linter.isort.no_lines_before = []
|
||||
linter.isort.lines_after_imports = -1
|
||||
linter.isort.lines_between_types = 0
|
||||
linter.isort.forced_separate = []
|
||||
linter.isort.section_order = [
|
||||
known { type = future },
|
||||
known { type = standard_library },
|
||||
known { type = third_party },
|
||||
known { type = first_party },
|
||||
known { type = local_folder },
|
||||
]
|
||||
linter.isort.default_section = known { type = third_party }
|
||||
linter.isort.no_sections = false
|
||||
linter.isort.from_first = false
|
||||
linter.isort.length_sort = false
|
||||
linter.isort.length_sort_straight = false
|
||||
linter.mccabe.max_complexity = 10
|
||||
linter.pep8_naming.ignore_names = [
|
||||
setUp,
|
||||
tearDown,
|
||||
setUpClass,
|
||||
tearDownClass,
|
||||
setUpModule,
|
||||
tearDownModule,
|
||||
asyncSetUp,
|
||||
asyncTearDown,
|
||||
setUpTestData,
|
||||
failureException,
|
||||
longMessage,
|
||||
maxDiff,
|
||||
]
|
||||
linter.pep8_naming.classmethod_decorators = []
|
||||
linter.pep8_naming.staticmethod_decorators = []
|
||||
linter.pycodestyle.max_line_length = 88
|
||||
linter.pycodestyle.max_doc_length = none
|
||||
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||
linter.pyflakes.extend_generics = []
|
||||
linter.pyflakes.allowed_unused_imports = []
|
||||
linter.pylint.allow_magic_value_types = [
|
||||
str,
|
||||
bytes,
|
||||
]
|
||||
linter.pylint.allow_dunder_method_names = []
|
||||
linter.pylint.max_args = 5
|
||||
linter.pylint.max_positional_args = 5
|
||||
linter.pylint.max_returns = 6
|
||||
linter.pylint.max_bool_expr = 5
|
||||
linter.pylint.max_branches = 12
|
||||
linter.pylint.max_statements = 50
|
||||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
formatter.unresolved_target_version = 3.11
|
||||
formatter.per_file_target_version = {}
|
||||
formatter.preview = disabled
|
||||
formatter.line_width = 88
|
||||
formatter.line_ending = auto
|
||||
formatter.indent_style = space
|
||||
formatter.indent_width = 4
|
||||
formatter.quote_style = double
|
||||
formatter.magic_trailing_comma = respect
|
||||
formatter.docstring_code_format = disabled
|
||||
formatter.docstring_code_line_width = dynamic
|
||||
|
||||
# Analyze Settings
|
||||
analyze.exclude = []
|
||||
analyze.preview = disabled
|
||||
analyze.target_version = 3.11
|
||||
analyze.string_imports = disabled
|
||||
analyze.extension = ExtensionMapping({})
|
||||
analyze.include_dependencies = {}
|
||||
|
||||
----- stderr -----
|
||||
@@ -0,0 +1,289 @@
|
||||
---
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- check
|
||||
- "--no-cache"
|
||||
- "--output-format"
|
||||
- concise
|
||||
- "--show-settings"
|
||||
- "--select"
|
||||
- UP007
|
||||
- foo/test.py
|
||||
snapshot_kind: text
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Resolved settings for: "[TMP]/foo/test.py"
|
||||
|
||||
# General Settings
|
||||
cache_dir = "[TMP]/foo/.ruff_cache"
|
||||
fix = false
|
||||
fix_only = false
|
||||
output_format = concise
|
||||
show_fixes = false
|
||||
unsafe_fixes = hint
|
||||
|
||||
# File Resolver Settings
|
||||
file_resolver.exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
file_resolver.extend_exclude = []
|
||||
file_resolver.force_exclude = false
|
||||
file_resolver.include = [
|
||||
"*.py",
|
||||
"*.pyi",
|
||||
"*.ipynb",
|
||||
"**/pyproject.toml",
|
||||
]
|
||||
file_resolver.extend_include = []
|
||||
file_resolver.respect_gitignore = true
|
||||
file_resolver.project_root = "[TMP]/foo"
|
||||
|
||||
# Linter Settings
|
||||
linter.exclude = []
|
||||
linter.project_root = "[TMP]/foo"
|
||||
linter.rules.enabled = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.rules.should_fix = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.per_file_ignores = {}
|
||||
linter.safety_table.forced_safe = []
|
||||
linter.safety_table.forced_unsafe = []
|
||||
linter.unresolved_target_version = 3.10
|
||||
linter.per_file_target_version = {}
|
||||
linter.preview = disabled
|
||||
linter.explicit_preview_rules = false
|
||||
linter.extension = ExtensionMapping({})
|
||||
linter.allowed_confusables = []
|
||||
linter.builtins = []
|
||||
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||
linter.external = []
|
||||
linter.ignore_init_module_imports = true
|
||||
linter.logger_objects = []
|
||||
linter.namespace_packages = []
|
||||
linter.src = [
|
||||
"[TMP]/foo",
|
||||
"[TMP]/foo/src",
|
||||
]
|
||||
linter.tab_size = 4
|
||||
linter.line_length = 88
|
||||
linter.task_tags = [
|
||||
TODO,
|
||||
FIXME,
|
||||
XXX,
|
||||
]
|
||||
linter.typing_modules = []
|
||||
linter.typing_extensions = true
|
||||
|
||||
# Linter Plugins
|
||||
linter.flake8_annotations.mypy_init_return = false
|
||||
linter.flake8_annotations.suppress_dummy_args = false
|
||||
linter.flake8_annotations.suppress_none_returning = false
|
||||
linter.flake8_annotations.allow_star_arg_any = false
|
||||
linter.flake8_annotations.ignore_fully_untyped = false
|
||||
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/tmp,
|
||||
/var/tmp,
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
linter.flake8_copyright.min_file_size = 0
|
||||
linter.flake8_errmsg.max_string_length = 0
|
||||
linter.flake8_gettext.functions_names = [
|
||||
_,
|
||||
gettext,
|
||||
ngettext,
|
||||
]
|
||||
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||
linter.flake8_import_conventions.aliases = {
|
||||
altair = alt,
|
||||
holoviews = hv,
|
||||
matplotlib = mpl,
|
||||
matplotlib.pyplot = plt,
|
||||
networkx = nx,
|
||||
numpy = np,
|
||||
numpy.typing = npt,
|
||||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
linter.flake8_pytest_style.parametrize_values_type = list
|
||||
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||
linter.flake8_pytest_style.raises_require_match_for = [
|
||||
BaseException,
|
||||
Exception,
|
||||
ValueError,
|
||||
OSError,
|
||||
IOError,
|
||||
EnvironmentError,
|
||||
socket.error,
|
||||
]
|
||||
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||
linter.flake8_pytest_style.mark_parentheses = false
|
||||
linter.flake8_quotes.inline_quotes = double
|
||||
linter.flake8_quotes.multiline_quotes = double
|
||||
linter.flake8_quotes.docstring_quotes = double
|
||||
linter.flake8_quotes.avoid_escape = true
|
||||
linter.flake8_self.ignore_names = [
|
||||
_make,
|
||||
_asdict,
|
||||
_replace,
|
||||
_fields,
|
||||
_field_defaults,
|
||||
_name_,
|
||||
_value_,
|
||||
]
|
||||
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||
linter.flake8_tidy_imports.banned_api = {}
|
||||
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||
linter.flake8_type_checking.strict = false
|
||||
linter.flake8_type_checking.exempt_modules = [
|
||||
typing,
|
||||
typing_extensions,
|
||||
]
|
||||
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||
linter.flake8_type_checking.runtime_required_decorators = []
|
||||
linter.flake8_type_checking.quote_annotations = false
|
||||
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||
linter.isort.required_imports = []
|
||||
linter.isort.combine_as_imports = false
|
||||
linter.isort.force_single_line = false
|
||||
linter.isort.force_sort_within_sections = false
|
||||
linter.isort.detect_same_package = true
|
||||
linter.isort.case_sensitive = false
|
||||
linter.isort.force_wrap_aliases = false
|
||||
linter.isort.force_to_top = []
|
||||
linter.isort.known_modules = {}
|
||||
linter.isort.order_by_type = true
|
||||
linter.isort.relative_imports_order = furthest_to_closest
|
||||
linter.isort.single_line_exclusions = []
|
||||
linter.isort.split_on_trailing_comma = true
|
||||
linter.isort.classes = []
|
||||
linter.isort.constants = []
|
||||
linter.isort.variables = []
|
||||
linter.isort.no_lines_before = []
|
||||
linter.isort.lines_after_imports = -1
|
||||
linter.isort.lines_between_types = 0
|
||||
linter.isort.forced_separate = []
|
||||
linter.isort.section_order = [
|
||||
known { type = future },
|
||||
known { type = standard_library },
|
||||
known { type = third_party },
|
||||
known { type = first_party },
|
||||
known { type = local_folder },
|
||||
]
|
||||
linter.isort.default_section = known { type = third_party }
|
||||
linter.isort.no_sections = false
|
||||
linter.isort.from_first = false
|
||||
linter.isort.length_sort = false
|
||||
linter.isort.length_sort_straight = false
|
||||
linter.mccabe.max_complexity = 10
|
||||
linter.pep8_naming.ignore_names = [
|
||||
setUp,
|
||||
tearDown,
|
||||
setUpClass,
|
||||
tearDownClass,
|
||||
setUpModule,
|
||||
tearDownModule,
|
||||
asyncSetUp,
|
||||
asyncTearDown,
|
||||
setUpTestData,
|
||||
failureException,
|
||||
longMessage,
|
||||
maxDiff,
|
||||
]
|
||||
linter.pep8_naming.classmethod_decorators = []
|
||||
linter.pep8_naming.staticmethod_decorators = []
|
||||
linter.pycodestyle.max_line_length = 88
|
||||
linter.pycodestyle.max_doc_length = none
|
||||
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||
linter.pyflakes.extend_generics = []
|
||||
linter.pyflakes.allowed_unused_imports = []
|
||||
linter.pylint.allow_magic_value_types = [
|
||||
str,
|
||||
bytes,
|
||||
]
|
||||
linter.pylint.allow_dunder_method_names = []
|
||||
linter.pylint.max_args = 5
|
||||
linter.pylint.max_positional_args = 5
|
||||
linter.pylint.max_returns = 6
|
||||
linter.pylint.max_bool_expr = 5
|
||||
linter.pylint.max_branches = 12
|
||||
linter.pylint.max_statements = 50
|
||||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
formatter.unresolved_target_version = 3.10
|
||||
formatter.per_file_target_version = {}
|
||||
formatter.preview = disabled
|
||||
formatter.line_width = 88
|
||||
formatter.line_ending = auto
|
||||
formatter.indent_style = space
|
||||
formatter.indent_width = 4
|
||||
formatter.quote_style = double
|
||||
formatter.magic_trailing_comma = respect
|
||||
formatter.docstring_code_format = disabled
|
||||
formatter.docstring_code_line_width = dynamic
|
||||
|
||||
# Analyze Settings
|
||||
analyze.exclude = []
|
||||
analyze.preview = disabled
|
||||
analyze.target_version = 3.10
|
||||
analyze.string_imports = disabled
|
||||
analyze.extension = ExtensionMapping({})
|
||||
analyze.include_dependencies = {}
|
||||
|
||||
----- stderr -----
|
||||
@@ -0,0 +1,287 @@
|
||||
---
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- check
|
||||
- "--no-cache"
|
||||
- "--output-format"
|
||||
- concise
|
||||
- "--show-settings"
|
||||
- test.py
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Resolved settings for: "[TMP]/foo/test.py"
|
||||
Settings path: "[TMP]/ruff.toml"
|
||||
|
||||
# General Settings
|
||||
cache_dir = "[TMP]/.ruff_cache"
|
||||
fix = false
|
||||
fix_only = false
|
||||
output_format = concise
|
||||
show_fixes = false
|
||||
unsafe_fixes = hint
|
||||
|
||||
# File Resolver Settings
|
||||
file_resolver.exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
file_resolver.extend_exclude = []
|
||||
file_resolver.force_exclude = false
|
||||
file_resolver.include = [
|
||||
"*.py",
|
||||
"*.pyi",
|
||||
"*.ipynb",
|
||||
"**/pyproject.toml",
|
||||
]
|
||||
file_resolver.extend_include = []
|
||||
file_resolver.respect_gitignore = true
|
||||
file_resolver.project_root = "[TMP]/"
|
||||
|
||||
# Linter Settings
|
||||
linter.exclude = []
|
||||
linter.project_root = "[TMP]/"
|
||||
linter.rules.enabled = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.rules.should_fix = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.per_file_ignores = {}
|
||||
linter.safety_table.forced_safe = []
|
||||
linter.safety_table.forced_unsafe = []
|
||||
linter.unresolved_target_version = none
|
||||
linter.per_file_target_version = {}
|
||||
linter.preview = disabled
|
||||
linter.explicit_preview_rules = false
|
||||
linter.extension = ExtensionMapping({})
|
||||
linter.allowed_confusables = []
|
||||
linter.builtins = []
|
||||
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||
linter.external = []
|
||||
linter.ignore_init_module_imports = true
|
||||
linter.logger_objects = []
|
||||
linter.namespace_packages = []
|
||||
linter.src = [
|
||||
"[TMP]/",
|
||||
"[TMP]/src",
|
||||
]
|
||||
linter.tab_size = 4
|
||||
linter.line_length = 88
|
||||
linter.task_tags = [
|
||||
TODO,
|
||||
FIXME,
|
||||
XXX,
|
||||
]
|
||||
linter.typing_modules = []
|
||||
linter.typing_extensions = true
|
||||
|
||||
# Linter Plugins
|
||||
linter.flake8_annotations.mypy_init_return = false
|
||||
linter.flake8_annotations.suppress_dummy_args = false
|
||||
linter.flake8_annotations.suppress_none_returning = false
|
||||
linter.flake8_annotations.allow_star_arg_any = false
|
||||
linter.flake8_annotations.ignore_fully_untyped = false
|
||||
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/tmp,
|
||||
/var/tmp,
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
linter.flake8_copyright.min_file_size = 0
|
||||
linter.flake8_errmsg.max_string_length = 0
|
||||
linter.flake8_gettext.functions_names = [
|
||||
_,
|
||||
gettext,
|
||||
ngettext,
|
||||
]
|
||||
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||
linter.flake8_import_conventions.aliases = {
|
||||
altair = alt,
|
||||
holoviews = hv,
|
||||
matplotlib = mpl,
|
||||
matplotlib.pyplot = plt,
|
||||
networkx = nx,
|
||||
numpy = np,
|
||||
numpy.typing = npt,
|
||||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
linter.flake8_pytest_style.parametrize_values_type = list
|
||||
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||
linter.flake8_pytest_style.raises_require_match_for = [
|
||||
BaseException,
|
||||
Exception,
|
||||
ValueError,
|
||||
OSError,
|
||||
IOError,
|
||||
EnvironmentError,
|
||||
socket.error,
|
||||
]
|
||||
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||
linter.flake8_pytest_style.mark_parentheses = false
|
||||
linter.flake8_quotes.inline_quotes = double
|
||||
linter.flake8_quotes.multiline_quotes = double
|
||||
linter.flake8_quotes.docstring_quotes = double
|
||||
linter.flake8_quotes.avoid_escape = true
|
||||
linter.flake8_self.ignore_names = [
|
||||
_make,
|
||||
_asdict,
|
||||
_replace,
|
||||
_fields,
|
||||
_field_defaults,
|
||||
_name_,
|
||||
_value_,
|
||||
]
|
||||
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||
linter.flake8_tidy_imports.banned_api = {}
|
||||
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||
linter.flake8_type_checking.strict = false
|
||||
linter.flake8_type_checking.exempt_modules = [
|
||||
typing,
|
||||
typing_extensions,
|
||||
]
|
||||
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||
linter.flake8_type_checking.runtime_required_decorators = []
|
||||
linter.flake8_type_checking.quote_annotations = false
|
||||
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||
linter.isort.required_imports = []
|
||||
linter.isort.combine_as_imports = false
|
||||
linter.isort.force_single_line = false
|
||||
linter.isort.force_sort_within_sections = false
|
||||
linter.isort.detect_same_package = true
|
||||
linter.isort.case_sensitive = false
|
||||
linter.isort.force_wrap_aliases = false
|
||||
linter.isort.force_to_top = []
|
||||
linter.isort.known_modules = {}
|
||||
linter.isort.order_by_type = true
|
||||
linter.isort.relative_imports_order = furthest_to_closest
|
||||
linter.isort.single_line_exclusions = []
|
||||
linter.isort.split_on_trailing_comma = true
|
||||
linter.isort.classes = []
|
||||
linter.isort.constants = []
|
||||
linter.isort.variables = []
|
||||
linter.isort.no_lines_before = []
|
||||
linter.isort.lines_after_imports = -1
|
||||
linter.isort.lines_between_types = 0
|
||||
linter.isort.forced_separate = []
|
||||
linter.isort.section_order = [
|
||||
known { type = future },
|
||||
known { type = standard_library },
|
||||
known { type = third_party },
|
||||
known { type = first_party },
|
||||
known { type = local_folder },
|
||||
]
|
||||
linter.isort.default_section = known { type = third_party }
|
||||
linter.isort.no_sections = false
|
||||
linter.isort.from_first = false
|
||||
linter.isort.length_sort = false
|
||||
linter.isort.length_sort_straight = false
|
||||
linter.mccabe.max_complexity = 10
|
||||
linter.pep8_naming.ignore_names = [
|
||||
setUp,
|
||||
tearDown,
|
||||
setUpClass,
|
||||
tearDownClass,
|
||||
setUpModule,
|
||||
tearDownModule,
|
||||
asyncSetUp,
|
||||
asyncTearDown,
|
||||
setUpTestData,
|
||||
failureException,
|
||||
longMessage,
|
||||
maxDiff,
|
||||
]
|
||||
linter.pep8_naming.classmethod_decorators = []
|
||||
linter.pep8_naming.staticmethod_decorators = []
|
||||
linter.pycodestyle.max_line_length = 88
|
||||
linter.pycodestyle.max_doc_length = none
|
||||
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||
linter.pyflakes.extend_generics = []
|
||||
linter.pyflakes.allowed_unused_imports = []
|
||||
linter.pylint.allow_magic_value_types = [
|
||||
str,
|
||||
bytes,
|
||||
]
|
||||
linter.pylint.allow_dunder_method_names = []
|
||||
linter.pylint.max_args = 5
|
||||
linter.pylint.max_positional_args = 5
|
||||
linter.pylint.max_returns = 6
|
||||
linter.pylint.max_bool_expr = 5
|
||||
linter.pylint.max_branches = 12
|
||||
linter.pylint.max_statements = 50
|
||||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
formatter.unresolved_target_version = 3.10
|
||||
formatter.per_file_target_version = {}
|
||||
formatter.preview = disabled
|
||||
formatter.line_width = 88
|
||||
formatter.line_ending = auto
|
||||
formatter.indent_style = space
|
||||
formatter.indent_width = 4
|
||||
formatter.quote_style = double
|
||||
formatter.magic_trailing_comma = respect
|
||||
formatter.docstring_code_format = disabled
|
||||
formatter.docstring_code_line_width = dynamic
|
||||
|
||||
# Analyze Settings
|
||||
analyze.exclude = []
|
||||
analyze.preview = disabled
|
||||
analyze.target_version = 3.10
|
||||
analyze.string_imports = disabled
|
||||
analyze.extension = ExtensionMapping({})
|
||||
analyze.include_dependencies = {}
|
||||
|
||||
----- stderr -----
|
||||
@@ -0,0 +1,287 @@
|
||||
---
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- check
|
||||
- "--no-cache"
|
||||
- "--output-format"
|
||||
- concise
|
||||
- "--show-settings"
|
||||
- foo/test.py
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Resolved settings for: "[TMP]/foo/test.py"
|
||||
Settings path: "[TMP]/ruff.toml"
|
||||
|
||||
# General Settings
|
||||
cache_dir = "[TMP]/.ruff_cache"
|
||||
fix = false
|
||||
fix_only = false
|
||||
output_format = concise
|
||||
show_fixes = false
|
||||
unsafe_fixes = hint
|
||||
|
||||
# File Resolver Settings
|
||||
file_resolver.exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
file_resolver.extend_exclude = []
|
||||
file_resolver.force_exclude = false
|
||||
file_resolver.include = [
|
||||
"*.py",
|
||||
"*.pyi",
|
||||
"*.ipynb",
|
||||
"**/pyproject.toml",
|
||||
]
|
||||
file_resolver.extend_include = []
|
||||
file_resolver.respect_gitignore = true
|
||||
file_resolver.project_root = "[TMP]/"
|
||||
|
||||
# Linter Settings
|
||||
linter.exclude = []
|
||||
linter.project_root = "[TMP]/"
|
||||
linter.rules.enabled = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.rules.should_fix = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.per_file_ignores = {}
|
||||
linter.safety_table.forced_safe = []
|
||||
linter.safety_table.forced_unsafe = []
|
||||
linter.unresolved_target_version = none
|
||||
linter.per_file_target_version = {}
|
||||
linter.preview = disabled
|
||||
linter.explicit_preview_rules = false
|
||||
linter.extension = ExtensionMapping({})
|
||||
linter.allowed_confusables = []
|
||||
linter.builtins = []
|
||||
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||
linter.external = []
|
||||
linter.ignore_init_module_imports = true
|
||||
linter.logger_objects = []
|
||||
linter.namespace_packages = []
|
||||
linter.src = [
|
||||
"[TMP]/",
|
||||
"[TMP]/src",
|
||||
]
|
||||
linter.tab_size = 4
|
||||
linter.line_length = 88
|
||||
linter.task_tags = [
|
||||
TODO,
|
||||
FIXME,
|
||||
XXX,
|
||||
]
|
||||
linter.typing_modules = []
|
||||
linter.typing_extensions = true
|
||||
|
||||
# Linter Plugins
|
||||
linter.flake8_annotations.mypy_init_return = false
|
||||
linter.flake8_annotations.suppress_dummy_args = false
|
||||
linter.flake8_annotations.suppress_none_returning = false
|
||||
linter.flake8_annotations.allow_star_arg_any = false
|
||||
linter.flake8_annotations.ignore_fully_untyped = false
|
||||
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/tmp,
|
||||
/var/tmp,
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
linter.flake8_copyright.min_file_size = 0
|
||||
linter.flake8_errmsg.max_string_length = 0
|
||||
linter.flake8_gettext.functions_names = [
|
||||
_,
|
||||
gettext,
|
||||
ngettext,
|
||||
]
|
||||
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||
linter.flake8_import_conventions.aliases = {
|
||||
altair = alt,
|
||||
holoviews = hv,
|
||||
matplotlib = mpl,
|
||||
matplotlib.pyplot = plt,
|
||||
networkx = nx,
|
||||
numpy = np,
|
||||
numpy.typing = npt,
|
||||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
linter.flake8_pytest_style.parametrize_values_type = list
|
||||
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||
linter.flake8_pytest_style.raises_require_match_for = [
|
||||
BaseException,
|
||||
Exception,
|
||||
ValueError,
|
||||
OSError,
|
||||
IOError,
|
||||
EnvironmentError,
|
||||
socket.error,
|
||||
]
|
||||
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||
linter.flake8_pytest_style.mark_parentheses = false
|
||||
linter.flake8_quotes.inline_quotes = double
|
||||
linter.flake8_quotes.multiline_quotes = double
|
||||
linter.flake8_quotes.docstring_quotes = double
|
||||
linter.flake8_quotes.avoid_escape = true
|
||||
linter.flake8_self.ignore_names = [
|
||||
_make,
|
||||
_asdict,
|
||||
_replace,
|
||||
_fields,
|
||||
_field_defaults,
|
||||
_name_,
|
||||
_value_,
|
||||
]
|
||||
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||
linter.flake8_tidy_imports.banned_api = {}
|
||||
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||
linter.flake8_type_checking.strict = false
|
||||
linter.flake8_type_checking.exempt_modules = [
|
||||
typing,
|
||||
typing_extensions,
|
||||
]
|
||||
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||
linter.flake8_type_checking.runtime_required_decorators = []
|
||||
linter.flake8_type_checking.quote_annotations = false
|
||||
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||
linter.isort.required_imports = []
|
||||
linter.isort.combine_as_imports = false
|
||||
linter.isort.force_single_line = false
|
||||
linter.isort.force_sort_within_sections = false
|
||||
linter.isort.detect_same_package = true
|
||||
linter.isort.case_sensitive = false
|
||||
linter.isort.force_wrap_aliases = false
|
||||
linter.isort.force_to_top = []
|
||||
linter.isort.known_modules = {}
|
||||
linter.isort.order_by_type = true
|
||||
linter.isort.relative_imports_order = furthest_to_closest
|
||||
linter.isort.single_line_exclusions = []
|
||||
linter.isort.split_on_trailing_comma = true
|
||||
linter.isort.classes = []
|
||||
linter.isort.constants = []
|
||||
linter.isort.variables = []
|
||||
linter.isort.no_lines_before = []
|
||||
linter.isort.lines_after_imports = -1
|
||||
linter.isort.lines_between_types = 0
|
||||
linter.isort.forced_separate = []
|
||||
linter.isort.section_order = [
|
||||
known { type = future },
|
||||
known { type = standard_library },
|
||||
known { type = third_party },
|
||||
known { type = first_party },
|
||||
known { type = local_folder },
|
||||
]
|
||||
linter.isort.default_section = known { type = third_party }
|
||||
linter.isort.no_sections = false
|
||||
linter.isort.from_first = false
|
||||
linter.isort.length_sort = false
|
||||
linter.isort.length_sort_straight = false
|
||||
linter.mccabe.max_complexity = 10
|
||||
linter.pep8_naming.ignore_names = [
|
||||
setUp,
|
||||
tearDown,
|
||||
setUpClass,
|
||||
tearDownClass,
|
||||
setUpModule,
|
||||
tearDownModule,
|
||||
asyncSetUp,
|
||||
asyncTearDown,
|
||||
setUpTestData,
|
||||
failureException,
|
||||
longMessage,
|
||||
maxDiff,
|
||||
]
|
||||
linter.pep8_naming.classmethod_decorators = []
|
||||
linter.pep8_naming.staticmethod_decorators = []
|
||||
linter.pycodestyle.max_line_length = 88
|
||||
linter.pycodestyle.max_doc_length = none
|
||||
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||
linter.pyflakes.extend_generics = []
|
||||
linter.pyflakes.allowed_unused_imports = []
|
||||
linter.pylint.allow_magic_value_types = [
|
||||
str,
|
||||
bytes,
|
||||
]
|
||||
linter.pylint.allow_dunder_method_names = []
|
||||
linter.pylint.max_args = 5
|
||||
linter.pylint.max_positional_args = 5
|
||||
linter.pylint.max_returns = 6
|
||||
linter.pylint.max_bool_expr = 5
|
||||
linter.pylint.max_branches = 12
|
||||
linter.pylint.max_statements = 50
|
||||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
formatter.unresolved_target_version = 3.10
|
||||
formatter.per_file_target_version = {}
|
||||
formatter.preview = disabled
|
||||
formatter.line_width = 88
|
||||
formatter.line_ending = auto
|
||||
formatter.indent_style = space
|
||||
formatter.indent_width = 4
|
||||
formatter.quote_style = double
|
||||
formatter.magic_trailing_comma = respect
|
||||
formatter.docstring_code_format = disabled
|
||||
formatter.docstring_code_line_width = dynamic
|
||||
|
||||
# Analyze Settings
|
||||
analyze.exclude = []
|
||||
analyze.preview = disabled
|
||||
analyze.target_version = 3.10
|
||||
analyze.string_imports = disabled
|
||||
analyze.extension = ExtensionMapping({})
|
||||
analyze.include_dependencies = {}
|
||||
|
||||
----- stderr -----
|
||||
@@ -0,0 +1,288 @@
|
||||
---
|
||||
source: crates/ruff/tests/cli/lint.rs
|
||||
info:
|
||||
program: ruff
|
||||
args:
|
||||
- check
|
||||
- "--no-cache"
|
||||
- "--output-format"
|
||||
- concise
|
||||
- test.py
|
||||
- "--show-settings"
|
||||
snapshot_kind: text
|
||||
---
|
||||
success: true
|
||||
exit_code: 0
|
||||
----- stdout -----
|
||||
Resolved settings for: "[TMP]/test.py"
|
||||
Settings path: "[TMP]/ruff.toml"
|
||||
|
||||
# General Settings
|
||||
cache_dir = "[TMP]/.ruff_cache"
|
||||
fix = false
|
||||
fix_only = false
|
||||
output_format = concise
|
||||
show_fixes = false
|
||||
unsafe_fixes = hint
|
||||
|
||||
# File Resolver Settings
|
||||
file_resolver.exclude = [
|
||||
".bzr",
|
||||
".direnv",
|
||||
".eggs",
|
||||
".git",
|
||||
".git-rewrite",
|
||||
".hg",
|
||||
".ipynb_checkpoints",
|
||||
".mypy_cache",
|
||||
".nox",
|
||||
".pants.d",
|
||||
".pyenv",
|
||||
".pytest_cache",
|
||||
".pytype",
|
||||
".ruff_cache",
|
||||
".svn",
|
||||
".tox",
|
||||
".venv",
|
||||
".vscode",
|
||||
"__pypackages__",
|
||||
"_build",
|
||||
"buck-out",
|
||||
"dist",
|
||||
"node_modules",
|
||||
"site-packages",
|
||||
"venv",
|
||||
]
|
||||
file_resolver.extend_exclude = []
|
||||
file_resolver.force_exclude = false
|
||||
file_resolver.include = [
|
||||
"*.py",
|
||||
"*.pyi",
|
||||
"*.ipynb",
|
||||
"**/pyproject.toml",
|
||||
]
|
||||
file_resolver.extend_include = []
|
||||
file_resolver.respect_gitignore = true
|
||||
file_resolver.project_root = "[TMP]/"
|
||||
|
||||
# Linter Settings
|
||||
linter.exclude = []
|
||||
linter.project_root = "[TMP]/"
|
||||
linter.rules.enabled = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.rules.should_fix = [
|
||||
non-pep604-annotation-union (UP007),
|
||||
]
|
||||
linter.per_file_ignores = {}
|
||||
linter.safety_table.forced_safe = []
|
||||
linter.safety_table.forced_unsafe = []
|
||||
linter.unresolved_target_version = 3.11
|
||||
linter.per_file_target_version = {}
|
||||
linter.preview = disabled
|
||||
linter.explicit_preview_rules = false
|
||||
linter.extension = ExtensionMapping({})
|
||||
linter.allowed_confusables = []
|
||||
linter.builtins = []
|
||||
linter.dummy_variable_rgx = ^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$
|
||||
linter.external = []
|
||||
linter.ignore_init_module_imports = true
|
||||
linter.logger_objects = []
|
||||
linter.namespace_packages = []
|
||||
linter.src = [
|
||||
"[TMP]/",
|
||||
"[TMP]/src",
|
||||
]
|
||||
linter.tab_size = 4
|
||||
linter.line_length = 88
|
||||
linter.task_tags = [
|
||||
TODO,
|
||||
FIXME,
|
||||
XXX,
|
||||
]
|
||||
linter.typing_modules = []
|
||||
linter.typing_extensions = true
|
||||
|
||||
# Linter Plugins
|
||||
linter.flake8_annotations.mypy_init_return = false
|
||||
linter.flake8_annotations.suppress_dummy_args = false
|
||||
linter.flake8_annotations.suppress_none_returning = false
|
||||
linter.flake8_annotations.allow_star_arg_any = false
|
||||
linter.flake8_annotations.ignore_fully_untyped = false
|
||||
linter.flake8_bandit.hardcoded_tmp_directory = [
|
||||
/tmp,
|
||||
/var/tmp,
|
||||
/dev/shm,
|
||||
]
|
||||
linter.flake8_bandit.check_typed_exception = false
|
||||
linter.flake8_bandit.extend_markup_names = []
|
||||
linter.flake8_bandit.allowed_markup_calls = []
|
||||
linter.flake8_bugbear.extend_immutable_calls = []
|
||||
linter.flake8_builtins.allowed_modules = []
|
||||
linter.flake8_builtins.ignorelist = []
|
||||
linter.flake8_builtins.strict_checking = false
|
||||
linter.flake8_comprehensions.allow_dict_calls_with_keyword_arguments = false
|
||||
linter.flake8_copyright.notice_rgx = (?i)Copyright\s+((?:\(C\)|©)\s+)?\d{4}((-|,\s)\d{4})*
|
||||
linter.flake8_copyright.author = none
|
||||
linter.flake8_copyright.min_file_size = 0
|
||||
linter.flake8_errmsg.max_string_length = 0
|
||||
linter.flake8_gettext.functions_names = [
|
||||
_,
|
||||
gettext,
|
||||
ngettext,
|
||||
]
|
||||
linter.flake8_implicit_str_concat.allow_multiline = true
|
||||
linter.flake8_import_conventions.aliases = {
|
||||
altair = alt,
|
||||
holoviews = hv,
|
||||
matplotlib = mpl,
|
||||
matplotlib.pyplot = plt,
|
||||
networkx = nx,
|
||||
numpy = np,
|
||||
numpy.typing = npt,
|
||||
pandas = pd,
|
||||
panel = pn,
|
||||
plotly.express = px,
|
||||
polars = pl,
|
||||
pyarrow = pa,
|
||||
seaborn = sns,
|
||||
tensorflow = tf,
|
||||
tkinter = tk,
|
||||
xml.etree.ElementTree = ET,
|
||||
}
|
||||
linter.flake8_import_conventions.banned_aliases = {}
|
||||
linter.flake8_import_conventions.banned_from = []
|
||||
linter.flake8_pytest_style.fixture_parentheses = false
|
||||
linter.flake8_pytest_style.parametrize_names_type = tuple
|
||||
linter.flake8_pytest_style.parametrize_values_type = list
|
||||
linter.flake8_pytest_style.parametrize_values_row_type = tuple
|
||||
linter.flake8_pytest_style.raises_require_match_for = [
|
||||
BaseException,
|
||||
Exception,
|
||||
ValueError,
|
||||
OSError,
|
||||
IOError,
|
||||
EnvironmentError,
|
||||
socket.error,
|
||||
]
|
||||
linter.flake8_pytest_style.raises_extend_require_match_for = []
|
||||
linter.flake8_pytest_style.mark_parentheses = false
|
||||
linter.flake8_quotes.inline_quotes = double
|
||||
linter.flake8_quotes.multiline_quotes = double
|
||||
linter.flake8_quotes.docstring_quotes = double
|
||||
linter.flake8_quotes.avoid_escape = true
|
||||
linter.flake8_self.ignore_names = [
|
||||
_make,
|
||||
_asdict,
|
||||
_replace,
|
||||
_fields,
|
||||
_field_defaults,
|
||||
_name_,
|
||||
_value_,
|
||||
]
|
||||
linter.flake8_tidy_imports.ban_relative_imports = "parents"
|
||||
linter.flake8_tidy_imports.banned_api = {}
|
||||
linter.flake8_tidy_imports.banned_module_level_imports = []
|
||||
linter.flake8_type_checking.strict = false
|
||||
linter.flake8_type_checking.exempt_modules = [
|
||||
typing,
|
||||
typing_extensions,
|
||||
]
|
||||
linter.flake8_type_checking.runtime_required_base_classes = []
|
||||
linter.flake8_type_checking.runtime_required_decorators = []
|
||||
linter.flake8_type_checking.quote_annotations = false
|
||||
linter.flake8_unused_arguments.ignore_variadic_names = false
|
||||
linter.isort.required_imports = []
|
||||
linter.isort.combine_as_imports = false
|
||||
linter.isort.force_single_line = false
|
||||
linter.isort.force_sort_within_sections = false
|
||||
linter.isort.detect_same_package = true
|
||||
linter.isort.case_sensitive = false
|
||||
linter.isort.force_wrap_aliases = false
|
||||
linter.isort.force_to_top = []
|
||||
linter.isort.known_modules = {}
|
||||
linter.isort.order_by_type = true
|
||||
linter.isort.relative_imports_order = furthest_to_closest
|
||||
linter.isort.single_line_exclusions = []
|
||||
linter.isort.split_on_trailing_comma = true
|
||||
linter.isort.classes = []
|
||||
linter.isort.constants = []
|
||||
linter.isort.variables = []
|
||||
linter.isort.no_lines_before = []
|
||||
linter.isort.lines_after_imports = -1
|
||||
linter.isort.lines_between_types = 0
|
||||
linter.isort.forced_separate = []
|
||||
linter.isort.section_order = [
|
||||
known { type = future },
|
||||
known { type = standard_library },
|
||||
known { type = third_party },
|
||||
known { type = first_party },
|
||||
known { type = local_folder },
|
||||
]
|
||||
linter.isort.default_section = known { type = third_party }
|
||||
linter.isort.no_sections = false
|
||||
linter.isort.from_first = false
|
||||
linter.isort.length_sort = false
|
||||
linter.isort.length_sort_straight = false
|
||||
linter.mccabe.max_complexity = 10
|
||||
linter.pep8_naming.ignore_names = [
|
||||
setUp,
|
||||
tearDown,
|
||||
setUpClass,
|
||||
tearDownClass,
|
||||
setUpModule,
|
||||
tearDownModule,
|
||||
asyncSetUp,
|
||||
asyncTearDown,
|
||||
setUpTestData,
|
||||
failureException,
|
||||
longMessage,
|
||||
maxDiff,
|
||||
]
|
||||
linter.pep8_naming.classmethod_decorators = []
|
||||
linter.pep8_naming.staticmethod_decorators = []
|
||||
linter.pycodestyle.max_line_length = 88
|
||||
linter.pycodestyle.max_doc_length = none
|
||||
linter.pycodestyle.ignore_overlong_task_comments = false
|
||||
linter.pyflakes.extend_generics = []
|
||||
linter.pyflakes.allowed_unused_imports = []
|
||||
linter.pylint.allow_magic_value_types = [
|
||||
str,
|
||||
bytes,
|
||||
]
|
||||
linter.pylint.allow_dunder_method_names = []
|
||||
linter.pylint.max_args = 5
|
||||
linter.pylint.max_positional_args = 5
|
||||
linter.pylint.max_returns = 6
|
||||
linter.pylint.max_bool_expr = 5
|
||||
linter.pylint.max_branches = 12
|
||||
linter.pylint.max_statements = 50
|
||||
linter.pylint.max_public_methods = 20
|
||||
linter.pylint.max_locals = 15
|
||||
linter.pylint.max_nested_blocks = 5
|
||||
linter.pyupgrade.keep_runtime_typing = false
|
||||
linter.ruff.parenthesize_tuple_in_subscript = false
|
||||
|
||||
# Formatter Settings
|
||||
formatter.exclude = []
|
||||
formatter.unresolved_target_version = 3.11
|
||||
formatter.per_file_target_version = {}
|
||||
formatter.preview = disabled
|
||||
formatter.line_width = 88
|
||||
formatter.line_ending = auto
|
||||
formatter.indent_style = space
|
||||
formatter.indent_width = 4
|
||||
formatter.quote_style = double
|
||||
formatter.magic_trailing_comma = respect
|
||||
formatter.docstring_code_format = disabled
|
||||
formatter.docstring_code_line_width = dynamic
|
||||
|
||||
# Analyze Settings
|
||||
analyze.exclude = []
|
||||
analyze.preview = disabled
|
||||
analyze.target_version = 3.11
|
||||
analyze.string_imports = disabled
|
||||
analyze.extension = ExtensionMapping({})
|
||||
analyze.include_dependencies = {}
|
||||
|
||||
----- stderr -----
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_linter"
|
||||
version = "0.13.3"
|
||||
version = "0.14.0"
|
||||
publish = false
|
||||
authors = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
|
||||
3
crates/ruff_linter/resources/test/fixtures/isort/required_imports/docstring_future_import.py
vendored
Normal file
3
crates/ruff_linter/resources/test/fixtures/isort/required_imports/docstring_future_import.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
"a docstring"
|
||||
from __future__ import annotations
|
||||
# EOF
|
||||
2
crates/ruff_linter/resources/test/fixtures/isort/required_imports/future_import.py
vendored
Normal file
2
crates/ruff_linter/resources/test/fixtures/isort/required_imports/future_import.py
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
from __future__ import annotations
|
||||
# EOF
|
||||
@@ -14,6 +14,6 @@ class Bar:
|
||||
]
|
||||
|
||||
|
||||
# OK: Allow named expressions in annotations.
|
||||
# This is no longer allowed on Python 3.14+
|
||||
x: (y := 1)
|
||||
print(y)
|
||||
|
||||
@@ -13,16 +13,16 @@ CStr2: TypeAlias = Union["C", str] # always okay
|
||||
|
||||
# References to a class from inside the class:
|
||||
class C:
|
||||
other: C = ... # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
other: C = ... # valid in a `.pyi` stub file, and in a `.py` runtime file with deferred annotations
|
||||
other2: "C" = ... # always okay
|
||||
def from_str(self, s: str) -> C: ... # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
def from_str(self, s: str) -> C: ... # valid in a `.pyi` stub file, and in a `.py` runtime file with deferred annotations
|
||||
def from_str2(self, s: str) -> "C": ... # always okay
|
||||
|
||||
# Circular references:
|
||||
class A:
|
||||
foo: B # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
foo: B # valid in a `.pyi` stub file, and in a `.py` runtime file with deferred annotations
|
||||
foo2: "B" # always okay
|
||||
bar: dict[str, B] # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
bar: dict[str, B] # valid in a `.pyi` stub file, and in a `.py` runtime file with deferred annotations
|
||||
bar2: dict[str, "A"] # always okay
|
||||
|
||||
class B:
|
||||
|
||||
@@ -56,3 +56,11 @@ f"{str(object=3)}"
|
||||
f"{str(x for x in [])}"
|
||||
|
||||
f"{str((x for x in []))}"
|
||||
|
||||
# Debug text cases - should not trigger RUF010
|
||||
f"{str(1)=}"
|
||||
f"{ascii(1)=}"
|
||||
f"{repr(1)=}"
|
||||
f"{str('hello')=}"
|
||||
f"{ascii('hello')=}"
|
||||
f"{repr('hello')=}"
|
||||
|
||||
@@ -67,17 +67,25 @@ impl<'a> Importer<'a> {
|
||||
/// Add an import statement to import the given module.
|
||||
///
|
||||
/// If there are no existing imports, the new import will be added at the top
|
||||
/// of the file. Otherwise, it will be added after the most recent top-level
|
||||
/// import statement.
|
||||
/// of the file. If there are future imports, the new import will be added
|
||||
/// after the last future import. Otherwise, it will be added after the most
|
||||
/// recent top-level import statement.
|
||||
pub(crate) fn add_import(&self, import: &NameImport, at: TextSize) -> Edit {
|
||||
let required_import = import.to_string();
|
||||
if let Some(stmt) = self.preceding_import(at) {
|
||||
// Insert after the last top-level import.
|
||||
Insertion::end_of_statement(stmt, self.source, self.stylist).into_edit(&required_import)
|
||||
} else {
|
||||
// Insert at the start of the file.
|
||||
Insertion::start_of_file(self.python_ast, self.source, self.stylist)
|
||||
.into_edit(&required_import)
|
||||
// Check if there are any future imports that we need to respect
|
||||
if let Some(last_future_import) = self.find_last_future_import() {
|
||||
// Insert after the last future import
|
||||
Insertion::end_of_statement(last_future_import, self.source, self.stylist)
|
||||
.into_edit(&required_import)
|
||||
} else {
|
||||
// Insert at the start of the file.
|
||||
Insertion::start_of_file(self.python_ast, self.source, self.stylist)
|
||||
.into_edit(&required_import)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -524,6 +532,18 @@ impl<'a> Importer<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
/// Find the last `from __future__` import statement in the AST.
|
||||
fn find_last_future_import(&self) -> Option<&'a Stmt> {
|
||||
let mut body = self.python_ast.iter().peekable();
|
||||
let _docstring = body.next_if(|stmt| ast::helpers::is_docstring_stmt(stmt));
|
||||
|
||||
body.take_while(|stmt| {
|
||||
stmt.as_import_from_stmt()
|
||||
.is_some_and(|import_from| import_from.module.as_deref() == Some("__future__"))
|
||||
})
|
||||
.last()
|
||||
}
|
||||
|
||||
/// Add a `from __future__ import annotations` import.
|
||||
pub(crate) fn add_future_import(&self) -> Edit {
|
||||
let import = &NameImport::ImportFrom(MemberNameImport::member(
|
||||
|
||||
@@ -27,14 +27,13 @@ use crate::fix::{FixResult, fix_file};
|
||||
use crate::message::create_syntax_error_diagnostic;
|
||||
use crate::noqa::add_noqa;
|
||||
use crate::package::PackageRoot;
|
||||
use crate::preview::is_py314_support_enabled;
|
||||
use crate::registry::Rule;
|
||||
#[cfg(any(feature = "test-rules", test))]
|
||||
use crate::rules::ruff::rules::test_rules::{self, TEST_RULES, TestRule};
|
||||
use crate::settings::types::UnsafeFixes;
|
||||
use crate::settings::{LinterSettings, TargetVersion, flags};
|
||||
use crate::source_kind::SourceKind;
|
||||
use crate::{Locator, directives, fs, warn_user_once};
|
||||
use crate::{Locator, directives, fs};
|
||||
|
||||
pub(crate) mod float;
|
||||
|
||||
@@ -442,14 +441,6 @@ pub fn lint_only(
|
||||
) -> LinterResult {
|
||||
let target_version = settings.resolve_target_version(path);
|
||||
|
||||
if matches!(target_version, TargetVersion(Some(PythonVersion::PY314)))
|
||||
&& !is_py314_support_enabled(settings)
|
||||
{
|
||||
warn_user_once!(
|
||||
"Support for Python 3.14 is in preview and may undergo breaking changes. Enable `preview` to remove this warning."
|
||||
);
|
||||
}
|
||||
|
||||
let parsed = source.into_parsed(source_kind, source_type, target_version.parser_version());
|
||||
|
||||
// Map row and column locations to byte slices (lazily).
|
||||
@@ -551,14 +542,6 @@ pub fn lint_fix<'a>(
|
||||
|
||||
let target_version = settings.resolve_target_version(path);
|
||||
|
||||
if matches!(target_version, TargetVersion(Some(PythonVersion::PY314)))
|
||||
&& !is_py314_support_enabled(settings)
|
||||
{
|
||||
warn_user_once!(
|
||||
"Support for Python 3.14 is in preview and may undergo breaking changes. Enable `preview` to remove this warning."
|
||||
);
|
||||
}
|
||||
|
||||
// Continuously fix until the source code stabilizes.
|
||||
loop {
|
||||
// Parse once.
|
||||
|
||||
@@ -7,10 +7,6 @@
|
||||
|
||||
use crate::settings::LinterSettings;
|
||||
|
||||
pub(crate) const fn is_py314_support_enabled(settings: &LinterSettings) -> bool {
|
||||
settings.preview.is_enabled()
|
||||
}
|
||||
|
||||
// Rule-specific behavior
|
||||
|
||||
// https://github.com/astral-sh/ruff/pull/15541
|
||||
@@ -259,3 +255,13 @@ pub(crate) const fn is_b006_unsafe_fix_preserve_assignment_expr_enabled(
|
||||
) -> bool {
|
||||
settings.preview.is_enabled()
|
||||
}
|
||||
|
||||
// https://github.com/astral-sh/ruff/pull/20520
|
||||
pub(crate) const fn is_fix_read_whole_file_enabled(settings: &LinterSettings) -> bool {
|
||||
settings.preview.is_enabled()
|
||||
}
|
||||
|
||||
// https://github.com/astral-sh/ruff/pull/20520
|
||||
pub(crate) const fn is_fix_write_whole_file_enabled(settings: &LinterSettings) -> bool {
|
||||
settings.preview.is_enabled()
|
||||
}
|
||||
|
||||
@@ -8,9 +8,12 @@ mod tests {
|
||||
use anyhow::Result;
|
||||
use test_case::test_case;
|
||||
|
||||
use ruff_python_ast::PythonVersion;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::LinterSettings;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_diagnostics, settings};
|
||||
use crate::{assert_diagnostics, assert_diagnostics_diff};
|
||||
|
||||
#[test_case(Rule::FastApiRedundantResponseModel, Path::new("FAST001.py"))]
|
||||
#[test_case(Rule::FastApiNonAnnotatedDependency, Path::new("FAST002_0.py"))]
|
||||
@@ -20,12 +23,35 @@ mod tests {
|
||||
let snapshot = format!("{}_{}", rule_code.name(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("fastapi").join(path).as_path(),
|
||||
&settings::LinterSettings::for_rule(rule_code),
|
||||
&LinterSettings::for_rule(rule_code),
|
||||
)?;
|
||||
assert_diagnostics!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::FastApiRedundantResponseModel, Path::new("FAST001.py"))]
|
||||
#[test_case(Rule::FastApiUnusedPathParameter, Path::new("FAST003.py"))]
|
||||
fn deferred_annotations_diff(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"deferred_annotations_diff_{}_{}",
|
||||
rule_code.name(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
assert_diagnostics_diff!(
|
||||
snapshot,
|
||||
Path::new("fastapi").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
unresolved_target_version: PythonVersion::PY313.into(),
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
&LinterSettings {
|
||||
unresolved_target_version: PythonVersion::PY314.into(),
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// FAST002 autofixes use `typing_extensions` on Python 3.8,
|
||||
// since `typing.Annotated` was added in Python 3.9
|
||||
#[test_case(Rule::FastApiNonAnnotatedDependency, Path::new("FAST002_0.py"))]
|
||||
@@ -34,9 +60,9 @@ mod tests {
|
||||
let snapshot = format!("{}_{}_py38", rule_code.name(), path.to_string_lossy());
|
||||
let diagnostics = test_path(
|
||||
Path::new("fastapi").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
unresolved_target_version: ruff_python_ast::PythonVersion::PY38.into(),
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
&LinterSettings {
|
||||
unresolved_target_version: PythonVersion::PY38.into(),
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
)?;
|
||||
assert_diagnostics!(snapshot, diagnostics);
|
||||
|
||||
@@ -0,0 +1,213 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/fastapi/mod.rs
|
||||
---
|
||||
--- Linter settings ---
|
||||
-linter.unresolved_target_version = 3.13
|
||||
+linter.unresolved_target_version = 3.14
|
||||
|
||||
--- Summary ---
|
||||
Removed: 10
|
||||
Added: 0
|
||||
|
||||
--- Removed ---
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:17:22
|
||||
|
|
||||
17 | @app.post("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
18 | async def create_item(item: Item) -> Item:
|
||||
19 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
14 | # Errors
|
||||
15 |
|
||||
16 |
|
||||
- @app.post("/items/", response_model=Item)
|
||||
17 + @app.post("/items/")
|
||||
18 | async def create_item(item: Item) -> Item:
|
||||
19 | return item
|
||||
20 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:22:22
|
||||
|
|
||||
22 | @app.post("/items/", response_model=list[Item])
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
23 | async def create_item(item: Item) -> list[Item]:
|
||||
24 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
19 | return item
|
||||
20 |
|
||||
21 |
|
||||
- @app.post("/items/", response_model=list[Item])
|
||||
22 + @app.post("/items/")
|
||||
23 | async def create_item(item: Item) -> list[Item]:
|
||||
24 | return item
|
||||
25 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:27:22
|
||||
|
|
||||
27 | @app.post("/items/", response_model=List[Item])
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
28 | async def create_item(item: Item) -> List[Item]:
|
||||
29 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
24 | return item
|
||||
25 |
|
||||
26 |
|
||||
- @app.post("/items/", response_model=List[Item])
|
||||
27 + @app.post("/items/")
|
||||
28 | async def create_item(item: Item) -> List[Item]:
|
||||
29 | return item
|
||||
30 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:32:22
|
||||
|
|
||||
32 | @app.post("/items/", response_model=Dict[str, Item])
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
33 | async def create_item(item: Item) -> Dict[str, Item]:
|
||||
34 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
29 | return item
|
||||
30 |
|
||||
31 |
|
||||
- @app.post("/items/", response_model=Dict[str, Item])
|
||||
32 + @app.post("/items/")
|
||||
33 | async def create_item(item: Item) -> Dict[str, Item]:
|
||||
34 | return item
|
||||
35 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:37:22
|
||||
|
|
||||
37 | @app.post("/items/", response_model=str)
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
38 | async def create_item(item: Item) -> str:
|
||||
39 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
34 | return item
|
||||
35 |
|
||||
36 |
|
||||
- @app.post("/items/", response_model=str)
|
||||
37 + @app.post("/items/")
|
||||
38 | async def create_item(item: Item) -> str:
|
||||
39 | return item
|
||||
40 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:42:21
|
||||
|
|
||||
42 | @app.get("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
43 | async def create_item(item: Item) -> Item:
|
||||
44 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
39 | return item
|
||||
40 |
|
||||
41 |
|
||||
- @app.get("/items/", response_model=Item)
|
||||
42 + @app.get("/items/")
|
||||
43 | async def create_item(item: Item) -> Item:
|
||||
44 | return item
|
||||
45 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:47:21
|
||||
|
|
||||
47 | @app.get("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
48 | @app.post("/items/", response_model=Item)
|
||||
49 | async def create_item(item: Item) -> Item:
|
||||
|
|
||||
help: Remove argument
|
||||
44 | return item
|
||||
45 |
|
||||
46 |
|
||||
- @app.get("/items/", response_model=Item)
|
||||
47 + @app.get("/items/")
|
||||
48 | @app.post("/items/", response_model=Item)
|
||||
49 | async def create_item(item: Item) -> Item:
|
||||
50 | return item
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:48:22
|
||||
|
|
||||
47 | @app.get("/items/", response_model=Item)
|
||||
48 | @app.post("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
49 | async def create_item(item: Item) -> Item:
|
||||
50 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
45 |
|
||||
46 |
|
||||
47 | @app.get("/items/", response_model=Item)
|
||||
- @app.post("/items/", response_model=Item)
|
||||
48 + @app.post("/items/")
|
||||
49 | async def create_item(item: Item) -> Item:
|
||||
50 | return item
|
||||
51 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:53:24
|
||||
|
|
||||
53 | @router.get("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
54 | async def create_item(item: Item) -> Item:
|
||||
55 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
50 | return item
|
||||
51 |
|
||||
52 |
|
||||
- @router.get("/items/", response_model=Item)
|
||||
53 + @router.get("/items/")
|
||||
54 | async def create_item(item: Item) -> Item:
|
||||
55 | return item
|
||||
56 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:118:23
|
||||
|
|
||||
116 | def setup_app(app_arg: FastAPI, non_app: str) -> None:
|
||||
117 | # Error
|
||||
118 | @app_arg.get("/", response_model=str)
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
119 | async def get_root() -> str:
|
||||
120 | return "Hello World!"
|
||||
|
|
||||
help: Remove argument
|
||||
115 |
|
||||
116 | def setup_app(app_arg: FastAPI, non_app: str) -> None:
|
||||
117 | # Error
|
||||
- @app_arg.get("/", response_model=str)
|
||||
118 + @app_arg.get("/")
|
||||
119 | async def get_root() -> str:
|
||||
120 | return "Hello World!"
|
||||
121 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/fastapi/mod.rs
|
||||
---
|
||||
--- Linter settings ---
|
||||
-linter.unresolved_target_version = 3.13
|
||||
+linter.unresolved_target_version = 3.14
|
||||
|
||||
--- Summary ---
|
||||
Removed: 3
|
||||
Added: 0
|
||||
|
||||
--- Removed ---
|
||||
FAST003 [*] Parameter `thing_id` appears in route path, but not in `single` signature
|
||||
--> FAST003.py:158:19
|
||||
|
|
||||
157 | ### Errors
|
||||
158 | @app.get("/things/{thing_id}")
|
||||
| ^^^^^^^^^^
|
||||
159 | async def single(other: Annotated[str, Depends(something_else)]): ...
|
||||
160 | @app.get("/things/{thing_id}")
|
||||
|
|
||||
help: Add `thing_id` to function signature
|
||||
156 |
|
||||
157 | ### Errors
|
||||
158 | @app.get("/things/{thing_id}")
|
||||
- async def single(other: Annotated[str, Depends(something_else)]): ...
|
||||
159 + async def single(other: Annotated[str, Depends(something_else)], thing_id): ...
|
||||
160 | @app.get("/things/{thing_id}")
|
||||
161 | async def default(other: str = Depends(something_else)): ...
|
||||
162 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST003 [*] Parameter `id` appears in route path, but not in `get_id_pydantic_full` signature
|
||||
--> FAST003.py:197:12
|
||||
|
|
||||
196 | # Errors
|
||||
197 | @app.get("/{id}")
|
||||
| ^^^^
|
||||
198 | async def get_id_pydantic_full(
|
||||
199 | params: Annotated[PydanticParams, Depends(PydanticParams)],
|
||||
|
|
||||
help: Add `id` to function signature
|
||||
196 | # Errors
|
||||
197 | @app.get("/{id}")
|
||||
198 | async def get_id_pydantic_full(
|
||||
- params: Annotated[PydanticParams, Depends(PydanticParams)],
|
||||
199 + params: Annotated[PydanticParams, Depends(PydanticParams)], id,
|
||||
200 | ): ...
|
||||
201 | @app.get("/{id}")
|
||||
202 | async def get_id_pydantic_short(params: Annotated[PydanticParams, Depends()]): ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
FAST003 [*] Parameter `id` appears in route path, but not in `get_id_pydantic_short` signature
|
||||
--> FAST003.py:201:12
|
||||
|
|
||||
199 | params: Annotated[PydanticParams, Depends(PydanticParams)],
|
||||
200 | ): ...
|
||||
201 | @app.get("/{id}")
|
||||
| ^^^^
|
||||
202 | async def get_id_pydantic_short(params: Annotated[PydanticParams, Depends()]): ...
|
||||
203 | @app.get("/{id}")
|
||||
|
|
||||
help: Add `id` to function signature
|
||||
199 | params: Annotated[PydanticParams, Depends(PydanticParams)],
|
||||
200 | ): ...
|
||||
201 | @app.get("/{id}")
|
||||
- async def get_id_pydantic_short(params: Annotated[PydanticParams, Depends()]): ...
|
||||
202 + async def get_id_pydantic_short(params: Annotated[PydanticParams, Depends()], id): ...
|
||||
203 | @app.get("/{id}")
|
||||
204 | async def get_id_init_not_annotated(params = Depends(InitParams)): ...
|
||||
205 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
@@ -1,195 +1,4 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/fastapi/mod.rs
|
||||
---
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:17:22
|
||||
|
|
||||
17 | @app.post("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
18 | async def create_item(item: Item) -> Item:
|
||||
19 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
14 | # Errors
|
||||
15 |
|
||||
16 |
|
||||
- @app.post("/items/", response_model=Item)
|
||||
17 + @app.post("/items/")
|
||||
18 | async def create_item(item: Item) -> Item:
|
||||
19 | return item
|
||||
20 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:22:22
|
||||
|
|
||||
22 | @app.post("/items/", response_model=list[Item])
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
23 | async def create_item(item: Item) -> list[Item]:
|
||||
24 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
19 | return item
|
||||
20 |
|
||||
21 |
|
||||
- @app.post("/items/", response_model=list[Item])
|
||||
22 + @app.post("/items/")
|
||||
23 | async def create_item(item: Item) -> list[Item]:
|
||||
24 | return item
|
||||
25 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:27:22
|
||||
|
|
||||
27 | @app.post("/items/", response_model=List[Item])
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
28 | async def create_item(item: Item) -> List[Item]:
|
||||
29 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
24 | return item
|
||||
25 |
|
||||
26 |
|
||||
- @app.post("/items/", response_model=List[Item])
|
||||
27 + @app.post("/items/")
|
||||
28 | async def create_item(item: Item) -> List[Item]:
|
||||
29 | return item
|
||||
30 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:32:22
|
||||
|
|
||||
32 | @app.post("/items/", response_model=Dict[str, Item])
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
33 | async def create_item(item: Item) -> Dict[str, Item]:
|
||||
34 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
29 | return item
|
||||
30 |
|
||||
31 |
|
||||
- @app.post("/items/", response_model=Dict[str, Item])
|
||||
32 + @app.post("/items/")
|
||||
33 | async def create_item(item: Item) -> Dict[str, Item]:
|
||||
34 | return item
|
||||
35 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:37:22
|
||||
|
|
||||
37 | @app.post("/items/", response_model=str)
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
38 | async def create_item(item: Item) -> str:
|
||||
39 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
34 | return item
|
||||
35 |
|
||||
36 |
|
||||
- @app.post("/items/", response_model=str)
|
||||
37 + @app.post("/items/")
|
||||
38 | async def create_item(item: Item) -> str:
|
||||
39 | return item
|
||||
40 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:42:21
|
||||
|
|
||||
42 | @app.get("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
43 | async def create_item(item: Item) -> Item:
|
||||
44 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
39 | return item
|
||||
40 |
|
||||
41 |
|
||||
- @app.get("/items/", response_model=Item)
|
||||
42 + @app.get("/items/")
|
||||
43 | async def create_item(item: Item) -> Item:
|
||||
44 | return item
|
||||
45 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:47:21
|
||||
|
|
||||
47 | @app.get("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
48 | @app.post("/items/", response_model=Item)
|
||||
49 | async def create_item(item: Item) -> Item:
|
||||
|
|
||||
help: Remove argument
|
||||
44 | return item
|
||||
45 |
|
||||
46 |
|
||||
- @app.get("/items/", response_model=Item)
|
||||
47 + @app.get("/items/")
|
||||
48 | @app.post("/items/", response_model=Item)
|
||||
49 | async def create_item(item: Item) -> Item:
|
||||
50 | return item
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:48:22
|
||||
|
|
||||
47 | @app.get("/items/", response_model=Item)
|
||||
48 | @app.post("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
49 | async def create_item(item: Item) -> Item:
|
||||
50 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
45 |
|
||||
46 |
|
||||
47 | @app.get("/items/", response_model=Item)
|
||||
- @app.post("/items/", response_model=Item)
|
||||
48 + @app.post("/items/")
|
||||
49 | async def create_item(item: Item) -> Item:
|
||||
50 | return item
|
||||
51 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:53:24
|
||||
|
|
||||
53 | @router.get("/items/", response_model=Item)
|
||||
| ^^^^^^^^^^^^^^^^^^^
|
||||
54 | async def create_item(item: Item) -> Item:
|
||||
55 | return item
|
||||
|
|
||||
help: Remove argument
|
||||
50 | return item
|
||||
51 |
|
||||
52 |
|
||||
- @router.get("/items/", response_model=Item)
|
||||
53 + @router.get("/items/")
|
||||
54 | async def create_item(item: Item) -> Item:
|
||||
55 | return item
|
||||
56 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST001 [*] FastAPI route with redundant `response_model` argument
|
||||
--> FAST001.py:118:23
|
||||
|
|
||||
116 | def setup_app(app_arg: FastAPI, non_app: str) -> None:
|
||||
117 | # Error
|
||||
118 | @app_arg.get("/", response_model=str)
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
119 | async def get_root() -> str:
|
||||
120 | return "Hello World!"
|
||||
|
|
||||
help: Remove argument
|
||||
115 |
|
||||
116 | def setup_app(app_arg: FastAPI, non_app: str) -> None:
|
||||
117 | # Error
|
||||
- @app_arg.get("/", response_model=str)
|
||||
118 + @app_arg.get("/")
|
||||
119 | async def get_root() -> str:
|
||||
120 | return "Hello World!"
|
||||
121 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -324,26 +324,6 @@ help: Add `name` to function signature
|
||||
91 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST003 [*] Parameter `thing_id` appears in route path, but not in `single` signature
|
||||
--> FAST003.py:158:19
|
||||
|
|
||||
157 | ### Errors
|
||||
158 | @app.get("/things/{thing_id}")
|
||||
| ^^^^^^^^^^
|
||||
159 | async def single(other: Annotated[str, Depends(something_else)]): ...
|
||||
160 | @app.get("/things/{thing_id}")
|
||||
|
|
||||
help: Add `thing_id` to function signature
|
||||
156 |
|
||||
157 | ### Errors
|
||||
158 | @app.get("/things/{thing_id}")
|
||||
- async def single(other: Annotated[str, Depends(something_else)]): ...
|
||||
159 + async def single(other: Annotated[str, Depends(something_else)], thing_id): ...
|
||||
160 | @app.get("/things/{thing_id}")
|
||||
161 | async def default(other: str = Depends(something_else)): ...
|
||||
162 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST003 [*] Parameter `thing_id` appears in route path, but not in `default` signature
|
||||
--> FAST003.py:160:19
|
||||
|
|
||||
@@ -364,47 +344,6 @@ help: Add `thing_id` to function signature
|
||||
164 | ### No errors
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST003 [*] Parameter `id` appears in route path, but not in `get_id_pydantic_full` signature
|
||||
--> FAST003.py:197:12
|
||||
|
|
||||
196 | # Errors
|
||||
197 | @app.get("/{id}")
|
||||
| ^^^^
|
||||
198 | async def get_id_pydantic_full(
|
||||
199 | params: Annotated[PydanticParams, Depends(PydanticParams)],
|
||||
|
|
||||
help: Add `id` to function signature
|
||||
196 | # Errors
|
||||
197 | @app.get("/{id}")
|
||||
198 | async def get_id_pydantic_full(
|
||||
- params: Annotated[PydanticParams, Depends(PydanticParams)],
|
||||
199 + params: Annotated[PydanticParams, Depends(PydanticParams)], id,
|
||||
200 | ): ...
|
||||
201 | @app.get("/{id}")
|
||||
202 | async def get_id_pydantic_short(params: Annotated[PydanticParams, Depends()]): ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST003 [*] Parameter `id` appears in route path, but not in `get_id_pydantic_short` signature
|
||||
--> FAST003.py:201:12
|
||||
|
|
||||
199 | params: Annotated[PydanticParams, Depends(PydanticParams)],
|
||||
200 | ): ...
|
||||
201 | @app.get("/{id}")
|
||||
| ^^^^
|
||||
202 | async def get_id_pydantic_short(params: Annotated[PydanticParams, Depends()]): ...
|
||||
203 | @app.get("/{id}")
|
||||
|
|
||||
help: Add `id` to function signature
|
||||
199 | params: Annotated[PydanticParams, Depends(PydanticParams)],
|
||||
200 | ): ...
|
||||
201 | @app.get("/{id}")
|
||||
- async def get_id_pydantic_short(params: Annotated[PydanticParams, Depends()]): ...
|
||||
202 + async def get_id_pydantic_short(params: Annotated[PydanticParams, Depends()], id): ...
|
||||
203 | @app.get("/{id}")
|
||||
204 | async def get_id_init_not_annotated(params = Depends(InitParams)): ...
|
||||
205 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
FAST003 [*] Parameter `id` appears in route path, but not in `get_id_init_not_annotated` signature
|
||||
--> FAST003.py:203:12
|
||||
|
|
||||
|
||||
@@ -34,9 +34,10 @@ use crate::{AlwaysFixableViolation, Applicability, Fix};
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// This rule's fix is marked as unsafe for `map` calls that contain
|
||||
/// `**kwargs`, as adding a `strict` keyword argument to such a call may lead
|
||||
/// to a duplicate keyword argument error.
|
||||
/// This rule's fix is marked as unsafe. While adding `strict=False` preserves
|
||||
/// the runtime behavior, it can obscure situations where the iterables are of
|
||||
/// unequal length. Ruff prefers to alert users so they can choose the intended
|
||||
/// behavior themselves.
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `map`](https://docs.python.org/3/library/functions.html#map)
|
||||
@@ -73,17 +74,7 @@ pub(crate) fn map_without_explicit_strict(checker: &Checker, call: &ast::ExprCal
|
||||
checker.comment_ranges(),
|
||||
checker.locator().contents(),
|
||||
),
|
||||
// If the function call contains `**kwargs`, mark the fix as unsafe.
|
||||
if call
|
||||
.arguments
|
||||
.keywords
|
||||
.iter()
|
||||
.any(|keyword| keyword.arg.is_none())
|
||||
{
|
||||
Applicability::Unsafe
|
||||
} else {
|
||||
Applicability::Safe
|
||||
},
|
||||
Applicability::Unsafe,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,9 +31,10 @@ use crate::{AlwaysFixableViolation, Applicability, Fix};
|
||||
/// ```
|
||||
///
|
||||
/// ## Fix safety
|
||||
/// This rule's fix is marked as unsafe for `zip` calls that contain
|
||||
/// `**kwargs`, as adding a `strict` keyword argument to such a call may lead
|
||||
/// to a duplicate keyword argument error.
|
||||
/// This rule's fix is marked as unsafe. While adding `strict=False` preserves
|
||||
/// the runtime behavior, it can obscure situations where the iterables are of
|
||||
/// unequal length. Ruff prefers to alert users so they can choose the intended
|
||||
/// behavior themselves.
|
||||
///
|
||||
/// ## References
|
||||
/// - [Python documentation: `zip`](https://docs.python.org/3/library/functions.html#zip)
|
||||
@@ -68,17 +69,7 @@ pub(crate) fn zip_without_explicit_strict(checker: &Checker, call: &ast::ExprCal
|
||||
checker.comment_ranges(),
|
||||
checker.locator().contents(),
|
||||
),
|
||||
// If the function call contains `**kwargs`, mark the fix as unsafe.
|
||||
if call
|
||||
.arguments
|
||||
.keywords
|
||||
.iter()
|
||||
.any(|keyword| keyword.arg.is_none())
|
||||
{
|
||||
Applicability::Unsafe
|
||||
} else {
|
||||
Applicability::Safe
|
||||
},
|
||||
Applicability::Unsafe,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
|
||||
assertion_line: 156
|
||||
---
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:4:1
|
||||
@@ -19,6 +20,7 @@ help: Add explicit value for parameter `strict=`
|
||||
5 | zip(range(3))
|
||||
6 | zip("a", "b")
|
||||
7 | zip("a", "b", *zip("c"))
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:5:1
|
||||
@@ -39,6 +41,7 @@ help: Add explicit value for parameter `strict=`
|
||||
6 | zip("a", "b")
|
||||
7 | zip("a", "b", *zip("c"))
|
||||
8 | zip(zip("a"), strict=False)
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:6:1
|
||||
@@ -59,6 +62,7 @@ help: Add explicit value for parameter `strict=`
|
||||
7 | zip("a", "b", *zip("c"))
|
||||
8 | zip(zip("a"), strict=False)
|
||||
9 | zip(zip("a", strict=True))
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:7:1
|
||||
@@ -79,6 +83,7 @@ help: Add explicit value for parameter `strict=`
|
||||
8 | zip(zip("a"), strict=False)
|
||||
9 | zip(zip("a", strict=True))
|
||||
10 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:7:16
|
||||
@@ -99,6 +104,7 @@ help: Add explicit value for parameter `strict=`
|
||||
8 | zip(zip("a"), strict=False)
|
||||
9 | zip(zip("a", strict=True))
|
||||
10 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:8:5
|
||||
@@ -118,6 +124,7 @@ help: Add explicit value for parameter `strict=`
|
||||
9 | zip(zip("a", strict=True))
|
||||
10 |
|
||||
11 | # OK
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:9:1
|
||||
@@ -138,6 +145,7 @@ help: Add explicit value for parameter `strict=`
|
||||
10 |
|
||||
11 | # OK
|
||||
12 | zip(range(3), strict=True)
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:24:1
|
||||
@@ -156,6 +164,7 @@ help: Add explicit value for parameter `strict=`
|
||||
25 | zip([1, 2, 3], repeat(1, times=4))
|
||||
26 |
|
||||
27 | import builtins
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:25:1
|
||||
@@ -176,6 +185,7 @@ help: Add explicit value for parameter `strict=`
|
||||
26 |
|
||||
27 | import builtins
|
||||
28 | # Still an error even though it uses the qualified name
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B905 [*] `zip()` without an explicit `strict=` parameter
|
||||
--> B905.py:29:1
|
||||
@@ -191,3 +201,4 @@ help: Add explicit value for parameter `strict=`
|
||||
28 | # Still an error even though it uses the qualified name
|
||||
- builtins.zip([1, 2, 3])
|
||||
29 + builtins.zip([1, 2, 3], strict=False)
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_bugbear/mod.rs
|
||||
assertion_line: 112
|
||||
---
|
||||
B912 [*] `map()` without an explicit `strict=` parameter
|
||||
--> B912.py:5:1
|
||||
@@ -20,6 +21,7 @@ help: Add explicit value for parameter `strict=`
|
||||
6 | map(lambda x, y, z: x + y + z, [1, 2, 3], [4, 5, 6], [7, 8, 9])
|
||||
7 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9]))
|
||||
8 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9]), strict=False)
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B912 [*] `map()` without an explicit `strict=` parameter
|
||||
--> B912.py:6:1
|
||||
@@ -40,6 +42,7 @@ help: Add explicit value for parameter `strict=`
|
||||
7 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9]))
|
||||
8 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9]), strict=False)
|
||||
9 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9], strict=True))
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B912 [*] `map()` without an explicit `strict=` parameter
|
||||
--> B912.py:7:1
|
||||
@@ -61,6 +64,7 @@ help: Add explicit value for parameter `strict=`
|
||||
9 | map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6], *map(lambda x: x, [7, 8, 9], strict=True))
|
||||
10 |
|
||||
11 | # Errors (limited iterators).
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B912 [*] `map()` without an explicit `strict=` parameter
|
||||
--> B912.py:9:1
|
||||
@@ -81,6 +85,7 @@ help: Add explicit value for parameter `strict=`
|
||||
10 |
|
||||
11 | # Errors (limited iterators).
|
||||
12 | map(lambda x, y: x + y, [1, 2, 3], repeat(1, 1))
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B912 [*] `map()` without an explicit `strict=` parameter
|
||||
--> B912.py:12:1
|
||||
@@ -99,6 +104,7 @@ help: Add explicit value for parameter `strict=`
|
||||
13 | map(lambda x, y: x + y, [1, 2, 3], repeat(1, times=4))
|
||||
14 |
|
||||
15 | import builtins
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B912 [*] `map()` without an explicit `strict=` parameter
|
||||
--> B912.py:13:1
|
||||
@@ -119,6 +125,7 @@ help: Add explicit value for parameter `strict=`
|
||||
14 |
|
||||
15 | import builtins
|
||||
16 | # Still an error even though it uses the qualified name
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
B912 [*] `map()` without an explicit `strict=` parameter
|
||||
--> B912.py:17:1
|
||||
@@ -139,3 +146,4 @@ help: Add explicit value for parameter `strict=`
|
||||
18 |
|
||||
19 | # OK
|
||||
20 | map(lambda x: x, [1, 2, 3], strict=True)
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -10,12 +10,12 @@ mod tests {
|
||||
use anyhow::Result;
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::assert_diagnostics;
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::flake8_builtins;
|
||||
use crate::settings::LinterSettings;
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::test::{test_path, test_resource_path};
|
||||
use crate::{assert_diagnostics, assert_diagnostics_diff};
|
||||
use ruff_python_ast::PythonVersion;
|
||||
|
||||
#[test_case(Rule::BuiltinVariableShadowing, Path::new("A001.py"))]
|
||||
@@ -64,6 +64,28 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::BuiltinAttributeShadowing, Path::new("A003.py"))]
|
||||
fn deferred_annotations_diff(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"deferred_annotations_diff_{}_{}",
|
||||
rule_code.name(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
assert_diagnostics_diff!(
|
||||
snapshot,
|
||||
Path::new("flake8_builtins").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
unresolved_target_version: PythonVersion::PY313.into(),
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
&LinterSettings {
|
||||
unresolved_target_version: PythonVersion::PY314.into(),
|
||||
..LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::BuiltinAttributeShadowing, Path::new("A003.py"))]
|
||||
fn preview_rules(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
|
||||
@@ -1,22 +1,4 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_builtins/mod.rs
|
||||
---
|
||||
A003 Python builtin is shadowed by method `str` from line 14
|
||||
--> A003.py:17:31
|
||||
|
|
||||
15 | pass
|
||||
16 |
|
||||
17 | def method_usage(self) -> str:
|
||||
| ^^^
|
||||
18 | pass
|
||||
|
|
||||
|
||||
A003 Python builtin is shadowed by class attribute `id` from line 3
|
||||
--> A003.py:20:34
|
||||
|
|
||||
18 | pass
|
||||
19 |
|
||||
20 | def attribute_usage(self) -> id:
|
||||
| ^^
|
||||
21 | pass
|
||||
|
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_builtins/mod.rs
|
||||
---
|
||||
A003 Python builtin is shadowed by method `str` from line 14
|
||||
--> A003.py:17:31
|
||||
|
|
||||
15 | pass
|
||||
16 |
|
||||
17 | def method_usage(self) -> str:
|
||||
| ^^^
|
||||
18 | pass
|
||||
|
|
||||
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_builtins/mod.rs
|
||||
---
|
||||
--- Linter settings ---
|
||||
-linter.unresolved_target_version = 3.13
|
||||
+linter.unresolved_target_version = 3.14
|
||||
|
||||
--- Summary ---
|
||||
Removed: 2
|
||||
Added: 0
|
||||
|
||||
--- Removed ---
|
||||
A003 Python builtin is shadowed by method `str` from line 14
|
||||
--> A003.py:17:31
|
||||
|
|
||||
15 | pass
|
||||
16 |
|
||||
17 | def method_usage(self) -> str:
|
||||
| ^^^
|
||||
18 | pass
|
||||
|
|
||||
|
||||
|
||||
A003 Python builtin is shadowed by class attribute `id` from line 3
|
||||
--> A003.py:20:34
|
||||
|
|
||||
18 | pass
|
||||
19 |
|
||||
20 | def attribute_usage(self) -> id:
|
||||
| ^^
|
||||
21 | pass
|
||||
|
|
||||
@@ -1,26 +1,6 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_builtins/mod.rs
|
||||
---
|
||||
A003 Python builtin is shadowed by method `str` from line 14
|
||||
--> A003.py:17:31
|
||||
|
|
||||
15 | pass
|
||||
16 |
|
||||
17 | def method_usage(self) -> str:
|
||||
| ^^^
|
||||
18 | pass
|
||||
|
|
||||
|
||||
A003 Python builtin is shadowed by class attribute `id` from line 3
|
||||
--> A003.py:20:34
|
||||
|
|
||||
18 | pass
|
||||
19 |
|
||||
20 | def attribute_usage(self) -> id:
|
||||
| ^^
|
||||
21 | pass
|
||||
|
|
||||
|
||||
A003 Python builtin is shadowed by method `property` from line 26
|
||||
--> A003.py:31:7
|
||||
|
|
||||
|
||||
@@ -1,6 +1,196 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_pyi/mod.rs
|
||||
---
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`.
|
||||
--> PYI055.py:4:4
|
||||
|
|
||||
2 | from typing import Union
|
||||
3 |
|
||||
4 | s: builtins.type[int] | builtins.type[str] | builtins.type[complex]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
5 | t: type[int] | type[str] | type[float]
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
1 | import builtins
|
||||
2 | from typing import Union
|
||||
3 |
|
||||
- s: builtins.type[int] | builtins.type[str] | builtins.type[complex]
|
||||
4 + s: type[int | str | complex]
|
||||
5 | t: type[int] | type[str] | type[float]
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | float]`.
|
||||
--> PYI055.py:5:4
|
||||
|
|
||||
4 | s: builtins.type[int] | builtins.type[str] | builtins.type[complex]
|
||||
5 | t: type[int] | type[str] | type[float]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
2 | from typing import Union
|
||||
3 |
|
||||
4 | s: builtins.type[int] | builtins.type[str] | builtins.type[complex]
|
||||
- t: type[int] | type[str] | type[float]
|
||||
5 + t: type[int | str | float]
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | str | complex]`.
|
||||
--> PYI055.py:6:4
|
||||
|
|
||||
4 | s: builtins.type[int] | builtins.type[str] | builtins.type[complex]
|
||||
5 | t: type[int] | type[str] | type[float]
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
3 |
|
||||
4 | s: builtins.type[int] | builtins.type[str] | builtins.type[complex]
|
||||
5 | t: type[int] | type[str] | type[float]
|
||||
- u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
6 + u: type[int | str | complex]
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float, complex]]`.
|
||||
--> PYI055.py:7:4
|
||||
|
|
||||
5 | t: type[int] | type[str] | type[float]
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
4 | s: builtins.type[int] | builtins.type[str] | builtins.type[complex]
|
||||
5 | t: type[int] | type[str] | type[float]
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
- v: Union[type[float], type[complex]]
|
||||
7 + v: type[Union[float, complex]]
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
10 | y: Union[Union[Union[type[float | int], type[complex]]]]
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float | int, complex]]`.
|
||||
--> PYI055.py:8:4
|
||||
|
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
10 | y: Union[Union[Union[type[float | int], type[complex]]]]
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
5 | t: type[int] | type[str] | type[float]
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
- w: Union[type[float | int], type[complex]]
|
||||
8 + w: type[Union[float | int, complex]]
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
10 | y: Union[Union[Union[type[float | int], type[complex]]]]
|
||||
11 | z: Union[type[complex], Union[Union[type[Union[float, int]]]]]
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[Union[float, int], complex]]`.
|
||||
--> PYI055.py:9:4
|
||||
|
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
10 | y: Union[Union[Union[type[float | int], type[complex]]]]
|
||||
11 | z: Union[type[complex], Union[Union[type[Union[float, int]]]]]
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
6 | u: builtins.type[int] | type[str] | builtins.type[complex]
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
- x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
9 + x: type[Union[Union[float, int], complex]]
|
||||
10 | y: Union[Union[Union[type[float | int], type[complex]]]]
|
||||
11 | z: Union[type[complex], Union[Union[type[Union[float, int]]]]]
|
||||
12 |
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[float | int, complex]]`.
|
||||
--> PYI055.py:10:4
|
||||
|
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
10 | y: Union[Union[Union[type[float | int], type[complex]]]]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
11 | z: Union[type[complex], Union[Union[type[Union[float, int]]]]]
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
7 | v: Union[type[float], type[complex]]
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
- y: Union[Union[Union[type[float | int], type[complex]]]]
|
||||
10 + y: type[Union[float | int, complex]]
|
||||
11 | z: Union[type[complex], Union[Union[type[Union[float, int]]]]]
|
||||
12 |
|
||||
13 |
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[Union[complex, Union[float, int]]]`.
|
||||
--> PYI055.py:11:4
|
||||
|
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
10 | y: Union[Union[Union[type[float | int], type[complex]]]]
|
||||
11 | z: Union[type[complex], Union[Union[type[Union[float, int]]]]]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
8 | w: Union[type[float | int], type[complex]]
|
||||
9 | x: Union[Union[type[Union[float, int]], type[complex]]]
|
||||
10 | y: Union[Union[Union[type[float | int], type[complex]]]]
|
||||
- z: Union[type[complex], Union[Union[type[Union[float, int]]]]]
|
||||
11 + z: type[Union[complex, Union[float, int]]]
|
||||
12 |
|
||||
13 |
|
||||
14 | def func(arg: type[int] | str | type[float]) -> None:
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[int | float]`.
|
||||
--> PYI055.py:14:15
|
||||
|
|
||||
14 | def func(arg: type[int] | str | type[float]) -> None:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
15 | ...
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
11 | z: Union[type[complex], Union[Union[type[Union[float, int]]]]]
|
||||
12 |
|
||||
13 |
|
||||
- def func(arg: type[int] | str | type[float]) -> None:
|
||||
14 + def func(arg: type[int | float] | str) -> None:
|
||||
15 | ...
|
||||
16 |
|
||||
17 |
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty]`.
|
||||
--> PYI055.py:29:7
|
||||
|
|
||||
28 | # OK
|
||||
29 | item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
help: Combine multiple `type` members
|
||||
26 |
|
||||
27 |
|
||||
28 | # OK
|
||||
- item: type[requests_mock.Mocker] | type[httpretty] = requests_mock.Mocker
|
||||
29 + item: type[requests_mock.Mocker | httpretty] = requests_mock.Mocker
|
||||
30 |
|
||||
31 |
|
||||
32 | def func():
|
||||
|
||||
PYI055 [*] Multiple `type` members in a union. Combine them into one, e.g., `type[requests_mock.Mocker | httpretty | str]`.
|
||||
--> PYI055.py:34:8
|
||||
|
|
||||
|
||||
@@ -11,18 +11,17 @@ TC003 [*] Move standard library import `collections.Counter` into a type-checkin
|
||||
|
|
||||
help: Move into type-checking block
|
||||
- from collections import Counter
|
||||
1 + from __future__ import annotations
|
||||
2 |
|
||||
3 | from elsewhere import third_party
|
||||
4 |
|
||||
5 | from . import first_party
|
||||
6 + from typing import TYPE_CHECKING
|
||||
7 +
|
||||
8 + if TYPE_CHECKING:
|
||||
9 + from collections import Counter
|
||||
1 |
|
||||
2 | from elsewhere import third_party
|
||||
3 |
|
||||
4 | from . import first_party
|
||||
5 + from typing import TYPE_CHECKING
|
||||
6 +
|
||||
7 + if TYPE_CHECKING:
|
||||
8 + from collections import Counter
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 | def f(x: first_party.foo): ...
|
||||
11 | def f(x: first_party.foo): ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `elsewhere.third_party` into a type-checking block
|
||||
@@ -36,19 +35,18 @@ TC002 [*] Move third-party import `elsewhere.third_party` into a type-checking b
|
||||
5 | from . import first_party
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from __future__ import annotations
|
||||
2 | from collections import Counter
|
||||
3 |
|
||||
1 | from collections import Counter
|
||||
2 |
|
||||
- from elsewhere import third_party
|
||||
4 |
|
||||
5 | from . import first_party
|
||||
6 + from typing import TYPE_CHECKING
|
||||
7 +
|
||||
8 + if TYPE_CHECKING:
|
||||
9 + from elsewhere import third_party
|
||||
3 |
|
||||
4 | from . import first_party
|
||||
5 + from typing import TYPE_CHECKING
|
||||
6 +
|
||||
7 + if TYPE_CHECKING:
|
||||
8 + from elsewhere import third_party
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 | def f(x: first_party.foo): ...
|
||||
11 | def f(x: first_party.foo): ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC001 [*] Move application import `.first_party` into a type-checking block
|
||||
@@ -60,17 +58,15 @@ TC001 [*] Move application import `.first_party` into a type-checking block
|
||||
| ^^^^^^^^^^^
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from __future__ import annotations
|
||||
2 | from collections import Counter
|
||||
3 |
|
||||
4 | from elsewhere import third_party
|
||||
5 |
|
||||
2 |
|
||||
3 | from elsewhere import third_party
|
||||
4 |
|
||||
- from . import first_party
|
||||
6 + from typing import TYPE_CHECKING
|
||||
7 +
|
||||
8 + if TYPE_CHECKING:
|
||||
9 + from . import first_party
|
||||
5 + from typing import TYPE_CHECKING
|
||||
6 +
|
||||
7 + if TYPE_CHECKING:
|
||||
8 + from . import first_party
|
||||
9 |
|
||||
10 |
|
||||
11 |
|
||||
12 | def f(x: first_party.foo): ...
|
||||
11 | def f(x: first_party.foo): ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -12,15 +12,14 @@ TC001 [*] Move application import `.first_party` into a type-checking block
|
||||
|
|
||||
help: Move into type-checking block
|
||||
- def f():
|
||||
1 + from __future__ import annotations
|
||||
2 + from typing import TYPE_CHECKING
|
||||
3 +
|
||||
4 + if TYPE_CHECKING:
|
||||
5 | from . import first_party
|
||||
6 + def f():
|
||||
7 |
|
||||
8 | def f(x: first_party.foo): ...
|
||||
9 |
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 | from . import first_party
|
||||
5 + def f():
|
||||
6 |
|
||||
7 | def f(x: first_party.foo): ...
|
||||
8 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC001 [*] Move application import `.foo` into a type-checking block
|
||||
@@ -33,24 +32,19 @@ TC001 [*] Move application import `.foo` into a type-checking block
|
||||
59 | def f(x: Union[foo.Ty, int]): ...
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from __future__ import annotations
|
||||
2 | def f():
|
||||
3 | from . import first_party
|
||||
4 |
|
||||
--------------------------------------------------------------------------------
|
||||
50 |
|
||||
51 |
|
||||
52 |
|
||||
53 | # unions
|
||||
52 | # unions
|
||||
- from typing import Union
|
||||
54 + from typing import Union, TYPE_CHECKING
|
||||
55 |
|
||||
56 + if TYPE_CHECKING:
|
||||
57 + from . import foo
|
||||
58 +
|
||||
59 |
|
||||
60 | def n():
|
||||
53 + from typing import Union, TYPE_CHECKING
|
||||
54 +
|
||||
55 + if TYPE_CHECKING:
|
||||
56 + from . import foo
|
||||
57 |
|
||||
58 |
|
||||
59 | def n():
|
||||
- from . import foo
|
||||
61 |
|
||||
62 | def f(x: Union[foo.Ty, int]): ...
|
||||
63 | def g(x: foo.Ty | int): ...
|
||||
60 |
|
||||
61 | def f(x: Union[foo.Ty, int]): ...
|
||||
62 | def g(x: foo.Ty | int): ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -220,32 +220,3 @@ help: Move into type-checking block
|
||||
52 | x = dict["pd.DataFrame", "pd.DataFrame"]
|
||||
53 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `module.Member` into a type-checking block
|
||||
--> TC002.py:172:24
|
||||
|
|
||||
170 | global Member
|
||||
171 |
|
||||
172 | from module import Member
|
||||
| ^^^^^^
|
||||
173 |
|
||||
174 | x: Member = 1
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 | """Tests to determine accurate detection of typing-only imports."""
|
||||
2 + from typing import TYPE_CHECKING
|
||||
3 +
|
||||
4 + if TYPE_CHECKING:
|
||||
5 + from module import Member
|
||||
6 |
|
||||
7 |
|
||||
8 | def f():
|
||||
--------------------------------------------------------------------------------
|
||||
173 | def f():
|
||||
174 | global Member
|
||||
175 |
|
||||
- from module import Member
|
||||
176 |
|
||||
177 | x: Member = 1
|
||||
178 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -1,26 +1,6 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
|
||||
---
|
||||
TC004 [*] Quote references to `pandas.DataFrame`. Import is in a type-checking block.
|
||||
--> quote.py:57:28
|
||||
|
|
||||
56 | if TYPE_CHECKING:
|
||||
57 | from pandas import DataFrame
|
||||
| ^^^^^^^^^
|
||||
58 |
|
||||
59 | def func(value: DataFrame):
|
||||
|
|
||||
help: Quote references
|
||||
56 | if TYPE_CHECKING:
|
||||
57 | from pandas import DataFrame
|
||||
58 |
|
||||
- def func(value: DataFrame):
|
||||
59 + def func(value: "DataFrame"):
|
||||
60 | ...
|
||||
61 |
|
||||
62 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC004 [*] Move import `pandas.DataFrame` out of type-checking block. Import is used for more than type hinting.
|
||||
--> quote.py:110:28
|
||||
|
|
||||
|
||||
@@ -11,18 +11,15 @@ TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
4 | def baz() -> DataFrame:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
- def f():
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 | from pandas import DataFrame
|
||||
5 + def f():
|
||||
6 |
|
||||
- def baz() -> DataFrame:
|
||||
7 + def baz() -> "DataFrame":
|
||||
8 | ...
|
||||
9 |
|
||||
10 |
|
||||
- def f():
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 | from pandas import DataFrame
|
||||
5 + def f():
|
||||
6 |
|
||||
7 | def baz() -> DataFrame:
|
||||
8 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
@@ -48,11 +45,8 @@ help: Move into type-checking block
|
||||
12 | def f():
|
||||
- from pandas import DataFrame
|
||||
13 |
|
||||
- def baz() -> DataFrame[int]:
|
||||
14 + def baz() -> "DataFrame[int]":
|
||||
14 | def baz() -> DataFrame[int]:
|
||||
15 | ...
|
||||
16 |
|
||||
17 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas` into a type-checking block
|
||||
@@ -78,11 +72,8 @@ help: Move into type-checking block
|
||||
19 | def f():
|
||||
- import pandas as pd
|
||||
20 |
|
||||
- def baz() -> pd.DataFrame:
|
||||
21 + def baz() -> "pd.DataFrame":
|
||||
21 | def baz() -> pd.DataFrame:
|
||||
22 | ...
|
||||
23 |
|
||||
24 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas` into a type-checking block
|
||||
@@ -108,11 +99,8 @@ help: Move into type-checking block
|
||||
26 | def f():
|
||||
- import pandas as pd
|
||||
27 |
|
||||
- def baz() -> pd.DataFrame.Extra:
|
||||
28 + def baz() -> "pd.DataFrame.Extra":
|
||||
28 | def baz() -> pd.DataFrame.Extra:
|
||||
29 | ...
|
||||
30 |
|
||||
31 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas` into a type-checking block
|
||||
@@ -138,11 +126,8 @@ help: Move into type-checking block
|
||||
33 | def f():
|
||||
- import pandas as pd
|
||||
34 |
|
||||
- def baz() -> pd.DataFrame | int:
|
||||
35 + def baz() -> "pd.DataFrame | int":
|
||||
35 | def baz() -> pd.DataFrame | int:
|
||||
36 | ...
|
||||
37 |
|
||||
38 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
@@ -168,11 +153,8 @@ help: Move into type-checking block
|
||||
41 | def f():
|
||||
- from pandas import DataFrame
|
||||
42 |
|
||||
- def baz() -> DataFrame():
|
||||
43 + def baz() -> "DataFrame()":
|
||||
43 | def baz() -> DataFrame():
|
||||
44 | ...
|
||||
45 |
|
||||
46 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
@@ -199,11 +181,8 @@ help: Move into type-checking block
|
||||
50 |
|
||||
- from pandas import DataFrame
|
||||
51 |
|
||||
- def baz() -> DataFrame[Literal["int"]]:
|
||||
52 + def baz() -> "DataFrame[Literal['int']]":
|
||||
52 | def baz() -> DataFrame[Literal["int"]]:
|
||||
53 | ...
|
||||
54 |
|
||||
55 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
@@ -229,11 +208,8 @@ help: Move into type-checking block
|
||||
67 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
68 |
|
||||
- def baz() -> DataFrame | Series:
|
||||
69 + def baz() -> "DataFrame | Series":
|
||||
69 | def baz() -> DataFrame | Series:
|
||||
70 | ...
|
||||
71 |
|
||||
72 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.Series` into a type-checking block
|
||||
@@ -259,11 +235,8 @@ help: Move into type-checking block
|
||||
67 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
68 |
|
||||
- def baz() -> DataFrame | Series:
|
||||
69 + def baz() -> "DataFrame | Series":
|
||||
69 | def baz() -> DataFrame | Series:
|
||||
70 | ...
|
||||
71 |
|
||||
72 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
@@ -290,23 +263,7 @@ help: Move into type-checking block
|
||||
- from pandas import DataFrame, Series
|
||||
75 |
|
||||
76 | def baz() -> (
|
||||
- DataFrame |
|
||||
- Series
|
||||
77 + "DataFrame | Series"
|
||||
78 | ):
|
||||
79 | ...
|
||||
80 |
|
||||
81 | class C:
|
||||
- x: DataFrame[
|
||||
- int
|
||||
- ] = 1
|
||||
82 + x: "DataFrame[int]" = 1
|
||||
83 |
|
||||
- def func() -> DataFrame[[DataFrame[_P, _R]], DataFrame[_P, _R]]:
|
||||
84 + def func() -> "DataFrame[[DataFrame[_P, _R]], DataFrame[_P, _R]]":
|
||||
85 | ...
|
||||
86 |
|
||||
87 |
|
||||
77 | DataFrame |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.Series` into a type-checking block
|
||||
@@ -333,23 +290,7 @@ help: Move into type-checking block
|
||||
- from pandas import DataFrame, Series
|
||||
75 |
|
||||
76 | def baz() -> (
|
||||
- DataFrame |
|
||||
- Series
|
||||
77 + "DataFrame | Series"
|
||||
78 | ):
|
||||
79 | ...
|
||||
80 |
|
||||
81 | class C:
|
||||
- x: DataFrame[
|
||||
- int
|
||||
- ] = 1
|
||||
82 + x: "DataFrame[int]" = 1
|
||||
83 |
|
||||
- def func() -> DataFrame[[DataFrame[_P, _R]], DataFrame[_P, _R]]:
|
||||
84 + def func() -> "DataFrame[[DataFrame[_P, _R]], DataFrame[_P, _R]]":
|
||||
85 | ...
|
||||
86 |
|
||||
87 |
|
||||
77 | DataFrame |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
@@ -375,11 +316,8 @@ help: Move into type-checking block
|
||||
92 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
93 |
|
||||
- def func(self) -> DataFrame | list[Series]:
|
||||
94 + def func(self) -> "DataFrame | list[Series]":
|
||||
94 | def func(self) -> DataFrame | list[Series]:
|
||||
95 | pass
|
||||
96 |
|
||||
97 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.Series` into a type-checking block
|
||||
@@ -405,9 +343,6 @@ help: Move into type-checking block
|
||||
92 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
93 |
|
||||
- def func(self) -> DataFrame | list[Series]:
|
||||
94 + def func(self) -> "DataFrame | list[Series]":
|
||||
94 | def func(self) -> DataFrame | list[Series]:
|
||||
95 | pass
|
||||
96 |
|
||||
97 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -11,18 +11,15 @@ TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser`
|
||||
4 | def test_remove_inner_quotes_double(self, user: AbstractBaseUser["int"]):
|
||||
|
|
||||
help: Move into type-checking block
|
||||
- def f():
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 | from django.contrib.auth.models import AbstractBaseUser
|
||||
5 + def f():
|
||||
6 |
|
||||
- def test_remove_inner_quotes_double(self, user: AbstractBaseUser["int"]):
|
||||
7 + def test_remove_inner_quotes_double(self, user: "AbstractBaseUser[int]"):
|
||||
8 | pass
|
||||
9 |
|
||||
10 |
|
||||
- def f():
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 | from django.contrib.auth.models import AbstractBaseUser
|
||||
5 + def f():
|
||||
6 |
|
||||
7 | def test_remove_inner_quotes_double(self, user: AbstractBaseUser["int"]):
|
||||
8 | pass
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -48,11 +45,8 @@ help: Move into type-checking block
|
||||
12 | def f():
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
13 |
|
||||
- def test_remove_inner_quotes_single(self, user: AbstractBaseUser['int']):
|
||||
14 + def test_remove_inner_quotes_single(self, user: "AbstractBaseUser[int]"):
|
||||
14 | def test_remove_inner_quotes_single(self, user: AbstractBaseUser['int']):
|
||||
15 | pass
|
||||
16 |
|
||||
17 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -78,11 +72,8 @@ help: Move into type-checking block
|
||||
19 | def f():
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
20 |
|
||||
- def test_remove_inner_quotes_mixed(self, user: AbstractBaseUser['int', "str"]):
|
||||
21 + def test_remove_inner_quotes_mixed(self, user: "AbstractBaseUser[int, str]"):
|
||||
21 | def test_remove_inner_quotes_mixed(self, user: AbstractBaseUser['int', "str"]):
|
||||
22 | pass
|
||||
23 |
|
||||
24 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -109,11 +100,8 @@ help: Move into type-checking block
|
||||
28 |
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
29 |
|
||||
- def test_literal_annotation_args_contain_quotes(self, type1: AbstractBaseUser[Literal["user", "admin"], Annotated["int", "1", 2]]):
|
||||
30 + def test_literal_annotation_args_contain_quotes(self, type1: "AbstractBaseUser[Literal['user', 'admin'], Annotated[int, '1', 2]]"):
|
||||
30 | def test_literal_annotation_args_contain_quotes(self, type1: AbstractBaseUser[Literal["user", "admin"], Annotated["int", "1", 2]]):
|
||||
31 | pass
|
||||
32 |
|
||||
33 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -140,11 +128,8 @@ help: Move into type-checking block
|
||||
37 |
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
38 |
|
||||
- def test_union_contain_inner_quotes(self, type1: AbstractBaseUser["int" | Literal["int"]]):
|
||||
39 + def test_union_contain_inner_quotes(self, type1: "AbstractBaseUser[int | Literal['int']]"):
|
||||
39 | def test_union_contain_inner_quotes(self, type1: AbstractBaseUser["int" | Literal["int"]]):
|
||||
40 | pass
|
||||
41 |
|
||||
42 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -171,11 +156,8 @@ help: Move into type-checking block
|
||||
46 |
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
47 |
|
||||
- def test_inner_literal_mixed_quotes(user: AbstractBaseUser[Literal['user', "admin"]]):
|
||||
48 + def test_inner_literal_mixed_quotes(user: "AbstractBaseUser[Literal['user', 'admin']]"):
|
||||
48 | def test_inner_literal_mixed_quotes(user: AbstractBaseUser[Literal['user', "admin"]]):
|
||||
49 | pass
|
||||
50 |
|
||||
51 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -202,11 +184,8 @@ help: Move into type-checking block
|
||||
55 |
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
56 |
|
||||
- def test_inner_literal_single_quote(user: AbstractBaseUser[Literal['int'], str]):
|
||||
57 + def test_inner_literal_single_quote(user: "AbstractBaseUser[Literal['int'], str]"):
|
||||
57 | def test_inner_literal_single_quote(user: AbstractBaseUser[Literal['int'], str]):
|
||||
58 | pass
|
||||
59 |
|
||||
60 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -233,11 +212,8 @@ help: Move into type-checking block
|
||||
64 |
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
65 |
|
||||
- def test_mixed_quotes_literal(user: AbstractBaseUser[Literal['user'], "int"]):
|
||||
66 + def test_mixed_quotes_literal(user: "AbstractBaseUser[Literal['user'], int]"):
|
||||
66 | def test_mixed_quotes_literal(user: AbstractBaseUser[Literal['user'], "int"]):
|
||||
67 | pass
|
||||
68 |
|
||||
69 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -264,9 +240,6 @@ help: Move into type-checking block
|
||||
73 |
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
74 |
|
||||
- def test_annotated_literal_mixed_quotes(user: AbstractBaseUser[Annotated[str, "max_length=20", Literal['user', "admin"]]]):
|
||||
75 + def test_annotated_literal_mixed_quotes(user: "AbstractBaseUser[Annotated[str, 'max_length=20', Literal['user', 'admin']]]"):
|
||||
75 | def test_annotated_literal_mixed_quotes(user: AbstractBaseUser[Annotated[str, "max_length=20", Literal['user', "admin"]]]):
|
||||
76 | pass
|
||||
77 |
|
||||
78 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -21,11 +21,8 @@ help: Move into type-checking block
|
||||
7 |
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
8 |
|
||||
- def test_union_literal_mixed_quotes(user: AbstractBaseUser[Union[Literal['active', "inactive"], str]]):
|
||||
9 + def test_union_literal_mixed_quotes(user: 'AbstractBaseUser[Union[Literal["active", "inactive"], str]]'):
|
||||
9 | def test_union_literal_mixed_quotes(user: AbstractBaseUser[Union[Literal['active', "inactive"], str]]):
|
||||
10 | pass
|
||||
11 |
|
||||
12 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -52,11 +49,8 @@ help: Move into type-checking block
|
||||
16 |
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
17 |
|
||||
- def test_callable_literal_mixed_quotes(callable_fn: AbstractBaseUser[Callable[["int", Literal['admin', "user"]], 'bool']]):
|
||||
18 + def test_callable_literal_mixed_quotes(callable_fn: 'AbstractBaseUser[Callable[[int, Literal["admin", "user"]], bool]]'):
|
||||
18 | def test_callable_literal_mixed_quotes(callable_fn: AbstractBaseUser[Callable[["int", Literal['admin', "user"]], 'bool']]):
|
||||
19 | pass
|
||||
20 |
|
||||
21 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models.AbstractBaseUser` into a type-checking block
|
||||
@@ -83,11 +77,8 @@ help: Move into type-checking block
|
||||
25 |
|
||||
- from django.contrib.auth.models import AbstractBaseUser
|
||||
26 |
|
||||
- def test_callable_annotated_literal(callable_fn: AbstractBaseUser[Callable[[int, Annotated[str, Literal['active', "inactive"]]], bool]]):
|
||||
27 + def test_callable_annotated_literal(callable_fn: 'AbstractBaseUser[Callable[[int, Annotated[str, Literal["active", "inactive"]]], bool]]'):
|
||||
27 | def test_callable_annotated_literal(callable_fn: AbstractBaseUser[Callable[[int, Annotated[str, Literal['active', "inactive"]]], bool]]):
|
||||
28 | pass
|
||||
29 |
|
||||
30 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models` into a type-checking block
|
||||
@@ -114,11 +105,8 @@ help: Move into type-checking block
|
||||
34 |
|
||||
- from django.contrib.auth import models
|
||||
35 |
|
||||
- def test_attribute(arg: models.AbstractBaseUser["int"]):
|
||||
36 + def test_attribute(arg: 'models.AbstractBaseUser[int]'):
|
||||
36 | def test_attribute(arg: models.AbstractBaseUser["int"]):
|
||||
37 | pass
|
||||
38 |
|
||||
39 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `django.contrib.auth.models` into a type-checking block
|
||||
@@ -145,11 +133,8 @@ help: Move into type-checking block
|
||||
43 |
|
||||
- from django.contrib.auth import models
|
||||
44 |
|
||||
- def test_attribute_typing_literal(arg: models.AbstractBaseUser[Literal["admin"]]):
|
||||
45 + def test_attribute_typing_literal(arg: 'models.AbstractBaseUser[Literal["admin"]]'):
|
||||
45 | def test_attribute_typing_literal(arg: models.AbstractBaseUser[Literal["admin"]]):
|
||||
46 | pass
|
||||
47 |
|
||||
48 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `third_party.Type` into a type-checking block
|
||||
@@ -176,11 +161,8 @@ help: Move into type-checking block
|
||||
62 | from typing import Literal
|
||||
- from third_party import Type
|
||||
63 |
|
||||
- def test_string_contains_opposite_quote(self, type1: Type[Literal["'"]], type2: Type[Literal["\'"]]):
|
||||
64 + def test_string_contains_opposite_quote(self, type1: 'Type[Literal["\'"]]', type2: 'Type[Literal["\'"]]'):
|
||||
64 | def test_string_contains_opposite_quote(self, type1: Type[Literal["'"]], type2: Type[Literal["\'"]]):
|
||||
65 | pass
|
||||
66 |
|
||||
67 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `third_party.Type` into a type-checking block
|
||||
@@ -207,7 +189,6 @@ help: Move into type-checking block
|
||||
70 | from typing import Literal
|
||||
- from third_party import Type
|
||||
71 |
|
||||
- def test_quote_contains_backslash(self, type1: Type[Literal["\n"]], type2: Type[Literal["\""]]):
|
||||
72 + def test_quote_contains_backslash(self, type1: 'Type[Literal["\\n"]]', type2: 'Type[Literal[\'"\']]'):
|
||||
72 | def test_quote_contains_backslash(self, type1: Type[Literal["\n"]], type2: Type[Literal["\""]]):
|
||||
73 | pass
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -1,21 +1,4 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
|
||||
---
|
||||
TC004 [*] Move import `typing.Any` out of type-checking block. Import is used for more than type hinting.
|
||||
--> TC004_4.py:4:24
|
||||
|
|
||||
3 | if TYPE_CHECKING:
|
||||
4 | from typing import Any
|
||||
| ^^^
|
||||
|
|
||||
help: Move out of type-checking block
|
||||
1 | from typing import TYPE_CHECKING, Type
|
||||
2 + from typing import Any
|
||||
3 |
|
||||
4 | if TYPE_CHECKING:
|
||||
- from typing import Any
|
||||
5 + pass
|
||||
6 |
|
||||
7 |
|
||||
8 | def example(*args: Any, **kwargs: Any):
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
|
||||
@@ -1,59 +1,4 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
|
||||
---
|
||||
TC004 [*] Move import `typing.List` out of type-checking block. Import is used for more than type hinting.
|
||||
--> TC004_5.py:4:24
|
||||
|
|
||||
3 | if TYPE_CHECKING:
|
||||
4 | from typing import List, Sequence, Set
|
||||
| ^^^^
|
||||
|
|
||||
help: Move out of type-checking block
|
||||
1 | from typing import TYPE_CHECKING
|
||||
2 + from typing import List, Sequence, Set
|
||||
3 |
|
||||
4 | if TYPE_CHECKING:
|
||||
- from typing import List, Sequence, Set
|
||||
5 + pass
|
||||
6 |
|
||||
7 |
|
||||
8 | def example(a: List[int], /, b: Sequence[int], *, c: Set[int]):
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC004 [*] Move import `typing.Sequence` out of type-checking block. Import is used for more than type hinting.
|
||||
--> TC004_5.py:4:30
|
||||
|
|
||||
3 | if TYPE_CHECKING:
|
||||
4 | from typing import List, Sequence, Set
|
||||
| ^^^^^^^^
|
||||
|
|
||||
help: Move out of type-checking block
|
||||
1 | from typing import TYPE_CHECKING
|
||||
2 + from typing import List, Sequence, Set
|
||||
3 |
|
||||
4 | if TYPE_CHECKING:
|
||||
- from typing import List, Sequence, Set
|
||||
5 + pass
|
||||
6 |
|
||||
7 |
|
||||
8 | def example(a: List[int], /, b: Sequence[int], *, c: Set[int]):
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC004 [*] Move import `typing.Set` out of type-checking block. Import is used for more than type hinting.
|
||||
--> TC004_5.py:4:40
|
||||
|
|
||||
3 | if TYPE_CHECKING:
|
||||
4 | from typing import List, Sequence, Set
|
||||
| ^^^
|
||||
|
|
||||
help: Move out of type-checking block
|
||||
1 | from typing import TYPE_CHECKING
|
||||
2 + from typing import List, Sequence, Set
|
||||
3 |
|
||||
4 | if TYPE_CHECKING:
|
||||
- from typing import List, Sequence, Set
|
||||
5 + pass
|
||||
6 |
|
||||
7 |
|
||||
8 | def example(a: List[int], /, b: Sequence[int], *, c: Set[int]):
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -1,44 +1,4 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
|
||||
---
|
||||
TC004 [*] Move import `typing.Tuple` out of type-checking block. Import is used for more than type hinting.
|
||||
--> TC004_9.py:4:24
|
||||
|
|
||||
3 | if TYPE_CHECKING:
|
||||
4 | from typing import Tuple, List, Dict
|
||||
| ^^^^^
|
||||
5 |
|
||||
6 | x: Tuple
|
||||
|
|
||||
help: Move out of type-checking block
|
||||
1 | from typing import TYPE_CHECKING
|
||||
2 + from typing import Tuple, List
|
||||
3 |
|
||||
4 | if TYPE_CHECKING:
|
||||
- from typing import Tuple, List, Dict
|
||||
5 + from typing import Dict
|
||||
6 |
|
||||
7 | x: Tuple
|
||||
8 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC004 [*] Move import `typing.List` out of type-checking block. Import is used for more than type hinting.
|
||||
--> TC004_9.py:4:31
|
||||
|
|
||||
3 | if TYPE_CHECKING:
|
||||
4 | from typing import Tuple, List, Dict
|
||||
| ^^^^
|
||||
5 |
|
||||
6 | x: Tuple
|
||||
|
|
||||
help: Move out of type-checking block
|
||||
1 | from typing import TYPE_CHECKING
|
||||
2 + from typing import Tuple, List
|
||||
3 |
|
||||
4 | if TYPE_CHECKING:
|
||||
- from typing import Tuple, List, Dict
|
||||
5 + from typing import Dict
|
||||
6 |
|
||||
7 | x: Tuple
|
||||
8 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -1,31 +1,6 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
|
||||
---
|
||||
TC004 [*] Move import `pandas.DataFrame` out of type-checking block. Import is used for more than type hinting.
|
||||
--> quote.py:57:28
|
||||
|
|
||||
56 | if TYPE_CHECKING:
|
||||
57 | from pandas import DataFrame
|
||||
| ^^^^^^^^^
|
||||
58 |
|
||||
59 | def func(value: DataFrame):
|
||||
|
|
||||
help: Move out of type-checking block
|
||||
1 + from pandas import DataFrame
|
||||
2 | def f():
|
||||
3 | from pandas import DataFrame
|
||||
4 |
|
||||
--------------------------------------------------------------------------------
|
||||
55 | from typing import TYPE_CHECKING
|
||||
56 |
|
||||
57 | if TYPE_CHECKING:
|
||||
- from pandas import DataFrame
|
||||
58 + pass
|
||||
59 |
|
||||
60 | def func(value: DataFrame):
|
||||
61 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC004 [*] Move import `pandas.DataFrame` out of type-checking block. Import is used for more than type hinting.
|
||||
--> quote.py:110:28
|
||||
|
|
||||
|
||||
@@ -1,39 +1,6 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
|
||||
---
|
||||
TC010 Invalid string member in `X | Y`-style union type
|
||||
--> TC010_2.py:4:4
|
||||
|
|
||||
4 | x: "int" | str # TC010
|
||||
| ^^^^^
|
||||
5 | x: ("int" | str) | "bool" # TC010
|
||||
|
|
||||
|
||||
TC010 Invalid string member in `X | Y`-style union type
|
||||
--> TC010_2.py:5:5
|
||||
|
|
||||
4 | x: "int" | str # TC010
|
||||
5 | x: ("int" | str) | "bool" # TC010
|
||||
| ^^^^^
|
||||
|
|
||||
|
||||
TC010 Invalid string member in `X | Y`-style union type
|
||||
--> TC010_2.py:5:20
|
||||
|
|
||||
4 | x: "int" | str # TC010
|
||||
5 | x: ("int" | str) | "bool" # TC010
|
||||
| ^^^^^^
|
||||
|
|
||||
|
||||
TC010 Invalid string member in `X | Y`-style union type
|
||||
--> TC010_2.py:12:20
|
||||
|
|
||||
12 | z: list[str, str | "int"] = [] # TC010
|
||||
| ^^^^^
|
||||
13 |
|
||||
14 | type A = Value["int" | str] # OK
|
||||
|
|
||||
|
||||
TC010 Invalid string member in `X | Y`-style union type
|
||||
--> TC010_2.py:16:30
|
||||
|
|
||||
|
||||
@@ -220,32 +220,3 @@ help: Move into type-checking block
|
||||
52 | x = dict["pd.DataFrame", "pd.DataFrame"]
|
||||
53 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `module.Member` into a type-checking block
|
||||
--> TC002.py:172:24
|
||||
|
|
||||
170 | global Member
|
||||
171 |
|
||||
172 | from module import Member
|
||||
| ^^^^^^
|
||||
173 |
|
||||
174 | x: Member = 1
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 | """Tests to determine accurate detection of typing-only imports."""
|
||||
2 + from typing import TYPE_CHECKING
|
||||
3 +
|
||||
4 + if TYPE_CHECKING:
|
||||
5 + from module import Member
|
||||
6 |
|
||||
7 |
|
||||
8 | def f():
|
||||
--------------------------------------------------------------------------------
|
||||
173 | def f():
|
||||
174 | global Member
|
||||
175 |
|
||||
- from module import Member
|
||||
176 |
|
||||
177 | x: Member = 1
|
||||
178 |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -1,5 +1,348 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_type_checking/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
--> quote.py:2:24
|
||||
|
|
||||
1 | def f():
|
||||
2 | from pandas import DataFrame
|
||||
| ^^^^^^^^^
|
||||
3 |
|
||||
4 | def baz() -> DataFrame:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
- def f():
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 | from pandas import DataFrame
|
||||
5 + def f():
|
||||
6 |
|
||||
7 | def baz() -> DataFrame:
|
||||
8 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
--> quote.py:9:24
|
||||
|
|
||||
8 | def f():
|
||||
9 | from pandas import DataFrame
|
||||
| ^^^^^^^^^
|
||||
10 |
|
||||
11 | def baz() -> DataFrame[int]:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + from pandas import DataFrame
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
10 |
|
||||
11 |
|
||||
12 | def f():
|
||||
- from pandas import DataFrame
|
||||
13 |
|
||||
14 | def baz() -> DataFrame[int]:
|
||||
15 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas` into a type-checking block
|
||||
--> quote.py:16:22
|
||||
|
|
||||
15 | def f():
|
||||
16 | import pandas as pd
|
||||
| ^^
|
||||
17 |
|
||||
18 | def baz() -> pd.DataFrame:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + import pandas as pd
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
17 |
|
||||
18 |
|
||||
19 | def f():
|
||||
- import pandas as pd
|
||||
20 |
|
||||
21 | def baz() -> pd.DataFrame:
|
||||
22 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas` into a type-checking block
|
||||
--> quote.py:23:22
|
||||
|
|
||||
22 | def f():
|
||||
23 | import pandas as pd
|
||||
| ^^
|
||||
24 |
|
||||
25 | def baz() -> pd.DataFrame.Extra:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + import pandas as pd
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
24 |
|
||||
25 |
|
||||
26 | def f():
|
||||
- import pandas as pd
|
||||
27 |
|
||||
28 | def baz() -> pd.DataFrame.Extra:
|
||||
29 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas` into a type-checking block
|
||||
--> quote.py:30:22
|
||||
|
|
||||
29 | def f():
|
||||
30 | import pandas as pd
|
||||
| ^^
|
||||
31 |
|
||||
32 | def baz() -> pd.DataFrame | int:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + import pandas as pd
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
31 |
|
||||
32 |
|
||||
33 | def f():
|
||||
- import pandas as pd
|
||||
34 |
|
||||
35 | def baz() -> pd.DataFrame | int:
|
||||
36 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
--> quote.py:38:24
|
||||
|
|
||||
37 | def f():
|
||||
38 | from pandas import DataFrame
|
||||
| ^^^^^^^^^
|
||||
39 |
|
||||
40 | def baz() -> DataFrame():
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + from pandas import DataFrame
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
39 |
|
||||
40 |
|
||||
41 | def f():
|
||||
- from pandas import DataFrame
|
||||
42 |
|
||||
43 | def baz() -> DataFrame():
|
||||
44 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
--> quote.py:47:24
|
||||
|
|
||||
45 | from typing import Literal
|
||||
46 |
|
||||
47 | from pandas import DataFrame
|
||||
| ^^^^^^^^^
|
||||
48 |
|
||||
49 | def baz() -> DataFrame[Literal["int"]]:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + from pandas import DataFrame
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
48 | def f():
|
||||
49 | from typing import Literal
|
||||
50 |
|
||||
- from pandas import DataFrame
|
||||
51 |
|
||||
52 | def baz() -> DataFrame[Literal["int"]]:
|
||||
53 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
--> quote.py:64:24
|
||||
|
|
||||
63 | def f():
|
||||
64 | from pandas import DataFrame, Series
|
||||
| ^^^^^^^^^
|
||||
65 |
|
||||
66 | def baz() -> DataFrame | Series:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + from pandas import DataFrame, Series
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
65 |
|
||||
66 |
|
||||
67 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
68 |
|
||||
69 | def baz() -> DataFrame | Series:
|
||||
70 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.Series` into a type-checking block
|
||||
--> quote.py:64:35
|
||||
|
|
||||
63 | def f():
|
||||
64 | from pandas import DataFrame, Series
|
||||
| ^^^^^^
|
||||
65 |
|
||||
66 | def baz() -> DataFrame | Series:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + from pandas import DataFrame, Series
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
65 |
|
||||
66 |
|
||||
67 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
68 |
|
||||
69 | def baz() -> DataFrame | Series:
|
||||
70 | ...
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
--> quote.py:71:24
|
||||
|
|
||||
70 | def f():
|
||||
71 | from pandas import DataFrame, Series
|
||||
| ^^^^^^^^^
|
||||
72 |
|
||||
73 | def baz() -> (
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + from pandas import DataFrame, Series
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
72 |
|
||||
73 |
|
||||
74 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
75 |
|
||||
76 | def baz() -> (
|
||||
77 | DataFrame |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.Series` into a type-checking block
|
||||
--> quote.py:71:35
|
||||
|
|
||||
70 | def f():
|
||||
71 | from pandas import DataFrame, Series
|
||||
| ^^^^^^
|
||||
72 |
|
||||
73 | def baz() -> (
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + from pandas import DataFrame, Series
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
72 |
|
||||
73 |
|
||||
74 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
75 |
|
||||
76 | def baz() -> (
|
||||
77 | DataFrame |
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.DataFrame` into a type-checking block
|
||||
--> quote.py:89:24
|
||||
|
|
||||
88 | def f():
|
||||
89 | from pandas import DataFrame, Series
|
||||
| ^^^^^^^^^
|
||||
90 |
|
||||
91 | def func(self) -> DataFrame | list[Series]:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + from pandas import DataFrame, Series
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
90 |
|
||||
91 |
|
||||
92 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
93 |
|
||||
94 | def func(self) -> DataFrame | list[Series]:
|
||||
95 | pass
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
TC002 [*] Move third-party import `pandas.Series` into a type-checking block
|
||||
--> quote.py:89:35
|
||||
|
|
||||
88 | def f():
|
||||
89 | from pandas import DataFrame, Series
|
||||
| ^^^^^^
|
||||
90 |
|
||||
91 | def func(self) -> DataFrame | list[Series]:
|
||||
|
|
||||
help: Move into type-checking block
|
||||
1 + from typing import TYPE_CHECKING
|
||||
2 +
|
||||
3 + if TYPE_CHECKING:
|
||||
4 + from pandas import DataFrame, Series
|
||||
5 | def f():
|
||||
6 | from pandas import DataFrame
|
||||
7 |
|
||||
--------------------------------------------------------------------------------
|
||||
90 |
|
||||
91 |
|
||||
92 | def f():
|
||||
- from pandas import DataFrame, Series
|
||||
93 |
|
||||
94 | def func(self) -> DataFrame | list[Series]:
|
||||
95 | pass
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
@@ -11,11 +11,11 @@ mod tests {
|
||||
use ruff_python_ast::PythonVersion;
|
||||
use test_case::test_case;
|
||||
|
||||
use crate::assert_diagnostics;
|
||||
use crate::registry::Rule;
|
||||
use crate::settings;
|
||||
use crate::settings::types::PreviewMode;
|
||||
use crate::test::test_path;
|
||||
use crate::{assert_diagnostics, assert_diagnostics_diff};
|
||||
|
||||
#[test_case(Path::new("full_name.py"))]
|
||||
#[test_case(Path::new("import_as.py"))]
|
||||
@@ -82,6 +82,29 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Rule::InvalidPathlibWithSuffix, Path::new("PTH210.py"))]
|
||||
#[test_case(Rule::InvalidPathlibWithSuffix, Path::new("PTH210_1.py"))]
|
||||
fn deferred_annotations_diff(rule_code: Rule, path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"deferred_annotations_diff_{}_{}",
|
||||
rule_code.name(),
|
||||
path.to_string_lossy()
|
||||
);
|
||||
assert_diagnostics_diff!(
|
||||
snapshot,
|
||||
Path::new("flake8_use_pathlib").join(path).as_path(),
|
||||
&settings::LinterSettings {
|
||||
unresolved_target_version: PythonVersion::PY313.into(),
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
&settings::LinterSettings {
|
||||
unresolved_target_version: PythonVersion::PY314.into(),
|
||||
..settings::LinterSettings::for_rule(rule_code)
|
||||
},
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Path::new("full_name.py"))]
|
||||
#[test_case(Path::new("import_as.py"))]
|
||||
#[test_case(Path::new("import_from_as.py"))]
|
||||
|
||||
@@ -1,17 +1,6 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
|
||||
---
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:21:1
|
||||
|
|
||||
20 | ### Errors
|
||||
21 | path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
22 | path.with_suffix("py")
|
||||
23 | path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:22:1
|
||||
|
|
||||
@@ -95,18 +84,6 @@ help: Add a leading dot
|
||||
28 | posix_path.with_suffix("py")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:27:1
|
||||
|
|
||||
25 | path.with_suffix(suffix="js")
|
||||
26 |
|
||||
27 | posix_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
28 | posix_path.with_suffix("py")
|
||||
29 | posix_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:28:1
|
||||
|
|
||||
@@ -189,18 +166,6 @@ help: Add a leading dot
|
||||
34 | pure_path.with_suffix("py")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:33:1
|
||||
|
|
||||
31 | posix_path.with_suffix(suffix="js")
|
||||
32 |
|
||||
33 | pure_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
34 | pure_path.with_suffix("py")
|
||||
35 | pure_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:34:1
|
||||
|
|
||||
@@ -283,18 +248,6 @@ help: Add a leading dot
|
||||
40 | pure_posix_path.with_suffix("py")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:39:1
|
||||
|
|
||||
37 | pure_path.with_suffix(suffix="js")
|
||||
38 |
|
||||
39 | pure_posix_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
40 | pure_posix_path.with_suffix("py")
|
||||
41 | pure_posix_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:40:1
|
||||
|
|
||||
@@ -377,18 +330,6 @@ help: Add a leading dot
|
||||
46 | pure_windows_path.with_suffix("py")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:45:1
|
||||
|
|
||||
43 | pure_posix_path.with_suffix(suffix="js")
|
||||
44 |
|
||||
45 | pure_windows_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
46 | pure_windows_path.with_suffix("py")
|
||||
47 | pure_windows_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:46:1
|
||||
|
|
||||
@@ -471,18 +412,6 @@ help: Add a leading dot
|
||||
52 | windows_path.with_suffix("py")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:51:1
|
||||
|
|
||||
49 | pure_windows_path.with_suffix(suffix="js")
|
||||
50 |
|
||||
51 | windows_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
52 | windows_path.with_suffix("py")
|
||||
53 | windows_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:52:1
|
||||
|
|
||||
@@ -565,18 +494,6 @@ help: Add a leading dot
|
||||
58 | Path().with_suffix("py")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:57:1
|
||||
|
|
||||
55 | windows_path.with_suffix(suffix="js")
|
||||
56 |
|
||||
57 | Path().with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
58 | Path().with_suffix("py")
|
||||
59 | PosixPath().with_suffix("py")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:58:1
|
||||
|
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
|
||||
---
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:13:5
|
||||
|
|
||||
11 | def test_path(p: Path) -> None:
|
||||
12 | ## Errors
|
||||
13 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
14 | p.with_suffix("py")
|
||||
15 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:14:5
|
||||
|
|
||||
@@ -96,18 +84,6 @@ help: Add a leading dot
|
||||
20 | p.with_suffix()
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:31:5
|
||||
|
|
||||
29 | def test_posix_path(p: PosixPath) -> None:
|
||||
30 | ## Errors
|
||||
31 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
32 | p.with_suffix("py")
|
||||
33 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:32:5
|
||||
|
|
||||
@@ -191,18 +167,6 @@ help: Add a leading dot
|
||||
38 | p.with_suffix()
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:49:5
|
||||
|
|
||||
47 | def test_pure_path(p: PurePath) -> None:
|
||||
48 | ## Errors
|
||||
49 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
50 | p.with_suffix("py")
|
||||
51 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:50:5
|
||||
|
|
||||
@@ -286,18 +250,6 @@ help: Add a leading dot
|
||||
56 | p.with_suffix()
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:67:5
|
||||
|
|
||||
65 | def test_pure_posix_path(p: PurePosixPath) -> None:
|
||||
66 | ## Errors
|
||||
67 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
68 | p.with_suffix("py")
|
||||
69 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:68:5
|
||||
|
|
||||
@@ -381,18 +333,6 @@ help: Add a leading dot
|
||||
74 | p.with_suffix()
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:85:5
|
||||
|
|
||||
83 | def test_pure_windows_path(p: PureWindowsPath) -> None:
|
||||
84 | ## Errors
|
||||
85 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
86 | p.with_suffix("py")
|
||||
87 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:86:5
|
||||
|
|
||||
@@ -476,18 +416,6 @@ help: Add a leading dot
|
||||
92 | p.with_suffix()
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:103:5
|
||||
|
|
||||
101 | def test_windows_path(p: WindowsPath) -> None:
|
||||
102 | ## Errors
|
||||
103 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
104 | p.with_suffix("py")
|
||||
105 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
PTH210 [*] Dotless suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:104:5
|
||||
|
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
|
||||
---
|
||||
--- Linter settings ---
|
||||
-linter.unresolved_target_version = 3.13
|
||||
+linter.unresolved_target_version = 3.14
|
||||
|
||||
--- Summary ---
|
||||
Removed: 7
|
||||
Added: 0
|
||||
|
||||
--- Removed ---
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:21:1
|
||||
|
|
||||
20 | ### Errors
|
||||
21 | path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
22 | path.with_suffix("py")
|
||||
23 | path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:27:1
|
||||
|
|
||||
25 | path.with_suffix(suffix="js")
|
||||
26 |
|
||||
27 | posix_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
28 | posix_path.with_suffix("py")
|
||||
29 | posix_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:33:1
|
||||
|
|
||||
31 | posix_path.with_suffix(suffix="js")
|
||||
32 |
|
||||
33 | pure_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
34 | pure_path.with_suffix("py")
|
||||
35 | pure_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:39:1
|
||||
|
|
||||
37 | pure_path.with_suffix(suffix="js")
|
||||
38 |
|
||||
39 | pure_posix_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
40 | pure_posix_path.with_suffix("py")
|
||||
41 | pure_posix_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:45:1
|
||||
|
|
||||
43 | pure_posix_path.with_suffix(suffix="js")
|
||||
44 |
|
||||
45 | pure_windows_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
46 | pure_windows_path.with_suffix("py")
|
||||
47 | pure_windows_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:51:1
|
||||
|
|
||||
49 | pure_windows_path.with_suffix(suffix="js")
|
||||
50 |
|
||||
51 | windows_path.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
52 | windows_path.with_suffix("py")
|
||||
53 | windows_path.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210.py:57:1
|
||||
|
|
||||
55 | windows_path.with_suffix(suffix="js")
|
||||
56 |
|
||||
57 | Path().with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^
|
||||
58 | Path().with_suffix("py")
|
||||
59 | PosixPath().with_suffix("py")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/flake8_use_pathlib/mod.rs
|
||||
---
|
||||
--- Linter settings ---
|
||||
-linter.unresolved_target_version = 3.13
|
||||
+linter.unresolved_target_version = 3.14
|
||||
|
||||
--- Summary ---
|
||||
Removed: 6
|
||||
Added: 0
|
||||
|
||||
--- Removed ---
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:13:5
|
||||
|
|
||||
11 | def test_path(p: Path) -> None:
|
||||
12 | ## Errors
|
||||
13 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
14 | p.with_suffix("py")
|
||||
15 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:31:5
|
||||
|
|
||||
29 | def test_posix_path(p: PosixPath) -> None:
|
||||
30 | ## Errors
|
||||
31 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
32 | p.with_suffix("py")
|
||||
33 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:49:5
|
||||
|
|
||||
47 | def test_pure_path(p: PurePath) -> None:
|
||||
48 | ## Errors
|
||||
49 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
50 | p.with_suffix("py")
|
||||
51 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:67:5
|
||||
|
|
||||
65 | def test_pure_posix_path(p: PurePosixPath) -> None:
|
||||
66 | ## Errors
|
||||
67 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
68 | p.with_suffix("py")
|
||||
69 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:85:5
|
||||
|
|
||||
83 | def test_pure_windows_path(p: PureWindowsPath) -> None:
|
||||
84 | ## Errors
|
||||
85 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
86 | p.with_suffix("py")
|
||||
87 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
|
||||
|
||||
PTH210 Invalid suffix passed to `.with_suffix()`
|
||||
--> PTH210_1.py:103:5
|
||||
|
|
||||
101 | def test_windows_path(p: WindowsPath) -> None:
|
||||
102 | ## Errors
|
||||
103 | p.with_suffix(".")
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
104 | p.with_suffix("py")
|
||||
105 | p.with_suffix(r"s")
|
||||
|
|
||||
help: Remove "." or extend to valid suffix
|
||||
@@ -1014,6 +1014,30 @@ mod tests {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Path::new("future_import.py"))]
|
||||
#[test_case(Path::new("docstring_future_import.py"))]
|
||||
fn required_import_with_future_import(path: &Path) -> Result<()> {
|
||||
let snapshot = format!(
|
||||
"required_import_with_future_import_{}",
|
||||
path.to_string_lossy()
|
||||
);
|
||||
let diagnostics = test_path(
|
||||
Path::new("isort/required_imports").join(path).as_path(),
|
||||
&LinterSettings {
|
||||
src: vec![test_resource_path("fixtures/isort")],
|
||||
isort: super::settings::Settings {
|
||||
required_imports: BTreeSet::from_iter([NameImport::Import(
|
||||
ModuleNameImport::module("this".to_string()),
|
||||
)]),
|
||||
..super::settings::Settings::default()
|
||||
},
|
||||
..LinterSettings::for_rule(Rule::MissingRequiredImport)
|
||||
},
|
||||
)?;
|
||||
assert_diagnostics!(snapshot, diagnostics);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test_case(Path::new("from_first.py"))]
|
||||
fn from_first(path: &Path) -> Result<()> {
|
||||
let snapshot = format!("from_first_{}", path.to_string_lossy());
|
||||
|
||||
@@ -4,6 +4,6 @@ source: crates/ruff_linter/src/rules/isort/mod.rs
|
||||
I002 [*] Missing required import: `from __future__ import annotations`
|
||||
--> existing_import.py:1:1
|
||||
help: Insert required import: `from __future__ import annotations`
|
||||
1 + from __future__ import annotations
|
||||
2 | from __future__ import generator_stop
|
||||
1 | from __future__ import generator_stop
|
||||
2 + from __future__ import annotations
|
||||
3 | import os
|
||||
|
||||
@@ -4,6 +4,6 @@ source: crates/ruff_linter/src/rules/isort/mod.rs
|
||||
I002 [*] Missing required import: `from __future__ import annotations as _annotations`
|
||||
--> existing_import.py:1:1
|
||||
help: Insert required import: `from __future__ import annotations as _annotations`
|
||||
1 + from __future__ import annotations as _annotations
|
||||
2 | from __future__ import generator_stop
|
||||
1 | from __future__ import generator_stop
|
||||
2 + from __future__ import annotations as _annotations
|
||||
3 | import os
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/isort/mod.rs
|
||||
---
|
||||
I002 [*] Missing required import: `import this`
|
||||
--> docstring_future_import.py:1:1
|
||||
help: Insert required import: `import this`
|
||||
1 | "a docstring"
|
||||
2 | from __future__ import annotations
|
||||
3 + import this
|
||||
4 | # EOF
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/isort/mod.rs
|
||||
---
|
||||
I002 [*] Missing required import: `import this`
|
||||
--> future_import.py:1:1
|
||||
help: Insert required import: `import this`
|
||||
1 | from __future__ import annotations
|
||||
2 + import this
|
||||
3 | # EOF
|
||||
@@ -3769,7 +3769,7 @@ lambda: fu
|
||||
def f(a: A) -> A: pass
|
||||
class A: pass
|
||||
",
|
||||
&[Rule::UndefinedName, Rule::UndefinedName],
|
||||
&[],
|
||||
);
|
||||
flakes(
|
||||
r"
|
||||
@@ -3783,7 +3783,7 @@ lambda: fu
|
||||
a: A
|
||||
class A: pass
|
||||
",
|
||||
&[Rule::UndefinedName],
|
||||
&[],
|
||||
);
|
||||
flakes(
|
||||
r"
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
|
||||
snapshot_kind: text
|
||||
---
|
||||
|
||||
F821 Undefined name `y`
|
||||
--> F821_18.py:19:7
|
||||
|
|
||||
17 | # This is no longer allowed on Python 3.14+
|
||||
18 | x: (y := 1)
|
||||
19 | print(y)
|
||||
| ^
|
||||
|
|
||||
|
||||
@@ -1,12 +1,4 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pyflakes/mod.rs
|
||||
---
|
||||
F821 Undefined name `Model`
|
||||
--> F821_2.py:5:13
|
||||
|
|
||||
4 | # F821 Undefined name `Model`
|
||||
5 | x: Literal["Model"]
|
||||
| ^^^^^
|
||||
6 |
|
||||
7 | from typing_extensions import Literal
|
||||
|
|
||||
|
||||
|
||||
@@ -21,48 +21,6 @@ F821 Undefined name `C`
|
||||
12 | CStr2: TypeAlias = Union["C", str] # always okay
|
||||
|
|
||||
|
||||
F821 Undefined name `C`
|
||||
--> F821_26.py:16:12
|
||||
|
|
||||
14 | # References to a class from inside the class:
|
||||
15 | class C:
|
||||
16 | other: C = ... # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
| ^
|
||||
17 | other2: "C" = ... # always okay
|
||||
18 | def from_str(self, s: str) -> C: ... # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
|
|
||||
|
||||
F821 Undefined name `C`
|
||||
--> F821_26.py:18:35
|
||||
|
|
||||
16 | other: C = ... # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
17 | other2: "C" = ... # always okay
|
||||
18 | def from_str(self, s: str) -> C: ... # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
| ^
|
||||
19 | def from_str2(self, s: str) -> "C": ... # always okay
|
||||
|
|
||||
|
||||
F821 Undefined name `B`
|
||||
--> F821_26.py:23:10
|
||||
|
|
||||
21 | # Circular references:
|
||||
22 | class A:
|
||||
23 | foo: B # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
| ^
|
||||
24 | foo2: "B" # always okay
|
||||
25 | bar: dict[str, B] # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
|
|
||||
|
||||
F821 Undefined name `B`
|
||||
--> F821_26.py:25:20
|
||||
|
|
||||
23 | foo: B # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
24 | foo2: "B" # always okay
|
||||
25 | bar: dict[str, B] # valid in a `.pyi` stub file, not in a `.py` runtime file
|
||||
| ^
|
||||
26 | bar2: dict[str, "A"] # always okay
|
||||
|
|
||||
|
||||
F821 Undefined name `Tree`
|
||||
--> F821_26.py:33:17
|
||||
|
|
||||
|
||||
@@ -43,6 +43,7 @@ where
|
||||
T: Ranged,
|
||||
{
|
||||
let mut diagnostic = checker.report_diagnostic(DeprecatedCElementTree, node.range());
|
||||
diagnostic.add_primary_tag(ruff_db::diagnostic::DiagnosticTag::Deprecated);
|
||||
let contents = checker.locator().slice(node);
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
contents.replacen("cElementTree", "ElementTree", 1),
|
||||
|
||||
@@ -265,6 +265,7 @@ pub(crate) fn deprecated_mock_attribute(checker: &Checker, attribute: &ast::Expr
|
||||
},
|
||||
attribute.value.range(),
|
||||
);
|
||||
diagnostic.add_primary_tag(ruff_db::diagnostic::DiagnosticTag::Deprecated);
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
"mock".to_string(),
|
||||
attribute.value.range(),
|
||||
@@ -313,6 +314,7 @@ pub(crate) fn deprecated_mock_import(checker: &Checker, stmt: &Stmt) {
|
||||
},
|
||||
name.range(),
|
||||
);
|
||||
diagnostic.add_primary_tag(ruff_db::diagnostic::DiagnosticTag::Deprecated);
|
||||
if let Some(content) = content.as_ref() {
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
content.clone(),
|
||||
@@ -351,6 +353,7 @@ pub(crate) fn deprecated_mock_import(checker: &Checker, stmt: &Stmt) {
|
||||
},
|
||||
stmt.range(),
|
||||
);
|
||||
diagnostic.add_primary_tag(ruff_db::diagnostic::DiagnosticTag::Deprecated);
|
||||
if let Some(indent) = indentation(checker.source(), stmt) {
|
||||
diagnostic.try_set_fix(|| {
|
||||
format_import_from(stmt, indent, checker.locator(), checker.stylist())
|
||||
|
||||
@@ -98,6 +98,7 @@ pub(crate) fn deprecated_unittest_alias(checker: &Checker, expr: &Expr) {
|
||||
},
|
||||
expr.range(),
|
||||
);
|
||||
diagnostic.add_primary_tag(ruff_db::diagnostic::DiagnosticTag::Deprecated);
|
||||
diagnostic.set_fix(Fix::safe_edit(Edit::range_replacement(
|
||||
format!("self.{target}"),
|
||||
expr.range(),
|
||||
|
||||
@@ -68,6 +68,7 @@ pub(crate) fn replace_universal_newlines(checker: &Checker, call: &ast::ExprCall
|
||||
};
|
||||
|
||||
let mut diagnostic = checker.report_diagnostic(ReplaceUniversalNewlines, arg.range());
|
||||
diagnostic.add_primary_tag(ruff_db::diagnostic::DiagnosticTag::Deprecated);
|
||||
|
||||
if call.arguments.find_keyword("text").is_some() {
|
||||
diagnostic.try_set_fix(|| {
|
||||
|
||||
@@ -57,6 +57,7 @@ pub(crate) fn typing_text_str_alias(checker: &Checker, expr: &Expr) {
|
||||
.is_some_and(|qualified_name| matches!(qualified_name.segments(), ["typing", "Text"]))
|
||||
{
|
||||
let mut diagnostic = checker.report_diagnostic(TypingTextStrAlias, expr.range());
|
||||
diagnostic.add_primary_tag(ruff_db::diagnostic::DiagnosticTag::Deprecated);
|
||||
diagnostic.try_set_fix(|| {
|
||||
let (import_edit, binding) = checker.importer().get_or_import_builtin_symbol(
|
||||
"str",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
source: crates/ruff_linter/src/rules/pyupgrade/mod.rs
|
||||
---
|
||||
UP006 Use `collections.defaultdict` instead of `typing.DefaultDict` for type annotation
|
||||
UP006 [*] Use `collections.defaultdict` instead of `typing.DefaultDict` for type annotation
|
||||
--> UP006_2.py:7:10
|
||||
|
|
||||
7 | def f(x: typing.DefaultDict[str, str]) -> None:
|
||||
@@ -9,3 +9,9 @@ UP006 Use `collections.defaultdict` instead of `typing.DefaultDict` for type ann
|
||||
8 | ...
|
||||
|
|
||||
help: Replace with `collections.defaultdict`
|
||||
4 | from collections import defaultdict
|
||||
5 |
|
||||
6 |
|
||||
- def f(x: typing.DefaultDict[str, str]) -> None:
|
||||
7 + def f(x: defaultdict[str, str]) -> None:
|
||||
8 | ...
|
||||
|
||||
@@ -171,6 +171,40 @@ help: Convert to `X | Y`
|
||||
35 |
|
||||
36 |
|
||||
|
||||
UP007 [*] Use `X | Y` for type annotations
|
||||
--> UP007.py:37:10
|
||||
|
|
||||
37 | def f(x: Union["str", int]) -> None:
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
38 | ...
|
||||
|
|
||||
help: Convert to `X | Y`
|
||||
34 | ...
|
||||
35 |
|
||||
36 |
|
||||
- def f(x: Union["str", int]) -> None:
|
||||
37 + def f(x: "str" | int) -> None:
|
||||
38 | ...
|
||||
39 |
|
||||
40 |
|
||||
|
||||
UP007 [*] Use `X | Y` for type annotations
|
||||
--> UP007.py:41:10
|
||||
|
|
||||
41 | def f(x: Union[("str", "int"), float]) -> None:
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
42 | ...
|
||||
|
|
||||
help: Convert to `X | Y`
|
||||
38 | ...
|
||||
39 |
|
||||
40 |
|
||||
- def f(x: Union[("str", "int"), float]) -> None:
|
||||
41 + def f(x: "str" | "int" | float) -> None:
|
||||
42 | ...
|
||||
43 |
|
||||
44 |
|
||||
|
||||
UP007 Use `X | Y` for type annotations
|
||||
--> UP007.py:46:9
|
||||
|
|
||||
|
||||
@@ -685,6 +685,46 @@ help: Remove outdated version block
|
||||
184 | print("py3")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
UP036 [*] Version block is outdated for minimum Python version
|
||||
--> UP036_0.py:185:4
|
||||
|
|
||||
183 | print("py3")
|
||||
184 |
|
||||
185 | if sys.version_info <= (3,13):
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
186 | print("py3")
|
||||
|
|
||||
help: Remove outdated version block
|
||||
182 | if sys.version_info < (3,13):
|
||||
183 | print("py3")
|
||||
184 |
|
||||
- if sys.version_info <= (3,13):
|
||||
- print("py3")
|
||||
185 |
|
||||
186 | if sys.version_info <= (3,13):
|
||||
187 | print("py3")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
UP036 [*] Version block is outdated for minimum Python version
|
||||
--> UP036_0.py:188:4
|
||||
|
|
||||
186 | print("py3")
|
||||
187 |
|
||||
188 | if sys.version_info <= (3,13):
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
189 | print("py3")
|
||||
|
|
||||
help: Remove outdated version block
|
||||
185 | if sys.version_info <= (3,13):
|
||||
186 | print("py3")
|
||||
187 |
|
||||
- if sys.version_info <= (3,13):
|
||||
- print("py3")
|
||||
188 |
|
||||
189 | if sys.version_info == 10000000:
|
||||
190 | print("py3")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
UP036 Version specifier is invalid
|
||||
--> UP036_0.py:191:24
|
||||
|
|
||||
@@ -715,6 +755,27 @@ UP036 Version specifier is invalid
|
||||
198 | print("py3")
|
||||
|
|
||||
|
||||
UP036 [*] Version block is outdated for minimum Python version
|
||||
--> UP036_0.py:200:4
|
||||
|
|
||||
198 | print("py3")
|
||||
199 |
|
||||
200 | if sys.version_info > (3,13):
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
201 | print("py3")
|
||||
|
|
||||
help: Remove outdated version block
|
||||
197 | if sys.version_info <= (3,10000000):
|
||||
198 | print("py3")
|
||||
199 |
|
||||
- if sys.version_info > (3,13):
|
||||
- print("py3")
|
||||
200 + print("py3")
|
||||
201 |
|
||||
202 | if sys.version_info >= (3,13):
|
||||
203 | print("py3")
|
||||
note: This is an unsafe fix and may change runtime behavior
|
||||
|
||||
UP036 [*] Version block is outdated for minimum Python version
|
||||
--> UP036_0.py:203:4
|
||||
|
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user