Commit Graph

332 Commits

Author SHA1 Message Date
Charlie Marsh 2643f74a5d
Iterate over lambdas in deferred type annotations (#9175)
Closes https://github.com/astral-sh/ruff/issues/9159.
2023-12-18 04:51:23 +00:00
Charlie Marsh c944d23053
Avoid nested quotations in auto-quoting fix (#9168)
## Summary

Given `Callable[[Callable[_P, _R]], Callable[_P, _R]]` from the
originating issue, when quoting `Callable`, we quoted the inner
`[Callable[_P, _R]]`, and then created a separate edit for the outer
`Callable`. Since there's an extra level of nesting in the subscript,
the edit for `[Callable[_P, _R]]` correctly did _not_ expand to the
entire expression. However, in this case, we should discard the inner
edit, since the expression is getting quoted by the outer edit anyway.

Closes https://github.com/astral-sh/ruff/issues/9162.
2023-12-17 12:53:58 +00:00
Charlie Marsh a336c1bc95
Add a rule to detect string members in runtime-evaluated unions (#9143)
## Summary

A common mistake is to add quotes around one member in an `X | Y`-style
type union, as in:

```python
contract_versions_list: list[ContractVersion] | 'QuerySet[ContractVersion]' | None = None
```

However, doing so will lead to a runtime error if the annotation is
runtime-evaluated. This PR lints against such patterns.

Closes https://github.com/astral-sh/ruff/issues/9139.
2023-12-16 21:22:06 +00:00
Steve C 85b27a994f
Fix dropped union expressions for piped non-types in `PYI055` autofix (#9161)
## Summary

Fix dropped union expressions for piped non-types in `PYI055` autofix

If you had `type[int] | type[str] | str`, it would have dropped the
`str`, which breaks the type!

Closes #9156 

## Test Plan

`cargo test`
2023-12-16 15:58:28 -05:00
Charlie Marsh 6ecf844214
Add base-class inheritance detection to flake8-django rules (#9151)
## Summary

As elsewhere, this only applies to classes defined within the same file.

Closes https://github.com/astral-sh/ruff/issues/9150.
2023-12-15 18:01:32 +00:00
konsti 82731b8194
Fix panic in D208 with multibyte indent (#9147)
Fix #9080

Example, where `[]` is a 2 byte non-breaking space:
```
def f():
    """ Docstring header
^^^^ Real indentation is 4 chars
      docstring body, over-indented
^^^^^^ Over-indentation is 6 - 4 = 2 chars due to this line
   [] []  docstring body 2, further indented
^^^^^ We take these 4 chars/5 bytes to match the docstring ...
     ^^^ ... and these 2 chars/3 bytes to remove the `over_indented_size` ...
        ^^ ... but preserve this real indent
```
2023-12-15 12:02:15 -05:00
Charlie Marsh d1a7bc38ff
Enable annotation quoting for multi-line expressions (#9142)
Given:

```python
x: DataFrame[
    int
] = 1
```

We currently wrap the annotation in single quotes, which leads to a
syntax error:

```python
x: "DataFrame[
    int
]" = 1
```

There are a few options for what to suggest for users here... Use triple
quotes:

```python
x: """DataFrame[
    int
]""" = 1
```

Or, use an implicit string concatenation (which may require
parentheses):

```python
x: ("DataFrame["
    "int"
"]") = 1
```

The solution I settled on here is to use the `Generator`, which
effectively means we write it out on a single line, like:

```python
x: "DataFrame[int]" = 1
```

It's kind of the "least opinionated" solution, but it does mean we'll
expand to a very long line in some cases.

Closes https://github.com/astral-sh/ruff/issues/9136.
2023-12-15 01:03:09 +00:00
Charlie Marsh 6c224cec52
Deduplicate edits when quoting annotations (#9140)
If you have multiple sub-expressions that need to be quoted, we'll
generate the same edit twice.

Closes https://github.com/astral-sh/ruff/issues/9135.
2023-12-14 19:46:35 +00:00
Charlie Marsh 1a65e544c5
Allow `flake8-type-checking` rules to automatically quote runtime-evaluated references (#6001)
## Summary

This allows us to fix usages like:

```python
from pandas import DataFrame

def baz() -> DataFrame:
    ...
```

By quoting the `DataFrame` in `-> DataFrame`. Without quotes, moving
`from pandas import DataFrame` into an `if TYPE_CHECKING:` block will
fail at runtime, since Python tries to evaluate the annotation to add it
to the function's `__annotations__`.

Unfortunately, this does require us to split our "annotation kind" flags
into three categories, rather than two:

- `typing-only`: The annotation is only evaluated at type-checking-time.
- `runtime-evaluated`: Python will evaluate the annotation at runtime
(like above) -- but we're willing to quote it.
- `runtime-required`: Python will evaluate the annotation at runtime
(like above), and some library (like Pydantic) needs it to be available
at runtime, so we _can't_ quote it.

This functionality is gated behind a setting
(`flake8-type-checking.quote-annotations`).

Closes https://github.com/astral-sh/ruff/issues/5559.
2023-12-13 03:12:38 +00:00
Charlie Marsh 4d2ee5bf98
Add named expression handling to `find_assigned_value` (#9109) 2023-12-12 20:07:33 -05:00
qdegraaf 8314c8bb05
[`typing`] Add `find_assigned_value` helper func to `typing.rs` to retrieve value of a given variable `id` (#8583)
## Summary

Adds `find_assigned_value` a function which gets the `&Expr` assigned to
a given `id` if one exists in the semantic model.

Open TODOs:

- [ ] Handle `binding.kind.is_unpacked_assignment()`: I am bit confused
by this one. The snippet from its documentation does not appear to be
counted as an unpacked assignment and the only ones I could find for
which that was true were invalid Python like:
```python
x, y = 1 
```
- [ ] How to handle AugAssign. Can we combine statements like:
```python
(a, b) = [(1, 2, 3), (4,)]
a += (6, 7)
```
to get the full value for a? Code currently just returns `None` for
these assign types

- [ ] Multi target assigns
```python
m_c = (m_d, m_e) = (0, 0)
trio.sleep(m_c)  # OK
trio.sleep(m_d)  # TRIO115
trio.sleep(m_e)  # TRIO115
```

## Test Plan

Used the function in two rules:

- `TRIO115`
- `PERF101`

Expanded both their fixtures for explicit multi target check
2023-12-13 00:24:47 +00:00
T-256 cb201bc4a5
`PIE804`: Prevent keyword arguments duplication (#8450) 2023-12-12 23:19:55 +00:00
Shantanu cb8eea64a8
[`pylint`] Add fix for `subprocess-run-without-check` (`PLW1510`) (#6708) 2023-12-12 05:08:17 +00:00
Tuomas Siipola a53d59f6bd
Support floating-point base in FURB163 (#9100)
<!--
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? -->

Check floating-point numbers similarly to integers in FURB163. For
example, both `math.log(x, 10)` and `math.log(x, 10.0)` should be
changed to `math.log10(x)`.

## Test Plan

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

Added couple of test cases.
2023-12-11 15:47:37 -05:00
Samuel Cormier-Iijima 1026ece946
E274: allow tab indentation before keyword (#9099)
## Summary

E274 currently flags any keyword at the start of a line indented with
tabs. This turns out to be due to a bug in `Whitespace::trailing` that
never considers any whitespace containing a tab as indentation.

## Test Plan

Added a simple test case.
2023-12-11 15:25:31 -05:00
Charlie Marsh f452bf8cad
Allow `matplotlib.use` calls to intersperse imports (#9094)
This PR allows `matplotlib.use` calls to intersperse imports without
triggering `E402`. This is a pragmatic choice as it's common to require
`matplotlib.use` calls prior to importing from within `matplotlib`
itself.

Closes https://github.com/astral-sh/ruff/issues/9091.
2023-12-11 17:06:25 +00:00
Simon Brugman 6e36dcfefe
[`refurb`] Implement `hashlib-digest-hex` (`FURB181`) (#9077)
## Summary

Implementation of  Refurb FURB181
Part of https://github.com/astral-sh/ruff/issues/1348

## Test Plan

Test cases from Refurb
2023-12-10 02:00:11 +00:00
asafamr-mm 6c2613b44e
Detect `unused-asyncio-dangling-task` (`RUF006`) on unused assignments (#9060)
## Summary

Fixes #8863 : Detect asyncio-dangling-task (RUF006) when discarding
return value

## Test Plan

added new two testcases, changed result of an old one that was made more
specific
2023-12-09 21:10:38 +00:00
Charlie Marsh cb8a2f5615
Add fix for comment-related whitespace rules (#9075)
Closes https://github.com/astral-sh/ruff/issues/9067.

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

Closes https://github.com/astral-sh/ruff/issues/8119.
2023-12-09 15:18:07 -05:00
Charlie Marsh 20e33bf514
Allow class names when `apps.get_model` is a non-string (#9065)
See:
https://github.com/astral-sh/ruff/issues/7675#issuecomment-1848206022
2023-12-08 22:59:05 -05:00
Dhruv Manilawala b7dd2b5941
Allow `EM` fixes even if `msg` variable is defined (#9059)
This PR updates the `EM` rules to generate the auto-fix even if the
`msg` variable is defined in the current scope.

As discussed in https://github.com/astral-sh/ruff/issues/9052.
2023-12-08 15:16:15 -06:00
Charlie Marsh e043bd46b5
Make `math-constant` rule more targeted (#9054)
## Summary

We now only flag `math.pi` if the value is in `[3.14, 3.15)`, and apply
similar rules to the other constants.

Closes https://github.com/astral-sh/ruff/issues/9049.
2023-12-08 12:42:18 -05:00
Charlie Marsh b021ede481
Allow `sys.path` modifications between imports (#9047)
## Summary

It's common to interleave a `sys.path` modification between imports at
the top of a file. This is a frequent cause of `# noqa: E402` false
positives, as seen in the ecosystem checks. This PR modifies E402 to
omit such modifications when determining the "import boundary".

(We could consider linting against `sys.path` modifications, but that
should be a separate rule.)

Closes: https://github.com/astral-sh/ruff/issues/5557.
2023-12-07 13:35:55 -05:00
Dhruv Manilawala cdac90ef68
New AST nodes for f-string elements (#8835)
Rebase of #6365 authored by @davidszotten.

## Summary

This PR updates the AST structure for an f-string elements.

The main **motivation** behind this change is to have a dedicated node
for the string part of an f-string. Previously, the existing
`ExprStringLiteral` node was used for this purpose which isn't exactly
correct. The `ExprStringLiteral` node should include the quotes as well
in the range but the f-string literal element doesn't include the quote
as it's a specific part within an f-string. For example,

```python
f"foo {x}"
# ^^^^
# This is the literal part of an f-string
```

The introduction of `FStringElement` enum is helpful which represent
either the literal part or the expression part of an f-string.

### Rule Updates

This means that there'll be two nodes representing a string depending on
the context. One for a normal string literal while the other is a string
literal within an f-string. The AST checker is updated to accommodate
this change. The rules which work on string literal are updated to check
on the literal part of f-string as well.

#### Notes

1. The `Expr::is_literal_expr` method would check for
`ExprStringLiteral` and return true if so. But now that we don't
represent the literal part of an f-string using that node, this improves
the method's behavior and confines to the actual expression. We do have
the `FStringElement::is_literal` method.
2. We avoid checking if we're in a f-string context before adding to
`string_type_definitions` because the f-string literal is now a
dedicated node and not part of `Expr`.
3. Annotations cannot use f-string so we avoid changing any rules which
work on annotation and checks for `ExprStringLiteral`.

## Test Plan

- All references of `Expr::StringLiteral` were checked to see if any of
the rules require updating to account for the f-string literal element
node.
- New test cases are added for rules which check against the literal
part of an f-string.
- Check the ecosystem results and ensure it remains unchanged.

## Performance

There's a performance penalty in the parser. The reason for this remains
unknown as it seems that the generated assembly code is now different
for the `__reduce154` function. The reduce function body is just popping
the `ParenthesizedExpr` on top of the stack and pushing it with the new
location.

- The size of `FStringElement` enum is the same as `Expr` which is what
it replaces in `FString::format_spec`
- The size of `FStringExpressionElement` is the same as
`ExprFormattedValue` which is what it replaces

I tried reducing the `Expr` enum from 80 bytes to 72 bytes but it hardly
resulted in any performance gain. The difference can be seen here:
- Original profile: https://share.firefox.dev/3Taa7ES
- Profile after boxing some node fields:
https://share.firefox.dev/3GsNXpD

### Backtracking

I tried backtracking the changes to see if any of the isolated change
produced this regression. The problem here is that the overall change is
so small that there's only a single checkpoint where I can backtrack and
that checkpoint results in the same regression. This checkpoint is to
revert using `Expr` to the `FString::format_spec` field. After this
point, the change would revert back to the original implementation.

## Review process

The review process is similar to #7927. The first set of commits update
the node structure, parser, and related AST files. Then, further commits
update the linter and formatter part to account for the AST change.

---------

Co-authored-by: David Szotten <davidszotten@gmail.com>
2023-12-07 10:28:05 -06:00
Charlie Marsh ebc7ac31cb
Avoid invalid combination of `force-sort-within-types` and `lines-between-types` (#9041)
Closes https://github.com/astral-sh/ruff/issues/8792.
2023-12-06 23:56:14 -05:00
Charlie Marsh 946b308197
Ensure that from-style imports are always ordered first in `__future__` (#9039)
Closes https://github.com/astral-sh/ruff/issues/8823.
2023-12-06 22:56:23 -05:00
Charlie Marsh acab5f3cf2
Enable `printf-string-formatting` fix with comments on right-hand side (#9037)
## Summary

This was added in https://github.com/astral-sh/ruff/pull/6364 (as a
follow-on to https://github.com/astral-sh/ruff/pull/6342), but I don't
think it applies in the same way, because we don't _remove_ the
right-hand side when converting from `%`-style formatting to `.format`
calls.

Closes https://github.com/astral-sh/ruff/issues/8107.
2023-12-06 22:43:21 -05:00
Dhruv Manilawala 9361e22fe9
Avoid `ANN2xx` autofix for abstract methods with empty body (#9034)
## Summary

This PR updates the `ANN201`, `ANN202`, `ANN205`, and `ANN206` rules to
not create a fix for the return type when it's an abstract method and
the function body is empty i.e., it only contains either a pass
statement, docstring or an ellipsis literal.

fixes: #9004

## Test Plan

Add the following test cases:
- Abstract method with pass statement
- Abstract method with docstring
- Abstract method with ellipsis literal
- Abstract method with possible return type
2023-12-06 20:47:36 -06:00
Charlie Marsh b918647927
Avoid removing parentheses on ctypes.WinError (#9027)
Re-resolves https://github.com/astral-sh/ruff/issues/6730.
2023-12-06 17:05:34 +00:00
Charlie Marsh 958702ded0
Respect trailing comma in unnecessary-dict-kwargs (#9015)
Closes https://github.com/astral-sh/ruff/issues/9014.
2023-12-05 21:30:29 +00:00
Philipp A b90027d037
[`pylint`] Implement `too-many-positional` (`PLR0917`) (#8995)
## Summary

Adds a rule that bans too many positional (i.e. not keyword-only)
parameters in function definitions.

Fixes https://github.com/astral-sh/ruff/issues/8946

Rule ID code taken from https://github.com/pylint-dev/pylint/pull/9278

## Test Plan
1. fixtures file checking multiple OKs/fails
2. parametrized test file
2023-12-04 18:03:09 +00:00
Charlie Marsh bfae1f1412
Convert over-indentation rule to use number of characters (#8983)
Closes https://github.com/astral-sh/ruff/issues/8978.
2023-12-03 20:45:30 +00:00
Charlie Marsh b358cbf398
Fix start >= end error in over-indentation (#8982)
Closes https://github.com/astral-sh/ruff/issues/8977.
2023-12-03 20:19:43 +00:00
Charlie Marsh 17c8817695
Avoid off-by-one error in stripping noqa following multi-byte char (#8979)
Closes https://github.com/astral-sh/ruff/issues/8976.
2023-12-03 11:01:58 -05:00
Charlie Marsh 1dda669f9a
Avoid syntax error via invalid ur string prefix (#8971)
## Summary

If a string has a Unicode prefix, we can't add the `r` prefix on top of
that -- we need to remove and replace it. (The Unicode prefix is
redundant anyway in Python 3.)

Closes https://github.com/astral-sh/ruff/issues/8967.
2023-12-02 18:37:49 +00:00
Tom Kuson 3fbabfe126
[`flake8-pyi`] Check PEP 695 type aliases for `snake-case-type-alias` and `t-suffixed-type-alias` (#8966)
## Summary

Check PEP 695 type alias definitions for `snake-case-type-alias`
(`PYI042`) and `t-suffixed-type-alias` (`PYI043`)

Related to #8771.

## Test Plan

`cargo test`
2023-12-02 13:26:43 -05:00
Charlie Marsh 20ab14e354
Avoid unnecessary index diagnostics when value is modified (#8970)
Closes https://github.com/astral-sh/ruff/issues/8969.
2023-12-02 18:17:17 +00:00
Charlie Marsh 22d8a989d4
Avoid underflow in `get_model` matching (#8965)
Closes https://github.com/astral-sh/ruff/issues/8962.
2023-12-02 13:56:57 +00:00
Charlie Marsh 277cd80175
Add erroneous for-loop test case for CFG (#8957) 2023-12-01 23:11:42 +00:00
Charlie Marsh 20a40771a5
Consider more wildcards in control flow graph matches (#8956) 2023-12-01 17:58:32 -05:00
qdegraaf 64c2535e28
[`pylint`] Add `add_argument` utility and autofix for `PLW1514` (#8928)
## Summary

- Adds `add_argument` similar to existing `remove_argument` utility to
safely add arguments to functions.
- Adds autofix for `PLW1514` as per specs requested in
https://github.com/astral-sh/ruff/issues/8883 as a test

## Test Plan

Checks on existing fixtures as well as additional test and fixture for
Python 3.9 and lower fix

## Issue Link

Closes: https://github.com/astral-sh/ruff/issues/8883
2023-12-01 18:23:56 +00:00
Charlie Marsh 5510a6131e
Ignore `@overload` and `@override` methods for too-many-arguments checks (#8954)
Closes https://github.com/astral-sh/ruff/issues/8945.
2023-12-01 18:22:53 +00:00
Charlie Marsh e5db72459e
Detect implicit returns in auto-return-types (#8952)
## Summary

Adds detection for branches without a `return` or `raise`, so that we
can properly `Optional` the return types. I'd like to remove this and
replace it with our code graph analysis from the `unreachable.rs` rule,
but it at least fixes the worst offenders.

Closes #8942.
2023-12-01 12:35:01 -05:00
Tom Kuson d66063bb33
[`flake8-pyi`] Check for kwarg and vararg `NoReturn` type annotations (#8948)
## Summary

Triggers `no-return-argument-annotation-in-stub` (`PYI050`) for vararg
and kwarg `NoReturn` type annotations.

Related to #8771.

## Test Plan

`cargo test`
2023-12-01 12:18:52 -05:00
Steve C cb1d3df085
[`pylint`] Implement `unnecessary-dict-index-lookup` (`PLR1733`) (#8036)
## Summary

Add
[R1733](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/unnecessary-dict-index-lookup.html)
and autofix!

See #970 

## Test Plan

`cargo test` and manually
2023-12-01 05:09:50 +00:00
Charlie Marsh 46a174a22e
Use full arguments range for zero-sleep-call (#8936) 2023-12-01 03:09:18 +00:00
Charlie Marsh 912c39ce2a
Add support for `@functools.singledispatch` (#8934)
## Summary

When a function uses `@functools.singledispatch`, we need to treat the
first argument of any implementations as runtime-required.

Closes https://github.com/astral-sh/ruff/issues/6849.
2023-12-01 03:04:58 +00:00
Steve C 70febb1862
[pylint] - add `unnecessary-list-index-lookup` (`PLR1736`) + autofix (#7999)
## Summary

Add
[R1736](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/unnecessary-list-index-lookup.html)
along with the autofix

See #970 

## Test Plan

`cargo test` and manually

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2023-11-30 17:45:12 -06:00
Steve C 4212b41796
[pylint] - implement R0202 and R0203 with autofixes (#8335)
## Summary

Implements
[`no-classmethod-decorator`/`R0202`](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/no-classmethod-decorator.html)
and
[`no-staticmethod-decorator`/`R0203`](https://pylint.readthedocs.io/en/latest/user_guide/messages/refactor/no-staticmethod-decorator.html)
with autofixes.

They're similar enough that all code is reusable for both.

See: #970 

## Test Plan

`cargo test`
2023-11-30 16:18:09 -06:00
Steve C bbad4b4c93
Add autofix for `PYI030` (#7934)
## Summary

Part 2 of implementing the reverted autofix for `PYI030`

Also handles `typing.Union` and `typing_extensions.Literal` etc, uses
the first subscript name it finds for each offensive line.

## Test Plan

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

`cargo test` and manually

---------

Co-authored-by: Zanie Blue <contact@zanie.dev>
2023-11-30 22:16:57 +00:00
Charlie Marsh d674e7946d
Ignore underlines when determining docstring logical lines (#8929) 2023-11-30 14:27:04 -05:00
Charlie Marsh c324cb6202
[`pep8-naming`] Allow Django model loads in `non-lowercase-variable-in-function` (`N806`) (#8917)
## Summary

Allows assignments of the form, e.g., `Attachment =
apps.get_model("zerver", "Attachment")`, for better compatibility with
Django.

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

## Test Plan

`cargo test`
2023-11-29 20:43:40 -05:00
Charlie Marsh 6435e4e4aa
Enable auto-return-type involving `Optional` and `Union` annotations (#8885)
## Summary

Previously, this was only supported for Python 3.10 and later, since we
always use the PEP 604-style unions.
2023-11-28 18:35:55 -08:00
Dhruv Manilawala b28556d739
Update `E402` to work at cell level for notebooks (#8872)
## Summary

This PR updates the `E402` rule to work at cell level for Jupyter
notebooks. This is enabled only in preview to gather feedback.

The implementation basically resets the import boundary flag on the
semantic model when we encounter the first statement in a cell.

Another potential solution is to introduce `E403` rule that is
specifically for notebooks that works at cell level while `E402` will be
disabled for notebooks.

## Test Plan

Add a notebook with imports in multiple cells and verify that the rule
works as expected.

resolves: #8669
2023-11-29 00:32:35 +00:00
Charlie Marsh 5d554edace
Allow booleans in `@override` methods (#8882)
Closes #8867.
2023-11-28 13:42:31 -08:00
Charlie Marsh 412688826c
Avoid filtering out un-representable types in return annotation (#8881)
## Summary

Given `Union[Dict, None]` (in our internal representation), we were
filtering out `Dict` since we treat it as un-representable (i.e., we
can't convert it to an expression), returning just `None` as the type
annotation. We should require that all members of the union are
representable.

Closes https://github.com/astral-sh/ruff/issues/8879.
2023-11-28 21:10:42 +00:00
Joffrey Bluthé 578ddf1bb1
[`isort`] Add support for length-sort settings (#8841)
## Summary

Closes #1567.

Add both `length-sort` and `length-sort-straight` settings for isort.

Here are a few notable points:
- The length is determined using the
[`unicode_width`](https://crates.io/crates/unicode-width) crate, i.e. we
are talking about displayed length (this is explicitly mentioned in the
description of the setting)
- The dots are taken into account in the length to be compatible with
the original isort
- I had to reorder a few fields of the module key struct for it all to
make sense (notably the `force_to_top` field is now the first one)

## Test Plan

I added tests for the following cases:
- Basic tests for length-sort with ASCII characters only
- Tests with non-ASCII characters
- Tests with relative imports
- Tests for length-sort-straight
2023-11-28 06:00:37 +00:00
Charlie Marsh ed14fd9163
[`pydocstyle`] Avoid non-character breaks in `over-indentation` (`D208`) (#8866)
Closes https://github.com/astral-sh/ruff/issues/8844.
2023-11-27 21:47:35 -08:00
Tom Kuson 60eb11fa50
[`refurb`] Implement `redundant-log-base` (`FURB163`) (#8842)
## Summary

Implement
[`simplify-math-log`](https://github.com/dosisod/refurb/blob/master/refurb/checks/math/simplify_log.py)
as `redundant-log-base` (`FURB163`).

Auto-fixes

```python
import math

math.log(2, 2)
```

to

```python
import math

math.log2(2)
```

Related to #1348.

## Test Plan

`cargo test`
2023-11-27 23:57:00 +00:00
Charlie Marsh 9b17724d77
[`pylint`] Extend `self-assigning-variable` to multi-target assignments (#8839)
Closes https://github.com/astral-sh/ruff/issues/8667.
2023-11-25 18:42:19 +00:00
Charlie Marsh 0d4af9d3c6
Allow space-before-colon after end-of-slice (#8838)
Closes https://github.com/astral-sh/ruff/issues/8752.
2023-11-25 18:16:43 +00:00
Chaojie 2590aa30ae
[flake8-bandit] Implement tarfile-unsafe-members (S202) (#8829)
See: https://github.com/astral-sh/ruff/issues/1646.

Bandit origin:
https://github.com/PyCQA/bandit/blob/main/bandit/plugins/tarfile_unsafe_members.py
2023-11-24 17:46:06 +00:00
Samuel Cormier-Iijima 852a8f4a4f
[PIE796] don't report when using ellipses for enum values in stub files (#8825)
## Summary

Just ignores ellipses as enum values inside stub files.

Fixes #8818.
2023-11-24 15:24:57 +00:00
Dhruv Manilawala 8365d2e0fd
Avoid `E703` for last expression in a cell (#8821)
## Summary

This PR updates the `E703` rule to avoid flagging any semicolons if
they're present after the last expression in a notebook cell. These are
intended to hide the cell output.

Part of #8669 

## Test Plan

Add test notebook and update the snapshots.
2023-11-23 07:40:57 -06:00
Dhruv Manilawala 5b726f70f4
Avoid `B015`,`B018` for last expression in a cell (#8815)
## Summary

This PR updates `B015` and `B018` to ignore last top-level expressions
in each cell of a Jupyter Notebook.

Part of #8669

## Test Plan

Add test cases for both rules and update the snapshots.
2023-11-22 15:33:23 +00:00
Dhruv Manilawala 0cb438dd65
Avoid `D100` for Jupyter Notebooks (#8816)
This PR avoids triggering `D100` for Jupyter Notebooks.

Part of #8669
2023-11-22 15:26:25 +00:00
Adrian 948094e691
[`pylint`] Add `allow-dunder-method-names` setting for `bad-dunder-method-name` (`PLW3201`) (#8812)
closes #8732

I noticed that the reference to the setting in the rule docs doesn't
work, but there seem to be something wrong with pylint settings in
general in the docs - the "For related settings, see ...." is also
missing there.
2023-11-21 23:44:23 +00:00
Jelmer Vernooij f1ed0f27c2
isort: Add support for the ``from-first`` setting (#8663)
# Summary

This setting behaves similarly to the ``from_first`` setting in isort
upstream, and sorts "from X import Y" type imports before straight
imports.

Like the other PR I added, happy to refactor if this is better in
another form.

Fixes #8662 

# Test plan

I've added a unit test, and ran this on a large codebase that relies on
this setting in isort to verify it doesn't have unexpected side effects.
2023-11-21 23:36:15 +00:00
Dhruv Manilawala 5ce6299e22
Avoid `PERF101` if there's an append in loop body (#8809)
## Summary

Avoid `PERF101` if there's an append in loop body

## Test Plan

Add new test cases for this pattern.

fixes: #8746
2023-11-21 15:35:42 -06:00
Charlie Marsh 5373759f62
Respect dictionary unpacking in `NamedTuple` assignments (#8810)
Closes https://github.com/astral-sh/ruff/issues/8803.
2023-11-21 19:30:48 +00:00
maltevesper 6fb6478887
[`flake8-simplify`] Omit select context managers from `SIM117` (#8801)
Semantically it makes sense to put certain contextmanagers into separate
with statements. Currently asyncio.timeout and its relatives in anyio
and trio are exempt from SIM117.

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

## Summary

Exempt asyncio.timeout and related functions from SIM117 (Collapse with
statements where possible).
See https://github.com/astral-sh/ruff/issues/8606 for more.

## Test Plan

Extended the insta tests.
2023-11-21 11:53:42 +00:00
Ezra Shaw bf729e7a77
fix: mark `__main__` as first-party import (#8805)
## Summary

Fixes #8750. `import __main__` is now considered a first-party import,
and is grouped accordingly by the linter and formatter.

## Test Plan

Added a test based off code supplied in the linked issue.
2023-11-21 11:52:28 +00:00
Iipin e306359411
Mark `pydantic_settings.BaseSettings` as having default copy semantics (#8793)
## Summary

In 2.0, Pydantic has moved the `BaseSettings` class to a separate
package called `pydantic-settings`
(https://docs.pydantic.dev/2.4/migration/#basesettings-has-moved-to-pydantic-settings),
which results in a false positive on `RUF012` (`mutable-class-default`).
A simple fix for that would be adding `pydantic_settings.BaseSettings`
base to the `has_default_copy_semantics` helper, which I've done in this
PR.

Related issue: #5308

## Test Plan

`cargo test`
2023-11-20 19:29:48 +00:00
Charlie Marsh 10d937c1a1
[`pep8-naming`] Avoid `N806` errors for type alias statements (#8785)
Allow, e.g.:

```python
def func():
    type MyInt = int
```

(We already allowed `MyInt: TypeAlias = int`.)

Closes https://github.com/astral-sh/ruff/issues/8773.
2023-11-20 12:28:52 +00:00
Chaojie 653e51ae97
[`flake8-bandit`] Implement `django-raw-sql` (`S611`) (#8651)
See: https://github.com/astral-sh/ruff/issues/1646.
2023-11-20 12:21:12 +00:00
Charlie Marsh 71573fd35c
Avoid repeated triggers in nested `tryceratops` diagnostics (#8772)
Closes https://github.com/astral-sh/ruff/issues/8770.
2023-11-19 23:43:59 +00:00
Charlie Marsh 95e2f632e6
Retain extra ellipses in protocols and abstract methods (#8769)
## Summary

It turns out that some type checkers rely on the presence of ellipses in
`Protocol` interfaces and abstract methods, in order to differentiate
between default implementations and stubs. This PR modifies the preview
behavior of `PIE790` to avoid flagging "unnecessary" ellipses in such
cases.

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

## Test Plan

`cargo test`
2023-11-19 10:05:29 -05:00
Charlie Marsh 00a015ca24
Respect local subclasses in `flake8-type-checking` (#8768)
If you define a subclass of `pydantic.BaseModel`, and then a subclass of
_that_ class in the same file, we'll now correctly treat it as
runtime-evaluated.

Closes https://github.com/astral-sh/ruff/issues/7893.
2023-11-19 09:49:25 -05:00
Charlie Marsh 94178a0320
[`flake8-pyi`] Respect local enum subclasses in `simple-defaults` (`PYI052`) (#8767)
We should reuse this approach in other rules, but this is a good start.

Closes https://github.com/astral-sh/ruff/issues/8764.
2023-11-19 09:31:59 -05:00
Alex Bieg 9279114521
Add Implementation for Pylint E1132: Repeated Keyword (#8706)
<!--
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

Adds the Pylint rule E1132 to check for repeated keyword arguments in a
function call.

## Test Plan

Tested via the included unit tests and manual spot checking.
2023-11-19 00:26:24 +00:00
Charlie Marsh 8b86e8004d
Extend `dict-get-with-none-default` (`SIM910`) to non-literals (#8762)
## Summary

Ensures that we can catch cases like:

```python
ages = {"Tom": 23, "Maria": 23, "Dog": 11}
age = ages.get("Cat", None)
```

Previously, the rule was somewhat useless, as it only checked for
literal accesses.

Closes https://github.com/astral-sh/ruff/issues/8760.
2023-11-19 00:21:53 +00:00
Tuomas Siipola 2faac1e7a8
[`refurb`] Implement `math-constant` (`FURB152`) (#8727)
## Summary

Implements
[FURB152](https://github.com/dosisod/refurb/blob/master/docs/checks.md#furb152-use-math-constant)
that checks for literals that are similar to constants in `math` module,
for example:

```python
A = 3.141592 * r ** 2
```

Use instead:
```python
A = math.pi * r ** 2
```

Related to #1348.
2023-11-17 17:37:44 +00:00
Zanie Blue bd99175fea
Update `D208` to preserve indentation offsets when fixing overindented lines (#8699)
Closes https://github.com/astral-sh/ruff/issues/8695

We track the smallest offset seen for overindented lines then only
reduce the indentation of the lines that far to preserve indentation in
other lines. This rule's behavior now matches our formatter, which is
nice.

We may want to gate this with preview.
2023-11-16 22:11:07 -06: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
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
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
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 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
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
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
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 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
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 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
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
Dhruv Manilawala d5606b7705
Consider the new f-string tokens for `flake8-commas` (#8582)
## Summary

This fixes the bug where the `flake8-commas` rules weren't taking the
new f-string tokens into account.

## Test Plan

Add new test cases around f-strings for all of `flake8-commas`'s rules.

fixes: #8556
2023-11-10 09:49:14 +05:30
Adrian 4ebd0bd31e
Support local and dynamic class- and static-method decorators (#8592)
## Summary

This brings ruff's behavior in line with what `pep8-naming` already does
and thus closes #8397.

I had initially implemented this to look at the last segment of a dotted
path only when the entry in the `*-decorators` setting started with a
`.`, but in the end I thought it's better to remain consistent w/
`pep8-naming` and doing a match against the last segment of the
decorator name in any case.

If you prefer to diverge from this in favor of less ambiguity in the
configuration let me know and I'll change it so you would need to put
e.g. `.expression` in the `classmethod-decorators` list.

## Test Plan

Tested against the file in the issue linked below, plus the new testcase
added in this PR.
2023-11-10 02:04:25 +00:00
Zanie Blue 565ddebb15
Improve detection of `TYPE_CHECKING` blocks imported from `typing_extensions` or `_typeshed` (#8429)
~Improves detection of types imported from `typing_extensions`. Removes
the hard-coded list of supported types in `typing_extensions`; instead
assuming all types could be imported from `typing`, `_typeshed`, or
`typing_extensions`.~

~The typing extensions package appears to re-export types even if they
do not need modification.~


Adds detection of `if typing_extensions.TYPE_CHECKING` blocks. Avoids
inserting a new `if TYPE_CHECKING` block and `from typing import
TYPE_CHECKING` if `typing_extensions.TYPE_CHECKING` is used (closes
https://github.com/astral-sh/ruff/issues/8427)

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-11-09 12:21:03 -06:00
Dhruv Manilawala 9d167a1f5c
Slice source code instead of generating it for `EM` fixes (#7746)
## Summary

This PR fixes the bug where the generated fix for `EM*` rules would
replace a
triple-quoted (f-)string with a single-quoted (f-)string. This changes
the
semantic of the string in case it contains a single-quoted string
literal. This
is especially evident with f-strings where the expression could contain
another
string within it. For example,

```python
f"""normal {"another"} normal"""
```

## Test Plan

Add test case for triple-quoted string and update the snapshots.

fixes: #6988
fixes: #7736
2023-11-09 05:22:15 +00:00
Charlie Marsh 9e184a9067
Revert "Avoid inserting trailing commas within f-strings" (#8576)
Reverts astral-sh/ruff#8574. This caused a bunch of ecosystem changes --
needs more work.
2023-11-09 05:02:04 +00:00
Charlie Marsh f499f0ca60
Avoid inserting trailing commas within f-strings (#8574)
Closes https://github.com/astral-sh/ruff/issues/8556.
2023-11-08 23:25:23 -05:00
Charlie Marsh 722687ad72
Detect runtime-evaluated base classes defined in the current file (#8572)
Closes https://github.com/astral-sh/ruff/issues/8250.

Closes https://github.com/astral-sh/ruff/issues/5486.
2023-11-08 22:38:06 -05:00
Dhruv Manilawala 4760af3dcb
Avoid `FURB113` autofix if comments are present (#8494)
This PR avoids creating the fix for `FURB113` if there are comments in
between the `append` calls.

fixes: #8105
2023-11-09 03:10:11 +00:00
Charlie Marsh 71e93a9fa4
Only flag flake8-trio rule when trio is present (#8550)
## Summary

Hoping to avoid some false positives by narrowing the scope of
https://github.com/astral-sh/ruff/pull/8534.
2023-11-07 22:27:58 +00:00
Kar Petrosyan e2c7b1ece6
[TRIO] Add TRIO109 rule (#8534)
## Summary

Adds TRIO109 from the [flake8-trio
plugin](https://github.com/Zac-HD/flake8-trio).
Relates to: https://github.com/astral-sh/ruff/issues/8451
2023-11-07 17:13:01 -05:00
Kar Petrosyan 0126f74c29
Add TRIO110 rule (#8537)
## Summary

Adds TRIO110 from the [flake8-trio
plugin](https://github.com/Zac-HD/flake8-trio).
Relates to: https://github.com/astral-sh/ruff/issues/8451
2023-11-07 21:27:19 +00:00
Chaojie fce9f63418
[`flake8-bandit`] Implement `mako-templates` (`S702`) (#8533)
See: https://github.com/astral-sh/ruff/issues/1646.
2023-11-07 20:58:43 +00:00
qdegraaf 9a8400a287
Avoid raising `TRIO115` violations for `trio.sleep(...)` calls with non-number values (#8532)
## Summary

Fixes bug in `TRIO115` where it would not `return` for values that were
not a `NumberLiteral` so
```python
x = "bla"
trio.sleep(x)
```
would set off a false positive

## Test Plan

Added test case to fixture
2023-11-06 16:49:12 -06:00
Charlie Marsh 37301375c8
Make `SIM118` fix as safe when the expression is a known dictionary (#8525)
## Summary

Given `key in obj.keys()`, `obj` _could_ be a dictionary, or it could be
another type that defines
a `.keys()` method. In the latter case, removing the `.keys()` attribute
could lead to a runtime error.

Previously, we marked all `SIM118` fixes as unsafe for this reason;
however, in preview, we now mark them as safe if we can
infer that the expression is a dictionary.

## Test Plan

Added a preview fixture.
2023-11-06 21:06:33 +00:00
Charlie Marsh eab8ca4d7e
Add dedicated method to find typed binding (#8517)
## Summary

We have this pattern in a bunch of places, where we find the _only_
binding to a name (and return `None`) if it's bound multiple times. This
PR DRYs it up into a method on `SemanticModel`.
2023-11-06 11:25:32 -05:00
Shantanu 2d5ce4532a
Flag all comparisons against builtin types in E721 (#8491)
See #8483. Generalised fix on top of #8485

Based on the output of `print("\n".join(k for k, v in
builtins.__dict__.items() if isinstance(v, type)))`
2023-11-05 21:28:47 -05:00
qdegraaf f3e2d12609
[`TRIO`] Add `TRIO115`: TrioZeroSleepCall (#8486)
## Summary

Adds `TRIO115` from the [flake8-trio
plugin](https://github.com/Zac-HD/flake8-trio).

## Test Plan

Added a new fixture, based on [the one from upstream
plugin](https://github.com/Zac-HD/flake8-trio/blob/main/tests/eval_files/trio115.py)

## Issue link

Relates to: https://github.com/astral-sh/ruff/issues/8451
2023-11-06 01:19:46 +00:00
Tom Kuson de2d7e97b1
[`refurb`] Implement `type-none-comparison` (`FURB169`) (#8487)
## Summary

Implement
[`no-is-type-none`](https://github.com/dosisod/refurb/blob/master/refurb/checks/builtin/no_is_type_none.py)
as `type-none-comparison` (`FURB169`).

Auto-fixes comparisons that use `type` to compare the type of an object
to `type(None)` to a `None` identity check. For example,

```python
type(foo) is type(None)
```

becomes

```python
foo is None
```

Related to #1348.

## Test Plan

`cargo test`
2023-11-06 00:56:20 +00:00
Charlie Marsh 8c146bbf11
Allow collapsed-ellipsis bodies in other statements (#8499)
## Summary

Black and Ruff's preview styles now collapse statements like:

```python
from contextlib import nullcontext

ctx = nullcontext()
with ctx: ...
```

Historically, we made an exception here for classes
(https://github.com/astral-sh/ruff/pull/2837). This PR extends it to
other statement kinds for consistency with the formatter.

Closes https://github.com/astral-sh/ruff/issues/8496.
2023-11-05 19:42:34 -05:00
qdegraaf 4170ef0508
[`TRIO`] Add `TRIO105`: `SyncTrioCall` (#8490)
## Summary

Adds `TRIO105` from the [flake8-trio
plugin](https://github.com/Zac-HD/flake8-trio). The `MethodName` logic
mirrors that of `TRIO100` to stay consistent within the plugin.

It is at 95% parity with the exception of upstream also checking for a
slightly more complex scenario where a call to `start()` on a
`trio.Nursery` context should also be immediately awaited. Upstream
plugin appears to just check for anything named `nursery` judging from
[the relevant issue](https://github.com/Zac-HD/flake8-trio/issues/56).

Unsure if we want to do so something similar or, alternatively, if there
is some capability in ruff to check for calls made on this context some
other way

## Test Plan

Added a new fixture, based on [the one from upstream
plugin](https://github.com/Zac-HD/flake8-trio/blob/main/tests/eval_files/trio105.py)

## Issue link

Refers: https://github.com/astral-sh/ruff/issues/8451
2023-11-05 19:56:10 +00:00
Tom Kuson 8c0d65c98e
Fix `F841` false negative on assignment to multiple variables (#8489)
## Summary

Closes #8441 behind preview feature flag.

## Test Plan

`cargo test`
2023-11-05 12:01:10 -05:00
Dhruv Manilawala b3c2935fa5
Avoid `D301` autofix for `u` prefixed strings (#8495)
This PR avoids creating the fix for `D301` if the string is prefixed
with `u` i.e., it's a unicode string. The reason being that `u` and `r`
cannot be used together as it's a syntax error.

Refer:
https://github.com/astral-sh/ruff/issues/8402#issuecomment-1788783287
2023-11-05 09:45:49 -05:00
qdegraaf 75c9be099f
[`E721`] Flag comparisons to `memoryview` (#8485)
## Summary

Adds `memoryview` to the list of typeclasses that `fn is_type()` uses
for type comparison checks so that it raises a violation if `is`, `is
not` or `isinstance()` are not used.

## Test Plan

Added examples to existing fixture

## Issue Link

Closes: https://github.com/astral-sh/ruff/issues/8483
2023-11-04 13:41:58 +00:00
Hugo van Kemenade 65effc6666
Add pyupgrade `UP041` to replace `TimeoutError` aliases (#8476)
## Summary

Add UP041 to replace `TimeoutError` aliases:

* Python 3.10+: `socket.timeout`
* Python 3.11+: `asyncio.TimeoutError`

Re:

* https://github.com/asottile/pyupgrade#timeouterror-aliases
*
https://docs.python.org/3/library/asyncio-exceptions.html#asyncio.TimeoutError
* https://docs.python.org/3/library/socket.html#socket.timeout

Based on `os_error_alias.rs`.

## Test Plan

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

By running:

```
cargo clippy --workspace --all-targets --all-features -- -D warnings  # Rust linting
RUFF_UPDATE_SCHEMA=1 cargo test  # Rust testing and updating ruff.schema.json
pre-commit run --all-files --show-diff-on-failure  # Rust and Python formatting, Markdown and Python linting, etc.
cargo insta review
```

And also running with different `--target-version` values:

```sh
cargo run -p ruff_cli -- check crates/ruff_linter/resources/test/fixtures/pyupgrade/UP041.py --no-cache --select UP041 --target-version py37 --diff
cargo run -p ruff_cli -- check crates/ruff_linter/resources/test/fixtures/pyupgrade/UP041.py --no-cache --select UP041 --target-version py310 --diff
cargo run -p ruff_cli -- check crates/ruff_linter/resources/test/fixtures/pyupgrade/UP041.py --no-cache --select UP041 --target-version py311 --diff
```
2023-11-03 17:24:47 +00:00
T-256 4982694b54
`D300`: prevent autofix when both triples are in body (#8462)
## Summary
Addresses
https://github.com/astral-sh/ruff/issues/8402#issuecomment-1788782750

## Test Plan

Added associated test
2023-11-03 12:49:50 -04:00
Christopher Covington 9f30ccc1f4
Autoformat confusable units (#4430)
I've seen errors crop up from using the different micro and mu
characters. Follow matching recommendations on which character to prefer
for micro, ohm, and angstrom. References:
* Section 22.2 Letterlike Symbols, subsection Unit Symbols, page 877 of
[The Unicode Standard, Version 15.0

](https://www.unicode.org/versions/Unicode15.0.0/UnicodeStandard-15.0.pdf)
* Section 2.5 Duplicated Characters of [Unicode Technical Report
25](https://www.unicode.org/reports/tr25/)
* [SI
brochure](https://www.bipm.org/documents/20126/41483022/SI-Brochure-9-EN.pdf)
*
https://github.com/unicode-org/icu/blob/main/icu4c/source/data/unidata/confusables.txt
2023-11-03 04:58:43 +00:00
Mateusz Sokół d04d964ace
Implement NumPy 2.0 migration rule (#7702)
## Summary

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

Hi! Currently NumPy Python API is undergoing a cleanup process that will
be delivered in NumPy 2.0 (release is planned for the end of the year).
Most changes are rather simple (renaming, removing or moving a member of
the main namespace to a new place), and they could be flagged/fixed by
an additional ruff rule for numpy (e.g. changing occurrences of
`np.float_` to `np.float64`).

Would you accept such rule?  

I named it `NPY201` in the existing group, so people will receive a
heads-up for changes arriving in 2.0 before actually migrating to it.

~~This is still a draft PR.~~ I'm not an expert in rust so if any part
of code can be done better please share!

NumPy 2.0 migration guide:
https://numpy.org/devdocs/numpy_2_0_migration_guide.html
NEP 52: https://numpy.org/neps/nep-0052-python-api-cleanup.html
NumPy cleanup tracking issue:
https://github.com/numpy/numpy/issues/23999


## Test Plan

A unit test is provided that checks all rule's fix cases.
2023-11-03 03:47:01 +00:00
Kar Petrosyan 2ff1afb15c
Add initial flake8-trio rule (#8439)
## Summary

This pull request adds
[flake8-trio](https://github.com/Zac-HD/flake8-trio) support to ruff,
which is a very useful plugin for trio users to avoid very common
mistakes.

Part of https://github.com/astral-sh/ruff/issues/8451.

## Test Plan

Traditional rule testing, as [described in the
documentation](https://docs.astral.sh/ruff/contributing/#rule-testing-fixtures-and-snapshots).
2023-11-03 01:05:12 +00:00
Zanie Blue a8a72306f0
Fix bug where `PLE1307` was raised when formatting `%c` with characters (#8407)
Closes https://github.com/astral-sh/ruff/issues/8406

---------

Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
2023-11-02 04:36:52 +00:00
Charlie Marsh c8122563a6
Avoid triggering `NamedTuple` rewrite with starred annotation (#8434)
See:
https://github.com/astral-sh/ruff/issues/8402#issuecomment-1788787357
2023-11-02 03:30:52 +00:00
Charlie Marsh f8f507cfc8
Avoid triggering single-element test for starred expressions (#8433)
See:
https://github.com/astral-sh/ruff/issues/8402#issuecomment-1788784721
2023-11-02 03:29:37 +00:00
Charlie Marsh 23ed4e9616
Avoid un-setting bracket flag in logical lines (#8380)
## Summary

By using `set`, we were setting the bracket flag to `false` if another
operator was visited.

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

## Test Plan

`cargo test`
2023-10-31 10:30:15 -04:00
Charlie Marsh c674db6e51
Fix invalid E231 error with f-strings (#8369)
## Summary

We were considering the `{` within an f-string to be a left brace, which
caused the "space-after-colon" rule to trigger incorrectly.

Closes https://github.com/astral-sh/ruff/issues/8299.
2023-10-30 19:38:13 -04:00
Andrew Shannon Brown 9b89bf7d8a
Implement pylint import-outside-toplevel rule (C0415) (#5180)
## Summary

Implements pylint C0415 (import-outside-toplevel) — imports should be at
the top level of a file.

The great debate I had on this implementation is whether "top-level" is
one word or two (`toplevel` or `top_level`). I opted for 2 because that
seemed to be how it is used in the codebase but the rule string itself
uses one-word "toplevel." 🤷 I'd be happy to change it as desired.

I suppose this could be auto-fixed by moving the import to the
top-level, but it seems likely that the author's intent was to actually
import this dynamically, so I view the main point of this rule is to
force some sort of explanation, and auto-fixing might be annoying.

For reference, this is what "pylint" reports:
```
> pylint crates/ruff/resources/test/fixtures/pylint/import_outside_top_level.py
************* Module import_outside_top_level
...
crates/ruff/resources/test/fixtures/pylint/import_outside_top_level.py:4:4: C0415: Import outside toplevel (string) (import-outside-toplevel)
```

ruff would now report:

```
import_outside_top_level.py:4:5: PLC0415 `import` should be used only at the top level of a file
  |
3 | def import_outside_top_level():
4 |     import string # [import-outside-toplevel]
  |     ^^^^^^^^^^^^^ PLC0415
  |
```

Contributes to https://github.com/astral-sh/ruff/issues/970.

## Test Plan

Snapshot test.
2023-10-29 16:40:26 +00:00
Harutaka Kawamura 44e21cfada
[pylint] Implement `useless-with-lock` (#8321) 2023-10-29 16:24:52 +00:00
Mathieu Kniewallner 317b6e8682
Use `tool.ruff.lint` in more places (#8317)
## Summary

As a follow-up of https://github.com/astral-sh/ruff/pull/7732, use
`tool.ruff.lint` in more places in documentations, tests and internal
usages.
2023-10-28 18:39:38 -05:00
Tom Kuson 10a50bf1e2
[`refurb`] Implement `isinstance-type-none` (`FURB168`) (#8308)
## Summary

Implement
[`no-isinstance-type-none`](https://github.com/dosisod/refurb/blob/master/refurb/checks/builtin/no_isinstance_type_none.py)
as `isinstance-type-none` (`FURB168`).

Auto-fixes calls to `isinstance` to check if an object is `None` to a
`None` identity check. For example,

```python
isinstance(foo, type(None))
```

becomes

```python
foo is None
```

Related to #1348.

## Test Plan

`cargo test`

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-10-28 22:37:02 +00:00
Harutaka Kawamura a151e50ad3
[pylint] Implement bad-open-mode (W1501) (#8294) 2023-10-28 22:30:31 +00:00
Lukas Burgholzer 81a2e74fe2
Extend `bad-dunder-method-name` to permit `__index__` (#8300)
## Summary

Fixes #8282

## Test Plan

`cargo test`
2023-10-28 07:15:30 -04:00
Charlie Marsh be3307e9a6
Make `unnecessary-paren-on-raise-exception` an unsafe edit (#8231)
## Summary

This rule is now unsafe if we can't verify that the `obj` in `raise
obj()` is a class or builtin. (If we verify that it's a function, we
don't raise at all, as before.)

See the documentation change for motivation behind the unsafe edit.

Closes https://github.com/astral-sh/ruff/issues/8228.
2023-10-26 11:33:54 -04:00
Spencer Brown 8304c41714
[`pylint`] Add buffer methods to `bad-dunder-method-name` (`PLW3201`) exclusions (#8190)
## Summary

Python 3.12 added the `__buffer__()`/`__release_buffer_()` special
methods, which are incorrectly flagged as invalid dunder methods by
`PLW3201`.

## Test Plan

Added definitions to the test suite, and confirmed they failed without
the fix and are ignored after the fix was done.
2023-10-25 00:03:44 -05:00
Zanie Blue 6f31e9c00e
Match rule prefixes from `external` codes setting in `unused-noqa` (#8177)
Supersedes https://github.com/astral-sh/ruff/pull/8176
Closes https://github.com/astral-sh/ruff/pull/8174

## Test plan

Old snapshot contains the new / unmatched `V` code
New snapshot contains no `V` prefixed codes
2023-10-24 22:28:35 +00:00
Harutaka Kawamura b9bff6f5d1
[`SIM112`] Ignore `https_proxy`, `http_proxy`, and `no_proxy` (#8140)
<!--
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? -->

Close #8123 

## Test Plan

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

New test cases

---------

Signed-off-by: harupy <hkawamura0130@gmail.com>
2023-10-23 08:48:36 -05:00
Charlie Marsh 7586091437
Include `backports.strenum` in `deprecated-imports` (#8113)
Closes https://github.com/astral-sh/ruff/issues/8102.
2023-10-21 23:13:03 +00:00
Charlie Marsh 4e07a65c15
Detect `sys.version_info` slices in `outdated-version-block` (#8112)
## Summary

Given `sys.version_info[:2] >= (3,0)`, we should treat this equivalently
to `sys.version_info >= (3,0)`.

Closes https://github.com/astral-sh/ruff/issues/8095.
2023-10-21 23:08:17 +00:00