Commit Graph

1841 Commits

Author SHA1 Message Date
Charlie Marsh 465943adf7
Revert "Upgrade to toml v0.5.11" (#2058)
This _did_ fix https://github.com/charliermarsh/ruff/issues/1894, but was a little premature. `toml` doesn't actually depend on `toml-edit` yet, and `v0.5.11` was mostly about deprecations AFAICT. So upgrading might solve that issue, but could introduce other incompatibilities, and I'd like to minimize churn. I expect that `toml` will have a new release soon, so we can revert this revert.

Reverts charliermarsh/ruff#2040.
2023-01-21 07:54:56 -05:00
Charlie Marsh 38eed292e4
Avoid removing comments in RUF005 (#2057)
Closes #2054.
2023-01-21 07:37:25 -05:00
Harutaka Kawamura 883e650a35
Fix S101 range to only highlight `assert` (#2052)
Fix:

```
resources/test/fixtures/flake8_bandit/S101.py:2:1: S101 Use of `assert` detected
  |
2 | assert True
  | ^^^^^^^^^^^ S101
  |

resources/test/fixtures/flake8_bandit/S101.py:8:5: S101 Use of `assert` detected
  |
8 |     assert x == 1
  |     ^^^^^^^^^^^^^ S101
  |

resources/test/fixtures/flake8_bandit/S101.py:11:5: S101 Use of `assert` detected
   |
11 |     assert x == 2
   |     ^^^^^^^^^^^^^ S101
   |

Found 3 error(s).
```

to:

```
resources/test/fixtures/flake8_bandit/S101.py:2:1: S101 Use of `assert` detected
  |
2 | assert True
  | ^^^^^^ S101
  |

resources/test/fixtures/flake8_bandit/S101.py:8:5: S101 Use of `assert` detected
  |
8 |     assert x == 1
  |     ^^^^^^ S101
  |

resources/test/fixtures/flake8_bandit/S101.py:11:5: S101 Use of `assert` detected
   |
11 |     assert x == 2
   |     ^^^^^^ S101
   |
```
2023-01-21 07:15:00 -05:00
Harutaka Kawamura eb1b5e5454
De-duplicate SIM102 (#2050)
The idea is the same as #1867. Avoids emitting `SIM102` twice for the following code:

```python
if a:
    if b:
        if c:
            d
```

```
resources/test/fixtures/flake8_simplify/SIM102.py:1:1: SIM102 Use a single `if` statement instead of nested `if` statements
resources/test/fixtures/flake8_simplify/SIM102.py:2:5: SIM102 Use a single `if` statement instead of nested `if` statements
```
2023-01-20 23:38:52 -05:00
Charlie Marsh 8e558a3458
Add scaffolding for `flake8-type-checking` extension (#2048)
This PR adds the scaffolding files for `flake8-type-checking`, along with the simplest rule (`empty-type-checking-block`), just as an example to get us started.

See: #1785.
2023-01-20 22:41:36 -05:00
Martin Fischer 4e4643aa5d refactor: Decouple Rule from linter prefixes
543865c96b introduced
RuleCode::origin() -> RuleOrigin generation via a macro, while that
signature now has been renamed to Rule::origin() -> Linter we actually
want to get rid of it since rules and linters shouldn't be this tightly
coupled (since one rule can exist in multiple linters).

Another disadvantage of the previous approach was that the prefixes
had to be defined in ruff_macros/src/prefixes.rs, which was easy to
miss when defining new linters in src/*, case in point
INP001 => violations::ImplicitNamespacePackage has in the meantime been
added without ruff_macros/src/prefixes.rs being updated accordingly
which resulted in `ruff --explain INP001` mistakenly reporting that the
rule belongs to isort (since INP001 starts with the isort prefix "I").
The derive proc macro introduced in this commit requires every variant
to have at least one #[prefix = "..."], eliminating such mistakes.
2023-01-20 20:25:57 -05:00
Martin Fischer b19258a243 refactor: Rename RuleCodePrefix to RuleSelector
More accurate since the enum also encompasses:

* ALL (which isn't a prefix at all)

* fully-qualified rule codes (which aren't prefixes unless you say
  they're a prefix to the empty string but that's not intuitive)
2023-01-20 20:25:57 -05:00
Martin Fischer 7fc42f8f85 refactor: Rename RuleOrigin to Linter
"origin" was accurate since ruff rules are currently always modeled
after one origin (except the Ruff-specific rules).

Since we however want to introduce a many-to-many mapping between codes
and rules, the term "origin" no longer makes much sense. Rules usually
don't have multiple origins but one linter implements a rule first and
then others implement it later (often inspired from another linter).
But we don't actually care much about where a rule originates from when
mapping multiple rule codes to one rule implementation, so renaming
RuleOrigin to Linter is less confusing with the many-to-many system.
2023-01-20 20:25:57 -05:00
Dmitry Dygalo babe1eb7be
perf: Reduce allocations (#2045)
I found a few places where some allocations could be avoided.
2023-01-20 20:06:48 -05:00
Simon Brugman 608b2191aa
[`flake8-executable`] EXE003-005 (#2023)
Tracking issue: https://github.com/charliermarsh/ruff/issues/2024

Implementation for EXE003, EXE004 and EXE005 of `flake8-executable` 
(shebang should contain "python", not have whitespace before, and should be on the first line)

Please take in mind that this is my first rust contribution.

The remaining EXE-rules are a combination of shebang (`lines.rs`), file permissions (`fs.rs`) and if-conditions (`ast.rs`). I was not able to find other rules that have interactions/dependencies in them. Any advice on how this can be best implemented would be very welcome.

For autofixing `EXE005`, I had in mind to _move_  the shebang line to the top op the file. This could be achieved by a combination of `Fix::insert` and `Fix::delete` (multiple fixes per diagnostic), or by implementing a dedicated `Fix::move`, or perhaps in other ways. For now I've left it out, but keen on hearing what you think would be most consistent with the package, and pointer where to start (if at all).

---
If you care about another testimonial:
`ruff` not only helps staying on top of the many excellent flake8 plugins and other Python code quality tools that are available, it also applies them at baffling speed.
(Planning to implement it soon for github.com/pandas-profiling/pandas-profiling (as largest contributor) and github.com/ing-bank/popmon.)
2023-01-20 18:19:07 -05:00
Eric Roberts 3939c2dbf7
Add support for pycodestyle E101 (#2038)
Rule described here: https://www.flake8rules.com/rules/E101.html

I tried to follow contributing guidelines closely, I've never worked with Rust before. Stumbled across Ruff a few days ago and would like to use it in our project, but we use a bunch of flake8 rules that are not yet implemented in ruff, so I decided to give it a go.
2023-01-20 17:24:58 -05:00
Charlie Marsh 20a9252e92
Upgrade to toml v0.5.11 (#2040)
In #1680, we moved over to `toml_edit`. But it looks like `toml` now uses `toml_edit`, and has implemented some improvements (e.g., this closes #1894).
2023-01-20 17:20:45 -05:00
Hugo van Kemenade a0e3347e43
README: `--force-exclude` is already set (#2042)
Re: https://github.com/charliermarsh/ruff-pre-commit/issues/19 / https://github.com/charliermarsh/ruff-pre-commit/pull/20

This is now always set, no need to include it in the README example.
2023-01-20 17:20:22 -05:00
Charlie Marsh 9e704a7c63
Only fix true-false returns for return-bool-condition-directly (#2037)
Closes #2035.
2023-01-20 13:17:19 -05:00
Zeddicus414 c9da98e0b7
Fix D404 NoThisPrefix not working with whitespace. (#2036)
D404 should trigger for """ This is a docstring."""

Add a few tests to ensure the fix worked.
2023-01-20 13:01:31 -05:00
Charlie Marsh 5377d24507 Bump version to 0.0.228 2023-01-20 09:58:56 -05:00
Florian Best db8e4500ee
fix(pydocstyle): Avoid trimming docstring if starts with leading quote (#2027)
Fixes: #2017

looks like the other way round is also possible to break:

```""" "foo"""`
2023-01-20 09:57:48 -05:00
Aarni Koskela bd2de5624e
Move readme dev details to CONTRIBUTING.md and fix contradictions (#2030)
Following up on #2018/#2019 discussion, this moves the readme's development-related bits to `CONTRIBUTING.md` to avoid duplication, and fixes up the commands accordingly 😄
2023-01-20 09:23:28 -05:00
Aarni Koskela 3a81f893cc
Bump terminfo to remove a whole bunch of unnecessary dependencies (#2022)
See 6281c6b8f7

```
$ cargo update -p terminfo
    Updating crates.io index
    Removing cfg-if v0.1.10
    Removing dirs v2.0.2
    Removing getrandom v0.1.16
    Removing phf v0.8.0
    Updating phf_codegen v0.8.0 -> v0.11.1
    Updating phf_generator v0.8.0 -> v0.11.1
    Removing phf_shared v0.8.0
    Removing rand v0.7.3
    Removing rand_chacha v0.2.2
    Removing rand_core v0.5.1
    Removing rand_hc v0.2.0
    Removing rand_pcg v0.2.1
    Updating terminfo v0.7.3 -> v0.7.5
    Removing wasi v0.9.0+wasi-snapshot-preview1
```
2023-01-20 09:09:02 -05:00
Charlie Marsh fd6dc2a343
Use platform-appropriate newline character for LibCST embedding (#2028)
Closes #2026.
2023-01-20 09:08:04 -05:00
Martin Fischer 8693236f9e Make CI test add_*.py scripts 2023-01-20 08:09:54 -05:00
Martin Fischer 44e2b6208a fix: Update add_rule.py to create new files for rules 2023-01-20 08:09:54 -05:00
Martin Fischer 16c81f75c2 fix: Update add_rule.py to account for 16e79c8d 2023-01-20 08:09:54 -05:00
Martin Fischer e1d6ac3265 fix: Update add_plugin.py to account for 9dc66b5a 2023-01-20 08:09:54 -05:00
Martin Fischer 3aec1100f5 fix: Update add_plugin.py to account for b78b6f27 2023-01-20 08:09:54 -05:00
Martin Fischer c00df647e1 fix: Update add_rule.py to account for 81996f1bc 2023-01-20 08:09:54 -05:00
Martin Fischer f012877be1 Add scripts/pyproject.toml to use ruff for ruff :) 2023-01-20 08:09:54 -05:00
Martin Fischer ff6defc988 refactor: Introduce get_indent helper for scripts 2023-01-20 08:09:54 -05:00
Martin Fischer 67ca50e9f2 refactor: Reduce code duplication in scripts/ 2023-01-20 08:09:54 -05:00
Martin Fischer 6cc160bc2b Mark scripts/add_*.py as executable 2023-01-20 08:09:54 -05:00
Ville Skyttä 4bdf506d80
Grammar fixes (#2014) 2023-01-20 07:44:23 -05:00
Charlie Marsh 4af2353ef9
Avoid trimming docstring if ends in trailing quote (#2025)
Closes #2017.
2023-01-20 07:41:58 -05:00
Ville Skyttä 6072edf5bf
Note `.astimezone()` in call-datetime-strptime-without-zone message (#2015) 2023-01-20 07:40:34 -05:00
Martin Fischer 4061eeeb32 Update CI to use MSRV for cargo test and build
As per Cargo.toml our minimal supported Rust version is 1.65.0, so we
should be using that version in our CI for cargo test and cargo build.

This was apparently accidentally changed in
79ca66ace5.
2023-01-20 07:39:40 -05:00
Aarni Koskela bea6deb0c3
Port pydocstyle code 401 (ImperativeMood) (#1999)
This adds support for pydocstyle code D401 using the `imperative` crate.
2023-01-20 07:18:27 -05:00
Colin Delahunty 81db00a3c4
Pyupgrade: Extraneous parenthesis (#1926) 2023-01-20 00:04:07 -05:00
Charlie Marsh cf56955ba6 Bump version to 0.0.227 2023-01-19 23:24:52 -05:00
Charlie Marsh 8a8939afd8
Avoid checking row types for single-name @parametrize decorators (#2013)
Closes #2008.
2023-01-19 22:13:17 -05:00
Martin Fischer 6acf2accc6 Improve --explain output
Previous output for `ruff --explain E711`:

    E711 (pycodestyle): Comparison to `None` should be `cond is None`

New output:

    none-comparison

    Code: E711 (pycodestyle)

    Autofix is always available.

    Message formats:

    * Comparison to `None` should be `cond is None`
    * Comparison to `None` should be `cond is not None`
2023-01-19 22:08:00 -05:00
Charlie Marsh ec0c7647ab
Avoid SIM401 in `elif` blocks (#2012)
For now, we're just gonna avoid flagging this for `elif` blocks, following the same reasoning as for ternaries. We can handle all of these cases, but we'll knock out the TODOs as a pair, and this avoids broken code.

Closes #2007.
2023-01-19 21:57:18 -05:00
Charlie Marsh 045229630e
Upgrade RustPython (#2011)
This lets us revert the "manual" fix introduced in #1944.
2023-01-19 21:49:12 -05:00
Martin Fischer c600991905 Change AsRef<str> impl for Rule to kebab-case
As we surface rule names more to users we want
them to be easier to type than PascalCase.

Prior art:

Pylint and ESLint also use kebab-case for their rule names.
Clippy uses snake_case but only for syntactical reasons
(so that the argument to e.g. #![allow(clippy::some_lint)]
can be parsed as a path[1]).

[1]: https://doc.rust-lang.org/reference/paths.html
2023-01-19 21:37:11 -05:00
Charlie Marsh f6a93a4c3d
Enable autofix for `FitsOnOneLine` (`D200`) (#2006)
Closes #1965.
2023-01-19 19:24:50 -05:00
Aarni Koskela de54ff114e
Add RUF005 "unpack instead of concatenating" check (#1957)
This PR adds a new check that turns expressions such as `[1, 2, 3] + foo` into `[1, 2, 3, *foo]`, since the latter is easier to read and faster:

```
~ $ python3.11 -m timeit -s 'b = [6, 5, 4]' '[1, 2, 3] + b'
5000000 loops, best of 5: 81.4 nsec per loop
~ $ python3.11 -m timeit -s 'b = [6, 5, 4]' '[1, 2, 3, *b]'
5000000 loops, best of 5: 66.2 nsec per loop
```

However there's a couple of gotchas:

* This felt like a `simplify` rule, so I borrowed an unused `SIM` code even if the upstream `flake8-simplify` doesn't do this transform. If it should be assigned some other code, let me know 😄 
* **More importantly** this transform could be unsafe if the other operand of the `+` operation has overridden `__add__` to do something else. What's the `ruff` policy around potentially unsafe operations? (I think some of the suggestions other ported rules give could be semantically different from the original code, but I'm not sure.)
* I'm not a very established Rustacean, so there's no doubt my code isn't quite idiomatic. (For instance, is there a neater way to write that four-way `match` statement?)

Thanks for `ruff`, by the way! :)
2023-01-19 17:38:17 -05:00
Charlie Marsh 64b398c72b Tweak some instructions in CONTRIBUTING.md 2023-01-19 17:17:39 -05:00
Aarni Koskela c99bd3fa60
Split up pydocstyle rules (#2003)
As per @not-mAs per @not-my-profile's [comment](https://github.com/charliermarsh/ruff/pull/1999#discussion_r1081579337):

> we actually want to break up such rules.rs files into smaller files

this breaks up `pydocstyle/rules.rs` into a directory.y-profile's [comment](https://github.com/charliermarsh/ruff/pull/1999#discussion_r1081579337):

> we actually want to break up such rules.rs files into smaller files

this breaks up `pydocstyle/rules.rs` into a directory.
2023-01-19 13:17:25 -05:00
Martin Fischer 8ac930f886 Fix that --explain panics
This commit fixes a bug accidentally introduced in
6cf770a692,
which resulted every `ruff --explain <code>` invocation to fail with:

    thread 'main' panicked at 'Mismatch between definition and access of `explain`.
    Could not downcast to ruff::registry::Rule, need to downcast to &ruff::registry::Rule',
    ruff_cli/src/cli.rs:184:18

We also add an integration test for --explain to prevent such bugs from
going by unnoticed in the future.
2023-01-19 12:58:44 -05:00
Charlie Marsh ad80fdc2cd
Avoid `SIM201` and `SIM202` errors in `__ne__` et al (#2001)
Closes #1986.
2023-01-19 11:27:27 -05:00
Aarni Koskela a0ea8fe22f
Apply #[derive(Default)] fixes suggested by Clippy (#2000)
These were bugging me every time I ran `clippy` 😁
2023-01-19 11:04:43 -05:00
Martin Fischer 3c3da8a88c derive-msg-formats 5/5: Remove placeholder implementations
# This commit has been generated via the following Python script:
# (followed by `cargo +nightly fmt` and `cargo dev generate-all`)
# For the reasoning see the previous commit(s).

import re
import sys

for path in (
    'src/violations.rs',
    'src/rules/flake8_tidy_imports/banned_api.rs',
    'src/rules/flake8_tidy_imports/relative_imports.rs',
):
    with open(path) as f:
        text = ''

        while line := next(f, None):

            if line.strip() != 'fn message(&self) -> String {':
                text += line
                continue

            text += '    #[derive_message_formats]\n' + line

            body = next(f)
            while (line := next(f)) != '    }\n':
                body += line

            # body = re.sub(r'(?<!code\| |\.push\()format!', 'format!', body)
            body = re.sub(
                r'("[^"]+")\s*\.to_string\(\)', r'format!(\1)', body, re.DOTALL
            )
            body = re.sub(
                r'(r#".+?"#)\s*\.to_string\(\)', r'format!(\1)', body, re.DOTALL
            )

            text += body + '    }\n'

            while (line := next(f)).strip() != 'fn placeholder() -> Self {':
                text += line
            while (line := next(f)) != '    }\n':
                pass

    with open(path, 'w') as f:
        f.write(text)
2023-01-19 11:03:32 -05:00