Commit Graph

3384 Commits

Author SHA1 Message Date
Charlie Marsh b0d6fd7343
Generate custom JSON schema for dynamic setting (#9632)
## Summary

If you paste in the TOML for our default configuration (from the docs),
it's rejected by our JSON Schema:

![Screenshot 2024-01-23 at 10 08
09 PM](https://github.com/astral-sh/ruff/assets/1309177/7b4ea6e8-07db-4590-bd1e-73a01a35d747)

It seems like the issue is with:

```toml
# Set the line length limit used when formatting code snippets in
# docstrings.
#
# This only has an effect when the `docstring-code-format` setting is
# enabled.
docstring-code-line-length = "dynamic"
```

Specifically, since that value uses a custom Serde implementation, I
guess Schemars bails out? This PR adds a custom representation to allow
`"dynamic"` (but no other strings):

![Screenshot 2024-01-23 at 10 27
21 PM](https://github.com/astral-sh/ruff/assets/1309177/ab7809d4-b077-44e9-8f98-ed893aaefe5d)

This seems like it should work but I don't have a great way to test it.

Closes https://github.com/astral-sh/ruff/issues/9630.
2024-01-24 04:26:02 +00:00
Akira Noda 57313d9d63
[`pylint`] Implement `assigning-non-slot` (`E0237`) (#9623)
## Summary

Implement [assigning-non-slot /
E0237](https://pylint.readthedocs.io/en/latest/user_guide/messages/error/assigning-non-slot.html)

related #970

## Test Plan

`cargo test`
2024-01-24 02:50:22 +00:00
Mikko Leppänen eab1a6862b
[`ruff`] Detect unnecessary `dict` comprehensions for iterables (`RUF025`) (#9613)
## Summary

Checks for unnecessary `dict` comprehension when creating a new
dictionary from iterable. Suggest to replace with
`dict.fromkeys(iterable)`

See: https://github.com/astral-sh/ruff/issues/9592

## Test Plan

```bash
cargo test
```
2024-01-24 02:15:38 +00:00
Micha Reiser 395bf3dc98
Fix the input for black's line ranges test file (#9622) 2024-01-23 10:40:23 +00:00
Charlie Marsh 47b8a897e7
[`flake8-simplify`] Support inverted returns in `needless-bool` (`SIM103`) (#9619)
Closes https://github.com/astral-sh/ruff/issues/9618.
2024-01-23 03:26:53 +00:00
Alex Waygood f5061dbb8e
Add a rule/autofix to sort `__slots__` and `__match_args__` (#9564)
## Summary

This PR introduces a new rule to sort `__slots__` and `__match_args__`
according to a [natural sort](https://en.wikipedia.org/wiki/Natural_sort_order), as was
requested in https://github.com/astral-sh/ruff/issues/1198#issuecomment-1881418365.

The implementation here generalises some of the machinery introduced in
3aae16f1bd
so that different kinds of sorts can be applied to lists of string
literals. (We use an "isort-style" sort for `__all__`, but that isn't
really appropriate for `__slots__` and `__match_args__`, where nearly
all items will be snake_case.) Several sections of code have been moved
from `sort_dunder_all.rs` to a new module, `sorting_helpers.rs`, which
`sort_dunder_all.rs` and `sort_dunder_slots.rs` both make use of.

`__match_args__` is very similar to `__all__`, in that it can only be a
tuple or a list. `__slots__` differs from the other two, however, in
that it can be any iterable of strings. If slots is a dictionary, the
values are used by the builtin `help()` function as per-attribute
docstrings that show up in the output of `help()`. (There's no
particular use-case for making `__slots__` a set, but it's perfectly
legal at runtime, so there's no reason for us not to handle it in this
rule.)

Note that we don't do an autofix for multiline `__slots__` if `__slots__` is a dictionary: that's out of scope. Everything else, we can nearly always fix, however.

## Test Plan

`cargo test` / `cargo insta review`.

I also ran this rule on CPython, and the diff looked pretty good

---

Co-authored-by: Micha Reiser <micha@reiser.io>
2024-01-22 12:21:55 +00:00
Steve C 9c8a4d927e
[`flake8-simplify`] Add fix for `if-with-same-arms` (`SIM114`) (#9591)
## Summary

 add fix for `if-with-same-arms` / `SIM114`

Also preserves comments!

## Test Plan

`cargo test`
2024-01-22 04:37:18 +00:00
trag1c 836e4406a5
Corrected code block hyperlink (#9602)
## Summary

Apparently MkDocs doesn't like when reference-style links have
formatting inside :)

<details>
<summary>Screenshots (before and after the change)</summary>
<img width="1235" alt="61353"
src="https://github.com/astral-sh/ruff/assets/77130613/e32a82bd-0c5d-4edb-998f-b53659a6c54d">

<img width="1237" alt="15526"
src="https://github.com/astral-sh/ruff/assets/77130613/bdafcda5-eb9c-4af6-af03-b4849c1e5c81">
</details>
2024-01-21 22:57:34 -05:00
Steve C e54ed28ba9
[`pylint`] Add fix for `collapsible-else-if` (`PLR5501`) (#9594)
## Summary

adds a fix for `collapsible-else-if` / `PLR5501`

## Test Plan

`cargo test`
2024-01-21 19:53:15 -05:00
Tom Kuson 1e4b421a00
[`ruff`] Implement `mutable-fromkeys-value` (`RUF024`) (#9597)
## Summary

Implement rule `mutable-fromkeys-value` (`RUF023`).

Autofixes

```python
dict.fromkeys(foo, [])
```

to

```python
{key: [] for key in foo}
```

The fix is marked as unsafe as it changes runtime behaviour. It also
uses `key` as the comprehension variable, which may not always be
desired.

Closes #4613.

## Test Plan

`cargo test`
2024-01-22 00:22:02 +00:00
Charlie Marsh a1f3cda190
Include global `--config` when determining namespace packages (#9603)
## Summary

When determining whether _any_ settings have namespace packages, we need
to consider the global settings (as would be provided via `--config`).
This was a subtle fallout of a refactor.

Closes https://github.com/astral-sh/ruff/issues/9579.

## Test Plan

Tested locally by compiling Ruff and running against this
[namespace-test](https://github.com/gokay05/namespace-test) repo.
2024-01-21 19:10:43 -05:00
Steve C 837984168a
[`pycodestyle`] Add fix for `multiple-imports-on-one-line` (`E401`) (#9518)
## Summary

Add autofix for `multiple_imports_on_one_line`, `E401`

## Test Plan

`cargo test`
2024-01-21 15:33:38 -05:00
Charlie Marsh b64aa1e86d
Split pycodestyle import rules into separate files (#9600) 2024-01-21 19:30:00 +00:00
Steve C 9e5f3f1b1b
[`pylint`] Add fix for `useless-else-on-loop` (`PLW0120`) (#9590)
## Summary

adds fix for `useless-else-on-loop` / `PLW0120`.

## Test Plan

`cargo test`
2024-01-21 11:17:58 -05:00
Steve C 49a445a23d
[`pylint`] Implement `potential-index-error` (`PLE0643`) (#9545)
## Summary

add `potential-index-error` rule (`PLE0643`)

See: #970 

## Test Plan

`cargo test`
2024-01-21 03:59:48 +00:00
Charlie Marsh 866bea60a5
Bump version to v0.1.14 (#9581) 2024-01-19 12:54:39 -05:00
Charlie Marsh df617c3093
[`flake8-blind-except`] Document exceptions to `blind-except` rule (#9580)
Closes https://github.com/astral-sh/ruff/issues/9571.
2024-01-19 16:58:31 +00:00
Micha Reiser 47ad7b4500
Approximate tokens len (#9546) 2024-01-19 17:39:37 +01:00
Alex Waygood b3a6f0ce81
[flake8-pyi] Fix PYI049 false negatives on call-based TypedDicts (#9567)
## Summary

Fixes another of the bullet points from #8771

## Test Plan

`cargo test` / `cargo insta review`
2024-01-18 10:01:21 +00:00
Thomas M Kehrenberg 7be706641d
[`pylint`] Exclude `self` and `cls` when counting method arguments (#9563)
## Summary

This PR detects whether PLR0917 is being applied to a method or class
method, and if so, it ignores the first argument for the purposes of
counting the number of positional arguments.

## Test Plan

New tests have been added to the corresponding fixture.

Closes #9552.
2024-01-18 03:17:45 +00:00
Alex Waygood 848e473f69
[flake8-pyi] Fix PYI047 false negatives on PEP-695 type aliases (#9566)
## Summary

Fixes one of the issues listed in
https://github.com/astral-sh/ruff/issues/8771. Fairly straightforward!

## Test Plan

`cargo test` / `cargo insta review`
2024-01-17 22:14:18 -05:00
Charlie Marsh 29c130f326
Make `ruff` the default binary (#9558)
## Summary

This makes `cargo run` equivalent to `cargo run -p ruff` which is almost
always what you want.
2024-01-16 18:31:24 -05:00
Charlie Marsh 8118d29419
Rename `ruff_cli` crate to `ruff` (#9557)
## Summary

Long ago, we had a single `ruff` crate. We started to break that up, and
at some point, we wanted to separate the CLI from the core library. So
we created `ruff_cli`, which created a `ruff` binary. Later, the `ruff`
crate was renamed to `ruff_linter` and further broken up into additional
crates.

(This is all from memory -- I didn't bother to look through the history
to ensure that this is 100% correct :))

Now that `ruff` no longer exists, this PR renames `ruff_cli` to `ruff`.
The primary benefit is that the binary target and the crate name are now
the same, which helps with downstream tooling like `cargo-dist`, and
also removes some complexity from the crate and `Cargo.toml` itself.

## Test Plan

- Ran `rm -rf target/release`.
- Ran `cargo build --release`.
- Verified that `./target/release/ruff` was created.
2024-01-16 17:47:01 -05:00
Charlie Marsh 45d374d838
[`refurb`] Avoid bailing when `reimplemented-operator` is called on function (#9556)
Closes https://github.com/astral-sh/ruff/issues/9549.
2024-01-16 20:26:18 +00:00
Tom Kuson f426c0fdaf
[`pylint`] (Re-)Implement `import-private-name` (`C2701`) (#9553)
## Summary

#5920 with a fix for the erroneous slice in `module_name`. Fixes #9547.

## Test Plan

Added `import bbb.ccc._ddd as eee` to the test fixture to ensure it no
longer panics.

`cargo test`
2024-01-16 14:03:11 -05:00
Alex Waygood 3aae16f1bd
Add rule and autofix to sort the contents of `__all__` (#9474)
## Summary

This implements the rule proposed in #1198 (though it doesn't close the
issue, as there are some open questions about configuration that might
merit some further discussion).

## Test Plan

`cargo test` / `cargo insta review`. I also ran this PR branch on the CPython
codebase with `--fix --select=RUF022 --preview `, and the results looked
pretty good to me.

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
Co-authored-by: Andrew Gallant <andrew@astral.sh>
2024-01-16 14:42:47 +00:00
Micha Reiser f9191b07c5
Revert "[`pylint`] Implement `import-private-name` (`C2701`)" (#9547) 2024-01-16 08:33:21 +00:00
Micha Reiser 21f2d0c90b
Add an explicit fast path for whitespace to `is_identifier_continuation` (#9532) 2024-01-16 08:23:43 +00:00
Tom Kuson 2b605527bd
[`pylint`] Implement `import-private-name` (`C2701`) (#5920)
## Summary

Implements [`import-private-name`
(`C2701`)](https://pylint.pycqa.org/en/latest/user_guide/messages/convention/import-private-name.html)
as `import-private-name` (`PLC2701`). Includes documentation.

Related to #970.

Closes https://github.com/astral-sh/ruff/issues/9138.

### PEP 420 namespace package limitation

`checker.module_path` doesn't seem to support automatic detection of
namespace packages (PEP 420). This leads to 'false' positives (Pylint
allows both).

Currently, for this to work like Pylint, users would have to [manually
input known namespace
packages](https://beta.ruff.rs/docs/settings/#namespace-packages).

## Test Plan

`cargo test`
2024-01-16 05:17:42 +00:00
Steve C 7ef7e0ddb6
[`tryceratops`] Add fix for `error-instead-of-exception` (`TRY400`) (#9520)
## Summary

add autofix for `error-instead-of-exception` (`TRY400`)

## Test Plan

`cargo test`
2024-01-16 03:00:04 +00:00
Steve C 2bddde2627
[`pygrep_hooks`] Add fix for `deprecated-log-warn` (`PGH002`) (#9519)
## Summary

add autofix for `deprecated_log_warn` (`PGH002`)

## Test Plan

`cargo test`

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-01-15 21:54:40 -05:00
Charlie Marsh 9a2f3e2cef
Ignore preview status for fixable and unfixable selectors (#9538)
## Summary

Right now, if you run with `explicit-preview-rules`, and use something
like `select = ["RUF017"]`, we won't actually enable fixing for that
rule, because `fixable = ["ALL"]` (the default) won't include `RUF017`
due to the `explicit-preview-rules`.

The framing in this PR is that `explicit-preview-rules` should only
affect the enablement selectors, whereas the fixable selectors should
just include all possible matching rules. I think this will lead to the
most intuitive behavior.

Closes https://github.com/astral-sh/ruff/issues/9282. (An alternative to
https://github.com/astral-sh/ruff/pull/9284.)
2024-01-15 21:48:41 -05:00
Charlie Marsh f9331c7683
Recursively visit deferred AST nodes (#9541)
## Summary

This PR is a more holistic fix for
https://github.com/astral-sh/ruff/issues/9534 and
https://github.com/astral-sh/ruff/issues/9159.

When we visit the AST, we track nodes that we need to visit _later_
(deferred nodes). For example, when visiting a function, we defer the
function body, since we don't want to visit the body until we've visited
the rest of the statements in the containing scope.

However, deferred nodes can themselves contain deferred nodes... For
example, a function body can contain a lambda (which contains a deferred
body). And then there are rarer cases, like a lambda inside of a type
annotation.

The aforementioned issues were fixed by reordering the deferral visits
to catch common cases. But even with those fixes, we still fail on cases
like:

```python
from __future__ import annotations

import re
from typing import cast

cast(lambda: re.match, 1)
```

Since we don't expect lambdas to appear inside of type definitions.

This PR modifies the `Checker` to keep visiting until all the deferred
stacks are empty. We _already_ do this for any one kind of deferred
node; now, we do it for _all_ of them at a level above.
2024-01-15 20:34:38 -05:00
Charlie Marsh da275b8572
Visit deferred lambdas before type definitions (#9540)
## Summary

This is effectively the same problem as
https://github.com/astral-sh/ruff/pull/9175. And this just papers over
it again, though I'm gonna try a more holistic fix in a follow-up PR.
The _real_ fix here is that we need to continue to visit deferred items
until they're exhausted since, e.g., we still get this case wrong
(flagging `re` as unused):

```python
import re

cast(lambda: re.match, 1)
```

Closes https://github.com/astral-sh/ruff/issues/9534.
2024-01-15 20:08:40 -05:00
Charlie Marsh b983ab1c6c
Update contributing docs to use `cargo bench -p ruff_benchmark` (#9535)
## Summary

I found that `cargo benchmark lexer` didn't work as expected:

```shell
❯ cargo benchmark lexer
    Finished bench [optimized] target(s) in 0.08s
     Running benches/formatter.rs (target/release/deps/formatter-4e1d9bf9d3ba529d)
     Running benches/linter.rs (target/release/deps/linter-e449086ddfd8ad8c)
```

Turns out that `cargo bench -p ruff_benchmark` is now recommended over
`cargo benchmark`, so updating the docs to reflect that.
2024-01-15 14:57:30 -05:00
Alex Waygood a1e65a92bd
Move `is_tuple_parenthesized` from the formatter to `ruff_python_ast` (#9533)
This allows it to be used in the linter as well as the formatter. It
will be useful in #9474
2024-01-15 16:10:40 +00:00
yataka 0753968ef3
add the "__prepare__" method to the list of recognized dunder method (#9529)
## Summary
Closes #9508 .
Add `__prepare__` method to dunder method list in
`is_known_dunder_method`.

## Test Plan
1. add "__prepare__" method to `Apple` class in
crates/ruff_linter/resources/test/fixtures/pylint/bad_dunder_method_name.py.
2. run `cargo test`
2024-01-15 14:37:19 +00:00
Steve C 6183b8e98b
[`refurb`] Implement `regex-flag-alias` with fix (`FURB167`) (#9516)
## Summary

add
[`FURB167`/`use-long-regex-flag`](https://github.com/dosisod/refurb/blob/master/refurb/checks/regex/use_long_flag.py)
with autofix

See: #1348 

## Test Plan

`cargo test`

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-01-14 23:40:17 +00:00
Steve C 0c0d3db1b5
[`flake8-bugbear`] Add fix for `duplicate-value` (`B033`) (#9510)
## Summary

Adds autofix for
[B033](https://docs.astral.sh/ruff/rules/duplicate-value/)

## Test Plan

`cargo test`
2024-01-14 23:20:16 +00:00
Charlie Marsh 953d48b7f4
[`flake8-simplify`] Avoid some more `enumerate-for-loop` false positives (`SIM113`) (#9515)
Avoids, e.g., [this false
positive](a4fad5dda1/zerver/data_import/slack.py (L634))
from the ecosystem check.
2024-01-14 13:02:13 -05:00
Chammika Mannakkara 0003c730e0
[`flake8-simplify`] Implement `enumerate-for-loop` (`SIM113`) (#7777)
Implements SIM113 from #998

Added tests
Limitations 
   - No fix yet
   - Only flag cases where index variable immediately precede `for` loop

@charliermarsh please review and let me know any improvements

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-01-14 11:00:59 -05:00
Hoël Bagard e8d7a6dfce
Use the `LinterSettings`'s tab size when expanding indent (#9506)
## Summary
In the `logical_lines`'s `expand_indent` , respect the
`LinterSettings::tab_size` setting instead of hardcoding the size of
tabs to 8.

Also see [this
conversation](https://github.com/astral-sh/ruff/pull/9266#discussion_r1447102212)

## Test Plan

Tested by running `cargo test`
2024-01-13 21:06:50 -05:00
Charlie Marsh 957a1f35c4
Ignore unnecessary dunder calls within dunder definitions (#9496)
Closes https://github.com/astral-sh/ruff/issues/9486.
2024-01-12 14:48:42 -05:00
Charlie Marsh 009430e034
[`ruff`] Avoid treating named expressions as static keys (`RUF011`) (#9494)
Closes https://github.com/astral-sh/ruff/issues/9487.
2024-01-12 14:33:45 -05:00
Jane Lewis 7504bf347b
`--show-settings` displays active settings in a far more readable format (#9464)
<!--
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?
-->

## Summary

Fixes #8334.

`Display` has been implemented for `ruff_workspace::Settings`, which
gives a much nicer and more readable output to `--show-settings`.

Internally, a `display_settings` utility macro has been implemented to
reduce the boilerplate of the display code.

### Work to be done

- [x] A lot of formatting for `Vec<_>` and `HashSet<_>` types have been
stubbed out, using `Debug` as a fallback. There should be a way to add
generic formatting support for these types as a modifier in
`display_settings`.
- [x] Several complex types were also stubbed out and need proper
`Display` implementations rather than falling back on `Debug`.
- [x] An open question needs to be answered: how important is it that
the output be valid TOML? Some types in settings, such as a hash-map
from a glob pattern to a multi-variant enum, will be hard to rework into
valid _and_ readable TOML.
- [x] Tests need to be implemented.

## Test Plan

Tests consist of a snapshot test for the default `--show-settings`
output and a doctest for `display_settings!`.
2024-01-12 14:30:29 -05:00
Charlie Marsh fee64b52ba
Limit inplace diagnostics to methods that accept inplace (#9495)
## Summary

This should reduce false positives like
https://github.com/astral-sh/ruff/issues/9491, by ignoring methods that
are clearly not on a DataFrame.

Closes https://github.com/astral-sh/ruff/issues/9491.
2024-01-12 14:12:54 -05:00
Charlie Marsh 3261d16e61
Add `--extension` support to the formatter (#9483)
## Summary

We added `--extension` to `ruff check`, but it's equally applicable to
`ruff format`.

Closes https://github.com/astral-sh/ruff/issues/9482.

Resolves https://github.com/astral-sh/ruff/discussions/9481.

## Test Plan

`cargo test`
2024-01-12 18:53:25 +00:00
Charlie Marsh d16c4a2d25
Bump version to v0.1.13 (#9493) 2024-01-12 09:27:39 -05:00
Aleksei Latyshev 1602df1643
Fix message for __aenter__ in PLC2801 (#9492)
<!--
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?
-->

## Summary

Fix the message for `__aenter__ ` in PLC2801 (introduced in
https://github.com/astral-sh/ruff/pull/9166)
There is no `aenter` builtin in Python, so the current message is
misleading.
I take the message from original lint
https://github.com/pylint-dev/pylint/blob/main/pylint/constants.py#L211

P.S. I think here should be more accurate synchronization with original
lint (e.g. the current implementation will not lint `__enter__` on my
first sight), but it is out-of-scope of this change.

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

## Test Plan

<!-- How was it tested? -->
2024-01-12 08:48:45 -05:00
Alex Waygood 395cdf04e5
Fix backticks in RUF021 docs (#9488)
The docs for this rule aren't generating properly:
https://docs.astral.sh/ruff/rules/parenthesize-chained-operators/#why-is-this-bad.
I assume this is the reason why!
2024-01-12 09:00:44 +00:00
KotlinIsland 3daf6e1b6d
(🐞) Add the missing period in error message (#9485)
<!--
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?
-->

## Summary

<!-- What's the purpose of the change? What does it do, and why? -->
I noticed that there should be a missing period added to some of the new
error messages for Unnecessary dunder call:
```
sandpit\test.py:6:16: PLC2801 Unnecessary dunder call to `__getattribute__`. Access attribute directly or use getattr built-in function..
```
## Test Plan

Static analysis of the implementation, as this has no existing test
cases.
2024-01-11 23:43:46 -05:00
Charlie Marsh a31a314b2b
Account for possibly-empty f-string values in truthiness logic (#9484)
Closes https://github.com/astral-sh/ruff/issues/9479.
2024-01-11 21:16:19 -05:00
Charlie Marsh f9dd7bb190
Remove `unreachable-code` feature (#9463)
## Summary

We haven't found time to flip this on, so feels like it's best to remove
it for now -- can always restore from source when we get back to it.
2024-01-11 20:24:57 -05:00
Charlie Marsh 350dcb807a
Include base pyproject when initializing cache settings (#9480)
## Summary

Regression from
https://github.com/astral-sh/ruff/pull/9453/files#diff-80a9c2637c432502a7075c792cc60db92282dd786999a78bfa9bb6f025afab35L482.

Closes https://github.com/astral-sh/ruff/issues/9478.

## Test Plan

```
rm -rf .ruff_cache
cargo run -p ruff_cli -- check ../foo.py
```

Failed prior to this PR; passes afterwards. The file must be outside of
the current working directory, and must not have a `pyproject.toml` in
any parent directory.
2024-01-11 19:18:49 -05:00
Charlie Marsh 55f8f3b2cc
Bump version to v0.1.12 (#9475) 2024-01-11 22:13:00 +00:00
trag1c eb4ed2471b
[`flake8-simplify`] Implement `SIM911` (#9460)
## Summary

Closes #9319, implements the [`SIM911` rule from
`flake8-simplify`](https://github.com/MartinThoma/flake8-simplify/pull/183).


#### Note
I wasn't sure whether or not to include
```rs
if checker.settings.preview.is_disabled() {
    return;
}
```
at the beginning of the function with violation logic if the rule's
already declared as part of `RuleGroup::Preview`.
I've seen both variants, so I'd appreciate some feedback on that :)
2024-01-11 14:42:43 -05:00
Micha Reiser f192c72596
Remove type parameter from `parse_*` methods (#9466) 2024-01-11 19:41:19 +01:00
Charlie Marsh 25bafd2d66
Restrict `builtin-attribute-shadowing` to actual shadowed references (#9462)
## Summary

This PR attempts to improve `builtin-attribute-shadowing` (`A003`), a
rule which has been repeatedly criticized, but _does_ have value (just
not in the current form).

Historically, this rule would flag cases like:

```python
class Class:
    id: int
```

This led to an increasing number of exceptions and special-cases to the
rule over time to try and improve it's specificity (e.g., ignore
`TypedDict`, ignore `@override`).

The crux of the issue is that given the above, referencing `id` will
never resolve to `Class.id`, so the shadowing is actually fine. There's
one exception, however:

```python
class Class:
    id: int

    def do_thing() -> id:
        pass
```

Here, `id` actually resolves to the `id` attribute on the class, not the
`id` builtin.

So this PR completely reworks the rule around this _much_ more targeted
case, which will almost always be a mistake: when you reference a class
member from within the class, and that member shadows a builtin.

Closes https://github.com/astral-sh/ruff/issues/6524.

Closes https://github.com/astral-sh/ruff/issues/7806.
2024-01-11 12:59:40 -05:00
Micha Reiser 501bc1c270
Avoid allocating during implicit concatenated string formatting (#9469) 2024-01-11 15:58:49 +01:00
Charlie Marsh 4a3bb67b5f
Move `pyproject_config` into `Resolver` (#9453)
## Summary

Sort of a random PR to make the coupling between `pyproject_config` and
`resolver` more explicit by passing it to the `Resolver`, rather than
threading it through to each individual method.
2024-01-10 17:58:53 -05:00
Micha Reiser 79f4abbb8d
Import Black's type aliases test (#9456) 2024-01-10 12:37:17 +00:00
Micha Reiser 58fcd96ac1
Update Black Tests (#9455) 2024-01-10 12:09:34 +00:00
Micha Reiser ac02d3aedd
Hug multiline-strings preview style (#9243) 2024-01-10 12:47:34 +01:00
Alex Waygood 6be73322da
[RUF021]: Add an autofix (#9449)
## Summary

This adds an autofix for the newly added RUF021 (see #9440).
2024-01-09 17:55:33 +00:00
Charlie Marsh ad1ca72a35
Add some additional Python 3.12 typing members to `deprecated-import` (#9445)
Closes https://github.com/astral-sh/ruff/issues/9443.
2024-01-09 12:52:01 -05:00
Charlie Marsh 381811b4a6
Skip extra settings resolution when namespace packages are empty (#9446)
Saves 2% on Airflow:

```shell
❯ hyperfine --warmup 20 -i "./target/release/main format ../airflow" "./target/release/ruff format ../airflow"
Benchmark 1: ./target/release/main format ../airflow
  Time (mean ± σ):      72.7 ms ±   0.4 ms    [User: 48.7 ms, System: 75.5 ms]
  Range (min … max):    72.0 ms …  73.7 ms    40 runs

Benchmark 2: ./target/release/ruff format ../airflow
  Time (mean ± σ):      71.4 ms ±   0.6 ms    [User: 46.2 ms, System: 76.2 ms]
  Range (min … max):    70.3 ms …  73.8 ms    41 runs

Summary
  './target/release/ruff format ../airflow' ran
    1.02 ± 0.01 times faster than './target/release/main format ../airflow'
```
2024-01-09 08:33:22 -05:00
Charlie Marsh 20af5a774f
Allow `Hashable = None` in type annotations (#9442)
Closes https://github.com/astral-sh/ruff/issues/9441.
2024-01-08 22:38:34 -05:00
Alex Waygood 86b1ae9383
Add rule to enforce parentheses in `a or b and c` (#9440)
Fixes #8721

## Summary

This implements the rule proposed in #8721, as RUF021. `and` always
binds more tightly than `or` when chaining the two together.

(This should definitely be autofixable, but I'm leaving that to a
followup PR for now.)

## Test Plan

`cargo test` / `cargo insta review`
2024-01-08 20:28:03 -05:00
Charlie Marsh 84ab21f073
Add a fix for `redefinition-while-unused` (#9419)
## Summary

This PR enables Ruff to remove redefined imports, as in:

```python
import os
import os

print(os)
```

Previously, Ruff would flag `F811` on the second `import os`, but
couldn't fix it.

For now, this fix is marked as safe, but only available in preview.

Closes https://github.com/astral-sh/ruff/issues/3477.
2024-01-09 00:29:20 +00:00
Charlie Marsh 985f1d10f6
Don't flag `redefined-while-unused` in if branches (#9418)
## Summary

On `main`, we flag redefinitions in cases like:

```python
import os

x = 1

if x > 0:
    import os
```

That is, we consider these to be in the "same branch", since they're not
in disjoint branches. This matches Flake8's behavior, but it seems to
lead to false positives.
2024-01-08 17:06:55 -05:00
Charlie Marsh f419af494f
Allow Boolean positionals in setters (#9429)
## Summary

Ignores Boolean trap enforcement for methods that appear to be setters
(as in the Qt and pygame APIs).

Closes https://github.com/astral-sh/ruff/issues/9287.
Closes https://github.com/astral-sh/ruff/issues/8923.
2024-01-08 13:02:16 -05:00
Micha Reiser 94968fedd5
Use Rust 1.75 toolchain (#9437) 2024-01-08 18:03:16 +01:00
Charlie Marsh ba71772d93
Parenthesize breaking named expressions in match guards (#9396)
## Summary

This is an attempt to solve
https://github.com/astral-sh/ruff/issues/9394 by avoiding breaks in
named expressions when invalid.
2024-01-08 14:47:01 +00:00
Micha Reiser b1a5df8694
Move `locate_cmp_ops` to `invalid_literal_comparisons` (#9438) 2024-01-08 13:15:36 +01:00
Charlie Marsh 04afdf177b
Disambiguate argument descriptors from section headers (#9427)
## Summary

Given a docstring like:

```python
def func(x: int, args: tuple[int]):
    """Toggle the gizmo.

    Args:
        x: Some argument.
        args: Some other arguments.
    """
```

We were considering the `args:` descriptor to be an indented docstring
section header (since `Args:`) is a valid header name. This led to very
confusing diagnostics.

This PR makes the parsing a bit more lax in this case, such that if we
see a nested header that's more deeply indented than the preceding
header, and the preceding section allows sub-items (like `Args:`), we
avoid treating the nested item as a section header.

Closes https://github.com/astral-sh/ruff/issues/9426.
2024-01-07 22:41:00 -05:00
Alex Waygood d5a439cbd3
[flake8-pyi] PYI053: Exclude string literals that are the first argument to `warnings.deprecated` or `typing_extensions.deprecated` (#9423)
Fixes #9420
2024-01-07 18:41:14 -05:00
Charlie Marsh 63953431a6
Include subscripts and attributes in static key rule (#9416) 2024-01-06 17:28:57 -05:00
Charlie Marsh f6841757eb
Use `comment_ranges` for isort directive extraction (#9414)
## Summary

No need to iterate over the token stream to find comments -- we already
know where they are.
2024-01-06 16:05:13 -05:00
Charlie Marsh 1666c7a5cb
Add size hints to string parser (#9413) 2024-01-06 15:59:34 -05:00
Charlie Marsh e80b3db10d
Remove duplicated `NameFinder` struct (#9412) 2024-01-06 20:47:28 +00:00
Charlie Marsh 701697c37e
Support variable keys in static dictionary key rule (#9411)
Closes https://github.com/astral-sh/ruff/issues/9410.
2024-01-06 20:44:40 +00:00
Charlie Marsh c2c9997682
Use `DisplayParseError` for stdin parser errors (#9409)
Just looks like an oversight in refactoring.
2024-01-06 15:28:12 +00:00
Charlie Marsh cee09765ef
Use transformed source code for diagnostic locations (#9408)
## Summary

After we apply fixes, the source code might be transformed. And yet,
we're using the _unmodified_ source code to compute locations in some
cases (e.g., for displaying parse errors, or Jupyter Notebook cells).
This can lead to subtle errors in reporting, or even panics. This PR
modifies the linter to use the _transformed_ source code for such
computations.

Closes https://github.com/astral-sh/ruff/issues/9407.
2024-01-06 10:22:34 -05:00
Alex Waygood cde4a7d7bf
[flake8-pyi] Fix false negative for PYI046 with unused generic protocols (#9405)
I just fixed this false negative in flake8-pyi
(https://github.com/PyCQA/flake8-pyi/pull/460), and then realised ruff
has the exact same bug! Luckily it's a very easy fix.

(The bug is that unused protocols go undetected if they're generic.)
2024-01-05 12:56:04 -06:00
Charlie Marsh 62eca330a8
Remove an unwrap from `unnecessary_literal_union.rs` (#9404) 2024-01-05 13:19:37 -05:00
Mikael Arguedas 59078c5403
homogenize PLR0914 message to match other PLR 09XX rules and pylint message (#9399) 2024-01-05 07:25:26 -05:00
qdegraaf c11f65381f
[`flake8-bandit`] Implement `S503` `SslWithBadDefaults` rule (#9391)
## Summary

Adds S503 rule for the
[flake8-bandit](https://github.com/tylerwince/flake8-bandit) plugin
port.

Checks for function defs argument defaults which have an insecure
ssl_version value. See also
https://bandit.readthedocs.io/en/latest/_modules/bandit/plugins/insecure_ssl_tls.html#ssl_with_bad_defaults

Some logic and the `const` can be shared with
https://github.com/astral-sh/ruff/pull/9390. When one of the two is
merged.

## Test Plan

Fixture added

## Issue Link

Refers: https://github.com/astral-sh/ruff/issues/1646
2024-01-05 01:38:41 +00:00
qdegraaf 6dfc1ccd6f
[`flake8-bandit`] Implement `S502` `SslInsecureVersion` rule (#9390)
## Summary

Adds S502 rule for the
[flake8-bandit](https://github.com/tylerwince/flake8-bandit) plugin
port.

Checks for calls to any function with keywords arguments `ssl_version`
or `method` or for kwargs `method` in calls to `OpenSSL.SSL.Context` and
`ssl_version` in calls to `ssl.wrap_socket` which have an insecure
ssl_version valu. See also
https://bandit.readthedocs.io/en/latest/_modules/bandit/plugins/insecure_ssl_tls.html#ssl_with_bad_version

## Test Plan

Fixture added

## Issue Link

Refers: https://github.com/astral-sh/ruff/issues/1646
2024-01-05 01:27:41 +00:00
Charlie Marsh 60ba7a7c0d
Allow `# fmt: skip` with interspersed same-line comments (#9395)
## Summary

This is similar to https://github.com/astral-sh/ruff/pull/8876, but more
limited in scope:

1. It only applies to `# fmt: skip` (like Black). Like `# isort: on`, `#
fmt: on` needs to be on its own line (still).
2. It only delimits on `#`, so you can do `# fmt: skip # noqa`, but not
`# fmt: skip - some other content` or `# fmt: skip; noqa`.

If we want to support the `;`-delimited version, we should revisit
later, since we don't support that in the linter (so `# fmt: skip; noqa`
wouldn't register a `noqa`).

Closes https://github.com/astral-sh/ruff/issues/8892.
2024-01-04 19:39:37 -05:00
Zanie Blue aaa00976ae
Generate deterministic ids when formatting notebooks (#9359)
When formatting notebooks, we populate the `id` field for cells that do
not have one. Previously, we generated a UUID v4 which resulted in
non-deterministic formatting. Here, we generate the UUID from a seeded
random number generator instead of using true randomness. For example,
here are the first five ids it would generate:

```
7fb27b94-1602-401d-9154-2211134fc71a
acae54e3-7e7d-407b-bb7b-55eff062a284
9a63283c-baf0-4dbc-ab1f-6479b197f3a8
8dd0d809-2fe7-4a7c-9628-1538738b07e2
72eea511-9410-473a-a328-ad9291626812
```

We also add a check that an id is not present in another cell to prevent
accidental introduction of duplicate ids.

The specification is lax, and we could just use incrementing integers
e.g. `0`, `1`, ... but I have a minor preference for retaining the UUID
format. Some discussion
[here](https://github.com/astral-sh/ruff/pull/9359#discussion_r1439607121)
— I'm happy to go either way though.

Discovered via #9293
2024-01-04 09:19:00 -06:00
Charlie Marsh 328262bfac
Add cell indexes to all diagnostics (#9387)
## Summary

Ensures that any lint rules that include line locations render them as
relative to the cell (and include the cell number) when inside a Jupyter
notebook.

Closes https://github.com/astral-sh/ruff/issues/6672.

## Test Plan

`cargo test`
2024-01-04 14:02:23 +00:00
Charlie Marsh f0d43dafcf
Ignore trailing quotes for unclosed l-brace errors (#9388)
## Summary

Given:

```python
F"{"ڤ
```

We try to locate the "unclosed left brace" error by subtracting the
quote size from the lexer offset -- so we subtract 1 from the end of the
source, which puts us in the middle of a Unicode character. I don't
think we should try to adjust the offset in this way, since there can be
content _after_ the quote. For example, with the advent of PEP 701, this
string could reasonably be fixed as:

```python
F"{"ڤ"}"
````

Closes https://github.com/astral-sh/ruff/issues/9379.
2024-01-04 05:00:55 +00:00
Charlie Marsh 9a14f403c8
Add missing preview link (#9386) 2024-01-03 19:54:25 -05:00
qdegraaf 3b323a09cb
[`flake8-bandit`] Add `S504` `SslWithNoVersion` rule (#9384)
## Summary
Adds `S504` rule for the
[flake8-bandit](https://github.com/tylerwince/flake8-bandit) plugin
port.

Checks for calls to `ssl.wrap_socket` which have no `ssl_version`
argument set. See also
https://bandit.readthedocs.io/en/latest/_modules/bandit/plugins/insecure_ssl_tls.html#ssl_with_no_version

## Test Plan

Fixture added 

## Issue Link

Refers: https://github.com/astral-sh/ruff/issues/1646
2024-01-03 21:56:41 +00:00
qdegraaf 5c93a524f1
[`flake8-bandit`] Implement `S4XX` suspicious import rules (#8831)
## Summary

Adds all `S4XX` rules to the
[flake8-bandit](https://github.com/tylerwince/flake8-bandit) plugin
port.

There is a lot of documentation to write, some tests can be expanded and
implementation can probably be refactored to be more compact. As there
is some discussion on whether this is actually useful. (See:
https://github.com/astral-sh/ruff/issues/1646#issuecomment-1732331441),
wanted to check which rules we want to have before I go through the
process of polishing this up.

## Test Plan

Fixtures for all rules based on `flake8-bandit`
[tests](https://github.com/tylerwince/flake8-bandit/tree/main/tests)

## Issue link

Refers: https://github.com/astral-sh/ruff/issues/1646
2024-01-03 18:26:26 +00:00
Steve C e3ad163785
[`pylint`] Implement `unnecessary-dunder-call` (`C2801`) (#9166)
## Summary

Implements
[`C2801`/`unnecessary-dunder-calls`](https://pylint.readthedocs.io/en/stable/user_guide/messages/convention/unnecessary-dunder-call.html)

There are more that this could cover, but the implementations get a
little less straightforward and ugly. Might come back to it in a future
PR, or someone else can!

See: #970 

## Test Plan

`cargo test`
2024-01-03 18:08:37 +00:00
Charlie Marsh 0e202718fd
Misc. small tweaks from perusing modules (#9383) 2024-01-03 12:30:25 -05:00
Charlie Marsh 7b6baff734
Respect multi-segment submodule imports when resolving qualified names (#9382)
Ensures that if the user has `import collections.abc`, then
`get_or_import_symbol` returns `collections.abc.Iterator` (or similar)
when requested.
2024-01-03 11:24:20 -05:00
Alex Waygood 1ffc738c84
[flake8-pyi] Add autofix for PYI058 (#9355)
## Summary

This PR adds an autofix for the newly added PYI058 rule (added in
#9313). ~~The PR's current implementation is that the fix is only
available if the fully qualified name of `Generator` or `AsyncGenerator`
is being used:~~
- ~~`-> typing.Generator` is converted to `-> typing.Iterator`;~~
- ~~`-> collections.abc.AsyncGenerator[str, Any]` is converted to `->
collections.abc.AsyncIterator[str]`;~~
- ~~but `-> Generator` is _not_ converted to `-> Iterator`. (It would
require more work to figure out if `Iterator` was already imported or
not. And if it wasn't, where should we import it from? `typing`,
`typing_extensions`, or `collections.abc`? It seems much more
complicated.)~~

The fix is marked as always safe for `__iter__` or `__aiter__` methods
in `.pyi` files, but unsafe for all such methods in `.py` files that
have more than one statement in the method body.

This felt slightly fiddly to accomplish, but I couldn't _see_ any
utilities in
https://github.com/astral-sh/ruff/tree/main/crates/ruff_linter/src/fix
that would have made it simpler to implement. Lmk if I'm missing
something, though -- my first time implementing an autofix! :)

## Test Plan

`cargo test` / `cargo insta review`.
2024-01-03 11:11:16 -05:00
Charlie Marsh dc5094d42a
Handle raises with implicit alternate branches (#9377)
Closes
https://github.com/astral-sh/ruff/issues/9304#issuecomment-1874739740.
2024-01-02 22:59:12 -05:00