Commit Graph

2256 Commits

Author SHA1 Message Date
Frazer McLean f67ff33177
Add lint rule for calling chmod with non-octal integers (#18541)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-06-19 11:30:29 +02:00
Nikolas Hearp dcf0a8d4d7
Mark `RET501` fix unsafe if comments are inside (#18780)
Co-authored-by: Charlie Marsh <crmarsh416@gmail.com>
2025-06-19 11:12:12 +02:00
Brent Westbrook e352a50b74
Use `LintContext::report_diagnostic_if_enabled` in `check_tokens` (#18769)
## Summary

This PR avoids the `Vec::retain` call in `check_tokens` by checking if
rules are enabled as their diagnostics are constructed.


2a425e43fd/crates/ruff_linter/src/checkers/tokens.rs (L174-L176)

Since `LintContext::report_diagnostic_if_enabled` required a
`LinterSettings`, I added a `settings` field to the context itself
instead of trying to pass it everywhere. This also turned
`LogicalLinesContext` into a trivial wrapper around `LintContext`, so I
just removed it in favor of using `LintContext` directly too.

The diff is a bit smaller with whitespace hidden since many blocks got
moved into something like this:

```rust
if let Some(mut diagnostic) = context.report_diagnostic.enabled(...) {
    // old code
}
```

## Test Plan

Existing tests
2025-06-18 17:05:36 -04:00
sobolevn 2a425e43fd
[UP008]: use `super()`, not `__super__` in error messages (#18743)
When I try to grep CPython with `__super__` I get 0 results:

```
(.venv) ~/Desktop/cpython  main ✔                                                    
» ag __super__ . 
                
```

That's how we can understand that the naming is not the best.
2025-06-18 13:57:57 -04:00
Brent Westbrook 87f0feb21a
Bump 0.12.0 (#18724)
- [x] Updated changelog
- [x] Updated breaking changes
2025-06-17 11:05:59 -04:00
Dylan a93992fa30 [`flake8-return`] Stabilize only add `return None` at the end when fixing `implicit-return` (`RET503`) (#18516)
This involved slightly more code changes than usual for a stabilization
- so maybe worth double-checking the logic!

I did verify by hand that the new stable behavior on the test fixture
matches the old preview behavior, even after the internal refactor.
2025-06-17 09:58:12 -04:00
Brent Westbrook 50f84808bc [`pyupgrade`] Stabilize `non-pep695-generic-function` (`UP047`) (#18524)
## Summary
- Stabilizes UP047 (non-pep695-generic-function) rule by changing it
from Preview to Stable

## Test plan
-  Rule is already tested in main test function, no migration needed
-  `make check` passes
-  `make test` passes

## Rule Documentation
- [Test
file](https://github.com/astral-sh/ruff/blob/main/crates/ruff_linter/src/rules/pyupgrade/mod.rs#L111)
- [Rule
documentation](https://docs.astral.sh/ruff/rules/non-pep695-generic-function/)
2025-06-17 09:58:12 -04:00
Brent Westbrook 6754e94abc [`pyupgrade`] Stabilize `non-pep695-generic-class` (`UP046`) (#18519)
## Summary
- Stabilizes UP046 (non-pep695-generic-class) rule by changing it from
Preview to Stable

## Test plan
-  Rule is already tested in main test function, no migration needed
-  `make check` passes
-  `make test` passes

## Rule Documentation
- [Test
file](https://github.com/astral-sh/ruff/blob/main/crates/ruff_linter/src/rules/pyupgrade/mod.rs#L109-L110)
- [Rule
documentation](https://docs.astral.sh/ruff/rules/non-pep695-generic-class/)
2025-06-17 09:58:12 -04:00
Brent Westbrook 33c8c7569d [`pandas-vet`] Deprecate `pandas-df-variable-name` (`PD901`) (#18618)
Summary
--

Deprecates PD901 as part of #7710. I don't feel particularly strongly
about this one, though I have certainly used `df` as a dataframe name in
the past, just going through the open issues in the 0.12 milestone.

Test Plan
--

N/a
2025-06-17 09:58:12 -04:00
Brent Westbrook 34dc8e0531 [`flake8-bandit`] Remove `suspicious-xmle-tree-usage` (`S320`) (#18617)
Summary
--

Closes #13707. The rule was deprecated in 0.10 (#16680) and slated for
removal in either this or the next release.

Test Plan
--

N/a
2025-06-17 09:58:12 -04:00
Dylan b01195b166 Stabilize `dataclass-enum` (`RUF049`) (#18570)
Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2025-06-17 09:58:12 -04:00
Dylan ce176b1acf Stabilize `unnecessary-dict-index-lookup` (`PLR1733`) (#18571)
Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2025-06-17 09:58:12 -04:00
Brent Westbrook 72c8dc006f Stabilize `starmap-zip` (`RUF058`) (#18525)
## Summary
- Stabilizes RUF058 (starmap-zip) rule by changing it from Preview to
Stable
- Migrates test cases from preview_rules to main rules function 
- Updates snapshots accordingly and removes old preview snapshots

## Test plan
-  Migrated tests from preview to main test function
-  `make check` passes
-  `make test` passes  
-  `make citest` passes (no leftover snapshots)

## Rule Documentation
- [Test
file](https://github.com/astral-sh/ruff/blob/main/crates/ruff_linter/src/rules/ruff/mod.rs#L103-L104)
- [Rule documentation](https://docs.astral.sh/ruff/rules/starmap-zip/)
2025-06-17 09:58:12 -04:00
Brent Westbrook ad9ae4e2b6 [`flake8-logging`] Stabilize `exc-info-outside-except-handler` (`LOG014`) (#18517)
## Summary
- Stabilizes LOG014 (exc-info-outside-except-handler) rule by changing
it from Preview to Stable

## Test plan
-  Rule is already tested in main test function, no migration needed
-  `make check` passes
-  `make test` passes

## Rule Documentation
- [Test
file](https://github.com/astral-sh/ruff/blob/main/crates/ruff_linter/src/rules/flake8_logging/mod.rs#L22-L23)
- [Rule
documentation](https://docs.astral.sh/ruff/rules/exc-info-outside-except-handler/)
2025-06-17 09:58:12 -04:00
Dylan de4fc5b171 [`pyupgrade`] Stabilize `non-pep604-annotation-optional` (`UP045`) and preview behavior for `non-pep604-annotation-union` (`UP007`) (#18505) 2025-06-17 09:58:12 -04:00
Dylan 56f2aaaebc Stabilize `pytest-warns-too-broad` (`PT030`) (#18568) 2025-06-17 09:58:12 -04:00
Dylan ebd2a27559 Stabilize `for-loop-writes` (`FURB122`) (#18565) 2025-06-17 09:58:12 -04:00
Dylan 1278e3442a Stabilize `pytest-warns-with-multiple-statements` (`PT031`) (#18569) 2025-06-17 09:58:12 -04:00
Dylan 7efbf469dd Stabilize `pytest-parameter-with-default-argument` (`PT028`) (#18566) 2025-06-17 09:58:12 -04:00
Dylan 2a1fed9327 Stabilize `nan-comparison` (`PLW0177`) (#18559) 2025-06-17 09:58:12 -04:00
Dylan 7de8a0b429 Stabilize `check-and-remove-from-set` (`FURB132`) (#18560) 2025-06-17 09:58:12 -04:00
Dylan 0a1c6cb70b Stabilize `unnecessary-round` (`RUF057`) (#18563) 2025-06-17 09:58:12 -04:00
Dylan 2dafc5a8bd Stabilize `eq-without-hash` (`PLW1641`) (#18561) 2025-06-17 09:58:12 -04:00
Dylan 72a4c3ed83 Stabilize `int-on-sliced-str` (`FURB166`) (#18558) 2025-06-17 09:58:12 -04:00
Dylan e559e21e93 [`pylint`] Stabilize `import-outside-top-level` (`PLC0415`) (#18554) 2025-06-17 09:58:12 -04:00
Dylan c948be495a [`ruff`] Stabilize `invalid-formatter-suppression-comment` (`RUF028`) (#18555) 2025-06-17 09:58:12 -04:00
Dylan cd245d292e Stabilize `verbose-decimal-constructor` (`FURB157`) (#18556) 2025-06-17 09:58:12 -04:00
Brent Westbrook 620b84443b [pyupgrade] Stabilize private-type-parameter (UP049) (#18515)
## Summary
Stabilizes the UP049 rule (private-type-parameter) by moving it from
Preview to Stable.

UP049 detects and fixes the use of private type parameters (those with
leading underscores) in PEP 695 generic classes and functions.

## Test plan
- Verified that UP049 tests pass:
`crates/ruff_linter/src/rules/pyupgrade/mod.rs`
- Ran full test suite with `make test` 
- Confirmed that no test migration was needed as UP049 was already in
the main `rules` test function

## Rule documentation
https://docs.astral.sh/ruff/rules/private-type-parameter/
2025-06-17 09:58:12 -04:00
Dylan 1f70ceba0c [`flake8-boolean-trap`] Stabilize lint `bool` suprtypes in `boolean-type-hint-positional-argument` (`FBT001`) (#18520)
Feel free to complain about the rephrasing in the docs!
2025-06-17 09:58:12 -04:00
Dylan 00e9de8db9 [`flake8-bandit`] Stabilize more trusted inputs in `subprocess-without-shell-equals-true` (`S603`) (#18521) 2025-06-17 09:58:12 -04:00
Dylan 7211660f8b [`flake8-pyi`] Stabilize autofix for `future-annotations-in-stub` (`PYI044`) (#18518) 2025-06-17 09:58:12 -04:00
Dylan c1610e2eaf [semantic errors] Stabilize semantic errors (#18523) 2025-06-17 09:58:12 -04:00
Dylan bf53bc4256 [syntax errors] Stabilize version-specific unsupported syntax errors (#18522) 2025-06-17 09:58:12 -04:00
Dylan 9f2ae1f568 [`ruff`] Stabilize checking for file-level directives in `unused-noqa` (`RUF100`) (#18497)
Note that the preview behavior was not documented (shame on us!) so the
documentation was not modified.

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2025-06-17 09:58:12 -04:00
Dylan 5cf2c40d13 [`flake8-simplify`] Stabilize further simplification to binary expressions in autofix for `if-else-block-instead-of-if-exp` (`SIM108`) (#18506) 2025-06-17 09:58:12 -04:00
Brent Westbrook 02b5376a3c [refurb] Stabilize `fromisoformat-replace-z` (FURB162) (#18510)
This PR stabilizes the FURB162 rule by moving it from preview to stable
status for the 0.12.0 release.

## Summary
- **Rule**: FURB162 (`fromisoformat-replace-z`)
- **Purpose**: Detects unnecessary timezone replacement operations when
calling `datetime.fromisoformat()`
- **Change**: Move from `RuleGroup::Preview` to `RuleGroup::Stable` in
`codes.rs`

## Verification Links
- **Tests**:
[refurb/mod.rs](https://github.com/astral-sh/ruff/blob/main/crates/ruff_linter/src/rules/refurb/mod.rs#L54)
- Confirms FURB162 has only standard tests, no preview-specific test
cases
- **Documentation**:
https://docs.astral.sh/ruff/rules/fromisoformat-replace-z/ - Current
documentation shows preview status that will be automatically updated
2025-06-17 09:58:12 -04:00
Brent Westbrook 18a134ae1f [ruff] Stabilize `class-with-mixed-type-vars` (RUF053) (#18512)
This PR stabilizes the RUF053 rule by moving it from preview to stable
status for the 0.12.0 release.

## Summary
- **Rule**: RUF053 (`class-with-mixed-type-vars`)
- **Purpose**: Detects classes that have both PEP 695 type parameter
lists while also inheriting from `typing.Generic`
- **Change**: Move from `RuleGroup::Preview` to `RuleGroup::Stable` in
`codes.rs` and migrate preview tests to stable tests

## Verification Links
- **Tests**:
[ruff/mod.rs](https://github.com/astral-sh/ruff/blob/main/crates/ruff_linter/src/rules/ruff/mod.rs#L98)
- Shows RUF053 moved from preview_rules to main rules test function
- **Documentation**:
https://docs.astral.sh/ruff/rules/class-with-mixed-type-vars/ - Current
documentation shows preview status that will be automatically updated
2025-06-17 09:58:12 -04:00
Dylan c063940d52 [`ruff`] Stabilize checking in presence of slices for `collection-literal-concatenation` (`RUF005`) (#18500) 2025-06-17 09:58:12 -04:00
Dylan 8aea383f29 [`refurb`] Stabilize fix safety for `readlines-in-for` (`FURB129`) (#18496)
Note that the preview behavior was not documented (shame on us!) so the
documentation was not modified.

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2025-06-17 09:58:12 -04:00
Victor Hugo Gomes cff5adf324
[`pyupgrade`] Suppress `UP008` diagnostic if `super` symbol is not builtin (#18688)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

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

## Summary

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

## Test Plan

Add regression test
<!-- How was it tested? -->
2025-06-16 15:09:31 -04:00
Nikolas Hearp 7880a20794
[pylint] Fix `PLW0128` to check assignment targets in square brackets and after asterisks (#18665)
## Summary

This fixes PLW0128 to check for redeclared assignments in square
brackets and after asterisks.

Fixes #18660
2025-06-16 15:02:30 -04:00
chiri 83b0cde2fc
[`refurb`] Make the fix for `FURB163` unsafe for `log2`, `log10`, `*args`, and deleted comments (#18645)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

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

## Summary
/closes #18639
<!-- What's the purpose of the change? What does it do, and why? -->

## Test Plan
update snapshots
<!-- How was it tested? -->

---------

Co-authored-by: Brent Westbrook <brentrwestbrook@gmail.com>
2025-06-16 18:13:47 +00:00
Denys Kyslytsyn c3aa965546
[`ruff`] Check for non-context-manager use of `pytest.raises`, `pytest.warns`, and `pytest.deprecated_call` (`RUF061`) (#17368)
<!--
Thank you for contributing to Ruff! To help us out with reviewing,
please consider the following:

- Does this pull request include a summary of the change? (See below.)
- Does this pull request include a descriptive title?
- Does this pull request include references to any relevant issues?
-->

This PR aims to close #16605.

## Summary

This PR introduces a new rule (`RUF061`) that detects non-contextmanager
usage of `pytest.raises`, `pytest.warns`, and `pytest.deprecated_call`.
This pattern is discouraged and [was proposed in
flake8-pytest-style](https://github.com/m-burst/flake8-pytest-style/pull/332),
but the corresponding PR has been open for over a month without
activity.

Additionally, this PR provides an unsafe fix for simple cases where the
non-contextmanager form can be transformed into the context manager
form. Examples of supported patterns are listed in `RUF061_raises.py`,
`RUF061_warns.py`, and `RUF061_deprecated_call.py` test files.

The more complex case from the original issue (involving two separate
statements):
```python
excinfo = pytest.raises(ValueError, int, "hello")
assert excinfo.match("^invalid literal")
```
is getting fixed like this:
```python
with pytest.raises(ValueError) as excinfo:
    int("hello")
assert excinfo.match("^invalid literal")
```
Putting match in the raises call requires multi-statement
transformation, which I am not sure how to implement.

## Test Plan

<!-- How was it tested? -->

New test files were added to cover various usages of the
non-contextmanager form of pytest.raises, warns, and deprecated_call.
2025-06-16 13:03:54 -04:00
Juriah a842899862
[`flake8-pyi`] Fix `custom-typevar-for-self` with string annotations (`PYI019`) (#18311)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

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

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

Solves #18257 

## Test Plan

<!-- How was it tested? -->
Snapshots updated with some cases (negative, positive, mixed
annotations).
2025-06-16 10:47:17 -04:00
Brent Westbrook e4423044f8
[`ruff`] Validate arguments before offering a fix (`RUF056`) (#18631)
## Summary

Fixes https://github.com/astral-sh/ruff/issues/18628 by avoiding a fix
if there are "unknown" arguments, including any keyword arguments and
more than the expected 2 positional arguments.

I'm a bit on the fence here because it also seems reasonable to avoid a
diagnostic at all. Especially in the final test case I added (`not
my_dict.get(default=False)`), the hint suggesting to remove
`default=False` seems pretty misleading. At the same time, I guess the
diagnostic at least calls attention to the call site, which could help
to fix the missing argument bug too.

As I commented on the issue, I double-checked that keyword arguments are
invalid as far back as Python 3.8, even though the positional-only
marker was only added to the
[docs](https://docs.python.org/3.11/library/stdtypes.html#dict.get) in
3.12 (link is to 3.11, showing its absence).

## Test Plan

New tests derived from the bug report

## Stabilization

This was planned to be stabilized in 0.12, and the bug is less severe
than some others, but if there's nobody opposed, I will plan **not to
stabilize** this one for now.
2025-06-13 23:07:02 +00:00
𝕂 793ff9bdbc
Fix false positive in for mutations in return statements (B909) (#18408)
<!--
Thank you for contributing to Ruff/ty! To help us out with reviewing,
please consider the following:

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

## Summary

Fixes false positive in B909 (`loop-iterator-mutation`) where mutations
inside return/break statements were incorrectly flagged as violations.
The fix adds tracking for when mutations occur within return/break
statements and excludes them from violation detection, as they don't
cause the iteration issues B909 is designed to prevent.



## Test Plan

- Added test cases covering the reported false positive scenarios to
`B909.py`
  - Verified existing B909 tests continue to pass (no regressions)
  - Ran `cargo test -p ruff_linter --lib flake8_bugbear` successfully

Fixes #18399
2025-06-13 10:39:55 -04:00
Ibraheem Ahmed c9dff5c7d5
[ty] AST garbage collection (#18482)
## Summary

Garbage collect ASTs once we are done checking a given file. Queries
with a cross-file dependency on the AST will reparse the file on demand.
This reduces ty's peak memory usage by ~20-30%.

The primary change of this PR is adding a `node_index` field to every
AST node, that is assigned by the parser. `ParsedModule` can use this to
create a flat index of AST nodes any time the file is parsed (or
reparsed). This allows `AstNodeRef` to simply index into the current
instance of the `ParsedModule`, instead of storing a pointer directly.

The indices are somewhat hackily (using an atomic integer) assigned by
the `parsed_module` query instead of by the parser directly. Assigning
the indices in source-order in the (recursive) parser turns out to be
difficult, and collecting the nodes during semantic indexing is
impossible as `SemanticIndex` does not hold onto a specific
`ParsedModuleRef`, which the pointers in the flat AST are tied to. This
means that we have to do an extra AST traversal to assign and collect
the nodes into a flat index, but the small performance impact (~3% on
cold runs) seems worth it for the memory savings.

Part of https://github.com/astral-sh/ty/issues/214.
2025-06-13 08:40:11 -04:00
Victor Hugo Gomes 76d9009a6e
[`pycodestyle`] Fix `E731` autofix creating a syntax error for expressions spanned across multiple lines (#18479) 2025-06-13 08:44:15 +02:00
Brent Westbrook 96171f41c2
[`ruff`] Handle extra arguments to `deque` (`RUF037`) (#18614)
## Summary

Fixes https://github.com/astral-sh/ruff/issues/18612 by:
- Bailing out without a fix in the case of `*args`, which I don't think
we can fix reliably
- Using an `Edit::deletion` from `remove_argument` instead of an
`Edit::range_replacement` in the presence of unrecognized keyword
arguments

I thought we could always switch to the `Edit::deletion` approach
initially, but it caused problems when `maxlen` was passed positionally,
which we didn't have any existing tests for.

The replacement fix can easily delete comments, so I also marked the fix
unsafe in these cases and updated the docs accordingly.

## Test Plan

New test cases derived from the issue.

## Stabilization

These are pretty significant changes, much like those to PYI059 in
https://github.com/astral-sh/ruff/pull/18611 (and based a bit on the
implementation there!), so I think it probably makes sense to
un-stabilize this for the 0.12 release, but I'm open to other thoughts
there.
2025-06-12 09:07:17 -04:00
chiri dbb0d60caa
[`pyupgrade`] Fix `super(__class__, self)` detection in UP008 (super-call-with-parameters) (#18478) 2025-06-12 08:52:45 +02:00