Commit Graph

2820 Commits

Author SHA1 Message Date
Ahmed Ashraf d85950ce5a
Update rule B005 docs (#8028)
## Summary

Rule B005 of flake8-bugbear docs has a typo in one of the examples that
leads to a confusion in the correctness of `.strip()` method


![image](https://github.com/astral-sh/ruff/assets/104530599/b4e19751-558e-4ebb-b82f-25c321ddc32b)

```python
# Wrong output (used in docs) 
"text.txt".strip(".txt")  # "ex" 

# Correct output
"text.txt".strip(".txt")  # "e"
```
2023-10-17 18:32:39 -04:00
Eiko Wagenknecht 88c0106421
[docs] fix typo (#8013)
## Summary

Fix a typo in the docs for quote style.

> a = "a string without any quotes"
> b = "It's monday morning"
> Ruff will change a to use single quotes when using quote-style =
"single". However, a will be unchanged, as converting to single quotes
would require the inner ' to be escaped, which leads to less readable
code: 'It\'s monday morning'.

It should read "However, **b** will be unchanged".

## Test Plan

N/A.
2023-10-17 14:16:28 +00:00
Charlie Marsh d942a777d7
Avoid flagging `bad-dunder-method-name` for `_` (#8015)
This is almost certainly _not_ an accidentally mistyped dunder method.
Closes https://github.com/astral-sh/ruff/issues/8005.
2023-10-17 10:13:04 -04:00
Steve C 8a529925b3
Add autofix for `D300` (#7967)
## Summary

Add fix for `D300`

## Test Plan

`cargo test` and manually
2023-10-17 09:37:46 -04:00
dependabot[bot] dc6b4ad2b4
Bump tracing from 0.1.37 to 0.1.39 (#7978)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Micha Reiser <micha@reiser.io>
2023-10-17 07:46:53 +00:00
Steve C 21ea290d6a
[pylint] Implement PLR0916 (`too-many-boolean-expressions`) (#7975)
## Summary

Add
[R0916](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/too-many-boolean-expressions.html),
no autofix available.

See: #970 

## Test Plan

`cargo test` and manually.
2023-10-17 04:44:25 +00:00
Steve C 5da0f9111e
implement PLR6201 with autofix (#7973)
## Summary

Implements
[R6201](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/use-set-for-membership.html)
along with the autofix!

See #970 

## Test Plan

`cargo test`, and manually
2023-10-17 04:15:21 +00:00
Charlie Marsh cb6d74c27b
Use set bracket replacement for `iteration-over-set` (#8001) 2023-10-17 04:12:05 +00:00
Sven Hager 73049df3ed
Implement the pylint rule PLW1514 (unspecified-encoding) (#7939)
## Summary

Implemented the pylint rule W1514 ( unspecified-encoding).
See also:
https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/unspecified-encoding.html


## Test Plan

Tested it with the submitted test case.
Additionally, we tested the new ruff rule (PLW1514) on our proprietary
Python code base.
2023-10-17 03:49:48 +00:00
Clément Schreiner bf0e5788ef
[pylint] Implement misplaced-bare-raise (E0704) (#7961)
## Summary

### What it does
This rule triggers an error when a bare raise statement is not in an
except or finally block.
### Why is this bad?
If raise statement is not in an except or finally block, there is no
active exception to
re-raise, so it will fail with a `RuntimeError` exception.
### Example
```python
def validate_positive(x):
   if x <= 0:
       raise
```
Use instead:
```python
def validate_positive(x):
   if x <= 0:
       raise ValueError(f"{x} is not positive")
```

## Test Plan

Added unit test and snapshot.
Manually compared ruff and pylint outputs on pylint's tests.

## References

- [pylint
documentation](https://pylint.pycqa.org/en/stable/user_guide/messages/error/misplaced-bare-raise.html)
- [pylint
implementation](https://github.com/pylint-dev/pylint/blob/main/pylint/checkers/exceptions.py#L339)
2023-10-17 03:07:46 +00:00
Zanie Blue 4113d65836
Rename `RuleGroup::Unspecified` to `Stable` (#7991)
Should help with #7989 and seems more accurate for our new model
2023-10-16 14:53:27 -05:00
Charlie Marsh 134def0119
Allow sunder names from `enum.Enum` (#7987)
Closes https://github.com/astral-sh/ruff/issues/7971.
2023-10-16 18:11:14 +00:00
Zanie Blue 1fabaca5de
Bump version to 0.1.0 (#7931)
[Rendered
changelog](https://github.com/astral-sh/ruff/blob/release/010/CHANGELOG.md)
2023-10-16 13:06:48 -05:00
Zanie Blue 523f542dbd
Remove support for providing output format via `format` option (#7984)
See the provided breaking changes note for details.

Removes support for the deprecated `--format`option in the `ruff check`
CLI, `format` inference as `output-format` in the configuration file,
and the `RUFF_FORMAT` environment variable.

The error message for use of `format` in the configuration file could be
better, but would require some awkward serde wrappers and it seems hard
to present the correct schema to the user still.
2023-10-16 13:06:12 -05:00
Charlie Marsh 84f7391cc5
Use Cow in printf rewrite rule (#7986)
Small thing that bothered me when looking into the regex update.
2023-10-16 16:47:03 +00:00
dependabot[bot] 7da4e28a98
Bump aho-corasick from 1.1.1 to 1.1.2 (#7979) 2023-10-16 09:33:22 -04:00
dependabot[bot] 84ec66a22c
Bump semver from 1.0.19 to 1.0.20 (#7977)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-10-16 08:44:58 +00:00
Charlie Marsh aa6846c78c
Add trailing zero between dot and exponential (#7956)
Closes https://github.com/astral-sh/ruff/issues/7952.
2023-10-15 21:42:00 -04:00
Charlie Marsh 3d03e75a9d
Force parentheses for power operations in unary expressions (#7955)
## Summary

E.g., given `-10**100`, reformat as `-(10**100)`.

Black special cases this (https://github.com/psf/black/pull/909) and
it's currently a deviation.

Closes https://github.com/astral-sh/ruff/issues/7951.
2023-10-15 21:41:50 -04:00
Charlie Marsh b6e75e58c9
Treat type aliases as typing-only expressions (#7968)
## Summary

Given `type RecordOrThings = Record | int | str`, the right-hand side
won't be evaluated at runtime. Same goes for `Record` in `type
RecordCallback[R: Record] = Callable[[R], None]`. This PR modifies the
visitation logic to treat them as typing-only.

Closes https://github.com/astral-sh/ruff/issues/7966.
2023-10-16 00:09:37 +00:00
Charlie Marsh 8061894af6
Resolve `cache-dir` relative to project root (#7962)
## Summary

Unlike other filepath-based settings, the `cache-dir` wasn't being
resolved relative to the project root, when specified as an absolute
path.

Closes https://github.com/astral-sh/ruff/issues/7958.
2023-10-14 19:00:23 +00:00
Victor Hugo Gomes e261eb7461
Fix false positive in `PLR6301` (#7933)
## Summary

Don't report a diagnostic if the method contains a `super()` call.

Closes #6961

## Test Plan

`cargo test`
2023-10-14 14:55:38 -04:00
Charlie Marsh bd06cbe0c5
Respect subscripted base classes in type-checking rules (#7954)
Closes https://github.com/astral-sh/ruff/issues/7945.
2023-10-13 19:44:16 +00:00
Zanie Blue ddffadb4b0
When only unsafe fixes are available, include note that no fixes are available first (#7950)
I believe this is a bit clearer.

When no fixes are available (safe _and_ unsafe) we will not include a
message at all.
2023-10-13 12:43:13 -05:00
Zanie Blue 8255e4ed6c
Revert "add autofix for `PYI030`" (#7943)
This reverts commit #7880 (d8c0360fc7)
which does not perform the correct fix per
https://github.com/astral-sh/ruff/pull/7934
2023-10-13 09:24:47 -05:00
Zanie Blue 889117ea87
Fix handling of `Applicability::Display` fixes when generating summary messages (#7932)
We were including `Display` fixes in the summary counts for unapplicable
fixes resulting in incorrect prompts to the user that a fix could be
enabled.
2023-10-12 20:33:31 -05:00
Jake Park c03a693ebc
[pylint] Implement consider-using-ternary (R1706) (#7811)
This is my first PR. Please feel free to give me any feedback for even
small drawbacks.

## Summary

Checks if pre-python 2.5 ternary syntax is used.

Before
```python
x, y = 1, 2
maximum = x >= y and x or y  # [consider-using-ternary]
```

After
```python
x, y = 1, 2
maximum = x if x >= y else y
```

References: 

[pylint](https://pylint.pycqa.org/en/latest/user_guide/messages/refactor/consider-using-ternary.html)
#970 
[and_or_ternary distinction
logic](https://github.com/pylint-dev/pylint/blob/main/pylint/checkers/refactoring/refactoring_checker.py#L1813)

## Test Plan

Unit test, python file, snapshot added.
2023-10-13 01:29:19 +00:00
Harutaka Kawamura 6f9c317aa5
Simplify `key in dct and dct[key]` to `dct.get(key)` (#7895)
## Summary

Close #5933

## Test Plan

`cargo test`
2023-10-13 01:08:52 +00:00
Dhruv Manilawala 66179af4f1
Add `cell` field to JSON output format (#7664)
## Summary

This PR adds a new `cell` field to the JSON output format which
indicates the Notebook cell this diagnostic (and fix) belongs to. It
also updates the location for the diagnostic and fixes as per the
`NotebookIndex`. It will be used in the VSCode extension to display the
diagnostic in the correct cell.

The diagnostic and edit start and end source locations are translated
for the notebook as per the `NotebookIndex`. The end source location for
an edit needs some special handling.

### Edit end location

To understand this, the following context is required:

1. Visible lines in Jupyter Notebook vs JSON array strings: The newline
is part of the string in the JSON format. This means that if there are 3
visible lines in a cell where the last line is empty then the JSON would
contain 2 strings in the source array, both ending with a newline:

**JSON format:**
```json
[
	"# first line\n",
	"# second line\n",
]
```

**Notebook view:**
```python
1 # first line
2 # second line
3
```

2. If an edit needs to remove an entire line including the newline, then
the end location would be the start of the next row.

To remove a statement in the following code:
```python
import os
```

The edit would be:
```
start: row 1, col 1
end: row 2, col 1
```

Now, here's where the problem lies. The notebook index doesn't have any
information for row 2 because it doesn't exists in the actual notebook.
The newline was added by Ruff to concatenate the source code and it's
removed before writing back. But, the edit is computed looking at that
newline.

This means that while translating the end location for an edit belong to
a Notebook, we need to check if both the start and end location belongs
to the same cell. If not, then the end location should be the first
character of the next row and if so, translate that back to the last
character of the previous row. Taking the above example, the translated
location for Notebook would be:
```
start: row 1, col 1
end: row 1, col 10
```

## Test Plan

Add test cases for notebook output in the JSON format and update
existing snapshots.
2023-10-13 01:06:02 +00:00
Steve C 1e184e69f3
Add autofix for `PYI055` (#7886) 2023-10-13 00:56:34 +00:00
Dhruv Manilawala f08a5f67eb
Add test for Notebook text output (#7925)
## Summary

This PR adds test cases for the Notebook output in text format.

## Test Plan

Update test snapshots.
2023-10-13 06:24:12 +05:30
Dhruv Manilawala cd564c4200
Use `OneIndexed` in `NotebookIndex` (#7921)
## Summary

This PR refactors the `NotebookIndex` struct to use `OneIndexed` to make
the
intent of the code clearer.

## Test Plan

Update the existing test case and run `cargo test` to verify the change.

- [x] Verify `--diff` output
- [x] Verify the diagnostics output
- [x] Verify `--show-source` output
2023-10-13 06:23:49 +05:30
konsti 3944c42d4c
Format comment before parameter default correctly (#7870)
**Summary** Handle comment before the default values of function
parameters correctly by inserting a line break instead of space after
the equals sign where required.

```python
def f(
    a = # parameter trailing comment; needs line break
    1,
    b =
    # default leading comment; needs line break
    2,
    c = ( # the default leading can only be end-of-line with parentheses; no line break
        3
    ),
    d = (
        # own line leading comment with parentheses; no line break
        4
    )
)
```

Fixes #7603

**Test Plan** Added the different cases and one more complex case as
fixtures.
2023-10-12 17:50:12 +02:00
Dhruv Manilawala 4454fbf7e5
Fix `E251` false positive inside f-strings (#7894)
## Summary

This PR fixes the bug where the rule `E251` was being triggered on a equal token
inside a f-string which was used in the context of debug expressions.

For example, the following was being flagged before the fix:

```python
print(f"{foo = }")
```

But, now it is not. This leads to false negatives such as:

```python
print(f"{foo(a = 1)}")
```

One solution would be to know if the opened parentheses was inside a f-string or
not. If it was then we can continue flagging until it's closed. If not, then we
should not flag it.

## Test Plan

Add new test cases and check that they don't raise any false positives.

fixes: #7882
2023-10-12 05:26:39 +00:00
Zanie Blue 23bbe7336a
Fix false negative in `outdated-version-block` when using greater than comparisons (#7920)
Closes #7902
2023-10-11 14:33:43 -05:00
Steve C a71c4dfabb
fix edge case with PIE804 (#7922)
## Summary

`foo(**{})` was an overlooked edge case for `PIE804` which introduced a
crash within the Fix, introduced in #7884.

I've made it so that `foo(**{})` turns into `foo()` when applied with
`--fix`, but is that desired/expected? 🤔 Should we just ignore instead?

## Test Plan

`cargo test`
2023-10-11 15:05:49 -04:00
Zanie Blue 40cad44f4a
Drop formatting specific rules from the default set (#7900)
Closes https://github.com/astral-sh/ruff/issues/7572

Drops formatting specific rules from the default rule set as they
conflict with formatters in general (and in particular, conflict with
our formatter). Most of these rules are in preview, but the removal of
`line-too-long` and `mixed-spaces-and-tabs` is a change to the stable
rule set.

## Example

The following no longer raises `E501`
```
echo "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx = 1" | ruff check -
```
2023-10-11 11:29:34 -05:00
Charlie Marsh c38617fa27
Remove per-diagnostic check for fixability (#7919)
## Summary

Throughout the codebase, we have this pattern:

```rust
let mut diagnostic = ...
if checker.patch(Rule::UnusedVariable) {
    // Do the fix.
}
diagnostics.push(diagnostic)
```

This was helpful when we computed fixes lazily; however, we now compute
fixes eagerly, and this is _only_ used to ensure that we don't generate
fixes for rules marked as unfixable.

We often forget to add this, and it leads to bugs in enforcing
`--unfixable`.

This PR instead removes all of these checks, moving the responsibility
of enforcing `--unfixable` up to `check_path`. This is similar to how
@zanieb handled the `--extend-unsafe` logic: we post-process the
diagnostics to remove any fixes that should be ignored.
2023-10-11 16:09:47 +00:00
Steve C 1835d7bb45
add autofix for `PLR1714` (#7910)
## Summary

Add autofix for `PLR1714` using tuples.

If added complexity is desired, we can lean into the `set` part by doing
some kind of builtin check on all of the comparator elements for
starters, since we otherwise don't know if something's hashable.

## Test Plan

`cargo test`, and manually.
2023-10-11 14:42:21 +00:00
Harutaka Kawamura f670f9b22c
[SIM115] Allow `open` followed by `close` (#7916) 2023-10-11 13:53:48 +00:00
Charlie Marsh 7a072cc2ea
Respect `--unfixable` in ISC rules (#7917)
Closes https://github.com/astral-sh/ruff/issues/7909.
2023-10-11 13:40:24 +00:00
Harutaka Kawamura 8c4b5d3c90
Visit pattern match guard as a boolean test (#7911) 2023-10-11 09:26:10 -04:00
konsti ec9d5cddd6
Less scary `ruff format` message (#7867) 2023-10-11 11:46:41 +00:00
konsti 0f759af3cf
Remove spaces from import statements (#7859)
**Summary** Remove spaces from import statements such as 

```python
import tqdm .  tqdm
from tqdm .    auto import tqdm
```

See also #7760 for a better solution.

**Test Plan** New fixtures
2023-10-11 11:35:41 +00:00
konsti 644011fb14
Formatter quoting for f-strings with triple quotes (#7826)
**Summary** Quoting of f-strings can change if they are triple quoted
and only contain single quotes inside.

Fixes #6841

**Test Plan** New fixtures

---------

Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
2023-10-11 11:30:34 +00:00
T-256 a1ee6d28ce
`UP018`: Improve Fix message (#7913)
<!--
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? -->
closes https://github.com/astral-sh/ruff/issues/7912

## Test Plan

<!-- How was it tested? -->
2023-10-11 09:41:51 +00:00
Steve C 826868da5b
add autofix for `PIE804` (#7884) 2023-10-11 01:07:34 +00:00
Steve C 5986ff748a
add autofix for `PLC0208` (#7887) 2023-10-11 00:48:10 +00:00
Zanie Blue 739a8aa10e
Add settings for promoting and demoting fixes (#7841)
Adds two configuration-file only settings `extend-safe-fixes` and
`extend-unsafe-fixes` which can be used to promote and demote the
applicability of fixes for rules.

Fixes with `Never` applicability cannot be promoted.
2023-10-10 20:04:21 +00:00
Charlie Marsh 090c1a4a19
Avoid converting f-strings within Django `gettext` calls (#7898)
## Summary

Django's `gettext` doesn't support f-strings, so we should avoid
translating `.format` calls in those cases.

Closes https://github.com/astral-sh/ruff/issues/7891.
2023-10-10 16:31:09 +00:00
Zanie Blue 2b95d3832b
Update fix summary message in `check --diff` to include unsafe fix hints (#7790)
Requires #7769 

Updates the CLI display for `ruff check --fix` to hint availability of
unsafe fixes.

 ```
❯ ruff check example.py --select F601,T201 --diff --no-cache
No errors fixed (1 fix available with `--unsafe-fixes`).
```

```
❯ ruff check example.py --select F601,T201,W292 --diff --no-cache
--- example.py
+++ example.py
@@ -1,2 +1,2 @@
 x = {'a': 1, 'a': 1}
-print(('foo'))
+print(('foo'))
\ No newline at end of file

Would fix 1 error (1 additional fix available with `--unsafe-fixes`).
```
```
❯ ruff check example.py --select F601,T201,W292 --diff --no-cache
--unsafe-fixes
--- example.py
+++ example.py
@@ -1,2 +1,2 @@
-x = {'a': 1}
-print(('foo'))
+x = {'a': 1, 'a': 1}
+print(('foo'))
\ No newline at end of file

Would fix 2 errors.
```
2023-10-10 10:50:35 -05:00
Charlie Marsh a3e8e77172
Allow bindings to be created and referenced within annotations (#7885)
## Summary

Given:

```python
baz: Annotated[
    str,
    [qux for qux in foo],
]
```

We treat `baz` as `BindingKind::Annotation`, to ensure that references
to `baz` are marked as unbound. However, we were _also_ treating `qux`
as `BindingKind::Annotation`, which meant that the load in the
comprehension _also_ errored.

Closes https://github.com/astral-sh/ruff/issues/7879.
2023-10-10 03:51:00 +00:00
Charlie Marsh ec7395ba69
Promote some rules to "always" fixable (#7840)
## Summary

This PR upgrades some rules from "sometimes" to "always" fixes, now that
we're getting ready to ship support in the CLI. The focus here was on
identifying rules for which the diagnostic itself is high-confidence,
and the fix itself is too (assuming that the diagnostic is correct).
This is _unlike_ rules that _may_ be a false positive, like those that
(e.g.) assume an object is a dictionary when you call `.values()` on it.

Specifically, I upgraded:

- A bunch of rules that only apply to `.pyi` files.
- Rules that rewrite deprecated imports or aliases.
- Some other misc. rules, like: `empty-print-string`, `unused-noqa`,
`getattr-with-constant`.

Open to feedback on any of these.
2023-10-10 03:30:46 +00:00
Steve C d8c0360fc7
add autofix for `PYI030` (#7880)
## Summary

Adds autofix to `PYI030`

Closes #7854. 

Unsure if the cloning method I chose is the best solution here, feel
free to suggest alternatives!

## Test Plan

`cargo test` as well as manually
2023-10-10 03:15:13 +00:00
Henry Schreiner 097b654ba7
fix(schema): restore limit on line-length (#7883)
## Summary

Restores functionality of #7875 but in the correct place. Closes #7877.

~~I couldn't figure out how to get cargo fmt to work, so hopefully
that's run in CI.~~ Nevermind, figured it out.

## Test Plan

Can see output of json.
2023-10-09 23:04:08 -04:00
Charlie Marsh d54cabd276
Remove min and max range on `line-length` JSON schema (#7875)
## Summary

This was introduced in https://github.com/astral-sh/ruff/pull/7412, but
SchemaStore doesn't accept it. I manually edited the JSON schema last
time, then tried to fix this, then gave up -- so removing for now.

(See, e.g., https://github.com/SchemaStore/schemastore/pull/3278, which
failed prior to removing the min and max.)
2023-10-09 15:36:43 -04:00
Harutaka Kawamura 7faa43108f
New rule: Prevent assignment expressions in assert statements (#7856) 2023-10-09 19:35:11 +00:00
Charlie Marsh 74b00c9b91
Fix commented-out `coalesce` keyword (#7876)
See:
https://github.com/astral-sh/ruff/pull/7874#issuecomment-1753498994.
2023-10-09 19:11:45 +00:00
Charlie Marsh 97e944003b
Add `sqlalchemy` methods to boolean-trap exclusion list (#7874)
Closes https://github.com/astral-sh/ruff/issues/7869.
2023-10-09 18:50:51 +00:00
Alex Waygood 016e16254a
Update UP038 docs to note that it results in slower code (#7872)
See discussion in #7871. I tried to use language similar to the existing
performance warnings in the `flake8-use-pathlib` docs, e.g.
https://docs.astral.sh/ruff/rules/os-path-abspath/#os-path-abspath-pth100
2023-10-09 11:45:14 -05:00
Charlie Marsh 61a41334a3
Show custom message for `Path.joinpath` with starred arguments (#7852)
Closes https://github.com/astral-sh/ruff/issues/7833.
2023-10-09 12:04:35 +00:00
Dhruv Manilawala 43883b7a15
Disallow f-strings in match pattern literal (#7857)
## Summary

This PR fixes a bug to disallow f-strings in match pattern literal.

```
literal_pattern ::=  signed_number
                     | signed_number "+" NUMBER
                     | signed_number "-" NUMBER
                     | strings
                     | "None"
                     | "True"
                     | "False"
                     | signed_number: NUMBER | "-" NUMBER
```

Source:
https://docs.python.org/3/reference/compound_stmts.html#grammar-token-python-grammar-literal_pattern

Also,

```console
$ python /tmp/t.py
  File "/tmp/t.py", line 4
    case "hello " f"{name}":
         ^^^^^^^^^^^^^^^^^^
SyntaxError: patterns may only match literals and attribute lookups
```

## Test Plan

Update existing test case and accordingly the snapshots. Also, add a new
test case to verify that the parser does raise an error.
2023-10-09 10:11:08 +00:00
bluthej 38f512d588
Fix diff (old and new were reversed) (#7855)
## Summary

Fixes #7853.

The old and new source files were reversed in the call to
`TextDiff::from_lines`, so the diff output of the CLI was also reversed.

## Test Plan

Two snapshots were updated in the process, so any reversal should be
caught :)
2023-10-09 12:58:13 +05:30
Zanie Blue 2d6557a51b
Only show warnings for empty preview selectors when enabling rules (#7842)
Closes https://github.com/astral-sh/ruff/issues/7491

Users found it confusing that warnings were displayed when ignoring a
preview rule (which has no effect without `--preview`). While we could
retain the warning with different messaging, I've opted to remove it for
now. With this pull request, we will only warn on `--select` and
`--extend-select` but not `--fixable`, `--unfixable`, `--ignore`, or
`--extend-fixable`.
2023-10-08 11:14:37 -05:00
Simon Høxbro Hansen 2ba5677700
Improvements to RUF015 (#7848)
## Summary

Resolves https://github.com/astral-sh/ruff/issues/7618. 

The list of builtin iterator is not exhaustive.

## Test Plan

`cargo test`

``` python
a = [1, 2]

examples = [
    enumerate(a),
    filter(lambda x: x, a),
    map(int, a),
    reversed(a),
    zip(a),
    iter(a),
]

for example in examples:
    print(next(example))
```
2023-10-08 14:49:45 +00:00
Tom Kuson 62f1ee08e7
[`refurb`] Implement `single-item-membership-test` (`FURB171`) (#7815)
## Summary

Implement
[`no-single-item-in`](https://github.com/dosisod/refurb/blob/master/refurb/checks/iterable/no_single_item_in.py)
as `single-item-membership-test` (`FURB171`).

Uses the helper function `generate_comparison` from the `pycodestyle`
implementations; this function should probably be moved, but I am not
sure where at the moment.

Update: moved it to `ruff_python_ast::helpers`.

Related to #1348.

## Test Plan

`cargo test`
2023-10-08 14:08:47 +00:00
Chris Pryer bdd925c0f2
Use workspace `tracing` in `ruff_formatter` crate (#7849)
I noticed that `tracing::instrument` wasn't available with only the
`"std"` feature enabled when trying to run `cargo doc -p
ruff_formatter`.

I could be misunderstanding something, but I couldn't even run the tests
for the crate.

```
ruff on  ruff-formatter-tracing [$] is 📦 v0.0.292 via 🦀 v1.72.0 
❯ cargo test -p ruff_formatter          
   Compiling ruff_formatter v0.0.0 (/Users/chrispryer/github/ruff/crates/ruff_formatter)
error[E0433]: failed to resolve: could not find `instrument` in `tracing`
   --> crates/ruff_formatter/src/printer/mod.rs:57:16
    |
57  |     #[tracing::instrument(name = "Printer::print", skip_all)]
    |                ^^^^^^^^^^ could not find `instrument` in `tracing`
    |
note: found an item that was configured out
   --> /Users/chrispryer/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tracing-0.1.37/src/lib.rs:959:29
    |
959 | pub use tracing_attributes::instrument;
    |                             ^^^^^^^^^^
    = note: the item is gated behind the `attributes` feature

For more information about this error, try `rustc --explain E0433`.
error: could not compile `ruff_formatter` (lib) due to previous error
warning: build failed, waiting for other jobs to finish...
error: could not compile `ruff_formatter` (lib test) due to previous error
```

Maybe the idea is to keep this crate minimal, but I figured I'd at least
point this out.
2023-10-08 09:50:10 -04:00
konsti dd36a2516e
Make serde a default feature of ruff_python_formatter (#7825)
This makes `cargo test -p ruff_python_formatter` actually run the tests
again
2023-10-08 09:47:13 -04:00
Chris Pryer b6c9cf1c5b
Update `ruff_python_formatter` generate.py comment (#7850)
I believe Docs.md is old.
2023-10-07 20:56:07 -04:00
Tom Kuson 805fd1bc93
Document `reimplemented-starmap` performance effects (#7846)
## Summary

Document the performance effects of `itertools.starmap`, including that
it is actually slower than comprehensions in Python 3.12.

Closes #7771.

## Test Plan

`python scripts/check_docs_formatted.py`
2023-10-07 09:27:02 -04:00
Zanie Blue 0fc76ba276
Rename applicability levels to `Safe`, `Unsafe`, and `Display` (#7843)
After working with the previous change in
https://github.com/astral-sh/ruff/pull/7821 I found the names a bit
unclear and their relationship with the user-facing API muddied. Since
the applicability is exposed to the user directly in our JSON output, I
think it's important that these names align with our configuration
options. I've replaced `Manual` or `Never` with `Display` which captures
our intent for these fixes (only for display). Here, we create room for
future levels, such as `HasPlaceholders`, which wouldn't fit into the
`Always`/`Sometimes`/`Never` levels.

Unlike https://github.com/astral-sh/ruff/pull/7819, this retains the
flat enum structure which is easier to work with.
2023-10-06 20:50:05 -05:00
Zanie Blue 4b537d1297
Update `non-pep695-type-alias` to require `--unsafe-fixes` outside of stub files (#7836)
Closes https://github.com/astral-sh/ruff/issues/6434
2023-10-06 14:56:40 -05:00
Zanie Blue 3c25d261fe
Write summary messages to stderr when fixing via stdin (instead of omitting them) (#7838)
Previously we just omitted diagnostic summaries when using `--fix` or
`--diff` with a stdin file. Now, we still write the summaries to stderr
instead of the main writer (which is generally stdout but could be
changed by `--output-file`).
2023-10-06 12:11:03 -05:00
Zanie Blue 4f95df1b6d
Fixup use of deprecated `--format` option in warning (#7837) 2023-10-06 16:10:48 +00:00
Zanie Blue 22e18741bd
Update CLI to respect fix applicability (#7769)
Rebase of https://github.com/astral-sh/ruff/pull/5119 authored by
@evanrittenhouse with additional refinements.

## Changes

- Adds `--unsafe-fixes` / `--no-unsafe-fixes` flags to `ruff check`
- Violations with unsafe fixes are not shown as fixable unless opted-in
- Fix applicability is respected now
    - `Applicability::Never` fixes are no longer applied
    - `Applicability::Sometimes` fixes require opt-in
    - `Applicability::Always` fixes are unchanged
- Hints for availability of `--unsafe-fixes` added to `ruff check`
output

## Examples

Check hints at hidden unsafe fixes
```
❯ ruff check example.py --no-cache --select F601,W292
example.py:1:14: F601 Dictionary key literal `'a'` repeated
example.py:2:15: W292 [*] No newline at end of file
Found 2 errors.
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
```

We could add an indicator for which violations have hidden fixes in the
future.

Check treats unsafe fixes as applicable with opt-in
```
❯ ruff check example.py --no-cache --select F601,W292 --unsafe-fixes
example.py:1:14: F601 [*] Dictionary key literal `'a'` repeated
example.py:2:15: W292 [*] No newline at end of file
Found 2 errors.
[*] 2 fixable with the --fix option.
```

Also can be enabled in the config file

```
❯ cat ruff.toml
unsafe-fixes = true
```

And opted-out per invocation

```
❯ ruff check example.py --no-cache --select F601,W292 --no-unsafe-fixes
example.py:1:14: F601 Dictionary key literal `'a'` repeated
example.py:2:15: W292 [*] No newline at end of file
Found 2 errors.
[*] 1 fixable with the `--fix` option (1 hidden fix can be enabled with the `--unsafe-fixes` option).
```

Diff does not include unsafe fixes
```
❯ ruff check example.py --no-cache --select F601,W292 --diff
--- example.py
+++ example.py
@@ -1,2 +1,2 @@
 x = {'a': 1, 'a': 1}
-print(('foo'))
+print(('foo'))
\ No newline at end of file

Would fix 1 error.
```

Unless there is opt-in
```
❯ ruff check example.py --no-cache --select F601,W292 --diff --unsafe-fixes
--- example.py
+++ example.py
@@ -1,2 +1,2 @@
-x = {'a': 1}
-print(('foo'))
+x = {'a': 1, 'a': 1}
+print(('foo'))
\ No newline at end of file

Would fix 2 errors.
```

https://github.com/astral-sh/ruff/pull/7790 will improve the diff
messages following this pull request

Similarly, `--fix` and `--fix-only` require the `--unsafe-fixes` flag to
apply unsafe fixes.

## Related

Replaces #5119
Closes https://github.com/astral-sh/ruff/issues/4185
Closes https://github.com/astral-sh/ruff/issues/7214
Closes https://github.com/astral-sh/ruff/issues/4845
Closes https://github.com/astral-sh/ruff/issues/3863
Addresses https://github.com/astral-sh/ruff/issues/6835
Addresses https://github.com/astral-sh/ruff/issues/7019
Needs follow-up https://github.com/astral-sh/ruff/issues/6962
Needs follow-up https://github.com/astral-sh/ruff/issues/4845
Needs follow-up https://github.com/astral-sh/ruff/issues/7436
Needs follow-up https://github.com/astral-sh/ruff/issues/7025
Needs follow-up https://github.com/astral-sh/ruff/issues/6434
Follow-up #7790 
Follow-up https://github.com/astral-sh/ruff/pull/7792

---------

Co-authored-by: Evan Rittenhouse <evanrittenhouse@gmail.com>
2023-10-06 03:41:43 +00:00
Zanie Blue e8d2cbc3f6
Fix invalid code in `FURB177` example (#7832) 2023-10-05 19:25:10 -05:00
Timo Brembeck 1dd5deb53d
Fix typo in docs of PLR6301 (#7831)
## Summary
The example code for [PLR6301
(no-self-use)](https://docs.astral.sh/ruff/rules/no-self-use/#example)
contains f-strings without placeholder expressions, which is discouraged
according to [F541
(f-string-missing-placeholders)](https://docs.astral.sh/ruff/rules/f-string-missing-placeholders/).
For such a trivial change, I didn't open a separate issue.
2023-10-05 21:16:43 +00:00
Zanie Blue b64f403dc2
Rename applicability levels to always, sometimes, and never (#7821)
Following much discussion for #4181 at
https://github.com/astral-sh/ruff/pull/5119,
https://github.com/astral-sh/ruff/discussions/5476, #7769,
https://github.com/astral-sh/ruff/pull/7819, and in
[Discord](https://discord.com/channels/1039017663004942429/1082324250112823306/1159144114231709746),
this pull request changes `Applicability` from using `Automatic`,
`Suggested`, and `Manual` to `Always`, `Sometimes`, and `Never`.

Also removes `Applicability::Unspecified` (replacing #7792).
2023-10-05 13:43:46 -05:00
Zanie Blue 7dc9887ab9
Remove unused empty file (#7830) 2023-10-05 13:35:50 -05:00
Dhruv Manilawala 709abd534a
Fix lexing single-quoted f-string with multi-line format spec (#7787)
## Summary

Reported at https://github.com/python/cpython/issues/110259

## Test Plan

Add test cases for the fix and update the snapshots
2023-10-05 23:12:09 +05:30
konsti 1eac457c1b
Fix typo (#7828) 2023-10-05 16:56:11 +00:00
Charlie Marsh 609a78b13e
Add trailing comment deviation to README (#7827)
Closes https://github.com/astral-sh/ruff/issues/7823.
2023-10-05 16:01:40 +00:00
Dhruv Manilawala 17fba99ed4
Report precise location for invalid conversion flag (#7809)
## Summary

This PR updates the parser definition to use the precise location when reporting
an invalid f-string conversion flag error.

Taking the following example code:
```python
f"{foo!x}"
```

On earlier version,
```
Error: f-string: invalid conversion character at byte offset 6
```

Now,
```
Error: f-string: invalid conversion character at byte offset 7
```

This becomes more useful when there's whitespace between `!` and the flag value
although that is not valid but we can't detect that now.

## Test Plan

As mentioned above.
2023-10-05 17:46:14 +05:30
Cosmo 76fcf63052
Correct error in tuple example in ruff formatter docs (#7822)
## Summary

The fourth element should be "d" instead of "c" in the tuple example in
the ruff formatter docs.

## Test Plan

N/A
2023-10-04 22:51:17 +00:00
Charlie Marsh 90de108bfa
Split up `ast_if.rs` into distinct rule files (#7820)
These node-centric rule files are too hard to navigate. Better to have a
single file per rule as we do elsewhere.
2023-10-04 19:39:05 +00:00
Charlie Marsh ad265fa6bc
Allow f-string modifications in line-shrinking cases (#7818)
## Summary

This PR resolves an issue raised in
https://github.com/astral-sh/ruff/discussions/7810, whereby we don't fix
an f-string that exceeds the line length _even if_ the resultant code is
_shorter_ than the current code.

As part of this change, I've also refactored and extracted some common
logic we use around "ensuring a fix isn't breaking the line length
rules".

## Test Plan

`cargo test`
2023-10-04 15:24:07 -04:00
Charlie Marsh 59c00b5298
Use a dedicated struct for "nested if" rule (#7817)
Internal refactor -- finding this rule hard to understand.
2023-10-04 18:18:59 +00:00
Charlie Marsh a0c846f9bd
Consider nursery rules to be in-preview for `ruff rule` (#7812)
## Summary

We treat these rules as `preview` elsewhere, so adding `preview: false`
to the JSON and such seems like an error.

Closes https://github.com/astral-sh/ruff/issues/7804.
2023-10-04 11:12:43 -04:00
Charlie Marsh bb87f75b0c
Move diffing logic into `SourceKind::diff` (#7813) 2023-10-04 15:08:53 +00:00
Charlie Marsh e674e87d1b
Show per-cell diffs when analyzing notebooks over `stdin` (#7789)
## Summary

The implementation here differs from the non-`stdin` version -- this is
now more consistent.

## Test Plan

```
❯ cat Untitled.ipynb | cargo run -p ruff_cli -- check --stdin-filename Untitled.ipynb --diff -n
    Finished dev [unoptimized + debuginfo] target(s) in 0.11s
     Running `target/debug/ruff check --stdin-filename Untitled.ipynb --diff -n`
--- Untitled.ipynb:cell 2
+++ Untitled.ipynb:cell 2
@@ -1 +0,0 @@
-import os
--- Untitled.ipynb:cell 4
+++ Untitled.ipynb:cell 4
@@ -1 +0,0 @@
-import sys
```
2023-10-04 13:58:07 +00:00
Jelle Zijlstra 600471e45f
Fix SIM110 with a yield in the condition (#7801)
And allow "await" in the loop iterable.

Fixes #7800
2023-10-04 08:59:19 -04:00
Dhruv Manilawala a1509dfc7c
Use correct start location for class/function clause header (#7802)
## Summary

This PR fixes the bug where the formatter would panic if a class/function with
decorators had a suppression comment.

The fix is to use to correct start location to find the `async`/`def`/`class`
keyword when decorators are present which is the end of the last
decorator.

## Test Plan

Add test cases for the fix and update the snapshots.
2023-10-04 07:55:01 +00:00
Jelle Zijlstra 7b4fb4fb5d
Fix issues with SIM101 (adjacent isinstance() calls) (#7798)
- Only trigger for immediately adjacent isinstance() calls with the same
target
- Preserve order of or conditions

Two existing tests changed:
- One was incorrectly reordering the or conditions, and is now correct.
- Another was combining two non-adjacent isinstance() calls. It's safe
enough in that example,
but this isn't safe to do in general, and it feels low-value to come up
with a heuristic for
when it is safe, so it seems better to not combine the calls in that
case.

Fixes https://github.com/astral-sh/ruff/issues/7797
2023-10-04 04:42:13 +00:00
Charlie Marsh f71c80af68
Show changed files when running under `--check` (#7788)
## Summary

We now list each changed file when running with `--check`.

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

## Test Plan

```
❯ cargo run -p ruff_cli -- format foo.py --check
   Compiling ruff_cli v0.0.292 (/Users/crmarsh/workspace/ruff/crates/ruff_cli)
rgo +    Finished dev [unoptimized + debuginfo] target(s) in 1.41s
     Running `target/debug/ruff format foo.py --check`
warning: `ruff format` is a work-in-progress, subject to change at any time, and intended only for experimentation.
Would reformat: foo.py
1 file would be reformatted
```
2023-10-03 18:50:06 +00:00
Charlie Marsh 90c259beb9
Respect `msgspec.Struct` default-copy semantics (#7786)
## Summary

The carve-out we have in `RUF012` for Pydantic classes also applies to
`msgspec.Struct`.

Closes https://github.com/astral-sh/ruff/issues/7785.
2023-10-03 16:51:25 +00:00
Tom Kuson 37d21c0d54
Check sequence type before triggering `unnecessary-enumerate` (`FURB148`) `len` suggestion (#7781)
## Summary

Check that the sequence type is a list, set, dict, or tuple before
recommending replacing the `enumerate(...)` call with `range(len(...))`.
Document behaviour so users are aware of the type inference limitation
leading to false negatives.

Closes #7656.
2023-10-03 14:39:14 +00:00
Dhruv Manilawala 69b8136463
Avoid curly brace escape in f-string format spec (#7780)
## Summary

This PR fixes a bug in the lexer for f-string format spec where it would
consider the `{{` (double curly braces) as an escape pattern.

This is not the case as evident by the
[PEP](https://peps.python.org/pep-0701/#how-to-produce-these-new-tokens)
as well but I missed the part:

> [..]
> * **If in “format specifier mode” (see step 3), an opening brace ({)
or a closing brace (}).**
> * If not in “format specifier mode” (see step 3), an opening brace ({)
or a closing brace (}) that is not immediately followed by another
opening/closing brace.

## Test Plan

Add a test case to verify the fix and update the snapshot.

fixes: #7778
2023-10-03 19:38:03 +05:30
Charlie Marsh c040fac12f
Preserve trailing comments in C414 fixes (#7775)
Closes https://github.com/astral-sh/ruff/issues/7772.
2023-10-03 04:36:51 +00:00
Charlie Marsh a6ebbf21c3
Fix documented examples for `unnecessary-subscript-reversal` (#7774)
## Summary

Two of the three listed examples were wrong: one was semantically
incorrect, another was _correct_ but not actually within the scope of
the rule.

Good motivation for us to start linting documentation examples :)

Closes https://github.com/astral-sh/ruff/issues/7773.
2023-10-03 04:18:49 +00:00
Tom Kuson e129f77bcf
Extend `reimplemented-starmap` (`FURB140`) to catch calls with a single and starred argument (#7768) 2023-10-02 21:38:05 -04:00
konsti 3ccd1d580d
Use crates.io unicode_names2 0.6.0 (#6478)
Update `unicode_names2` to the crates.io release 0.6.0, removing a git
dependency.
2023-10-02 18:17:38 -04:00
Charlie Marsh f872c3bf0f
Document one-call chaining deviation (#7767)
## Summary

I missed this in the prior pass.

Closes https://github.com/astral-sh/ruff/issues/7051.
2023-10-02 21:46:04 +00:00
Colton Berry 55fa887099
Change `crlf` to `cr-lf` in docs (#7766)
## Summary
This change fixes an error in the documentation where cr-lf was
displayed as crlf which if you tried to enter into the configuration
file running ruff would break.

## Test Plan
I ran the tests locally and I ran the documentation server locally and
verified the edit

### [Documentation
Site](https://docs.astral.sh/ruff/settings/#format-line-ending)

![image](https://github.com/astral-sh/ruff/assets/50351006/8e63e49c-63ff-4027-a583-537c710e1305)

### Local

![image](https://github.com/astral-sh/ruff/assets/50351006/8845a235-8b2c-4157-99c8-908ee8f039b3)
2023-10-02 21:09:11 +00:00
Charlie Marsh c6d0bdd572
Bump Ruff version to v0.0.292 (#7761) 2023-10-02 12:14:47 -04:00
Charlie Marsh 75f759ed55
Upgrade LibCST to support Python 3.12 (#7764)
## Summary

We'll revert back to the crates.io release once it's up-to-date, but
better to get this out now that Python 3.12 is released.

## Test Plan

`cargo test`
2023-10-02 12:14:35 -04:00
Charlie Marsh 97c092a102
Add formatter TOML configuration to the README (#7762)
## Summary

This section is dated -- we now support configuration.
2023-10-02 15:07:02 +00:00
Charlie Marsh bdf285225d
Enable formatting for Jupyter notebooks (#7749)
## Summary

This PR enables `ruff format` to format Jupyter notebooks.

Most of the work is contained in a new `format_source` method that
formats a generic `SourceKind`, then returns `Some(transformed)` if the
source required formatting, or `None` otherwise.

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

## Test Plan

Ran `cat foo.py | cargo run -p ruff_cli -- format --stdin-filename
Untitled.ipynb`; verified that the console showed a reasonable error:

```console
warning: Failed to read notebook Untitled.ipynb: Expected a Jupyter Notebook, which must be internally stored as JSON, but this file isn't valid JSON: EOF while parsing a value at line 1 column 0
```

Ran `cat Untitled.ipynb | cargo run -p ruff_cli -- format
--stdin-filename Untitled.ipynb`; verified that the JSON output
contained formatted source code.
2023-10-02 14:44:18 +00:00
konsti 0961f008b8
Rename `FixKind` to `FixAvailability` (#7658)
**Summary** `FixKind` feels to generic, i suggest renaming it to
something like `FixAvailibility`.

Commands used:

```bash
rg FixKind --files-with-matches | xargs sed -i 's/FixKind/FixAvailability/g'
rg fix_kind --files-with-matches | xargs sed -i 's/fix_kind/fix_availability/g'
rg FIX_KIND --files-with-matches | xargs sed -i 's/FIX_KIND/FIX_AVAILABILITY/g'
cargo fmt
```

`rg -i "fix.kind"` doesn't show any matches anymore.
2023-10-02 14:38:25 +00:00
Charlie Marsh ebdfcee87f
Write full Jupyter notebook to `stdout` (#7748)
## Summary

When writing back notebooks via `stdout`, we need to write back the
entire JSON content, not _just_ the fixed source code. Otherwise,
writing the output _back_ to the file will yield an invalid notebook.

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

## Test Plan

`cargo test`
2023-10-02 14:20:13 +00:00
Charlie Marsh c71ff7eae1
Avoid printing continuations within import identifiers (#7744)
## Summary

It turns out that _some_ identifiers can contain newlines --
specifically, dot-delimited import identifiers, like:
```python
import foo\
    .bar
```

At present, we print all identifiers verbatim, which causes us to retain
the `\` in the formatted output. This also leads to violating some debug
assertions (see the linked issue, though that's a symptom of this
formatting failure).

This PR adds detection for import identifiers that contain newlines, and
formats them via `text` (slow) rather than `source_code_slice` (fast) in
those cases.

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

## Test Plan

`cargo test`
2023-10-02 09:51:07 -04:00
dependabot[bot] 7d7e0824af
Bump ureq from 2.7.1 to 2.8.0 (#7756) 2023-10-02 09:49:59 -04:00
dependabot[bot] 8d1d5b8d80
Bump pep440_rs from 0.3.11 to 0.3.12 (#7755) 2023-10-02 09:49:50 -04:00
konsti 13748dd27c
Use `locator.slice(range)` over `locator.contents()[range]` (#7759)
**Summary** Refactoring inspired by
https://github.com/astral-sh/ruff/pull/7741#discussion_r1342168033
2023-10-02 09:07:32 +00:00
konsti f70e8a7524
Fix PLE251 rules with f-string escaping (#7741)
**Summary** The `value` of the `FStringMiddle` for `f"""}}ab"""` is
`}ab`, i.e. the curly brace escaping is decoded. If we iterate over
string this gives us false indices causing exploding fixes for PLE251
rules (PLE2510, PLE2512, PLE2513, PLE2514, PLE2515). Instead, we now use
the source range.

Handles
https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998106
Handles
https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741998256

**Test Plan** Minimized fuzzing cases as fixtures.
2023-10-02 08:43:39 +00:00
Charlie Marsh 1df8101b9e
Require documentation for all lint rules (#7751)
## Summary

Now that all rules have documentation, we can enforce the requirement in
our tests.
2023-10-02 01:49:07 +00:00
jan Apisu 6a4437ea81
Add documentation for remaining undocumented lint rules (#7750) 2023-10-02 00:56:33 +00:00
Charlie Marsh 4d2de898e3
Decrease PEP 593 error to a debug warning (#7745)
## Summary

There's no way for users to fix this warning if they're intentionally
using an "invalid" PEP 593 annotation, as is the case in CPython. This
is a symptom of having warnings that aren't themselves diagnostics. If
we want this to be user-facing, we should add a diagnostic for it!

## Test Plan

Ran `cargo run -p ruff_cli -- check foo.py -n` on:

```python
from typing import Annotated

Annotated[int]
```
2023-10-01 14:40:36 -04:00
Charlie Marsh d8a6279fe5
Remove string allocation in relative import formatting (#7743) 2023-10-01 18:15:43 +00:00
Charlie Marsh 2838f7af98
Skip all bracketed expressions when locating comparison ops (#7740)
Closes https://github.com/astral-sh/ruff/issues/7737.
2023-10-01 14:57:40 +00:00
Charlie Marsh 1cf3b5676f
Perform insertions before replacements (#7739)
## Summary

If we have, e.g.:

```python
sum((
            factor.dims for factor in bases
        ), [])
```

We generate three edits: two insertions (for the `operator` and
`functools` imports), and then one replacement (for the `sum` call
itself). We need to ensure that the insertions come before the
replacement; otherwise, the edits will appear overlapping and
out-of-order.

Closes https://github.com/astral-sh/ruff/issues/7718.
2023-10-01 14:53:54 +00:00
Dhruv Manilawala e91ffe3e93
Consume the escaped Windows newline (`\r\n`) for `FStringMiddle` (#7722)
## Summary

This PR fixes a bug where if a Windows newline (`\r\n`) character was
escaped, then only the `\r` was consumed and not `\n` leading to an
unterminated string error.

## Test Plan

Add new test cases to check the newline escapes.

fixes: #7632
2023-10-01 07:58:20 +05:30
Dhruv Manilawala e72d617f4b
Remove escaped mac/windows eol from AST string value (#7724)
## Summary

This PR fixes the bug where the value of a string node type includes the
escaped mac/windows newline character.

Note that the token value still includes them, it's only removed when
parsing the string content.

## Test Plan

Add new test cases for the string node type to check that the escapes
aren't being included in the string value.

fixes: #7723
2023-10-01 07:37:59 +05:30
Charlie Marsh c782770e90
Add consistent period in options documentation (#7725) 2023-09-30 23:07:30 +00:00
Charlie Marsh 1646939383
Ignore overlong pragma comments when enforcing linter line length (#7692)
## Summary

This PR modifies the `line-too-long` and `doc-line-too-long` rules to
ignore lines that are too long due to the presence of a pragma comment
(e.g., `# type: ignore` or `# noqa`). That is, if a line only exceeds
the limit due to the pragma comment, it will no longer be flagged as
"too long". This behavior mirrors that of the formatter, thus ensuring
that we don't flag lines under E501 that the formatter would otherwise
avoid wrapping.

As a concrete example, given a line length of 88, the following would
_no longer_ be considered an E501 violation:

```python
# The string literal is 88 characters, including quotes.
"shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:sh"  # type: ignore
```

This, however, would:

```python
# The string literal is 89 characters, including quotes.
"shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:shape:sha"  # type: ignore
```

In addition to mirroring the formatter, this also means that adding a
pragma comment (like `# noqa`) won't _cause_ additional violations to
appear (namely, E501). It's very common for users to add a `# type:
ignore` or similar to a line, only to find that they then have to add a
suppression comment _after_ it that was required before, as in `# type:
ignore # noqa: E501`.

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

## Test Plan

`cargo test`
2023-09-29 23:26:52 +00:00
Dhruv Manilawala b519b56e81
Compute `NotebookIndex` for `Diagnostics` on stdin (#7663)
## Summary

This PR fixes the bug where the `NotebookIndex` was not being computed
when
using stdin as the input source.

## Test Plan

On `main`, the diagnostic output won't include the cell number when
using stdin
while it'll be included after this fix.

### `main`

```console
$ cat ~/playground/ruff/notebooks/test.ipynb | cargo run --bin ruff -- check --isolated --no-cache - --stdin-filename ~/playground/ruff/notebooks/test.ipynb
/Users/dhruv/playground/ruff/notebooks/test.ipynb:2:8: F401 [*] `math` imported but unused
/Users/dhruv/playground/ruff/notebooks/test.ipynb:7:8: F811 Redefinition of unused `random` from line 1
/Users/dhruv/playground/ruff/notebooks/test.ipynb:8:8: F401 [*] `pprint` imported but unused
/Users/dhruv/playground/ruff/notebooks/test.ipynb:12:4: F632 [*] Use `==` to compare constant literals
/Users/dhruv/playground/ruff/notebooks/test.ipynb:13:38: F632 [*] Use `==` to compare constant literals
Found 5 errors.
[*] 4 potentially fixable with the --fix option.
```

### `dhruv/notebook-index-stdin`

```console
$ cat ~/playground/ruff/notebooks/test.ipynb | cargo run --bin ruff -- check --isolated --no-cache - --stdin-filename ~/playground/ruff/notebooks/test.ipynb       
/Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 3:2:8: F401 [*] `math` imported but unused
/Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 5:1:8: F811 Redefinition of unused `random` from line 1
/Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 5:2:8: F401 [*] `pprint` imported but unused
/Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 6:2:4: F632 [*] Use `==` to compare constant literals
/Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 6:3:38: F632 [*] Use `==` to compare constant literals
Found 5 errors.
[*] 4 potentially fixable with the --fix option.
```
2023-09-29 20:37:41 +00:00
Charlie Marsh 8c8988ea40
Improve performance of `commented-out-code` (~50-80%) (#7706)
## Summary

This PR implements a variety of optimizations to improve performance of
the Eradicate rule, which always shows up in all-rules benchmarks and
bothers me. (These improvements are not hugely important, but it was
kind of a fun Friday thing to spent a bit of time on.)

The improvements include:

- Doing cheaper work first (checking for some explicit substrings
upfront).
- Using `aho-corasick` to speed an exact substring search.
- Merging multiple regular expressions using a `RegexSet`.
- Removing some unnecessary `\s*` and other pieces from the regular
expressions (since we already trim strings before matching on them).

## Test Plan

I benchmarked this function in a standalone crate using a variety of
cases. Criterion reports that this version is up to 80% faster, and
almost every case is at least 50% faster:

```
Eradicate/Detection/# Warn if we are installing over top of an existing installation. This can
                        time:   [101.84 ns 102.32 ns 102.82 ns]
                        change: [-77.166% -77.062% -76.943%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  3 (3.00%) high mild
Eradicate/Detection/#from foo import eradicate
                        time:   [74.872 ns 75.096 ns 75.314 ns]
                        change: [-84.180% -84.131% -84.079%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 1 outliers among 100 measurements (1.00%)
  1 (1.00%) high mild
Eradicate/Detection/# encoding: utf8
                        time:   [46.522 ns 46.862 ns 47.237 ns]
                        change: [-29.408% -28.918% -28.471%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 7 outliers among 100 measurements (7.00%)
  6 (6.00%) high mild
  1 (1.00%) high severe
Eradicate/Detection/# Issue #999
                        time:   [16.942 ns 16.994 ns 17.058 ns]
                        change: [-57.243% -57.064% -56.815%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 3 outliers among 100 measurements (3.00%)
  2 (2.00%) high mild
  1 (1.00%) high severe
Eradicate/Detection/# type: ignore
                        time:   [43.074 ns 43.163 ns 43.262 ns]
                        change: [-17.614% -17.390% -17.152%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 5 outliers among 100 measurements (5.00%)
  3 (3.00%) high mild
  2 (2.00%) high severe
Eradicate/Detection/# user_content_type, _ = TimelineEvent.objects.using(db_alias).get_or_create(
                        time:   [209.40 ns 209.81 ns 210.23 ns]
                        change: [-32.806% -32.630% -32.470%] (p = 0.00 < 0.05)
                        Performance has improved.
Eradicate/Detection/# this is = to that :(
                        time:   [72.659 ns 73.068 ns 73.473 ns]
                        change: [-68.884% -68.775% -68.655%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 9 outliers among 100 measurements (9.00%)
  7 (7.00%) high mild
  2 (2.00%) high severe
Eradicate/Detection/#except Exception:
                        time:   [92.063 ns 92.366 ns 92.691 ns]
                        change: [-64.204% -64.052% -63.909%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 4 outliers among 100 measurements (4.00%)
  2 (2.00%) high mild
  2 (2.00%) high severe
Eradicate/Detection/#print(1)
                        time:   [68.359 ns 68.537 ns 68.725 ns]
                        change: [-72.424% -72.356% -72.278%] (p = 0.00 < 0.05)
                        Performance has improved.
Found 2 outliers among 100 measurements (2.00%)
  1 (1.00%) low mild
  1 (1.00%) high mild
Eradicate/Detection/#'key': 1 + 1,
                        time:   [79.604 ns 79.865 ns 80.135 ns]
                        change: [-69.787% -69.667% -69.549%] (p = 0.00 < 0.05)
                        Performance has improved.
```
2023-09-29 20:13:12 +00:00
Charlie Marsh e9f8b91eb5
Preserve parentheses in `quadratic-list-summation` (#7719)
Closes https://github.com/astral-sh/ruff/issues/7718.
2023-09-29 20:04:56 +00:00
Charlie Marsh b5280061f8
Use fixed source code for parser context (#7717)
## Summary

The parser now uses the raw source code as global context and slices
into it to parse debug text. It turns out we were always passing in the
_old_ source code, so when code was fixed, we were making invalid
accesses. This PR modifies the call to use the _fixed_ source code,
which will always be consistent with the tokens.

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

## Test Plan

`cargo test`
2023-09-29 14:10:32 -04:00
Charlie Marsh b42a8972bf
Use `Expr::is_*` methods in more matches (#7714) 2023-09-29 17:28:50 +00:00
Charlie Marsh bb65fb8486
Document next round of intentional formatter deviations (#7679)
## Summary

Based on today's triage with @MichaReiser.

Closes https://github.com/astral-sh/ruff/issues/7652.
Closes https://github.com/astral-sh/ruff/issues/7320.
Closes https://github.com/astral-sh/ruff/issues/7052.
Closes https://github.com/astral-sh/ruff/issues/7314.
Closes https://github.com/astral-sh/ruff/issues/7317.
Closes https://github.com/astral-sh/ruff/issues/7323.
Closes https://github.com/astral-sh/ruff/issues/7320.
Closes https://github.com/astral-sh/ruff/issues/7315.
2023-09-29 17:27:30 +00:00
Charlie Marsh 253fbb665f
Track fix isolation in `unnecessary-pass` (#7715)
## Summary

This wasn't necessary in the past, since we _only_ applied this rule to
bodies that contained two statements, one of which was a `pass`. Now
that it applies to any `pass` in a block with multiple statements, we
can run into situations in which we remove both passes, and so need to
apply the fixes in isolation.

See:
https://github.com/astral-sh/ruff/issues/7455#issuecomment-1741107573.
2023-09-29 17:23:04 +00:00
Tom Kuson dc51d03866
Fix documentation for `no-return-argument-annotation-in-stub` [`PYI050`] (#7708)
## Summary

The markdown documentation was present, but in the wrong place, so was
not displaying on the website. I moved it and added some references.

Related to #2646.

## Test Plan

`python scripts/check_docs_formatted.py`
2023-09-29 12:48:51 -04:00
Zanie Blue 614a19cb4e
Remove unused black compatibility tests (#7712)
Previously attempted to repair these tests at
https://github.com/astral-sh/ruff/pull/6992 but I don't think we should
prioritize that and instead I would like to remove this dead code.
2023-09-29 10:31:54 -05:00
Micha Reiser e2ec42539b
Attach dangling comments to the comprehension instead of the `if` or `iter` nodes (#7693) 2023-09-29 10:45:01 +01:00
Dhruv Manilawala e62e245c61
Add support for PEP 701 (#7376)
## Summary

This PR adds support for PEP 701 in Ruff. This is a rollup PR of all the
other individual PRs. The separate PRs were created for logic separation
and code reviews. Refer to each pull request for a detail description on
the change.

Refer to the PR description for the list of pull requests within this PR.

## Test Plan

### Formatter ecosystem checks

Explanation for the change in ecosystem check:
https://github.com/astral-sh/ruff/pull/7597#issue-1908878183

#### `main`

```
| project      | similarity index  | total files       | changed files     |
|--------------|------------------:|------------------:|------------------:|
| cpython      |           0.76083 |              1789 |              1631 |
| django       |           0.99983 |              2760 |                36 |
| transformers |           0.99963 |              2587 |               319 |
| twine        |           1.00000 |                33 |                 0 |
| typeshed     |           0.99983 |              3496 |                18 |
| warehouse    |           0.99967 |               648 |                15 |
| zulip        |           0.99972 |              1437 |                21 |
```

#### `dhruv/pep-701`

```
| project      | similarity index  | total files       | changed files     |
|--------------|------------------:|------------------:|------------------:|
| cpython      |           0.76051 |              1789 |              1632 |
| django       |           0.99983 |              2760 |                36 |
| transformers |           0.99963 |              2587 |               319 |
| twine        |           1.00000 |                33 |                 0 |
| typeshed     |           0.99983 |              3496 |                18 |
| warehouse    |           0.99967 |               648 |                15 |
| zulip        |           0.99972 |              1437 |                21 |
```
2023-09-29 02:55:39 +00:00
Daniel Parizher 78b8741352
[`refurb`] Implement `implicit-cwd` (FURB177) (#7704)
## Summary

Implement
[`no-implicit-cwd`](https://github.com/dosisod/refurb/blob/master/docs/checks.md#furb177-no-implicit-cwd)
as `implicit-cwd`

Related to #1348.

## Test Plan

`cargo test`
2023-09-29 02:18:59 +00:00
Charlie Marsh 246d93ec37
Document single-specifier behavior in printf-string-formatting (#7705)
Closes https://github.com/astral-sh/ruff/issues/7579.
2023-09-29 01:55:11 +00:00
Tom Kuson 3347524164
Extend `unnecessary-pass` (`PIE790`) to trigger on all unnecessary `pass` statements (#7697)
## Summary

Extend `unnecessary-pass` (`PIE790`) to trigger on all unnecessary
`pass` statements by checking for `pass` statements in any class or
function body with more than one statement.

Closes #7600.

## Test Plan

`cargo test`
2023-09-29 01:39:11 +00:00
Mathieu Kniewallner 598974545b
feat(rules): implement `flake8-bandit` `S505` (#7703)
Part of #1646.

## Summary

Implement `S505`
([`weak_cryptographic_key`](https://bandit.readthedocs.io/en/latest/plugins/b505_weak_cryptographic_key.html))
rule from `bandit`.

For this rule, `bandit` [reports the issue
with](https://github.com/PyCQA/bandit/blob/1.7.5/bandit/plugins/weak_cryptographic_key.py#L47-L56):
- medium severity for DSA/RSA < 2048 bits and EC < 224 bits
- high severity for DSA/RSA < 1024 bits and EC < 160 bits

Since Ruff does not handle severities for `bandit`-related rules, we
could either report the issue if we have lower values than medium
severity, or lower values than high one. Two reasons led me to choose
the first option:
- a medium severity issue is still a security issue we would want to
report to the user, who can then decide to either handle the issue or
ignore it
- `bandit` [maps the EC key algorithms to their respective key lengths
in
bits](https://github.com/PyCQA/bandit/blob/1.7.5/bandit/plugins/weak_cryptographic_key.py#L112-L133),
but there is no value below 160 bits, so technically `bandit` would
never report medium severity issues for EC keys, only high ones

Another consideration is that as shared just above, for EC key
algorithms, `bandit` has a mapping to map the algorithms to their
respective key lengths. In the implementation in Ruff, I rather went
with an explicit list of EC algorithms known to be vulnerable (which
would thus be reported) rather than implementing a mapping to retrieve
the associated key length and comparing it with the minimum value.

## Test Plan

Snapshot tests from
https://github.com/PyCQA/bandit/blob/1.7.5/examples/weak_cryptographic_key_sizes.py.
2023-09-28 21:27:37 -04:00
Tom Kuson c2a9cf8ae5
Ignore TODO tags in `commented-out-code` (#7523)
## Summary

Extend the `task-tags` checking logic to ignore TODO tags (with or
without parentheses). For example,

```python
# TODO(tjkuson): Rewrite in Rust
```

is no longer flagged as commented-out code.

Closes #7031.

I also updated the documentation to inform users that the rule is prone
to false positives like this!

EDIT: Accidentally linked to the wrong issue when first opening this PR,
now corrected.

## Test Plan

`cargo test`
2023-09-28 23:13:11 +00:00
Mathieu Kniewallner cfbebcf354
fix(rules): improve S507 detection (#7661)
## Summary

Follow-up on https://github.com/astral-sh/ruff/pull/7528 that improves
detections of mis-usages of policy in `paramiko`.

First commit applies the same fix as in `bandit`
(https://github.com/PyCQA/bandit/pull/1064), as `paramiko` supports
passing both a class and a class instance for the policy in
`set_missing_host_key_policy`
(8e389c7766/paramiko/client.py (L171-L191)).

Second commit improve the detection of `paramiko` import paths that
trigger a violation, as `AutoAddPolicy`, `WarningPolicy` and `SSHClient`
are not only exposed in `paramiko.client`, but also in `paramiko`
(66117732de/paramiko/__init__.py (L121-L164)).

## Test Plan

Snapshot tests.
2023-09-28 21:35:59 +00:00
Charlie Marsh 5e75467757
Insert necessary padding in B014 fixes (#7699)
See:
https://github.com/astral-sh/ruff/issues/7455#issuecomment-1739801758.
2023-09-28 21:11:09 +00:00
Charlie Marsh 9611f8134f
Parenthesize multi-line attributes in B009 (#7701)
Closes
https://github.com/astral-sh/ruff/issues/7455#issuecomment-1739800901.
2023-09-28 16:59:00 -04:00
Charlie Marsh f45281345d
Include radix base prefix in large number representation (#7700)
## Summary

When lexing a number like `0x995DC9BBDF1939FA` that exceeds our small
number representation, we were only storing the portion after the base
(in this case, `995DC9BBDF1939FA`). When using that representation in
code generation, this could lead to invalid syntax, since
`995DC9BBDF1939FA)` on its own is not a valid integer.

This PR modifies the code to store the full span, including the radix
prefix.

See:
https://github.com/astral-sh/ruff/issues/7455#issuecomment-1739802958.

## Test Plan

`cargo test`
2023-09-28 20:38:06 +00:00
Zanie Blue 316f75987d
Add `explicit-preview-rules` to toggle explicit selection of preview rules (#7390)
Closes #7434 

Replaces the `PREVIEW` selector (removed in #7389) with a configuration
option `explicit-preview-rules` which requires selectors to use exact
rule codes for all preview rules. This allows users to enable preview
without opting into all preview rules at once.

## Test plan

Unit tests
2023-09-28 15:00:33 -05:00
Charlie Marsh 695dbbc539
Always prefer double quotes for docstrings and triple-quoted srings (#7680)
## Summary

At present, `quote-style` is used universally. However, [PEP
8](https://peps.python.org/pep-0008/) and [PEP
257](https://peps.python.org/pep-0257/) suggest that while either single
or double quotes are acceptable in general (as long as they're
consistent), docstrings and triple-quoted strings should always use
double quotes. In our research, the vast majority of Ruff users that
enable the `flake8-quotes` rules only enable them for inline strings
(i.e., non-triple-quoted strings).

Additionally, many Black forks (like Blue and Pyink) use double quotes
for docstrings and triple-quoted strings.

Our decision for now is to always prefer double quotes for triple-quoted
strings (which should include docstrings). Based on feedback, we may
consider adding additional options (e.g., a `"preserve"` mode, to avoid
changing quotes; or a `"multiline-quote-style"` to override this).

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

## Test Plan

`cargo test`
2023-09-28 15:11:33 -04:00
Charlie Marsh f62b4c801f
Extend pragma comment cases (#7687)
## Summary

Extends the pragma comment detection in the formatter to support
case-insensitive `noqa` (as supposed by Ruff), plus a variety of other
pragmas (`isort:`, `nosec`, etc.).

Also extracts the detection out into the trivia crate so that we can
reuse it in the linter (see:
https://github.com/astral-sh/ruff/issues/7471).

## Test Plan

`cargo test`
2023-09-28 18:55:19 +00:00
Charlie Marsh 46b85ab0a9
Misc. follow-ups to single-element tuple patterns (#7698)
Just changes to internal comments and tests.

See comments in https://github.com/astral-sh/ruff/pull/7683.
2023-09-28 18:49:13 +00:00
Charlie Marsh 1c02fcd7ce
Avoid unnecessary comments check in `maybe_parenthesize_expression` (#7686)
## Summary

No-op refactor, but we can evaluate early if the first part of
`preserve_parentheses || has_comments` is `true`, and thus avoid looking
up the node comments.

## Test Plan

`cargo test`
2023-09-28 13:42:12 -04:00
Micha Reiser f53c410ff8
Prefer preserving `WithItem` parentheses (#7694) 2023-09-28 14:42:40 +01:00