Commit Graph

873 Commits

Author SHA1 Message Date
Dhruv Manilawala f9a828f493
Move `Q003` to AST checker (#10923)
## Summary

This PR moves the `Q003` rule to AST checker.

This is the final rule that used the docstring detection state machine
and thus this PR removes it as well.

resolves: #7595 
resolves: #7808 

## Test Plan

- [x] `cargo test`
- [x] Make sure there are no changes in the ecosystem
2024-04-14 23:44:12 +05:30
Steve C 812b0976a9
[`pylint`] Support inverted comparisons (`PLR1730`) (#10920)
## Summary

Adds more aggressive logic to PLR1730, `if-stmt-min-max`

Closes #10907 

## Test Plan

`cargo test`

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-04-13 22:57:20 +00:00
Hoël Bagard b356c4376c
Fix S310 `suspicious-url-open-usage` description (#10917)
## Summary

The "What it does" section of the docstring is missing a verb, this PR
adds it.
2024-04-13 12:52:04 +01:00
Sebastian Pipping 85ca5b7eed
Fix last example of flake8-bugbear rule `B023` "function uses loop variable" (#10913)
<!--
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

Hi! 👋 

Thanks for sharing ruff as software libre — it helps me keep Python code
quality up with pre-commit, both locally and CI 🙏

While studying the examples at
https://docs.astral.sh/ruff/rules/function-uses-loop-variable/#example I
noticed that the last of the examples had a bug: prior to this fix, `ì`
was passed to the lambda for `x` rather than for `i` — the two are
mixed-up. The reason it's easy to overlook is because addition is an
commutative operation and so `x + i` and `i + x` give the same result
(and least with integers), despite the mix-up. For proof, let me demo
the relevant part with before and after:

```python
In [1]: from functools import partial

In [2]: [partial(lambda x, i: (x, i), i)(123) for i in range(3)]
Out[2]: [(0, 123), (1, 123), (2, 123)]

In [3]: [partial(lambda x, i: (x, i), i=i)(123) for i in range(3)]
Out[3]: [(123, 0), (123, 1), (123, 2)]
```

Does that make sense?

## Test Plan

<!-- How was it tested? -->
Was manually tested using IPython.


CC @r4f @grandchild
2024-04-12 20:07:52 +00:00
Charlie Marsh c2421068bc
Limit commutative non-augmented-assignments to primitive data types (#10912)
## Summary

I think this is the best we can do without type inference. At least it
will still catch some common cases.

Closes #10911.
2024-04-12 15:02:29 -04:00
Charlie Marsh e9870fe468
Avoid `non-augmented-assignment` for reversed, non-commutative operators (#10909)
Closes https://github.com/astral-sh/ruff/issues/10900.
2024-04-12 10:04:57 -04:00
Charlie Marsh a013050c11
Respect `per-file-ignores` for `RUF100` on blanket `# noqa` (#10908)
## Summary

If `RUF100` was included in a per-file-ignore, we respected it on cases
like `# noqa: F401`, but not the blanket variant (`# noqa`).

Closes https://github.com/astral-sh/ruff/issues/10906.
2024-04-12 13:45:29 +00:00
Dhruv Manilawala 2e37cf6b3b
Bump version to v0.3.7 (#10895) 2024-04-12 03:39:45 +00:00
wolfgangshi a9e4393008
[`pylint`] Implement rule to prefer augmented assignment (`PLR6104`) (#9932)
## Summary

Implement new rule: Prefer augmented assignment (#8877). It checks for
the assignment statement with the form of `<expr> = <expr>
<binary-operator> …` with a unsafe fix to use augmented assignment
instead.

## Test Plan

1. Snapshot test is included in the PR.
2. Manually test with playground.
2024-04-11 23:08:42 -04:00
Charlie Marsh 312f43475f
[`pylint`] Recode `nan-comparison` rule to `W0177` (#10894)
## Summary

This was accidentally committed under `W0117`, but the actual Pylint
code is `W0177`:
https://pylint.readthedocs.io/en/latest/user_guide/checkers/features.html.

Closes https://github.com/astral-sh/ruff/issues/10791.
2024-04-11 22:49:20 -04:00
Martin Imre 03899dcba3
[`flake8-bugbear`] Implement `loop-iterator-mutation` (`B909`) (#9578)
## Summary
This PR adds the implementation for the current
[flake8-bugbear](https://github.com/PyCQA/flake8-bugbear)'s B038 rule.
The B038 rule checks for mutation of loop iterators in the body of a for
loop and alerts when found.

Rational: 
Editing the loop iterator can lead to undesired behavior and is probably
a bug in most cases.

Closes #9511.

Note there will be a second iteration of B038 implemented in
`flake8-bugbear` soon, and this PR currently only implements the weakest
form of the rule.
I'd be happy to also implement the further improvements to B038 here in
ruff 🙂
See https://github.com/PyCQA/flake8-bugbear/issues/454 for more
information on the planned improvements.

## Test Plan
Re-using the same test file that I've used for `flake8-bugbear`, which
is included in this PR (look for the `B038.py` file).


Note: this is my first time using `rust` (beside `rustlings`) - I'd be
very happy about thorough feedback on what I could've done better
🙂 - Bring it on 😀
2024-04-11 19:52:52 +00:00
Carl Meyer 25f5a8b201
Struct not tuple for compiled per-file ignores (#10864)
## Summary

Code cleanup for per-file ignores; use a struct instead of a tuple.

Named the structs for individual ignores and the list of ignores
`CompiledPerFileIgnore` and `CompiledPerFileIgnoreList`. Name choice is
because we already have a `PerFileIgnore` struct for a
pre-compiled-matchers form of the config. Name bikeshedding welcome.

## Test Plan

Refactor, should not change behavior; existing tests pass.

---------

Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2024-04-11 13:47:57 -06:00
Charlie Marsh e7d1d43f39
[`pylint`] Reverse min-max logic in `if-stmt-min-max` (#10890)
Closes https://github.com/astral-sh/ruff/issues/10889.
2024-04-11 14:16:13 -04:00
Dhruv Manilawala 4e8a84617c
Bump version to v0.3.6 (#10883)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2024-04-11 15:53:01 +00:00
Auguste Lalande ffea1bb0a3
[`refurb`] Implement `write-whole-file` (`FURB103`) (#10802)
## Summary

Implement `write-whole-file` (`FURB103`), part of #1348. This is largely
a copy and paste of `read-whole-file` #7682.

## Test Plan

Text fixture added.

---------

Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
2024-04-11 14:21:45 +05:30
Charlie Marsh 1eee6f16e4
[`flake8-pytest-style`] Fix single-tuple conversion in `pytest-parametrize-values-wrong-type` (#10862)
## Summary

This looks like a typo (without test coverage).

Closes https://github.com/astral-sh/ruff/issues/10861.
2024-04-10 14:20:09 -04:00
Auguste Lalande de46a36bbc
[`pygrep-hooks`] Improve `blanket-noqa` error message (`PGH004`) (#10851)
## Summary

Improve `blanket-noqa` error message in cases where codes are provided
but not detected due to formatting issues. Namely `# noqa X100` (missing
colon) or `noqa : X100` (space before colon). The behavior is similar to
`NQA002` and `NQA003` from `flake8-noqa` mentioned in #850. The idea to
merge the rules into `PGH004` was suggested by @MichaReiser
https://github.com/astral-sh/ruff/pull/10325#issuecomment-2025535444.

## Test Plan

Test cases added to fixture.
2024-04-10 04:30:25 +00:00
Charlie Marsh dbf8d0c82c
Show negated condition in `needless-bool` diagnostics (#10854)
## Summary

Closes https://github.com/astral-sh/ruff/issues/10843.
2024-04-10 04:29:43 +00:00
Carl Meyer 02e88fdbb1
Support negated patterns in [extend-]per-file-ignores (#10852)
Fixes #3172 

## Summary

Allow prefixing [extend-]per-file-ignores patterns with `!` to negate
the pattern; listed rules / prefixes will be ignored in all files that
don't match the pattern.

## Test Plan

Added tests for the feature.

Rendered docs and checked rendered output.
2024-04-09 21:53:41 -06:00
Carl Meyer e13e57e024
Localize cleanup for FunctionDef and ClassDef (#10837)
## Summary

Came across this code while digging into the semantic model with
@AlexWaygood, and found it confusing because of how it splits
`push_scope` from the paired `pop_scope` (took me a few minutes to even
figure out if/where we were popping the pushed scope). Since this
"cleanup" is already totally split by node type, there doesn't seem to
be any gain in having it as a separate "step" rather than just
incorporating it into the traversal clauses for those node types.

I left the equivalent cleanup step alone for the expression case,
because in that case it is actually generic across several different
node types, and due to the use of the common `visit_generators` utility
there isn't a clear way to keep the pushes and corresponding pops
localized.

Feel free to just reject this if I've missed a good reason for it to
stay this way!

## Test Plan

Tests and clippy.
2024-04-08 13:29:38 -06:00
Aleksei Latyshev 6050bab5db
[`refurb`] Support `itemgetter` in `reimplemented-operator` (`FURB118`) (#10526)
## Summary
Lint about function like expressions which are equivalent to
`operator.itemgetter`.
See:
https://github.com/astral-sh/ruff/issues/1348#issuecomment-1909421747

## Test Plan
cargo test
2024-04-07 02:31:59 +00:00
Alex Waygood 2a51dcfdf7
[`pyflakes`] Allow forward references in class bases in stub files (`F821`) (#10779)
## Summary

Fixes #3011.

Type checkers currently allow forward references in all contexts in stub
files, and stubs frequently make use of this capability (although it
doesn't actually seem to be specc'd anywhere --neither in PEP 484, nor
https://typing.readthedocs.io/en/latest/source/stubs.html#id6, nor the
CPython typing docs). Implementing it so that Ruff allows forward
references in _all contexts_ in stub files seems non-trivial, however
(or at least, I couldn't figure out how to do it easily), so this PR
does not do that. Perhaps it _should_; if we think this apporach isn't
principled enough, I'm happy to close it and postpone changing anything
here.

However, this does reduce the number of F821 errors Ruff emits on
typeshed down from 76 to 2, which would mean that we could enable the
rule at typeshed. The remaining 2 F821 errors can be trivially fixed at
typeshed by moving definitions around; forward references in class bases
were really the only remaining places where there was a real _use case_
for forward references in stub files that Ruff wasn't yet allowing.

## Test plan

`cargo test`. I also ran this PR branch on typeshed to check to see if
there were any new false positives caused by the changes here; there
were none.
2024-04-07 01:15:58 +01:00
Alex Waygood 86588695e3
[`flake8-slots`] Flag subclasses of call-based `typing.NamedTuple`s as well as subclasses of `collections.namedtuple()` (`SLOT002`) (#10808) 2024-04-07 00:16:06 +01:00
Alex Waygood 47e0cb8985
[`flake8-pyi`] Various improvements to PYI034 (#10807)
More accurately identify whether a class is a metaclass, a subclass of `collections.abc.Iterator`, or a subclass of `collections.abc.AsyncIterator`
2024-04-07 00:15:48 +01:00
Tibor Reiss 3194f90db1
[`pylint`] Implement `if-stmt-min-max` (`PLR1730`, `PLR1731`) (#10002)
Add rule [consider-using-min-builtin
(R1730)](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/consider-using-min-builtin.html)
and [consider-using-max-builtin
(R1731)](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/consider-using-max-builtin.html)

See https://github.com/astral-sh/ruff/issues/970 for rules

Test Plan: `cargo test`
2024-04-06 17:32:05 +00:00
Charlie Marsh ee4bff3475
Add comment test for `FURB110` (#10804) 2024-04-06 16:49:22 +00:00
Auguste Lalande 7fb012d0df
[`refurb`] Do not allow any keyword arguments for `read-whole-file` in `rb` mode (`FURB101`) (#10803)
## Summary

`Path.read_bytes()` does not support any keyword arguments, so `FURB101`
should not be triggered if the file is opened in `rb` mode with any
keyword arguments.

## Test Plan

Move erroneous test to "Non-error" section of fixture.
2024-04-06 12:41:39 -04:00
Steve C 44459f92ef
[`refurb`] Implement `if-expr-instead-of-or-operator` (`FURB110`) (#10687)
## Summary

Add
[`FURB110`](https://github.com/dosisod/refurb/blob/master/refurb/checks/logical/use_or.py)

See: #1348 

## Test Plan

`cargo test`
2024-04-06 16:39:40 +00:00
Alex Waygood 1dc93107dc
Improve internal documentation for the semantic model (#10788) 2024-04-06 16:28:32 +00:00
Charlie Marsh 7fb5f47efe
Respect `# noqa` directives on `__all__` openers (#10798)
## Summary

Historically, given:

```python
__all__ = [  # noqa: F822
    "Bernoulli",
    "Beta",
    "Binomial",
]
```

The F822 violations would be attached to the `__all__`, so this `# noqa`
would be enforced for _all_ definitions in the list. This changed in
https://github.com/astral-sh/ruff/pull/10525 for the better, in that we
now use the range of each string. But these `# noqa` directives stopped
working.

This PR sets the `__all__` as a parent range in the diagnostic, so that
these directives are respected once again.

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

## Test Plan

`cargo test`
2024-04-06 14:51:17 +00:00
Charlie Marsh 83db62bcda
Use within-scope shadowed bindings in `asyncio-dangling-task` (#10793)
## Summary

I think this is using the wrong shadowing, as seen by the change in the
test fixture.
2024-04-06 10:44:03 -04:00
Bohdan b45fd61ec5
[`pyupgrade`] Replace `str, Enum` with `StrEnum` (`UP042`) (#10713)
## Summary

Add new rule `pyupgrade - UP042` (I picked next available number).
Closes https://github.com/astral-sh/ruff/discussions/3867
Closes https://github.com/astral-sh/ruff/issues/9569

It should warn + provide a fix `class A(str, Enum)` -> `class
A(StrEnum)` for py311+.

## Test Plan

Added UP042.py test.

## Notes

I did not find a way to call `remove_argument` 2 times consecutively, so
the automatic fixing works only for classes that inherit exactly `str,
Enum` (regardless of the order).

I also plan to extend this rule to support IntEnum in next PR.
2024-04-06 01:56:28 +00:00
Auguste Lalande c2790f912b
[`pylint`] Implement `bad-staticmethod-argument` (`PLW0211`) (#10781)
## Summary

Implement `bad-staticmethod-argument` from pylint, part of #970.

## Test Plan

Text fixture added.
2024-04-05 21:33:39 +00:00
Micha Reiser 2e7a1a4cb1
D403: Require capitalizing single word sentence (#10776) 2024-04-05 08:42:00 +02:00
Jane Lewis d050d6da2e
`ruff server` now supports the `source.organizeImports` source action (#10652)
## Summary

This builds on top of the work in
https://github.com/astral-sh/ruff/pull/10597 to support `Ruff: Organize
imports` as an available source action.

To do this, we have to support `Clone`-ing for linter settings, since we
need to modify them in place to select import-related diagnostics
specifically (`I001` and `I002`).

## Test Plan


https://github.com/astral-sh/ruff/assets/19577865/04282d01-dfda-4ac5-aa8f-6a92d5f85bfd
2024-04-04 22:20:50 +00:00
Dhruv Manilawala d02b1069b5
Add semantic model flag when inside f-string replacement field (#10766)
## Summary

This PR adds a new semantic model flag to indicate that the checker is
inside an f-string replacement field. This will be used to ignore
certain checks if the target version doesn't support a specific feature
like PEP 701.

fixes: #10761 

## Test Plan

Add a test case from the raised issue.
2024-04-04 09:08:48 +05:30
Alex Waygood 6b4fa17097
Rework docs for pydocstyle rules (#10754) 2024-04-03 22:34:00 +01:00
Carl Meyer 5e2482824c
[flake8_comprehensions] add sum/min/max to unnecessary comprehension check (C419) (#10759)
Fixes #3259 

## Summary

Renames `UnnecessaryComprehensionAnyAll` to
`UnnecessaryComprehensionInCall` and extends the check to `sum`, `min`,
and `max`, in addition to `any` and `all`.

## Test Plan

Updated snapshot test.

Built docs locally and verified the docs for this rule still render
correctly.
2024-04-03 14:44:33 -06:00
Charlie Marsh e54b591ec7
Use section name range for all section-related docstring diagnostics (#10740)
## Summary

We may not have had access to this in the past, but in short, if the
diagnostic is related to a specific section of a docstring, it seems
better to highlight the section (via the header) than the _entire_
docstring.

This should be completely compatible with existing `# noqa` since it's
always inside of a multi-line string anyway, and in such cases the `#
noqa` is always placed at the end of the multiline string.

Closes https://github.com/astral-sh/ruff/issues/10736.
2024-04-02 22:10:04 -04:00
Carl Meyer 814b26f82e
[flake8_comprehensions] update docs for unnecessary-comprehension-any-all (C419) (#10744)
Ref #3259; see in particular
https://github.com/astral-sh/ruff/issues/3259#issuecomment-2033127339

## Summary

Improve the accuracy of the docs for this lint rule/fix.

## Test Plan

Generated the docs locally and visited the page for this rule:

![Screenshot 2024-04-02 at 4 56
40 PM](https://github.com/astral-sh/ruff/assets/61586/64f25cf6-edfe-4682-ac8e-7e21b834f5f2)

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2024-04-02 17:42:55 -06:00
Charlie Marsh dff8f93457
[`flake8-return`] Ignore assignments to annotated variables in `unnecessary-assign` (#10741)
## Summary

Closes https://github.com/astral-sh/ruff/issues/10732.
2024-04-02 16:18:05 -04:00
Aleksei Latyshev 859e3fc7fa
[`refurb`] Implement `int-on-sliced-str` (`FURB166`) (#10650)
## Summary
implement int_on_sliced_str (FURB166) lint
- #1348
- [original
lint](https://github.com/dosisod/refurb/blob/master/refurb/checks/builtin/use_int_base_zero.py)

## Test Plan
cargo test
2024-04-02 19:29:42 +00:00
Aleksei Latyshev 0de23760ff
[`pylint`] Don't recommend decorating staticmethods with `@singledispatch` (`PLE1519`, `PLE1520`) (#10637)
Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2024-04-02 16:47:31 +00:00
Charlie Marsh 159bad73d5
Accept non-aliased (but correct) import in unconventional-import-alias (#10729)
## Summary

Given:

```toml
[tool.ruff.lint.flake8-import-conventions.aliases]
"django.conf.settings" = "settings"
```

We should accept `from django.conf import settings`.

Closes https://github.com/astral-sh/ruff/issues/10599.
2024-04-01 23:47:20 -04:00
Charlie Marsh 7b48443624
Respect `Q00*` ignores in `flake8-quotes` rules (#10728)
## Summary

We lost the per-rule ignores when these were migrated to the AST, so if
_any_ `Q` rule is enabled, they're now all enabled.

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

## Test Plan

Ran:

```shell
ruff check . --isolated --select Q --ignore Q000
ruff check . --isolated --select Q --ignore Q001
ruff check . --isolated --select Q --ignore Q002
ruff check . --isolated --select Q --ignore Q000,Q001
ruff check . --isolated --select Q --ignore Q000,Q002
ruff check . --isolated --select Q --ignore Q001,Q002
```

...against:

```python
'''
bad docsting
'''
a = 'single'
b = '''
bad multi line
'''
```
2024-04-02 03:21:12 +00:00
Charlie Marsh d36f60999d
Ignore annotated lambdas in class scopes (#10720)
## Summary

An annotated lambda assignment within a class scope is often
intentional. For example, within a dataclass or Pydantic model, these
are treated as fields rather than methods (and so can be passed values
in constructors).

I originally wrote this to special-case dataclasses and Pydantic
models... But was left feeling like we'd see more false positives here
for little gain (an annotated lambda within a `class` is likely
intentional?). Open to opinions, though.

Closes https://github.com/astral-sh/ruff/issues/10718.
2024-04-01 15:44:45 -04:00
Charlie Marsh 67f0f615b2
Recursively resolve `TypeDicts` for N815 violations (#10719)
## Summary

Only works within a single file for now.

Closes https://github.com/astral-sh/ruff/issues/10671.
2024-04-01 17:40:55 +00:00
Charlie Marsh 200ebeebdc
Bump version to v0.3.5 (#10717) 2024-04-01 13:15:32 -04:00
renovate[bot] a0e1544848
chore(deps): update rust crate pep440_rs to 0.5.0 (#10703) 2024-04-01 16:02:18 +00:00
Steve C f6b6f0df67
[`ruff`] Fix panic in unused `# noqa` removal with multi-byte space (`RUF100`) (#10682)
## Summary

Currently, [this
line](716688d44e/crates/ruff_linter/src/fix/edits.rs (L101))
assumes that the `noqa` comment begins with an octothorpe followed by a
space. (`# `) With anyone's random code, this of course is not always
true.

When there's a multi-byte character after the leading octothorpe, such
as
[`\u0085`](https://www.fileformat.info/info/unicode/char/85/index.htm),
we try slicing from within the character, causing a panic.

To fix this, the logic has been changed to remove unused `noqa`
directives and keep any trailing comments, or removing the whole comment
if the comment is just the unused `noqa`

Fixes #10097.

## Test Plan

`cargo test`
2024-04-01 01:00:37 +00:00