Commit graph

2973 commits

Author SHA1 Message Date
Ofek Lev
4c86b155f2
Fix typo (#8735) 2023-11-16 22:10:09 -06:00
Vince Chan
e2109c1353
Improve debug printing for resolving origin of config settings (#8729)
## Summary

When running ruff in verbose mode with `-v`, the first debug logs show
where the config settings are taken from. For example:
```
❯ ruff check ./some_file.py -v
[2023-11-17][00:16:25][ruff_cli::resolve][DEBUG] Using pyproject.toml (parent) at /Users/vince/demo/ruff.toml
```

This threw me off for a second because I knew I had no python project
there, and therefore no `pyproject.toml` file. Then I realised it was
actually reading a `ruff.toml` file (obvious when you read the whole
print I suppose) and that the pyproject.toml is a hardcoded string in
the debug log.

I think it would be nice to tweak the wording slightly so it is clear
that the settings don't neccessarily have to come from a
`pyproject.toml` file.
2023-11-17 01:10:36 +00:00
Charlie Marsh
1fcccf82fc
Avoid syntax error via importing trio.lowlevel (#8730)
We ended up with a syntax error here via `from trio import
lowlevel.checkpoint`. The new solution avoids that error, but does miss
cases like:

```py
from trio.lowlevel import Timer
```

Where it could insert `from trio.lowlevel import Timer, checkpoint`.
Instead, it'll add `from trio import lowlevel`.

See:
https://github.com/astral-sh/ruff/issues/8402#issuecomment-1810838129
2023-11-17 01:07:59 +00:00
konsti
14e65afdc6
Update to Rust 1.74 and use new clippy lints table (#8722)
Update to [Rust
1.74](https://blog.rust-lang.org/2023/11/16/Rust-1.74.0.html) and use
the new clippy lints table.

The update itself introduced a new clippy lint about superfluous hashes
in raw strings, which got removed.

I moved our lint config from `rustflags` to the newly stabilized
[workspace.lints](https://doc.rust-lang.org/stable/cargo/reference/workspaces.html#the-lints-table).
One consequence is that we have to `unsafe_code = "warn"` instead of
"forbid" because the latter now actually bans unsafe code:

```
error[E0453]: allow(unsafe_code) incompatible with previous forbid
  --> crates/ruff_source_file/src/newlines.rs:62:17
   |
62 |         #[allow(unsafe_code)]
   |                 ^^^^^^^^^^^ overruled by previous forbid
   |
   = note: `forbid` lint level was set on command line
```

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-11-16 18:12:46 -05:00
Charlie Marsh
6d5d079a18
Avoid missing namespace violations in scripts with shebangs (#8710)
## Summary

I think it's reasonable to avoid raising `INP001` for scripts, and
shebangs are one sufficient way to detect scripts.

Closes https://github.com/astral-sh/ruff/issues/8690.
2023-11-16 17:21:33 -05:00
Zanie Blue
d1e88dc984
Update UP032 to unescape curly braces in literal parts of converted strings (#8697)
Closes #8694
2023-11-16 13:59:54 -06:00
konsti
dda31b6996
List all ipython builtins (#8719)
I checked for ipython-specific builtins on python 3.11 using
```python
import json
from subprocess import check_output

builtins_python = json.loads(check_output(["python3", "-c" "import json; print(json.dumps(dir(__builtins__)))"]))
builtins_ipython = json.loads(check_output(["ipython3", "-c" "import json; print(json.dumps(dir(__builtins__)))"]))
print(sorted(set(builtins_ipython) - set(builtins_python)))
```
and updated the relevant constant and match. The list changes from

`display`

to

`__IPYTHON__`, `display`, `get_ipython`.

Followup to #8707
2023-11-16 19:06:25 +01:00
Charlie Marsh
b6a7787318
Remove pyproject.toml from fixtures directory (#8726)
## Summary

This exists to power a test, but it ends up affecting the behavior of
all files in the directory. Namely, it means that these files _aren't_
excluded when you format or lint them directly, since in that case, Ruff
will fall back to looking at the `pyproject.toml` in
`crates/ruff_linter/resources/test/fixtures`, which _doesn't_ exclude
these files, unlike our top-level `pyproject.toml`.
2023-11-16 13:04:52 -05:00
Jonas Haag
5fa961f670
Improve N803 example (#8714) 2023-11-16 12:50:31 -05:00
Charlie Marsh
2424188bb2
Trim trailing empty strings when converting to f-strings (#8712)
## Summary

When converting from a `.format` call to an f-string, we can trim any
trailing empty tokens.

Closes https://github.com/astral-sh/ruff/issues/8683.
2023-11-15 23:14:49 -05:00
Charlie Marsh
a59172528c
Add fix for future-required-type-annotation (#8711)
## Summary

We already support inserting imports for `I002` -- this PR just adds the
same fix for `FA102`, which is explicitly about `from __future__ import
annotations`.

Closes https://github.com/astral-sh/ruff/issues/8682.
2023-11-16 03:08:02 +00:00
Charlie Marsh
cd29761b9c
Run unicode prefix rule over tokens (#8709)
## Summary

It seems like the range of an `ExprStringLiteral` can be somewhat
unreliable when the string is part of an implicit concatenation with an
f-string. Using the tokens themselves is more reliable.

Closes #8680.
Closes https://github.com/astral-sh/ruff/issues/7784.
2023-11-16 02:30:42 +00:00
Charlie Marsh
4ac78d5725
Treat display as a builtin in IPython (#8707)
## Summary

`display` is a special-cased builtin in IPython. This PR adds it to the
builtin namespace when analyzing IPython notebooks.

Closes https://github.com/astral-sh/ruff/issues/8702.
2023-11-16 01:58:44 +00:00
Alan Du
2083352ae3
Add autofix for PIE800 (#8668)
## Summary

This adds an autofix for PIE800 (unnecessary spread) -- whenever we see
a `**{...}` inside another dictionary literal, just delete the `**{` and
`}` to inline the key-value pairs. So `{"a": "b", **{"c": "d"}}` becomes
just `{"a": "b", "c": "d"}`.

I have enabled this just for preview mode.

## Test Plan

Updated the preview snapshot test.
2023-11-15 18:11:04 +00:00
Tuomas Siipola
0e2ece5217
Implement FURB136 (#8664)
## Summary

Implements
[FURB136](https://github.com/dosisod/refurb/blob/master/docs/checks.md#furb136-use-min-max)
that checks for `if` expressions that can be replaced with `min()` or
`max()` calls. See issue #1348 for more information.

This implementation diverges from Refurb's original implementation by
retaining the order of equal values. For example, Refurb suggest that
the following expressions:

```python
highest_score1 = score1 if score1 > score2 else score2
highest_score2 = score1 if score1 >= score2 else score2
```

should be to rewritten as:

```python
highest_score1 = max(score1, score2)
highest_score2 = max(score1, score2)
```

whereas this implementation provides more correct alternatives:

```python
highest_score1 = max(score2, score1)
highest_score2 = max(score1, score2)
```

## Test Plan

Unit test checks all eight possibilities.
2023-11-15 18:10:13 +00:00
konsti
a783b14e7d
Add --skip-magic-trailing-comma to formatter dev comment (#8689)
Testing the compatibility with the future stable black style, i realized
the `ruff_python_formatter` dev main was lacking the
`--skip-magic-trailing-comma` option. This does not affect `ruff
format`.

Usage:
```shell
cargo run --bin ruff_python_formatter -p ruff_python_formatter -- --skip-magic-trailing-comma --emit stdout scratch.py
```
2023-11-15 09:23:46 +00:00
Jelmer Vernooij
9d76e4e0b9
isort: Support disabling sections with `no-sections = true` (#8657)
## Summary

This adds a ``no-sections`` option for isort in the linter, similar to
the ``no_sections`` option that exists in upstream isort
(https://pycqa.github.io/isort/docs/configuration/options.html#no-sections)

This option puts all imports except for ``__future__`` into the same
section, and is mostly used by monorepos.

I've taken a bit of a leap in assuming that ruff wants to support the
exact same option; more than happy to refactor if you'd prefer a
different way of setting this up.

Fixes #8653

## Test Plan

I've added a test and have run it on a large Python codebase that uses
isort with --no-sections. The option is disabled by default.
2023-11-14 21:45:51 +00:00
bluthej
561277925f
[isort] Simplify code structure for ordering imports (#8685)
While fixing #8661 I noticed that the code structure for sorting imports
could be simplified.

## Summary

- Move the logic for `force_sort_within_sections` from `isort/mod.rs` to
`isort/ordering.rs` => now there is just one line in `isort/mod.rs`:
`let imports = order_imports(import_block, settings);` which yields the
sorted imports
- Change the function signature of `order_imports` to directly return a
`Vec<EitherImport<'a>>` => no need for `OrderedImportBlock`

I think this is a bit of an improvement because the code is simpler and
there should be a bit of a speedup when setting
`force-sort-within-sections` to true. Indeed, when it's set to true
we're now directly ordering all the imports, whereas before we would
first order the straight imports, then the from imports, combine them
and finally sort the combination a second time (this is probably not
noticeable in practice though).

## Test Plan

No tests added, this is a simple refactor.
2023-11-14 16:43:46 -05:00
Dhruv Manilawala
4099b9610f
F-strings doesn't contain bytes literal for PLW0129 (#8675)
For the `PLW0129` rule, the f-string case shouldn't match against bytes
literal as f-strings cannot contain them. F-strings are made up of
either string literals or formatted expressions.
2023-11-14 18:56:18 +05:30
Charlie Marsh
f7d249ae06
Remove repeated and erroneous scoped settings headers in docs (#8670)
Closes https://github.com/astral-sh/ruff/issues/8505.
2023-11-14 05:44:30 +00:00
Charlie Marsh
bf2cc3f520
Add autotyping-like return type inference for annotation rules (#8643)
## Summary

This PR adds (unsafe) fixes to the flake8-annotations rules that enforce
missing return types, offering to automatically insert type annotations
for functions with literal return values. The logic is smart enough to
generate simplified unions (e.g., `float` instead of `int | float`) and
deal with implicit returns (`return` without a value).

Closes https://github.com/astral-sh/ruff/issues/1640 (though we could
open a separate issue for referring parameter types).

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

## Test Plan

`cargo test`
2023-11-13 23:34:15 -05:00
bluthej
23c819b4b3
Fix ordering for force-sort-within-sections (#8665)
Fixes #8661 

## Summary

Imports like `from x import y` don't have an "asname" for the module, so
they were placed before imports like `import x as w` since `None` <
`Some(s)` for any string s.
The fix is to first sort by `first_alias`, since it's `None` for `import
x as w`, and then by `asname`.

## Test Plan

I included the example from the issue to avoid future regressions.
2023-11-13 18:27:56 -05:00
Adrian
16060670b8
Add new rule to check for useless quote escapes (#8630)
When using the autofixer for `Q000` it does not remove the backslashes
from quotes that no longer need escaping.

This new rule checks for such backslashes (regardless whether they come
from the autofixer or not) and can remove them.

fixes #8617
2023-11-13 21:59:37 +00:00
Charlie Marsh
534fc34f11
Extend unnecessary-pass (PIE790) to include ellipses in preview (#8641)
## Summary

This PR extends `unnecessary-pass` (`PIE790`) to flag unnecessary
ellipsis expressions in addition to `pass` statements. A `pass` is
equivalent to a standalone `...`, so it feels correct to me that a
single rule should cover both cases.

When we look to v0.2.0, we should also consider deprecating `PYI013`,
which flags ellipses only for classes.

Closes https://github.com/astral-sh/ruff/issues/8602.
2023-11-13 19:28:16 +00:00
Charlie Marsh
df9ade7fd9
Use AST transformer for relocate (#8660) 2023-11-13 13:24:27 -05:00
Charlie Marsh
345e1401cf
Treat class C: ... and class C(): ... equivalently (#8659)
## Summary

These should be seen as identical from the `ComparableAst` perspective.
2023-11-13 18:03:04 +00:00
Alan Du
6f23bdb78f
Generalize PIE807 to handle dict literals (#8608)
## Summary

PIE807 will rewrite `lambda: []` to `list` -- AFAICT though, the same
rationale also applies to dicts, so I've modified the code to also
rewrite `lambda: {}` to `dict`.

Two things I'm not sure about:
* Should this go to a new rule? This no longer actually matches the
behavior of flake8-pie, and while I think thematically it makes sense to
be part of the same rule, we could make it a standalone rule (but if so,
where should I put it and what error code should I use)?
* If we want a single rule, are there backwards compatibility concerns
with the rule name change (from `reimplemented_list_builtin` to
`reimplemented_container_builtin`?

## Test Plan

Added snapshot tests of the functionality.
2023-11-13 17:55:17 +00:00
Charlie Marsh
d574fcd1ac
Compare formatted and unformatted ASTs during formatter tests (#8624)
## Summary

This PR implements validation in the formatter tests to ensure that we
don't modify the AST during formatting. Black has similar logic.

In implementing this, I learned that Black actually _does_ modify the
AST, and their test infrastructure normalizes the AST to wipe away those
differences. Specifically, Black changes the indentation of docstrings,
which _does_ modify the AST; and it also inserts parentheses in `del`
statements, which changes the AST too.

Ruff also does both these things, so we _also_ implement the same
normalization using a new visitor that allows for modifying the AST.

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

## Test Plan

`cargo test`
2023-11-13 17:43:27 +00:00
Charlie Marsh
3592f44ade
Allow whitespace around colon in slices for whitespace-before-punctuation (E203) (#8654)
## Summary

This PR makes `whitespace-before-punctuation` (`E203`) compatible with
the formatter by relaxing the rule a bit, as compared to the pycodestyle
implementation. It's also more consistent with PEP 8, which says:

> However, in a slice the colon acts like a binary operator, and should
have equal amounts on either side (treating it as the operator with the
lowest priority).

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

## Test Plan

`cargo test`
2023-11-13 12:16:13 -05:00
Andrew Gallant
8984072df2
ruff_python_formatter: copy and inline shared traits (#8656)
It seems as though using `include!(...)` to avoid the source code copy
breaks rust-analzer. Namely, it treats the included file as unlinked,
and so any part of analysis (e.g., goto-definition) that needs that file
to reason about the code ends up failing.

<!--
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? -->

## Test Plan

<!-- How was it tested? -->
2023-11-13 12:16:04 -05:00
dependabot[bot]
5ba852a878
Bump annotate-snippets from 0.9.1 to 0.9.2 (#8646) 2023-11-13 14:55:15 +00:00
dependabot[bot]
c4fc2b8584
Bump pyproject-toml from 0.8.0 to 0.8.1 (#8648) 2023-11-13 14:53:47 +00:00
dependabot[bot]
1c5f2288ba
Bump fs-err from 2.9.0 to 2.10.0 (#8649) 2023-11-13 09:38:44 -05:00
dependabot[bot]
62f1830898
Bump quick-junit from 0.3.3 to 0.3.5 (#8645) 2023-11-13 09:38:31 -05:00
Charlie Marsh
213d315373
Avoid recommending Self usages in metaclasses (#8639)
PEP 673 forbids the use of `typing(_extensions).Self` in metaclasses, so
we want to avoid flagging `PYI034` on metaclasses. This is based on an
analogous change in `flake8-pyi`:
https://github.com/PyCQA/flake8-pyi/pull/436.

Closes https://github.com/astral-sh/ruff/issues/8353.
2023-11-12 19:47:48 -05:00
Charlie Marsh
7fd95e15d9
Document conventions in the FAQ (#8638)
Enumerates all rules defined in each convention in the FAQ. These lists
mirror
[pydocstyle](https://www.pydocstyle.org/en/latest/error_codes.html#default-conventions).

Closes https://github.com/astral-sh/ruff/issues/8573.
2023-11-12 22:56:39 +00:00
Charlie Marsh
cbd9157bbf
Use function range for no-self-use (#8637)
Previously, this rule used the range of the `self` annotation, but it's
a lot more natural to use the range of the function name (since it also
means the `# noqa` is associated with the method rather than its first
argument).

Closes https://github.com/astral-sh/ruff/issues/8635.
2023-11-12 16:37:52 -05:00
Charlie Marsh
70f491d31e
Omit unrolled augmented assignments in PIE794 (#8634)
Closes https://github.com/astral-sh/ruff/issues/8497.
2023-11-12 20:40:33 +00:00
Jonathan Plasse
776eb8724f
Fix FBT001 false negative with unions and optional (#7501)
## Summary

- Close #7487

In the spirit of `flake8-boolean-trap`, any positional argument that can
accept a boolean should raise `FBT001`.
Raise `FBT001` for all annotations that accept booleans (e.g.
`Optional[bool]`, `Union[int, bool]`).

## Test Plan

Add a fixture, with an annotation using `|`, `Optional`, and `Union`,
and containing a boolean.
2023-11-12 15:09:23 -05:00
Charlie Wilson
5f78580775
Remove unecessary commentary in PD901 message (#8625)
## Summary

Removes unnecessary commentary from the PD901 message. This does make it
different from pandas-vet, but it improves consistency with the rest of
messages.

Current Message:

> `df` is a bad variable name. Be kinder to your future self.


New Message

> `df` is a bad variable name.


## Test Plan

The relevant snapshot has been updated with the new message.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-11-12 17:20:05 +00:00
Bodo Graumann
4d301f6dcc
Improve docs for RUF001, RUF002 and RUF003 (#8628)
I got an error from RUF001 and wanted to override it. How to do that was
not quite obvious. In the process I have tried to improve the
documentation for the rule and it's siblings.
2023-11-12 17:19:25 +00:00
Charlie Marsh
96b265ccec
Implement autofix for multiple-spaces-after-operator and multiple-spaces-before-operator (#8623) 2023-11-11 23:46:16 +00:00
Charlie Marsh
e0a0ddcf7d
Implement autofix for multiple-spaces-after-keyword and multiple-spaces-before-keyword (#8622)
Closes https://github.com/astral-sh/ruff/issues/8312.
2023-11-11 23:41:12 +00:00
Charlie Marsh
9724dfd939
Implement autofix for unnecessary-lambda (PLW0108) (#8621)
Closes https://github.com/astral-sh/ruff/issues/8618.
2023-11-11 18:34:02 -05:00
Jesse Serrao
39728a1198
Add check for is comparison with mutable initialisers to rule F632 (#8607)
## Summary

Adds an extra check to F632 to check for any `is` comparisons to a
mutable initialisers.
Implements #8589 .

Example:
```Python
named_var = {}
if named_var is {}:  # F632 (fix)
    pass
```
The if condition will always evaluate to False because it checks on
identity and it's impossible to take the same identity as a hard coded
list/set/dict initializer.

## Test Plan

Multiple test cases were added to ensure the rule works + doesn't flag
false positives + the fix works correctly.
2023-11-11 00:29:23 +00:00
Shantanu
8207d6df82
Fix unnecessary parentheses in UP007 fix (#8610)
Fixes #8609
2023-11-10 19:15:09 -05:00
Jake Park
c8edac9d2b
[pylint] Implement redefined-argument-from-local (R1704) (#8159)
## Summary

It implements Pylint rule R1704: redefined-argument-from-local

Problematic code:
```python
def show(host_id=10.11):
    # +1: [redefined-argument-from-local]
    for host_id, host in [[12.13, "Venus"], [14.15, "Mars"]]:
        print(host_id, host)
```

Correct code:
```python
def show(host_id=10.11):
    for inner_host_id, host in [[12.13, "Venus"], [14.15, "Mars"]]:
        print(host_id, inner_host_id, host)
```

References:
[Pylint
documentation](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/redefined-argument-from-local.html)
[Related Issue](https://github.com/astral-sh/ruff/issues/970)

## Test Plan

`cargo test`
2023-11-10 14:13:07 -05:00
Alan Du
5a1a8bebca
Allow overriding pydocstyle convention rules (#8586)
## Summary

This fixes #2606 by moving where we apply the convention ignores --
instead of applying that at the very end, e track, we now track which
rules have been specifically enabled (via `Specificity::Rule`). If they
have, then we do *not* apply the docstring overrides at the end.

## Test Plan

Added unit tests to `ruff_workspace` and an integration test to
`ruff_cli`
2023-11-10 18:47:37 +00:00
Dhruv Manilawala
3e00ddce38
Preserve trailing semicolon for Notebooks (#8590)
## Summary

This PR updates the formatter to preserve trailing semicolon for Jupyter
Notebooks.

The motivation behind the change is that semicolons in notebooks are
typically used to hide the output, for example when plotting. This is
highlighted in the linked issue.

The conditions required as to when the trailing semicolon should be
preserved are:
1. It should be a top-level statement which is last in the module.
2. For statement, it can be either assignment, annotated assignment, or
augmented assignment. Here, the target should only be a single
identifier i.e., multiple assignments or tuple unpacking isn't
considered.
3. For expression, it can be any.

## Test Plan

Add a new integration test in `ruff_cli`. The test notebook basically
acts as a document as to which trailing semicolons are to be preserved.

fixes: #8254
2023-11-10 21:53:35 +05:30
Andrew Gallant
a7dbe9d670
refine pyupgrade's TimeoutErrorAlias lint (UP041) to remove false positives (#8587)
Previously, this lint had its alias detection logic a little
backwards. That is, for Python 3.11+, it would *only* detect
asyncio.TimeoutError as an alias, but it should have also detected
socket.timeout as an alias. And in Python <3.11, it would falsely
detect asyncio.TimeoutError as an alias where it should have only
detected socket.timeout as an alias.

We fix it so that both asyncio.TimeoutError and socket.timeout are
detected as aliases in Python 3.11+, and only socket.timeout is
detected as an alias in Python 3.10.

Fixes #8565

## Test Plan

I tested this by updating the existing snapshot test which had
erroneously
asserted that socket.timeout should not be replaced with TimeoutError in
Python
3.11+. I also added a new regression test that targets Python 3.10 and
ensures
that the suggestion to replace asyncio.TimeoutError with TimeoutError
does not
occur.
2023-11-10 10:15:33 -05:00