Commit graph

2595 commits

Author SHA1 Message Date
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
konsti
1e173f7909
Rename Autofix to Fix (#7657)
**Summary** Mostly mechanical symbol rename and search-and-replace, with
small changes to the markdown docs to read better
2023-09-28 10:53:05 +00:00
Charlie Marsh
8028de8956
Improve some comments in normalize_comment (#7688) 2023-09-28 03:08:25 +00:00
Charlie Marsh
a6d79c03b3
Break with on end-of-line trailing comments (#7685)
## Summary

Ensures that:

```python
with (
    a  # comment
):
    pass
```

Retains its parentheses.

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

## Test Plan

`cargo test`
2023-09-28 00:16:40 +00:00
Charlie Marsh
58b50a6290
Avoid expanding single-element tuple patterns (#7683)
## Summary

The formatting for tuple patterns is now intended to match that of `for`
loops:

- Always parenthesize single-element tuples.
- Don't break on the trailing comma in single-element tuples.
- For other tuples, preserve the parentheses, and insert if-breaks.

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

## Test Plan

`cargo test`
2023-09-27 23:57:18 +00:00
qdegraaf
c8360a1333
Expand DeprecatedLogWarn to check for Expr::Atrribute calls (#7677)
## Summary

`PGH002`, which checks for use of deprecated `logging.warn` calls, did
not check for calls made on the attribute `warn` yet. Since
https://github.com/astral-sh/ruff/pull/7521 we check both cases for
similar rules wherever possible. To be consistent this PR expands PGH002
to do the same.

## Test Plan

Expanded existing fixtures with `logger.warn()` calls

## Issue links

Fixes final inconsistency mentioned in
https://github.com/astral-sh/ruff/issues/7502
2023-09-27 11:38:52 -04:00
qdegraaf
34480c0e4d
chore: remove redundant Expr::Call checks (#7678)
## Summary

As we bind the `ast::ExprCall` in the big `match expr` in
`expression.rs`
```rust
Expr::Call(
    call @ ast::ExprCall {
     ...
```

There is no need for additional `let/if let` checks on `ExprCall` in
downstream rules. Found a few older rules which still did this while
working on something else. This PR removes the redundant check from
these rules.

## Test Plan

`cargo test`
2023-09-27 11:36:20 -04:00
Micha Reiser
e863fa55cb
Rename ConfigurationOptions derive macro to OptionsMetadata
## Summary

It's common practice to name derive macros the same as the trait that they implement (`Debug`, `Display`, `Eq`, `Serialize`, ...). 

This PR renames the `ConfigurationOptions` derive macro to `OptionsMetadata` to match the trait name.

## Test Plan

`cargo build`
2023-09-27 09:04:26 +02:00
Micha Reiser
0c65d0c8a6
Add lint section to Ruff configuration
## Summary

This PR adds a new `lint` section to the configuration that groups all linter-specific settings. The existing top-level configurations continue to work without any warning because the `lint.*` settings are experimental. 

The configuration merges the top level and `lint.*` settings where the settings in `lint` have higher precedence (override the top-level settings). The reasoning behind this is that the settings in `lint.` are more specific and more specific settings should override less specific settings.

I decided against showing the new `lint.*` options on our website because it would make the page extremely long (it's technically easy to do, just attribute `lint` with `[option_group`]). We may want to explore adding an `alias` field to the `option` attribute and show the alias on the website along with its regular name. 

## Test Plan

* I added new integration tests
* I verified that the generated `options.md` is identical
* Verified the default settings in the playground

![Screenshot from 2023-09-22 13-52-23](7b4d9689-aa88-402e-9199-9c43c8d8cc2d)
2023-09-27 08:46:27 +02:00
Charlie Marsh
15f3d8c8e0
Improvement documentation around ignore-names globbing (#7674)
## Summary

Improves the documentation on the setting itself, along with that on the
relevant rules.

Closes https://github.com/astral-sh/ruff/issues/7660.
2023-09-27 04:49:41 +00:00
Charlie Marsh
0a8cad2550
Allow named expressions in __all__ assignments (#7673)
## Summary

This PR adds support for named expressions when analyzing `__all__`
assignments, as per https://github.com/astral-sh/ruff/issues/7672. It
also loosens the enforcement around assignments like: `__all__ =
list(some_other_expression)`. We shouldn't flag these as invalid, even
though we can't analyze the members, since we _know_ they evaluate to a
`list`.

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

## Test Plan

`cargo test`
2023-09-27 00:36:55 -04:00
Simon Høxbro Hansen
fbbc982c29
Ensure that B006 autofixes are inserted after imports (#7629)
## Summary

Fixes #7616 by ensuring that
[B006](https://docs.astral.sh/ruff/rules/mutable-argument-default/#mutable-argument-default-b006)
fixes are inserted after module imports.

I have created a new test file, `B006_5.py`. This is mainly because I
have been working on this on and off, and the merge conflicts were
easier to handle in a separate file. If needed, I can move it into
another file.

## Test Plan

`cargo test`
2023-09-27 01:26:29 +00:00
qdegraaf
2aef46cb6f
Add Expr::Name checks to rules which use is_logger_candidate (#7521)
## Summary

Expands several rules to also check for `Expr::Name` values. As they
would previously not consider:
```python
from logging import error

error("foo")
```
as potential violations
```python
import logging

logging.error("foo")
```
as potential violations leading to inconsistent behaviour. 

The rules impacted are:

- `BLE001`
- `TRY400`
- `TRY401`
- `PLE1205`
- `PLE1206`
- `LOG007`
- `G001`-`G004`
- `G101`
- `G201`
- `G202`

## Test Plan

Fixtures for all impacted rules expanded. 

## Issue Link

Refers: https://github.com/astral-sh/ruff/issues/7502
2023-09-27 00:21:22 +00:00
Zanie Blue
528f386131
Show preview notice on rule pages for nursery rules (#7670)
<!--
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? -->

The note about rules being in preview was not being displayed for legacy
nursery rules.

Adds a link to the new preview documentation as well.

## Test Plan

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

Built locally and checked a nursery rule e.g.
http://127.0.0.1:8000/ruff/rules/no-indented-block-comment/
2023-09-26 17:53:29 -05:00
bluthej
ee533332ed
Refactor: use Settings struct (#7665)
## Summary

Pass around a `Settings` struct instead of individual members to
simplify function signatures and to make it easier to add new settings.

This PR was suggested in [this
comment](https://github.com/astral-sh/ruff/issues/1567#issuecomment-1734182803).

## Note on the choices

I chose which functions to modify based on which seem most likely to use
new settings, but suggestions on my choices are welcome!
2023-09-26 12:17:18 -05:00
Dhruv Manilawala
8165925e01
Use 1-based cell indices consistently for Notebooks (#7662)
## Summary

This PR fixes the bug where the cell indices displayed in the `--diff` output
and the ones in the normal output were different. This was due to the fact that
the `--diff` output was using the `enumerate` function to iterate over
the cells which starts at 0.

## Test Plan

Ran the following command with and without the `--diff` flag:

```console
cargo run --bin ruff -- check --no-cache --isolated ~/playground/ruff/notebooks/test.ipynb
```

### `main`

<details><summary>Diagnostics output:</summary>
<p>

```console
$ cargo run --bin ruff -- check --no-cache --isolated ~/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.
```

</p>
</details>

<details><summary>Diff output:</summary>
<p>

```console
$ cargo run --bin ruff -- check --no-cache --isolated ~/playground/ruff/notebooks/test.ipynb --diff
--- /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 2
+++ /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 2
@@ -1,2 +1 @@
-import random
-import math
+import random
--- /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 4
+++ /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 4
@@ -1,4 +1,3 @@
 import random
-import pprint
 
 random.randint(10, 20)
--- /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 5
+++ /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 5
@@ -1,3 +1,3 @@
 foo = 1
-if foo is 2:
-    raise ValueError(f"Invalid foo: {foo is 1}")
+if foo == 2:
+    raise ValueError(f"Invalid foo: {foo == 1}")

Would fix 4 errors.
```

</p>
</details> 

### `dhruv/consistent-cell-indices`

<details><summary>Diagnostic output:</summary>
<p>

```console
$ cargo run --bin ruff -- check --no-cache --isolated ~/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.
```

</p>
</details> 

<details><summary>Diff output:</summary>
<p>

```console
$ cargo run --bin ruff -- check --no-cache --isolated ~/playground/ruff/notebooks/test.ipynb --diff
--- /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 3
+++ /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 3
@@ -1,2 +1 @@
-import random
-import math
+import random
--- /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 5
+++ /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 5
@@ -1,4 +1,3 @@
 import random
-import pprint
 
 random.randint(10, 20)
--- /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 6
+++ /Users/dhruv/playground/ruff/notebooks/test.ipynb:cell 6
@@ -1,3 +1,3 @@
 foo = 1
-if foo is 2:
-    raise ValueError(f"Invalid foo: {foo is 1}")
+if foo == 2:
+    raise ValueError(f"Invalid foo: {foo == 1}")

Would fix 4 errors.
```

</p>
</details> 

fixes: #6673
2023-09-26 19:43:59 +05:30
konsti
4d16e2308d
Formatter and parser refactoring (#7569)
I got confused and refactored a bit, now the naming should be more
consistent. This is the basis for the range formatting work.

Chages:
* `format_module` -> `format_module_source` (format a string)
* `format_node` -> `format_module_ast` (format a program parsed into an
AST)
* Added `parse_ok_tokens` that takes `Token` instead of `Result<Token>`
* Call the source code `source` consistently
* Added a `tokens_and_ranges` helper
* `python_ast` -> `module` (because that's the type)
2023-09-26 15:29:43 +02:00
konsti
26f9b4a8e6
Don't suggest replacing builtin.open() with Path.open() if the latter doesn't support all options (#7637)
**Summary** Check that `closefd` and `opener` aren't being used with
`builtin.open()` before suggesting `Path.open()` because pathlib doesn't
support these arguments.

Closes #7620

**Test Plan** New cases in the fixture.
2023-09-26 09:07:35 +00:00
Charlie Marsh
93b5d8a0fb
Implement our own small-integer optimization (#7584)
## Summary

This is a follow-up to #7469 that attempts to achieve similar gains, but
without introducing malachite. Instead, this PR removes the `BigInt`
type altogether, instead opting for a simple enum that allows us to
store small integers directly and only allocate for values greater than
`i64`:

```rust
/// A Python integer literal. Represents both small (fits in an `i64`) and large integers.
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct Int(Number);

#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub enum Number {
    /// A "small" number that can be represented as an `i64`.
    Small(i64),
    /// A "large" number that cannot be represented as an `i64`.
    Big(Box<str>),
}

impl std::fmt::Display for Number {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            Number::Small(value) => write!(f, "{value}"),
            Number::Big(value) => write!(f, "{value}"),
        }
    }
}
```

We typically don't care about numbers greater than `isize` -- our only
uses are comparisons against small constants (like `1`, `2`, `3`, etc.),
so there's no real loss of information, except in one or two rules where
we're now a little more conservative (with the worst-case being that we
don't flag, e.g., an `itertools.pairwise` that uses an extremely large
value for the slice start constant). For simplicity, a few diagnostics
now show a dedicated message when they see integers that are out of the
supported range (e.g., `outdated-version-block`).

An additional benefit here is that we get to remove a few dependencies,
especially `num-bigint`.

## Test Plan

`cargo test`
2023-09-25 15:13:21 +00:00
Charlie Marsh
65aebf127a
Treat form feed as whitespace in SimpleTokenizer (#7626)
## Summary

This is whitespace as per `is_python_whitespace`, and right now it tends
to lead to panics in the formatter. Seems reasonable to treat it as
whitespace in the `SimpleTokenizer` too.

Closes .https://github.com/astral-sh/ruff/issues/7624.
2023-09-25 14:34:59 +00:00
Charlie Marsh
17ceb5dcb3
Preserve newlines after nested compound statements (#7608)
## Summary

Given:
```python
if True:
    if True:
        pass
    else:
        pass
        # a

        # b
        # c

else:
    pass
```

We want to preserve the newline after the `# c` (before the `else`).
However, the `last_node` ends at the `pass`, and the comments are
trailing comments on the `pass`, not trailing comments on the
`last_node` (the `if`). As such, when counting the trailing newlines on
the outer `if`, we abort as soon as we see the comment (`# a`).

This PR changes the logic to skip _all_ comments (even those with
newlines between them). This is safe as we know that there are no
"leading" comments on the `else`, so there's no risk of skipping those
accidentally.

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

## Test Plan

No change in compatibility.

Before:

| 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.99979 | 3496 | 22 |
| warehouse | 0.99967 | 648 | 15 |
| zulip | 0.99972 | 1437 | 21 |

After:

| 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 |
2023-09-25 14:21:44 +00:00
Micha Reiser
8ce138760a
Emit LexError for dedent to incorrect level (#7638) 2023-09-25 11:45:44 +01:00
dependabot[bot]
10e35e38d7
Bump semver from 1.0.18 to 1.0.19 (#7641)
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2023-09-25 09:09:17 +00:00
Charlie Marsh
39ddad7454
Refactor FURB105 into explicit cases (#7634)
## Summary

I was having trouble keeping track of the various cases here, so opted
to refactor into a more explicit `match`.
2023-09-24 18:46:09 +00:00
Charlie Marsh
f32b0eef9c
Flag FURB105 with starred kwargs (#7630) 2023-09-24 14:28:20 +00:00
Dhruv Manilawala
15813a65f3
Update return type for PT022 autofix (#7613)
## Summary

This PR fixes the autofix behavior for `PT022` to create an additional
edit for the return type if it's present. The edit will update the
return type from `Generator[T, ...]` to `T`. As per the [official
documentation](https://docs.python.org/3/library/typing.html?highlight=typing%20generator#typing.Generator),
the first position is the yield type, so we can ignore other positions.

```python
typing.Generator[YieldType, SendType, ReturnType]
```

## Test Plan

Add new test cases, `cargo test` and review the snapshots.

fixes: #7610
2023-09-24 06:39:47 +00:00