Commit graph

1081 commits

Author SHA1 Message Date
cake-monotone
96dd1b1587
Consider __new__ methods as special function type for enforcing class method or static method rules (#13305)
## Summary

`__new__` methods are technically static methods, with `cls` as their
first argument. However, Ruff currently classifies them as classmethod,
which causes two issues:

- It conveys incorrect information, leading to confusion. For example,
in cases like ARG003, `__new__` is explicitly treated as a classmethod.
- Future rules that should apply to staticmethod may not be applied
correctly due to this misclassification.

Motivated by this, the current PR makes the following adjustments:

1. Introduces `FunctionType::NewMethod` as an enum variant, since, for
the purposes of lint rules, `__new__` sometimes behaves like a static
method and other times like a class method. This is an internal change.

2. The following rule behaviors and messages are totally unchanged:
- [too-many-arguments
(PLR0913)](https://docs.astral.sh/ruff/rules/too-many-arguments/#too-many-arguments-plr0913)
- [too-many-positional-arguments
(PLR0917)](https://docs.astral.sh/ruff/rules/too-many-positional-arguments/#too-many-positional-arguments-plr0917)
3. The following rule behaviors are unchanged, but the messages have
been changed for correctness to use "`__new__` method" instead of "class
method":
- [self-or-cls-assignment
(PLW0642)](https://docs.astral.sh/ruff/rules/self-or-cls-assignment/#self-or-cls-assignment-plw0642)
4. The following rules are changed _unconditionally_ (not gated behind
preview) because their current behavior is an honest bug: it just isn't
true that `__new__` is a class method, and it _is_ true that `__new__`
is a static method:
- [unused-class-method-argument
(ARG003)](https://docs.astral.sh/ruff/rules/unused-class-method-argument/#unused-class-method-argument-arg003)
no longer applies to `__new__`
- [unused-static-method-argument
(ARG004)](https://docs.astral.sh/ruff/rules/unused-static-method-argument/#unused-static-method-argument-arg004)
now applies to `__new__`
5. The only changes which differ based on `preview` are the following:
- [invalid-first-argument-name-for-class-method
(N804)](https://docs.astral.sh/ruff/rules/invalid-first-argument-name-for-class-method/#invalid-first-argument-name-for-class-method-n804):
This is _skipped_ when `preview` is _enabled_. When `preview` is
_disabled_, the rule is the same but the _message_ has been modified to
say "`__new__` method" instead of "class method".
- [bad-staticmethod-argument
(PLW0211)](https://docs.astral.sh/ruff/rules/bad-staticmethod-argument/#bad-staticmethod-argument-plw0211):
When `preview` is enabled, this now applies to `__new__`.

Closes #13154

---------

Co-authored-by: dylwil3 <dylwil3@gmail.com>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-02-16 14:12:25 -06:00
Brent Westbrook
3a0d45c85b
[flake8-debugger] Also flag sys.breakpointhook and sys.__breakpointhook__ (T100) (#16191)
## Summary

Fixes #16189.

Only `sys.breakpointhook` is flagged by the upstream linter:

007a745c86/pylint/checkers/stdlib.py (L38)

but I think it makes sense to flag
[`__breakpointhook__`](https://docs.python.org/3/library/sys.html#sys.__breakpointhook__)
too, as suggested in the issue because it
> contain[s] the original value of breakpointhook [...] in case [it
happens] to get replaced with broken or alternative objects.

## Test Plan

New T100 test cases
2025-02-16 14:50:16 -05:00
Ayush Baweja
df45a9db64
[flake8-comprehensions]: Handle trailing comma in C403 fix (#16110)
## Summary

Resolves [#16099 ](https://github.com/astral-sh/ruff/issues/16099) based
on [#15929 ](https://github.com/astral-sh/ruff/pull/15929)

## Test Plan

Added test case `s = set([x for x in range(3)],)` and updated snapshot.

---------

Co-authored-by: dylwil3 <dylwil3@gmail.com>
2025-02-15 11:45:41 -06:00
InSync
3c69b685ee
[ruff] Implicit class variable in dataclass (RUF045) (#14349)
## Summary

Implement lint rule to flag un-annotated variable assignments in dataclass definitions.

Resolves #12877.

---------

Co-authored-by: dylwil3 <dylwil3@gmail.com>
2025-02-15 09:08:13 -06:00
Vlad Nedelcu
219712860c
[refurb] Check for subclasses includes subscript expressions (FURB189) (#16155)
## Summary

Added checks for subscript expressions on builtin classes as in FURB189.
The object is changed to use the collections objects and the types from
the subscript are kept.

Resolves #16130 

> Note: Added some comments in the code explaining why
## Test Plan


- Added a subscript dict and list class to the test file.
- Tested locally to check that the symbols are changed and the types are
kept.
- No modifications changed on optional `str` values.
2025-02-14 20:21:26 +01:00
InSync
3d0a58eb60
[pyupgrade] Unwrap unary expressions correctly (UP018) (#15919)
## Summary

Resolves #15859.

The rule now adds parentheses if the original call wraps an unary
expression and is:

* The left-hand side of a binary expression where the operator is `**`.
* The caller of a call expression.
* The subscripted of a subscript expression.
* The object of an attribute access.

The fix will also be marked as unsafe if there are any comments in its
range.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2025-02-14 08:42:00 +01:00
Vlad Nedelcu
cb8b23d609
[flake8-pyi] Avoid flagging custom-typevar-for-self on metaclass methods (PYI019) (#16141)
Some checks are pending
CI / cargo build (release) (push) Waiting to run
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
2025-02-13 18:44:11 +00:00
InSync
7d2e40be2d
[pylint] Do not offer fix for raw strings (PLE251) (#16132)
Some checks are pending
CI / cargo fmt (push) Waiting to run
CI / cargo build (release) (push) Waiting to run
CI / Determine changes (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
## Summary

Resolves #13294, follow-up to #13882.

At #13882, it was concluded that a fix should not be offered for raw
strings. This change implements that. The five rules in question are now
no longer always fixable.

## Test Plan

`cargo nextest run` and `cargo insta test`.

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
2025-02-13 08:36:11 +00:00
Alex Waygood
c31352f52b
[ruff] Skip RUF001 diagnostics when visiting string type definitions (#16122) 2025-02-12 16:27:38 +00:00
Vasco Schiavo
ae1b381c06
[pylint] Correct ordering of arguments in fix for if-stmt-min-max (PLR1730) (#16080)
Some checks are pending
CI / cargo test (linux) (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
The PR addresses the issue #16040 .

---

The logic used into the rule is the following:

Suppose to have an expression of the form 

```python
if a cmp b:
    c = d
```
where `a`,` b`, `c` and `d` are Python obj and `cmp` one of `<`, `>`,
`<=`, `>=`.

Then:

- `if a=c and b=d`
    
    - if `<=` fix with `a = max(b, a)`
    - if `>=`  fix with `a = min(b, a)`
    - if `>` fix with `a = min(a, b)`
    - if `<` fix with `a = max(a, b)`

- `if a=d and b=c`

    - if `<=` fix with `b = min(a, b)`
    - if `>=`  fix with `b = max(a, b)`
    - if `>` fix with `b = max(b, a)`
    - if `<` fix with `b = min(b, a)`
 
- do nothing, i.e., we cannot fix this case.

---

In total we have 8 different and possible cases.

```

| Case  | Expression       | Fix           |
|-------|------------------|---------------|
| 1     | if a >= b: a = b | a = min(b, a) |
| 2     | if a <= b: a = b | a = max(b, a) |
| 3     | if a <= b: b = a | b = min(a, b) |
| 4     | if a >= b: b = a | b = max(a, b) |
| 5     | if a > b: a = b  | a = min(a, b) |
| 6     | if a < b: a = b  | a = max(a, b) |
| 7     | if a < b: b = a  | b = min(b, a) |
| 8     | if a > b: b = a  | b = max(b, a) |
```

I added them in the tests. 

Please double-check that I didn't make any mistakes. It's quite easy to
mix up > and <.

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
2025-02-12 10:27:46 +01:00
Wei Lee
86c5cba472
[airflow] Fix ImportPathMoved / ProviderName misuse (AIR303) (#16013)
## Summary


* fix ImportPathMoved / ProviderName misuse
* oncrete names, such as `["airflow", "config_templates",
"default_celery", "DEFAULT_CELERY_CONFIG"]`, should use `ProviderName`.
In contrast, module paths like `"airflow", "operators", "weekday", ...`
should use `ImportPathMoved`. Misuse may lead to incorrect detection.

## Test Plan

update test fixture
2025-02-12 12:34:16 +05:30
Brent Westbrook
7b487d853a
[pydocstyle] Handle arguments with the same names as sections (D417) (#16011)
## Summary

Fixes #16007. The logic from the last fix for this (#9427) was
sufficient, it just wasn't being applied because `Attributes` sections
aren't expected to have nested sections. I just deleted the outer
conditional, which should hopefully fix this for all section types.

## Test Plan

New regression test, plus the existing D417 tests.
2025-02-11 12:05:29 -05:00
InSync
7fbd89cb39
[pyupgrade] Handle micro version numbers correctly (UP036) (#16091)
## Summary

Resolves #16082.

`UP036` will now also take into consideration whether or not a micro
version number is set:

* If a third element doesn't exist, the existing logic is preserved.
* If it exists but is not an integer literal, the check will not be
reported.
* If it is an integer literal but doesn't fit into a `u8`, the check
will be reported as invalid.
* Otherwise, the compared version is determined to always be less than
the target version when:
	* The target's minor version is smaller than that of the comparator, or
* The operator is `<`, the micro version is 0, and the two minor
versions compare equal.

As this is considered a bugfix, it is not preview-gated.

## Test Plan

`cargo nextest run` and `cargo insta test`.

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
2025-02-11 07:40:56 +00:00
Dylan
f30fac6326
[ruff] Skip singleton starred expressions for incorrectly-parenthesized-tuple-in-subscript (RUF031) (#16083)
Some checks are pending
CI / cargo test (linux) (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
The index in subscript access like `d[*y]` will not be linted or
autofixed with parentheses, even when
`lint.ruff.parenthesize-tuple-in-subscript = true`.

Closes #16077
2025-02-10 11:30:07 -06:00
ABDULRAHMAN ALRAHMA
d2f661f795
RUF009 should behave similar to B008 and ignore attributes with immutable types (#16048)
This PR resolved #15772

Before PR:
```
def _(
    this_is_fine: int = f(),           # No error
    this_is_not: list[int] = f()       # B008: Do not perform function call `f` in argument defaults
): ...


@dataclass
class _:
    this_is_not_fine: list[int] = f()  # RUF009: Do not perform function call `f` in dataclass defaults
    this_is_also_not: int = f()        # RUF009: Do not perform function call `f` in dataclass defaults
```

After PR:
```
def _(
    this_is_fine: int = f(),           # No error
    this_is_not: list[int] = f()       # B008: Do not perform function call `f` in argument defaults
): ...


@dataclass
class _:
    this_is_not_fine: list[int] = f()  # RUF009: Do not perform function call `f` in dataclass defaults
    this_is_fine: int = f()
```
2025-02-10 09:46:23 +01:00
InSync
07cf8852a3
[pylint] Also report when the object isn't a literal (PLE1310) (#15985)
## Summary

Follow-up to #15984.

Previously, `PLE1310` would only report when the object is a literal:

```python
'a'.strip('//')  # error

foo = ''
foo.strip('//')  # no error
```

After this change, objects whose type can be inferred to be either `str`
or `bytes` will also be reported in preview.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2025-02-10 09:31:27 +01:00
InSync
f367aa8367
[ruff] Indented form feeds (RUF054) (#16049)
## Summary

Resolves #12321.

The physical-line-based `RUF054` checks for form feed characters that
are preceded by only tabs and spaces, but not any other characters,
including form feeds.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2025-02-09 19:23:48 -05:00
Dylan
0af4b23d9f
[ruff] Skip type definitions for missing-f-string-syntax (RUF027) (#16054)
As an f-string is never correct in a type definition context, we skip
[missing-f-string-syntax
(RUF027)](https://docs.astral.sh/ruff/rules/missing-f-string-syntax/#missing-f-string-syntax-ruf027)
in this case.

Closes #16037
2025-02-09 10:16:28 -06:00
InSync
a46fbda948
[flake8-datetime] Ignore .replace() calls while looking for .astimezone (#16050)
Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2025-02-09 15:48:59 +00:00
InSync
a04ddf2a55
[pyupgrade] [ruff] Don't apply renamings if the new name is shadowed in a scope of one of the references to the binding (UP049, RUF052) (#16032)
Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2025-02-08 11:25:23 +00:00
InSync
a29009e4ed
[pyupgrade] Comments within parenthesized value ranges should not affect applicability (UP040) (#16027)
## Summary

Follow-up to #16026.

Previously, the fix for this would be marked as unsafe, even though all
comments are preserved:

```python
# .pyi
T: TypeAlias = (  # Comment
	int | str
)
```

Now it is safe: comments within the parenthesized range no longer affect
applicability.

## Test Plan

`cargo nextest run` and `cargo insta test`.

---------

Co-authored-by: Dylan <53534755+dylwil3@users.noreply.github.com>
2025-02-07 14:44:33 -06:00
InSync
19f3424a1a
[pylint] Do not report calls when object type and argument type mismatch, remove custom escape handling logic (PLE1310) (#15984)
## Summary

Resolves #15968.

Previously, these would be considered violations:

```python
b''.strip('//')
''.lstrip('//', foo = "bar")
```

...while these are not:

```python
b''.strip(b'//')
''.strip('\\b\\x08')
```

Ruff will now not report when the types of the object and that of the
argument mismatch, or when there are extra arguments.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2025-02-07 14:31:07 -06:00
Brent Westbrook
d4a5772d96
[flake8-builtins] Match upstream module name comparison (A005) (#16006)
See #15951 for the original discussion and reviews. This is just the
first half of that PR (reaching parity with `flake8-builtins` without
adding any new configuration options) split out for nicer changelog
entries.

For posterity, here's a script for generating the module structure that
was useful for interactive testing and creating the table
[here](https://github.com/astral-sh/ruff/pull/15951#issuecomment-2640662041).
The results for this branch are the same as the `Strict` column there,
as expected.

```shell
mkdir abc collections foobar urlparse

for i in */
do
	touch $i/__init__.py
done	

cp -r abc foobar collections/.
cp -r abc collections foobar/.

touch ruff.toml

touch foobar/logging.py
```

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
2025-02-07 13:55:56 -05:00
Alex Waygood
efa8a3ddcc
[pyupgrade] Don't introduce invalid syntax when upgrading old-style type aliases with parenthesized multiline values (UP040) (#16026) 2025-02-07 17:05:17 +00:00
Wei Lee
618bfaf884
[airflow] Add external_task.{ExternalTaskMarker, ExternalTaskSensor} for AIR302 (#16014)
## Summary

Apply suggestions similar to
https://github.com/astral-sh/ruff/pull/15922#discussion_r1940697704


## Test Plan

a test fixture has been updated
2025-02-07 16:38:34 +05:30
InSync
7db5a924af
[flake8-comprehensions] Detect overshadowed list/set/dict, ignore variadics and named expressions (C417) (#15955)
## Summary

Part of #15809 and #15876.

This change brings several bugfixes:

* The nested `map()` call in `list(map(lambda x: x, []))` where `list`
is overshadowed is now correctly reported.
* The call will no longer reported if:
	* Any arguments given to `map()` are variadic.
	* Any of the iterables contain a named expression.

## Test Plan

`cargo nextest run` and `cargo insta test`.

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
2025-02-07 08:58:05 +00:00
Junhson Jean-Baptiste
349f93389e
[flake8-simplify] Only trigger SIM401 on known dictionaries (SIM401) (#15995)
## Summary

This change resolves #15814 to ensure that `SIM401` is only triggered on
known dictionary types. Before, the rule was getting triggered even on
types that _resemble_ a dictionary but are not actually a dictionary.

I did this using the `is_known_to_be_of_type_dict(...)` functionality.
The logic for this function was duplicated in a few spots, so I moved
the code to a central location, removed redundant definitions, and
updated existing calls to use the single definition of the function!

## Test Plan

Since this PR only modifies an existing rule, I made changes to the
existing test instead of adding new ones. I made sure that `SIM401` is
triggered on types that are clearly dictionaries and that it's not
triggered on a simple custom dictionary-like type (using a modified
version of [the code in the issue](#15814))

The additional changes to de-duplicate `is_known_to_be_of_type_dict`
don't break any existing tests -- I think this should be fine since the
logic remains the same (please let me know if you think otherwise, I'm
excited to get feedback and work towards a good fix 🙂).

---------

Co-authored-by: Junhson Jean-Baptiste <junhsonjb@naan.mynetworksettings.com>
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-02-07 08:25:20 +00:00
InSync
bb979e05ac
[flake8-pie] Remove following comma correctly when the unpacked dictionary is empty (PIE800) (#16008)
## Summary

Resolves #15997.

Ruff used to introduce syntax errors while fixing these cases, but no
longer will:

```python
{"a": [], **{},}
#         ^^^^ Removed, leaving two contiguous commas

{"a": [], **({})}
#         ^^^^^ Removed, leaving a stray closing parentheses
```

Previously, the function would take a shortcut if the unpacked
dictionary is empty; now, both cases are handled using the same logic
introduced in #15394. This change slightly modifies that logic to also
remove the first comma following the dictionary, if and only if it is
empty.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2025-02-07 08:52:10 +01:00
InSync
84ceddcbd9
[ruff] Classes with mixed type variable style (RUF053) (#15841) 2025-02-06 18:35:51 +00:00
Vasco Schiavo
81059d05fc
[pep8-naming] Consider any number of leading underscore for N801 (#15988)
Some checks failed
CI / Determine changes (push) Has been cancelled
CI / cargo fmt (push) Has been cancelled
CI / cargo build (release) (push) Has been cancelled
CI / python package (push) Has been cancelled
CI / pre-commit (push) Has been cancelled
CI / mkdocs (push) Has been cancelled
CI / cargo clippy (push) Has been cancelled
CI / cargo test (linux) (push) Has been cancelled
CI / cargo test (linux, release) (push) Has been cancelled
CI / cargo test (windows) (push) Has been cancelled
CI / cargo test (wasm) (push) Has been cancelled
CI / cargo build (msrv) (push) Has been cancelled
CI / cargo fuzz build (push) Has been cancelled
CI / fuzz parser (push) Has been cancelled
CI / test scripts (push) Has been cancelled
CI / ecosystem (push) Has been cancelled
CI / cargo shear (push) Has been cancelled
CI / formatter instabilities and black similarity (push) Has been cancelled
CI / test ruff-lsp (push) Has been cancelled
CI / benchmarks (push) Has been cancelled
## Summary

The PR addresses the issue #15939 

Let me know if you think there are other test cases I should add ;-)
2025-02-06 14:08:27 +05:30
Vasco Schiavo
24bab7e82e
[pycodestyle] Exempt sys.path += ... calls (E402) (#15980)
## Summary

The PR addresses issue #15886 .
2025-02-06 08:51:51 +01:00
Dylan
c69b19fe1d
[flake8-comprehensions] Handle trailing comma in fixes for unnecessary-generator-list/set (C400,C401) (#15929)
The unsafe fixes for the rules [unnecessary-generator-list
(C400)](https://docs.astral.sh/ruff/rules/unnecessary-generator-list/#unnecessary-generator-list-c400)
and [unnecessary-generator-set
(C401)](https://docs.astral.sh/ruff/rules/unnecessary-generator-set/#unnecessary-generator-set-c401)
used to introduce syntax errors if the argument to `list` or `set` had a
trailing comma, because the fix would retain the comma after
transforming the function call to a comprehension.

This PR accounts for the trailing comma when replacing the end of the
call with a `]` or `}`.

Closes #15852
2025-02-05 07:38:03 -06:00
Dylan
16f2a93fca
[ruff] Analyze deferred annotations before enforcing mutable-(data)class-default and function-call-in-dataclass-default-argument (RUF008,RUF009,RUF012) (#15921) 2025-02-05 06:44:19 -06:00
InSync
4855e0b288
[refurb] Handle unparenthesized tuples correctly (FURB122, FURB142) (#15953)
## Summary

Resolves #15936.

The fixes will now attempt to preserve the original iterable's format
and quote it if necessary. For `FURB142`, comments within the fix range
will make it unsafe as well.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2025-02-05 10:16:54 +01:00
InSync
82cb8675dd
[pep8-naming] Ignore @override methods (N803) (#15954)
## Summary

Resolves #15925.

`N803` now checks for functions instead of parameters. In preview mode,
if a method is decorated with `@override` and the current scope is that
of a class, it will be ignored.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2025-02-05 09:35:57 +01:00
InSync
5852217198
[refurb] Also report non-name expressions (FURB169) (#15905)
## Summary

Follow-up to #15779.

Prior to this change, non-name expressions are not reported at all:

```python
type(a.b) is type(None)  # no error
```

This change enhances the rule so that such cases are also reported in
preview. Additionally:

* The fix will now be marked as unsafe if there are any comments within
its range.
* Error messages are slightly modified.

## Test Plan

`cargo nextest run` and `cargo insta test`.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-02-05 08:46:37 +01:00
Brent Westbrook
6bb32355ef
[pyupgrade] Rename private type parameters in PEP 695 generics (UP049) (#15862)
## Summary

This is a new rule to implement the renaming of PEP 695 type parameters
with leading underscores after they have (presumably) been converted
from standalone type variables by either UP046 or UP047. Part of #15642.

I'm not 100% sure the fix is always safe, but I haven't come up with any
counterexamples yet. `Renamer` seems pretty precise, so I don't think
the usual issues with comments apply.

I initially tried writing this as a rule that receives a `Stmt` rather
than a `Binding`, but in that case the
`checker.semantic().current_scope()` was the global scope, rather than
the scope of the type parameters as I needed. Most of the other rules
using `Renamer` also used `Binding`s, but it does have the downside of
offering separate diagnostics for each parameter to rename.

## Test Plan

New snapshot tests for UP049 alone and the combination of UP046, UP049,
and PYI018.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-02-04 13:22:57 -05:00
Alex Waygood
64e64d2681
[flake8-pyi] Make PYI019 autofixable for .py files in preview mode as well as stubs (#15889)
Some checks are pending
CI / cargo test (linux) (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / cargo fuzz build (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
2025-02-04 16:41:22 +00:00
Alex Waygood
5bf0e2e95e
[flake8-pyi] Make PEP-695 functions with multiple type parameters fixable by PYI019 again (#15938) 2025-02-04 14:38:22 +00:00
Brent Westbrook
b5e5271adf
Preserve triple quotes and prefixes for strings (#15818)
## Summary

This is a follow-up to #15726, #15778, and #15794 to preserve the triple
quote and prefix flags in plain strings, bytestrings, and f-strings.

I also added a `StringLiteralFlags::without_triple_quotes` method to
avoid passing along triple quotes in rules like SIM905 where it might
not make sense, as discussed
[here](https://github.com/astral-sh/ruff/pull/15726#discussion_r1930532426).

## Test Plan

Existing tests, plus many new cases in the `generator::tests::quote`
test that should cover all combinations of quotes and prefixes, at least
for simple string bodies.

Closes #7799 when combined with #15694, #15726, #15778, and #15794.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-02-04 08:41:06 -05:00
Mike Perlov
15dd3b5ebd
[pylint] Fix missing parens in unsafe fix for unnecessary-dunder-call (PLC2801) (#15762)
Co-authored-by: Micha Reiser <micha@reiser.io>
2025-02-04 09:54:01 +00:00
Wei Lee
de4d9979eb
[airflow] BashOperator has been moved to airflow.providers.standard.operators.bash.BashOperator (AIR302) (#15922)
## Summary

Extend AIR302 with 

* `airflow.operators.bash.BashOperator →
airflow.providers.standard.operators.bash.BashOperator`
* change existing rules `airflow.operators.bash_operator.BashOperator →
airflow.operators.bash.BashOperator` to
`airflow.operators.bash_operator.BashOperator →
airflow.providers.standard.operators.bash.BashOperator`

## Test Plan

a test fixture has been updated
2025-02-04 14:28:00 +05:30
InSync
ba02294af3
[flake8-logging] .exception() and exc_info= outside exception handlers (LOG004, LOG014) (#15799) 2025-02-04 09:52:12 +01:00
Justin Bramley
dc5e922221
[flake8-comprehensions] Handle extraneous parentheses around list comprehension (C403) (#15877)
## Summary

Given the following code:

```python
set(([x for x in range(5)]))
```

the current implementation of C403 results in

```python
{(x for x in range(5))}
```

which is a set containing a generator rather than the result of the
generator.

This change removes the extraneous parentheses so that the resulting
code is:

```python
{x for x in range(5)}
```


## Test Plan

`cargo nextest run` and `cargo insta test`
2025-02-03 13:26:03 -05:00
Alex Waygood
62075afe4f
[flake8-pyi] Significantly improve accuracy of PYI019 if preview mode is enabled (#15888)
Some checks are pending
CI / cargo fuzz build (push) Blocked by required conditions
CI / Determine changes (push) Waiting to run
CI / cargo fmt (push) Waiting to run
CI / cargo clippy (push) Blocked by required conditions
CI / cargo test (linux) (push) Blocked by required conditions
CI / cargo test (linux, release) (push) Blocked by required conditions
CI / cargo test (windows) (push) Blocked by required conditions
CI / cargo test (wasm) (push) Blocked by required conditions
CI / cargo build (release) (push) Waiting to run
CI / cargo build (msrv) (push) Blocked by required conditions
CI / fuzz parser (push) Blocked by required conditions
CI / test scripts (push) Blocked by required conditions
CI / ecosystem (push) Blocked by required conditions
CI / cargo shear (push) Blocked by required conditions
CI / python package (push) Waiting to run
CI / pre-commit (push) Waiting to run
CI / mkdocs (push) Waiting to run
CI / formatter instabilities and black similarity (push) Blocked by required conditions
CI / test ruff-lsp (push) Blocked by required conditions
CI / benchmarks (push) Blocked by required conditions
2025-02-03 15:45:10 +00:00
InSync
3c09100484
[flake8-pyi] Fix more complex cases (PYI019) (#15821)
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-02-02 18:38:49 +00:00
Alex Waygood
0d191a13c1
[flake8-pyi] Fix incorrect behaviour of custom-typevar-return-type preview-mode autofix if typing was already imported (PYI019) (#15853) 2025-01-31 16:46:31 +00:00
InSync
b2cb757fa8
[flake8-pyi] Remove type parameter correctly when it is the last (PYI019) (#15854) 2025-01-31 16:22:54 +00:00
Alex Waygood
44ac17b3ba
[flake8-pyi] Fix several correctness issues with custom-type-var-return-type (PYI019) (#15851) 2025-01-31 14:19:35 +00:00
Brent Westbrook
f1418be81c
[pyupgrade] Reuse replacement logic from UP046 and UP047 (UP040) (#15840)
## Summary

This is a follow-up to #15565, tracked in #15642, to reuse the string
replacement logic from the other PEP 695 rules instead of the
`Generator`, which has the benefit of preserving more comments. However,
comments in some places are still dropped, so I added a check for this
and update the fix safety accordingly. I also added a `## Fix safety`
section to the docs to reflect this and the existing `isinstance`
caveat.

## Test Plan

Existing UP040 tests, plus some new cases.
2025-01-31 08:10:53 -05:00