Commit graph

44 commits

Author SHA1 Message Date
Adam Johnson
5ca6cc2cc8
Exempt unittest context methods for SIM115 rule (#16439) 2025-02-28 16:29:50 +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
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
Brent Westbrook
23c98849fc
Preserve quotes in generated f-strings (#15794)
## Summary

This is another follow-up to #15726 and #15778, extending the
quote-preserving behavior to f-strings and deleting the now-unused
`Generator::quote` field.

## Details
I also made one unrelated change to `rules/flynt/helpers.rs` to remove a
`to_string` call for making a `Box<str>` and tweaked some arguments to
some of the `Generator::unparse_f_string` methods to make the code
easier to follow, in my opinion. Happy to revert especially the latter
of these if needed.

Unfortunately this still does not fix the issue in #9660, which appears
to be more of an escaping issue than a quote-preservation issue. After
#15726, the result is now `a = f'# {"".join([])}' if 1 else ""` instead
of `a = f"# {''.join([])}" if 1 else ""` (single quotes on the outside
now), but we still don't have the desired behavior of double quotes
everywhere on Python 3.12+. I added a test for this but split it off
into another branch since it ended up being unaddressed here, but my
`dbg!` statements showed the correct preferred quotes going into
[`UnicodeEscape::with_preferred_quote`](https://github.com/astral-sh/ruff/blob/main/crates/ruff_python_literal/src/escape.rs#L54).

## Test Plan

Existing rule and `Generator` tests.

---------

Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
2025-01-29 13:28:22 -05:00
Brent Westbrook
9bf138c45a
Preserve quote style in generated code (#15726)
## Summary

This is a first step toward fixing #7799 by using the quoting style
stored in the `flags` field on `ast::StringLiteral`s to select a quoting
style. This PR does not include support for f-strings or byte strings.

Several rules also needed small updates to pass along existing quoting
styles instead of using `StringLiteralFlags::default()`. The remaining
snapshot changes are intentional and should preserve the quotes from the
input strings.

## Test Plan

Existing tests with some accepted updates, plus a few new RUF055 tests
for raw strings.

---------

Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2025-01-27 13:41:03 -05:00
InSync
001e5adec5
[flake8-simplify] Avoid double negations (SIM103) (#15562)
## Summary

Related to [this
comment](https://github.com/astral-sh/ruff/issues/6184#issuecomment-2578673788)
at #6184.

---------

Co-authored-by: Dylan <53534755+dylwil3@users.noreply.github.com>
2025-01-18 17:06:46 +00:00
InSync
556116ee76
[flake8-simplify] Do not emit diagnostics for expressions inside string type annotations (SIM222, SIM223) (#15405)
## Summary

Resolves #7127.

## Test Plan

`cargo nextest run` and `cargo insta test`.
2025-01-17 12:18:35 +05:30
InSync
0b15f17939
[flake8-simplify] More precise inference for dictionaries (SIM300) (#15164)
Co-authored-by: Micha Reiser <micha@reiser.io>
2024-12-30 10:41:33 +00:00
InSync
be69f61b3e
[flake8-simplify] Infer "unknown" truthiness for literal iterables whose items are all unpacks (SIM222) (#14263)
## Summary

Resolves #14237.

## Test Plan

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

---------

Co-authored-by: Dhruv Manilawala <dhruvmanila@gmail.com>
2024-11-11 15:23:34 -05:00
Charlie Marsh
71a122f060
Allow open without context manager in return statement (#14066)
## Summary

Closes https://github.com/astral-sh/ruff/issues/13862.
2024-11-03 14:16:27 -05:00
Simon Brugman
f8374280c0
[flake8-simplify] Implementation for split-of-static-string (SIM905) (#14008)
## Summary

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

## Test Plan

Standard snapshot testing

flake8-simplify surprisingly only has a single test case

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-11-02 17:15:36 +00:00
Zanie Blue
11f06e0d55
Detect SIM910 when using variadic keyword arguments, i.e., **kwargs (#13503)
Closes https://github.com/astral-sh/ruff/issues/13493
2024-09-25 10:02:59 -05:00
Steve C
0b5828a1e8
[flake8-simplify] - extend open-file-with-context-handler to work with dbm.sqlite3 (SIM115) (#13104)
## Summary

Adds upcoming `dbm.sqlite3` to rule that suggests using context managers
to open things with.

See: https://docs.python.org/3.13/library/dbm.html#module-dbm.sqlite3

## Test Plan

`cargo test`
2024-08-26 08:11:03 +01:00
Steve C
d37e2e5d33
[flake8-simplify] Extend open-file-with-context-handler to work with other standard-library IO modules (SIM115) (#12959)
Co-authored-by: Alex Waygood <alex.waygood@gmail.com>
2024-08-22 14:18:55 +01:00
Dylan
0c2b88f224
[flake8-simplify] Further simplify to binary in preview for if-else-block-instead-of-if-exp (SIM108) (#12796)
In most cases we should suggest a ternary operator, but there are three
edge cases where a binary operator is more appropriate.

Given an if-else block of the form

```python
if test:
    target_var = body_value
else:
    target_var = else_value
```
This PR updates the check for SIM108 to the following:

- If `test == body_value` and preview enabled, suggest to replace with
`target_var = test or else_value`
- If `test == not body_value` and preview enabled, suggest to replace
with `target_var = body_value and else_value`
- If `not test == body_value` and preview enabled, suggest to replace
with `target_var = body_value and else_value`
- Otherwise, suggest to replace with `target_var = body_value if test
else else_value`

Closes #12189.
2024-08-10 16:49:25 +00:00
Charlie Marsh
5107a50ae7
Parenthesize conditions based on precedence when merging if arms (#12737)
## Summary

Closes https://github.com/astral-sh/ruff/issues/12732.
2024-08-07 23:03:24 -04:00
Dhruv Manilawala
1968332d93 Redirect PLR1701 to SIM101 (#12021)
## Summary

This rule removes `PLR1701` and redirects it to `SIM101`.

In addition to that, the `SIM101` autofix has been fixed to add padding
if required.

### `PLR1701` has bugs

It also seems that the implementation of `PLR1701` is incorrect in
multiple scenarios. For example, the following code snippet:
```py
# There are two _different_ variables `a` and `b`
if isinstance(a, int) or isinstance(b, bool) or isinstance(a, float):
    pass
# There's another condition `or 1`
if isinstance(self.k, int) or isinstance(self.k, float) or 1:
    pass
```
is fixed to:
```py
# Fixed to only considering variable `a`
if isinstance(a, (float, int)):
    pass
# The additional condition is not present in the fix
if isinstance(self.k, (float, int)):
    pass
```

Playground: https://play.ruff.rs/6cfbdfb7-f183-43b0-b59e-31e728b34190

## Documentation Preview

### `PLR1701`

<img width="1397" alt="Screenshot 2024-06-25 at 11 14 40"
src="779ee84d-7c4d-4bb8-a3a4-c2b23a313eba">

## Test Plan

Remove the test cases for `PLR1701`, port the padding test case to
`SIM101` and update the snapshot.
2024-06-27 13:44:11 +02:00
Charlie Marsh
b36dd1aa51
[flake8-simplify] Simplify double negatives in SIM103 (#11684)
## Summary

Closes: https://github.com/astral-sh/ruff/issues/11685.
2024-06-01 23:21:11 +00:00
Charlie Marsh
a38c05bf13
Avoid recommending context manager in __enter__ implementations (#11575)
## Summary

Closes https://github.com/astral-sh/ruff/issues/11567.
2024-05-28 01:44:24 +00:00
Charlie Marsh
51dec8d95b
[flake8-simplify] Avoid raising SIM911 for non-zip attribute calls (#11126)
## Summary

The `matches!` macro here is slightly off and allows _all_ attribute
calls through.

Closes https://github.com/astral-sh/ruff/issues/11125.
2024-04-24 13:05:17 +00:00
Alex Waygood
4284e079b5
Improve inference capabilities of the BuiltinTypeChecker (#10976) 2024-04-16 18:53:22 +01:00
Charlie Marsh
dbf8d0c82c
Show negated condition in needless-bool diagnostics (#10854)
## Summary

Closes https://github.com/astral-sh/ruff/issues/10843.
2024-04-10 04:29:43 +00:00
Ottavio Hartman
526abebbae
[flake8-simplify] Detect implicit else cases in needless-bool (SIM103) (#10414)
Fixes #10402 

## Summary

For SIM103, detect and simplify the following case:

[playground
link](https://play.ruff.rs/d98570aa-b180-495b-8600-5c4c3fd02526)
```python
def main():
    if foo > 5:
        return True
    return False
```

## Test Plan

Unit tested only.
2024-03-18 00:15:28 +00:00
Adrien Ball
c3bba54b6b
Fix SIM113 false positive with async for loops (#9996)
## Summary
Ignore `async for` loops when checking the SIM113 rule.

Closes #9995 

## Test Plan
A new test case was added to SIM113.py with an async for loop.
2024-02-15 22:40:01 -05:00
Steve C
214563261d
[flake8-simplify] - Fix syntax error in autofix (SIM114) (#9704)
## Summary

A fix for
https://github.com/astral-sh/ruff/issues/8402#issuecomment-1916215124

Improves the code, as well. :)

## Test Plan

`cargo test`
2024-01-30 11:36:44 -05:00
Steve C
9c8a4d927e
[flake8-simplify] Add fix for if-with-same-arms (SIM114) (#9591)
## Summary

 add fix for `if-with-same-arms` / `SIM114`

Also preserves comments!

## Test Plan

`cargo test`
2024-01-22 04:37:18 +00:00
Charlie Marsh
953d48b7f4
[flake8-simplify] Avoid some more enumerate-for-loop false positives (SIM113) (#9515)
Avoids, e.g., [this false
positive](a4fad5dda1/zerver/data_import/slack.py (L634))
from the ecosystem check.
2024-01-14 13:02:13 -05:00
Chammika Mannakkara
0003c730e0
[flake8-simplify] Implement enumerate-for-loop (SIM113) (#7777)
Implements SIM113 from #998

Added tests
Limitations 
   - No fix yet
   - Only flag cases where index variable immediately precede `for` loop

@charliermarsh please review and let me know any improvements

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2024-01-14 11:00:59 -05:00
Charlie Marsh
a31a314b2b
Account for possibly-empty f-string values in truthiness logic (#9484)
Closes https://github.com/astral-sh/ruff/issues/9479.
2024-01-11 21:16:19 -05:00
trag1c
eb4ed2471b
[flake8-simplify] Implement SIM911 (#9460)
## Summary

Closes #9319, implements the [`SIM911` rule from
`flake8-simplify`](https://github.com/MartinThoma/flake8-simplify/pull/183).


#### Note
I wasn't sure whether or not to include
```rs
if checker.settings.preview.is_disabled() {
    return;
}
```
at the beginning of the function with violation logic if the rule's
already declared as part of `RuleGroup::Preview`.
I've seen both variants, so I'd appreciate some feedback on that :)
2024-01-11 14:42:43 -05:00
Dimitri Papadopoulos Orfanos
d04d49cc0e
Fix typos found by codespell (#9346)
## Summary

Fix typos found by
[codespell](https://github.com/codespell-project/codespell).

## Test Plan

CI tests.
2024-01-02 02:08:15 +00:00
asafamr-mm
5d41c84ef7
SIM300: CONSTANT_CASE variables are improperly flagged for yoda violation (#9164)
## Summary

fixes #6956 
details in issue

Following an advice in
https://github.com/astral-sh/ruff/issues/6956#issuecomment-1817672585,
this change separates expressions to 3 levels of "constant likelihood":
*  literals, empty dict and tuples... (definitely constant, level 2)
*  CONSTANT_CASE vars (probably constant, 1)
* all other expressions (0)

a comparison is marked yoda if the level is strictly higher on its left
hand side

following
https://github.com/astral-sh/ruff/issues/6956#issuecomment-1697107822
marking compound expressions of literals (e.g. `60 * 60` ) as constants
this change current behaviour on
`SomeClass().settings.SOME_CONSTANT_VALUE > (60 * 60)` in the fixture
from error to ok
2023-12-20 20:26:07 +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
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
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
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
Flowrey
fa556d1c74
Make SIM401 catch ternary operations (#7415)
## Summary

Make SIM401 rules to catch ternary operations when preview is enabled.

Fixes #7288.

## Test Plan

Tested against `SIM401.py` fixtures.
2023-10-20 20:47:00 +00:00
Charlie Marsh
256b98ab9a
Avoid if-else simplification for TYPE_CHECKING blocks (#8072)
Closes https://github.com/astral-sh/ruff/issues/8071.
2023-10-19 19:15:54 -04:00
Harutaka Kawamura
f670f9b22c
[SIM115] Allow open followed by close (#7916) 2023-10-11 13:53:48 +00:00
Jelle Zijlstra
600471e45f
Fix SIM110 with a yield in the condition (#7801)
And allow "await" in the loop iterable.

Fixes #7800
2023-10-04 08:59:19 -04:00
Jelle Zijlstra
7b4fb4fb5d
Fix issues with SIM101 (adjacent isinstance() calls) (#7798)
- Only trigger for immediately adjacent isinstance() calls with the same
target
- Preserve order of or conditions

Two existing tests changed:
- One was incorrectly reordering the or conditions, and is now correct.
- Another was combining two non-adjacent isinstance() calls. It's safe
enough in that example,
but this isn't safe to do in general, and it feels low-value to come up
with a heuristic for
when it is safe, so it seems better to not combine the calls in that
case.

Fixes https://github.com/astral-sh/ruff/issues/7797
2023-10-04 04:42:13 +00:00
Charlie Marsh
75f759ed55
Upgrade LibCST to support Python 3.12 (#7764)
## Summary

We'll revert back to the crates.io release once it's up-to-date, but
better to get this out now that Python 3.12 is released.

## Test Plan

`cargo test`
2023-10-02 12:14:35 -04:00
Charlie Marsh
8ba8896a7f
Skip BOM when inserting start-of-file imports (#7622)
See:
https://github.com/astral-sh/ruff/issues/7455#issuecomment-1732387485.
2023-09-23 19:36:50 +00:00
Charlie Marsh
5849a75223
Rename ruff crate to ruff_linter (#7529) 2023-09-20 08:38:27 +02:00