Commit Graph

520 Commits

Author SHA1 Message Date
Charlie Marsh 3200015c06
Fix banned-from documentation (#6959)
Closes https://github.com/astral-sh/ruff/issues/6839.
2023-08-29 00:51:15 +00:00
Valeriy Savchenko 26d53c56a2
[refurb] Implement `repeated-append` rule (`FURB113`) (#6702)
## Summary

As an initial effort with replicating `refurb` rules (#1348 ), this PR
adds support for
[FURB113](https://github.com/dosisod/refurb/blob/master/refurb/checks/builtin/list_extend.py)
and adds a new category of checks.

## Test Plan

I included a new test + checked that all other tests pass.
2023-08-28 22:51:59 +00:00
konsti e615870659
Unify line size settings between ruff and the formatter (#6873) 2023-08-28 06:44:56 +00:00
Micha Reiser a6aa16630d
Move `Configuration` to `ruff_workspace` crate (#6920) 2023-08-28 06:21:35 +00:00
Charlie Marsh 281ce56dc1
Make isort's `detect-same-package` behavior configurable (#6833)
## Summary

Our first-party import detection uses a heuristic that doesn't exist in
isort: if an import appears to be from within the same package as the
containing file, we mark it as first-party. For example, if you have a
directory `./foo/__init__.py`, and you import `from foo import bar` in
`./foo/baz.py`, we'll mark that as first-party. (See:
https://github.com/astral-sh/ruff/pull/1266.)

This is often unnecessary, and arguably should be removed (though it
does have some important use-cases that are otherwise unserved -- I
believe Dagster uses it to ensure that all packages mark imports from
within the same package as first-party, but not imports _across_
different first-party packages)... but it does exist, and it does help
in cases in which the `src` field is not properly configured.

This PR adds an option to turn off this behavior:

```toml
[tool.ruff.isort]
detect-same-package = false
```

This is being introduced to help codebases migrating over from isort
that may want more consistent behavior with their current sorting.

## Test Plan

`cargo test`
2023-08-24 14:09:26 -04:00
Victor Hugo Gomes 0aad0c41f6
[`pylint`] Implement `no-self-use` (`R6301`) (#6574) 2023-08-22 03:44:38 +00:00
Harutaka Kawamura a489b96a65
[`flake8-pie`] Implement `unnecessary-range-start` (`PIE808`) (#6690) 2023-08-19 21:59:11 +00:00
Evan Rittenhouse e3ecbe660e
[`ruff`] Implement `quadratic-list-summation` rule (`RUF017`) (#6489)
## Summary

Adds `RUF017`. Closes #5073 

## Test Plan

`cargo t`
2023-08-16 23:13:05 -04:00
Harutaka Kawamura 8c3a8c4fc6
Support glob patterns for `raises_require_match_for` and `raises_require_match_for` (#6635)
## Summary

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

Support glob patterns for `raises_require_match_for` and
`raises_require_match_for`. Resolve #6473

## Test Plan

New tests + existing tests
2023-08-17 02:15:50 +00:00
Harutaka Kawamura d9a81f4fbb
[`flake8-pytest-style`] Implement duplicate parameterized fixture detection (`PT014`) (#6598) 2023-08-16 03:35:46 +00:00
Harutaka Kawamura 70696061cd
[`flake8-pytest-style`] Implement `pytest-unittest-raises-assertion` (`PT027`) (#6554) 2023-08-14 20:25:23 +00:00
Charlie Marsh cd634a9489
Expand documentation around flake8-type-checking rules for SQLAlchemy (#6570)
## Summary

Not addressing the root issue as much as improving the documentation.

Closes https://github.com/astral-sh/ruff/issues/6510.
2023-08-14 19:47:10 +00:00
Presley Graham c03e2acadb
[`flake8-tidy-imports`] Add `TID253` (#6378)
## Summary

Add a new rule `TID253` (`banned-module-level-imports`), to ban a
user-specified list of imports from appearing at module level. This rule
doesn't exist in `flake8-tidy-imports`, so it's unique to Ruff. The
implementation is pretty similar to `TID251`.

Briefly discussed
[here](https://github.com/astral-sh/ruff/discussions/6370).

## Test Plan

Added a new test case, checking that inline imports are allowed and that
non-inline imports from the banned list are disallowed.
2023-08-12 18:45:34 +00:00
Zanie Blue 5b47350c25
Document default behavior of `W505` in setting (#6463)
Addresses https://github.com/astral-sh/ruff/discussions/6459
2023-08-11 16:41:31 -05:00
Victor Hugo Gomes eb68addf97
[`pylint`] Implement `bad-dunder-name` (`W3201`) (#6486)
## Summary

Checks for any misspelled dunder name method and for any method defined
with `__...__` that's not one of the pre-defined methods.

The pre-defined methods encompass all of Python's standard dunder
methods.

ref: #970

## Test Plan
Snapshots and manual runs of pylint.
2023-08-11 01:31:16 +00:00
Tom Kuson 9ff80a82b4
[`pylint`] Implement `subprocess-run-check` (`W1510`) (#6487)
## Summary

Implements [`subprocess-run-check`
(`W1510`)](https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/subprocess-run-check.html)
as `subprocess-run-without-check` (`PLW1510`). Includes documentation.

Related to #970.

## Test Plan

`cargo test`
2023-08-10 20:54:53 -04:00
Zanie Blue 1050c4e104
Extend `target-version` documentation (#6482)
Closes https://github.com/astral-sh/ruff/issues/6462
2023-08-10 12:11:37 -05:00
Tom Kuson 1b9fed8397
Error on zero tab width (#6429)
## Summary

Error if `tab-size` is set to zero (it is used as a divisor). Closes
#6423.

Also fixes a typo.

## Test Plan

Running ruff with a config

```toml
[tool.ruff]
tab-size = 0
```

returns an error message to the user saying that `tab-size` must be
greater than zero.
2023-08-08 16:51:37 -04:00
Victor Hugo Gomes b8ca220eeb
[`flake8-pyi`] Implement PYI055 (#6316) 2023-08-04 01:36:00 +00:00
Zanie Blue 718e3945e3
Add rule to upgrade type alias annotations to keyword (UP040) (#6289)
Adds rule to convert type aliases defined with annotations i.e. `x:
TypeAlias = int` to the new PEP-695 syntax e.g. `type x = int`.

Does not support using new generic syntax for type variables, will be
addressed in a follow-up.
Added as part of pyupgrade — ~the code 100 as chosen to avoid collision
with real pyupgrade codes~.

Part of #4617 
Builds on #5062
2023-08-03 16:13:06 +00:00
qdegraaf d40597a266
[`flake8-pyi`] Implement `custom_type_var_return_type` (`PYI019`) (#6204)
## Summary

Implements `Y019` from
[flake8-pyi](https://github.com/PyCQA/flake8-pyi).

The rule checks if

-  instance methods that return `self` 
-  class methods that return an instance of `cls`
- `__new__` methods

Return a custom `TypeVar` instead of `typing.Self` and raises a
violation if this is the case. The rule also covers
[PEP-695](https://peps.python.org/pep-0695/) syntax as introduced in
upstream in https://github.com/PyCQA/flake8-pyi/pull/402

## Test Plan

Added fixtures with test cases from upstream implementation (plus
additional one for an excluded edge case, mentioned in upstream
implementation)
2023-08-03 00:42:42 +00:00
Silvano Cerza 82410524d9
[`pylint`] Implement Pylint `bad-format-character` (`E1300`) (#6171)
## Summary

Relates to #970.

Add new `bad-format-character` Pylint rule.

I had to make a change in `crates/ruff_python_literal/src/format.rs` to
get a more detailed error in case the format character is not correct. I
chose to do this since most of the format spec parsing functions are
private. It would have required me reimplementing most of the parsing
logic just to know if the format char was correct.

This PR also doesn't reflect current Pylint functionality in two ways.

It supports new format strings correctly, Pylint as of now doesn't. See
pylint-dev/pylint#6085.

In case there are multiple adjacent string literals delimited by
whitespace the index of the wrong format char will relative to the
single string. Pylint will instead reported it relative to the
concatenated string.

Given this:
```
"%s" "%z" % ("hello", "world")
```

Ruff will report this:
```Unsupported format character 'z' (0x7a) at index 1```

Pylint instead:
```Unsupported format character 'z' (0x7a) at index 3```

I believe it's more sensible to report the index relative to the
individual string.

## Test Plan

Added new snapshot and a small test in
`crates/ruff_python_literal/src/format.rs`.

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-08-02 21:32:43 +00:00
Victor Hugo Gomes 9f38dbd06e
[`flake8-pyi`] Implement PYI051 (#6215)
## Summary
Checks for the presence of redundant `Literal` types and builtin super
types in an union. See [original
source](2a86db8271/pyi.py (L1261)).

This implementation has a couple of differences from the original. The
first one is, we support the `complex` and `float` builtin types. The
second is, when reporting diagnostic for a `Literal` with multiple
members of the same type, we print the entire `Literal` while `flak8`
only prints the `Literal` with its first member.
For example:
```python
from typing import Literal

x: Literal[1, 2] | int
```  
Ruff will show `Literal[1, 2]` while flake8 only shows `Literal[1]`.

```shell
$ ruff crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:4:18: PYI051 `Literal["foo"]` is redundant in an union with `str`
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:5:37: PYI051 `Literal[b"bar", b"foo"]` is redundant in an union with `bytes`
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:6:37: PYI051 `Literal[5]` is redundant in an union with `int`
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:6:67: PYI051 `Literal["foo"]` is redundant in an union with `str`
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:7:37: PYI051 `Literal[b"str_bytes"]` is redundant in an union with `bytes`
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:7:51: PYI051 `Literal[42]` is redundant in an union with `int`
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:9:31: PYI051 `Literal[1J]` is redundant in an union with `complex`
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:9:53: PYI051 `Literal[3.14]` is redundant in an union with `float`
Found 8 errors.
```

```shell
$ flake8 crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:4:18: Y051 "Literal['foo']" is redundant in a union with "str"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:5:37: Y051 "Literal[b'bar']" is redundant in a union with "bytes"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:6:37: Y051 "Literal[5]" is redundant in a unionwith "int"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:6:67: Y051 "Literal['foo']" is redundant in a union with "str"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:7:37: Y051 "Literal[b'str_bytes']" is redundantin a union with "bytes"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI051.pyi:7:51: Y051 "Literal[42]" is redundant in a union with "int"
```

While implementing this rule, I found a bug in the `is_unchecked_union`
check. This is the new check.


1ab86bad35/crates/ruff/src/checkers/ast/analyze/expression.rs (L85-L102)

The purpose of the check was to prevent rules from navigating through
nested `Union`s, as they already handle nested `Union`s. The way it was
implemented, this was not happening, the rules were getting executed
more than one time and sometimes were receiving expressions that were
not `Union`. For example, with the following code:
 ```python
  typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]
 ```

The rules were receiving the expressions in the following order:
- `typing.Union[Literal[5], int, typing.Union[Literal["foo"], str]]`
     - `Literal[5]`
     - `typing.Union[Literal["foo"], str]]`

This was causing `PYI030` to report redundant information, for example:
 ```python
typing.Union[Literal[5], int, typing.Union[Literal["foo"],
Literal["bar"]]]
 ```
This is the `PYI030` output for this code:
```shell
PYI030 Multiple literal members in a union. Use a single literal, e.g. `Literal[5, "foo", "bar"]`
YI030 Multiple literal members in a union. Use a single literal, e.g.`Literal[5, "foo"]`
```

If I haven't misinterpreted the rule, that looks incorrect. I didn't
have the time to check the `PYI016` rule.

The last thing is, I couldn't find a reason for the "Why is this bad?"
section for `PYI051`.

Ref: #848 

## Test Plan

Snapshots and manual runs of flake8.
\
2023-08-02 15:37:40 -04:00
Dhruv Manilawala 44bdf20221
[`pep8-naming`]: New config option `extend-ignore-names` (#6169)
## Summary

This PR adds a new config option for `pep8-naming` plugin called
`extend-ignore-names` which is used to extend the default values in
`ignore-names` option.

resolves: #6050
2023-07-29 17:11:04 +05:30
Victor Hugo Gomes e0d5c7564f
[`flake8-pyi`] Implement PYI049 (#6136)
## Summary

Checks for the presence of unused private `typing.TypedDict`
definitions.

ref #848 

## Test Plan

Snapshots and manual runs of flake8
2023-07-29 00:34:36 +00:00
Victor Hugo Gomes 7838d8c8af
Implement PYI047 (#6134)
## Summary

Checks for the presence of unused private `typing.TypeAlias`
definitions.

ref #848 

## Test Plan

Snapshots and manual runs of flake8
2023-07-29 00:21:29 +00:00
Aarni Koskela 3d54d31cd9
Implement E241 and E242 (tab/multiple ws after commas) (#6094)
## Summary

This PR implements pycodestyle's E241 (tab after comma) and E242
(multiple whitespace after comma) lints.

These are marked as nursery rules like many other pycodestyle rules.

Refs #2402

## Test Plan

E24.py copied from pycodestyle.
2023-07-27 18:58:41 +00:00
Jelle van der Waa 0853004f41
[pylint] Implement `eq-without-hash` rule (PLW1641) (#5955)
Implement
https://pylint.pycqa.org/en/latest/user_guide/messages/warning/eq-without-hash.html
Issue https://github.com/astral-sh/ruff/issues/970

It's not enabled by default in pylint, so I guess it shouldn't in Ruff
either?
2023-07-27 18:28:44 +00:00
Victor Hugo Gomes 86539c1fc5
[`flake8-pyi`] Implement `PYI046` (#6098)
## Summary
Checks for the presence of unused private `typing.Protocol` definitions.

ref #848 

## Test Plan

Snapshots and manual runs of flake8.
2023-07-27 02:34:56 +00:00
Simon Brugman ffdd653c54
[`flake8-use-pathlib`] Implement `glob` (`PTH207`) (#5939)
Discovered that the usage of `glob.glob` is
[widespread](https://grep.app/search?current=7&q=glob.glob%28&filter%5Blang%5D%5B0%5D=Python)
when working on the previous lints for `flake8-use-pathlib`.
2023-07-26 23:15:05 +00:00
Victor Hugo Gomes c0dbcb3434
[`flake8-pyi`] Implement PYI018 (#6018)
## Summary

Check for unused private `TypeVar`. See [original
implementation](2a86db8271/pyi.py (L1958)).

```
$ flake8 --select Y018 crates/ruff/resources/test/fixtures/flake8_pyi/PYI018.pyi

crates/ruff/resources/test/fixtures/flake8_pyi/PYI018.pyi:4:1: Y018 TypeVar "_T" is not used
crates/ruff/resources/test/fixtures/flake8_pyi/PYI018.pyi:5:1: Y018 TypeVar "_P" is not used
```

```
$ ./target/debug/ruff --select PYI018 crates/ruff/resources/test/fixtures/flake8_pyi/PYI018.pyi --no-cache

crates/ruff/resources/test/fixtures/flake8_pyi/PYI018.pyi:4:1: PYI018 TypeVar `_T` is never used
crates/ruff/resources/test/fixtures/flake8_pyi/PYI018.pyi:5:1: PYI018 TypeVar `_P` is never used
Found 2 errors.
```
In the file `unused_private_type_declaration.rs`, I'm planning to add
other rules that are similar to `PYI018` like the `PYI046`, `PYI047` and
`PYI049`.

ref #848

## Test Plan

Snapshots and manual runs of flake8.
2023-07-26 22:56:15 +00:00
Charlie Marsh 8113615534
Add some additional documentation around import categorization (#6107)
Closes https://github.com/astral-sh/ruff/issues/5529.
2023-07-26 22:39:01 +00:00
Charlie Marsh f9726af4ef
Allow specification of `logging.Logger` re-exports via `logger-objects` (#5750)
## Summary

This PR adds a `logger-objects` setting that allows users to mark
specific symbols a `logging.Logger` objects. Currently, if a `logger` is
imported, we only flagged it as a `logging.Logger` if it comes exactly
from the `logging` module or is `flask.current_app.logger`.

This PR allows users to mark specific loggers, like
`logging_setup.logger`, to ensure that they're covered by the
`flake8-logging-format` rules and others.

For example, if you have a module `logging_setup.py` with the following
contents:

```python
import logging

logger = logging.getLogger(__name__)
```

Adding `"logging_setup.logger"` to `logger-objects` will ensure that
`logging_setup.logger` is treated as a `logging.Logger` object when
imported from other modules (e.g., `from logging_setup import logger`).

Closes https://github.com/astral-sh/ruff/issues/5694.
2023-07-24 00:38:20 -04:00
Tom Kuson 727153cf45
[`pylint`] Impement `self-assigning-variable` (`W0127`) (#6015)
## Summary

Implements Pylint rule [`self-assigning-variable`
(`W0127`)](https://pylint.pycqa.org/en/latest/user_guide/messages/warning/self-assigning-variable.html)
as `self-assigning-variable` (`PLW0127`). Includes documentation.
Related to #970.

## Test Plan

`cargo test`
2023-07-24 02:27:09 +00:00
Tom Kuson 3b56f6d616
[`pylint`] Implement `subprocess-popen-preexec-fn` (`W1509`) (#5978)
## Summary

Implements Pylint rule [`subprocess-popen-preexec-fn`
(`W1509`)](https://pylint.pycqa.org/en/latest/user_guide/messages/warning/subprocess-popen-preexec-fn.html)
as `subprocess-popen-preexec-fn` (`PLW1509`). Includes documentation.
Related to #970.

## Test Plan

`cargo test`
2023-07-24 02:06:19 +00:00
Simon Brugman f886b58c92
[`flake8-use-pathlib`] Implement `os-sep-split` (`PTH206`) (#5936)
Implements
https://github.com/astral-sh/ruff/issues/5905#issuecomment-1644822548

---------

Co-authored-by: konsti <konstin@mailbox.org>
2023-07-23 12:22:26 +02:00
Victor Hugo Gomes 33657d3a1c
[`flake8-pyi`] Implement PYI056 (#5959)
## Summary

Checks that `append`, `extend` and `remove` methods are not called on
`__all__`. See [original
implementation](2a86db8271/pyi.py (L1133-L1138)).

```
$ flake8 --select Y026 crates/ruff/resources/test/fixtures/flake8_pyi/PYI056.pyi

crates/ruff/resources/test/fixtures/flake8_pyi/PYI056.pyi:3:1: Y056 Calling ".append()" on "__all__" may not be supported by all type checkers (use += instead)
crates/ruff/resources/test/fixtures/flake8_pyi/PYI056.pyi:4:1: Y056 Calling ".extend()" on "__all__" may not be supported by all type checkers (use += instead)
crates/ruff/resources/test/fixtures/flake8_pyi/PYI056.pyi:5:1: Y056 Calling ".remove()" on "__all__" may not be supported by all type checkers (use += instead)
```

```
$ ./target/debug/ruff --select PYI026 crates/ruff/resources/test/fixtures/flake8_pyi/PYI056.pyi --no-cache

crates/ruff/resources/test/fixtures/flake8_pyi/PYI056.pyi:3:1: PYI056 Calling ".append()" on "__all__" may not be supported by all type checkers (use += instead)
crates/ruff/resources/test/fixtures/flake8_pyi/PYI056.pyi:4:1: PYI056 Calling ".extend()" on "__all__" may not be supported by all type checkers (use += instead)
crates/ruff/resources/test/fixtures/flake8_pyi/PYI056.pyi:5:1: PYI056 Calling ".remove()" on "__all__" may not be supported by all type checkers (use += instead)
Found 3 errors.
```

ref #848

## Test Plan

Snapshots and manual runs of flake8.
2023-07-22 04:25:54 +00:00
qdegraaf 2cde9b8aa6
[`flake8-pyi`] Implement PYI017 (#5895)
## Summary

Implements `PYI017` or `Y017` from `flake8-pyi` plug-in. Mirrors
[upstream
implementation](ceab86d16b/pyi.py (L1039-L1048)).
It checks for any assignment with more than 1 target or an assignment to
anything other than a name, and raises a violation for these in stub
files.

Couldn't find a clear and concise explanation for why this is to be
avoided and what is preferred for attribute cases like:

```python
a.b = int
```
So welcome some input there, to learn and to finish up the docs.

## Test Plan

Added test cases from upstream plug-in in a fixture (both `.py` and
`.pyi`). Added a few more.

## Issue link

Refers: https://github.com/astral-sh/ruff/issues/848
2023-07-20 16:35:38 +00:00
Simon Brugman 4bba0bcab8
[`flake8-use-pathlib`] Implement `os-path-getsize` and `os-path-get(a|m|c)-time` (`PTH202-205`) (#5835)
Reviving https://github.com/astral-sh/ruff/pull/2348 step by step

Pt 3. implement detection for:
- `os.path.getsize`
- `os.path.getmtime`
- `os.path.getctime`
- `os.path.getatime`
2023-07-20 02:05:13 +00:00
Simon Brugman d35cb6942f
[`flake8-use-pathlib`] Implement `path-constructor-default-argument` (`PTH201`) (#5833)
Reviving https://github.com/astral-sh/ruff/pull/2348 step by step

Pt 2. PTH201: Path Constructor Default Argument

- rule originates from `refurb`:
https://github.com/charliermarsh/ruff/issues/1348
- Using PTH201 rather than FURBXXX to keep all pathlib logic together
2023-07-20 01:50:54 +00:00
Victor Hugo Gomes a37d91529b
[`flake8-pyi`] Implement PYI026 (#5844)
## Summary
Checks for `typehint.TypeAlias` annotation in type aliases. See
[original
source](https://github.com/PyCQA/flake8-pyi/blob/main/pyi.py#L1085).
```
$ flake8 --select Y026 crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:4:1: Y026 Use typing_extensions.TypeAlias for type aliases, e.g. "NewAny: TypeAlias = Any"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:5:1: Y026 Use typing_extensions.TypeAlias for type aliases, e.g. "OptinalStr: TypeAlias = typing.Optional[str]"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:6:1: Y026 Use typing_extensions.TypeAlias for type aliases, e.g. "Foo: TypeAlias = Literal['foo']"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:7:1: Y026 Use typing_extensions.TypeAlias for type aliases, e.g. "IntOrStr: TypeAlias = int | str"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:8:1: Y026 Use typing_extensions.TypeAlias for type aliases, e.g. "AliasNone: TypeAlias = None"
```

```
$ ./target/debug/ruff --select PYI026 crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi --no-cache
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:4:1: PYI026 Use `typing.TypeAlias` for type aliases in `NewAny`, e.g. "NewAny: typing.TypeAlias = Any"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:5:1: PYI026 Use `typing.TypeAlias` for type aliases in `OptinalStr`, e.g. "OptinalStr: typing.TypeAlias = typing.Optional[str]"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:6:1: PYI026 Use `typing.TypeAlias` for type aliases in `Foo`, e.g. "Foo: typing.TypeAlias = Literal["foo"]"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:7:1: PYI026 Use `typing.TypeAlias` for type aliases in `IntOrStr`, e.g. "IntOrStr: typing.TypeAlias = int | str"
crates/ruff/resources/test/fixtures/flake8_pyi/PYI026.pyi:8:1: PYI026 Use `typing.TypeAlias` for type aliases in `AliasNone`, e.g. "AliasNone: typing.TypeAlias = None"
Found 5 errors.
```

ref: #848 

## Test Plan

Snapshots, manual runs of flake8.
2023-07-20 01:39:55 +00:00
konsti a459d8ffc7
Filter off-by-default RUF014 out of schema (#5832)
**Summary** Previously, `RUF014` would be part of ruff.schema.json
depending on whether or not the `unreachable-code` feature was active.
This caused problems for contributors who got unrelated RUF014 changes
when updating the schema without the feature active.

An alternative would be to always add `RUF014`.

**Test plan** `cargo dev generate-all` and `cargo run --bin ruff_dev
--features unreachable-code -- generate-all` now have the same effect.
2023-07-19 21:06:10 +00:00
Charlie Marsh 598549d24e
Fix incorrect reference in `extend-immutable-calls` documentation (#5890) 2023-07-19 19:57:05 +00:00
Charlie Marsh 8001a2f121
Expand convention documentation (#5819) 2023-07-17 14:12:46 +00:00
Simon Brugman de2a13fcd7
[`pandas-vet`] series constant series (#5802)
## Summary

Implementation for https://github.com/astral-sh/ruff/issues/5588

Q1: are there any additional semantic helpers that could be used to
guard this rule? Which existing rules should be similar in that respect?
Can we at least check if `pandas` is imported (any pointers welcome)?
Currently, the rule flags:
```python
data = {"a": "b"}
data.nunique() == 1
```

Q2: Any pointers on naming of the rule and selection of the code? It was
proposed, but not replied to/implemented in the upstream. `pandas` did
accept a PR to update their cookbook to reflect this rule though.

## Test Plan

TODO:
- [X] Checking for ecosystem CI results
- [x] Test on selected [real-world
cases](https://github.com/search?q=%22nunique%28%29+%3D%3D+1%22+language%3APython+&type=code)
  - [x] https://github.com/sdv-dev/SDMetrics
  - [x] https://github.com/google-research/robustness_metrics
  - [x] https://github.com/soft-matter/trackpy
  - [x] https://github.com/microsoft/FLAML/
- [ ] Add guarded test cases
2023-07-17 01:55:34 +00:00
Justin Prieto 25e491ad6f
[`flake8-pyi`] Implement PYI041 (#5722)
## Summary

Implements PYI041 from flake8-pyi. See [original
code](2a86db8271/pyi.py (L1283)).

This check only applies to function parameters in order to avoid issues
with mypy. See https://github.com/PyCQA/flake8-pyi/issues/299.

ref: #848

## Test Plan

Snapshots, manual runs of flake8.
2023-07-13 16:48:17 +00:00
Justin Prieto 19f475ae1f
[`flake8-pyi`] Implement PYI036 (#5668)
## Summary

Implements PYI036 from `flake8-pyi`. See [original
code](https://github.com/PyCQA/flake8-pyi/blob/main/pyi.py#L1585)

## Test Plan

- Updated snapshots
- Checked against manual runs of flake8

ref: #848
2023-07-13 02:50:00 +00:00
Tom Kuson 2b03bd18f4
Implement Pylint `consider-using-in` (#5193)
## Summary

Implement Pylint rule [`consider-using-in`
(`R1714`)](https://pylint.pycqa.org/en/latest/user_guide/messages/refactor/consider-using-in.html)
as `repeated-equality-comparison-target` (`PLR1714`). This rule checks
for expressions that can be re-written as a membership test for better
readability and performance.

For example,

```python
foo == "bar" or foo == "baz" or foo == "qux"
```

should be rewritten as

```python
foo in {"bar", "baz", "qux"}
```

Related to #970. Includes documentation.

### Implementation quirks

The implementation does not work with Yoda conditions (e.g., `"a" ==
foo` instead of `foo == "a"`). The Pylint version does. I couldn't find
a way of supporting Yoda-style conditions without it being inefficient,
so didn't (I don't think people write Yoda conditions any way).

## Test Plan

Added fixture.

`cargo test`
2023-07-13 01:32:34 +00:00
Zanie 0666added9
Add RUF016: Detection of invalid index types (#5602)
Detects invalid types for tuple, list, bytes, string indices.

For example, the following will raise a `TypeError` at runtime and when
imported Python will display a `SyntaxWarning`

```python
var = [1, 2, 3]["x"]
```

```
example.py:1: SyntaxWarning: list indices must be integers or slices, not str; perhaps you missed a comma?
  var = [1, 2, 3]["x"]
Traceback (most recent call last):
  File "example.py", line 1, in <module>
    var = [1, 2, 3]["x"]
          ~~~~~~~~~^^^^^
TypeError: list indices must be integers or slices, not str
```

Previously, Ruff would not report the invalid syntax but now a violation
will be reported. This does not apply to cases where a variable, call,
or complex expression is used in the index — detection is roughly
limited to static definitions, which matches Python's warnings.

```
❯ ./target/debug/ruff example.py --select RUF015 --show-source --no-cache
example.py:1:17: RUF015 Indexed access to type `list` uses type `str` instead of an integer or slice.
  |
1 | var = [1, 2, 3]["x"]
  |                 ^^^ RUF015
  |
```

Closes https://github.com/astral-sh/ruff/issues/5082
xref
ffff1440d1
2023-07-12 00:23:06 -05:00
Charlie Marsh 9f486fa841
[`flake8-bugbear`] Implement `re-sub-positional-args` (`B034`) (#5669)
## Summary

Needed to do some coding to end the day.

Closes #5665.
2023-07-11 03:52:55 +00:00
Evan Rittenhouse 28fe2d334a
Implement `UnnecessaryListAllocationForFirstElement` (#5549)
## Summary

Fixes #5503. Ready for final review as the `mkdocs` issue involving SSH
keys is fixed.

Note that this will only throw on a `Name` - it will be refactorable
once we have a type-checker. This means that this is the only sort of
input that will throw.
```python
x = range(10)
list(x)[0]
```

I thought it'd be confusing if we supported direct function results.
Consider this example, assuming we support direct results:
```python
# throws
list(range(10))[0]

def createRange(bound):
    return range(bound)

# "why doesn't this throw, but a direct `range(10)` call does?"
list(createRange(10))[0]
```
If it's necessary, I can go through the list of built-ins and find those
which produce iterables, then add them to the throwing list.

## Test Plan

Added a new fixture, then ran `cargo t`
2023-07-10 16:32:41 +00:00
Tom Kuson 3562d809b2
[`pylint`] Implement Pylint `typevar-name-incorrect-variance` (`C0105`) (#5651)
## Summary

Implement Pylint `typevar-name-incorrect-variance` (`C0105`) as
`type-name-incorrect-variance` (`PLC0105`). Includes documentation.
Related to #970.

The Pylint implementation checks only `TypeVar`, but this PR checks
`ParamSpec` as well.

## Test Plan

Added test fixture.

`cargo test`
2023-07-10 12:28:44 -04:00
konsti d0dae7e576
Fix CI by downgrading to cargo insta 1.29.0 (#5589)
Since the (implicit) update to cargo-insta 1.30, CI would pass even when
the tests failed. This downgrades to cargo insta 1.29.0 and CI fails
again when it should (which i can't show here, because CI needs to pass
to merge this PR). I've improved the unreferenced snapshot handling in
the process

See https://github.com/mitsuhiko/insta/issues/392
2023-07-08 14:54:49 +00:00
Zanie bb7303f867
Implement PYI030: Unnecessary literal union (#5570)
Implements PYI030 as part of
https://github.com/astral-sh/ruff/issues/848

> Union expressions should never have more than one Literal member, as
Literal[1] | Literal[2] is semantically identical to Literal[1, 2].

Note we differ slightly from the flake8-pyi implementation:

- We detect cases where there are parentheses or nested unions
- We detect cases with mixed `Union` and `|` syntax
- We use the same error message for all violations; flake8-pyi has two
different messages
- We retain the user's quoting style when displaying string literals;
flake8-pyi uses single quotes
- We warn on duplicates of the same literal `Literal[1] | Literal[1]`
2023-07-07 16:43:10 +00:00
Charlie Marsh b11492e940
Fix remaining Copyright rule references (#5577) 2023-07-07 02:49:19 +00:00
Charlie Marsh cd4718988a
Update JSON schema (#5576)
Confused as to how this got merged, but... oh well.
2023-07-06 22:38:39 -04:00
qdegraaf 6f548d9872
`[isort]` Add `--case-sensitive` flag (#5539)
## Summary

Adds a `--case-sensitive` setting/flag to isort (default: `false`)
which, when set to `true` sorts imports case sensitively instead of case
insensitively.

Tests and Docs can be improved, can do that if the general idea of the
implementation is in order.

First `isort` edit so any and all feedback is welcomed even more than
usual.

## Test Plan

Added a fixture with an assortment of imports in various cases.

## Issue links

Closes: https://github.com/astral-sh/ruff/issues/5514
2023-07-05 16:10:53 -04:00
Tom Kuson 9478454b96
[`pylint`] Implement Pylint `typevar-double-variance` (`C0131`) (#5517)
## Summary

Implement Pylint `typevar-double-variance` (`C0131`) as
`type-bivariance` (`PLC0131`). Includes documentation. Related to #970.
Renamed the rule to be more clear (it's not immediately obvious what
'double' means, IMO).

The Pylint implementation checks only `TypeVar`, but this PR checks
`ParamSpec` as well.

## Test Plan

Added tests.

`cargo test`
2023-07-05 14:53:41 -04:00
Tom Kuson 0e67757edb
[`pylint`] Implement Pylint `typevar-name-mismatch` (`C0132`) (#5501)
## Summary

Implement Pylint `typevar-name-mismatch` (`C0132`) as
`type-param-name-mismatch` (`PLC0132`). Includes documentation. Related
to #970.

The Pylint implementation checks only `TypeVar`, but this PR checks
`TypeVarTuple`, `ParamSpec`, and `NewType` as well. This seems to better
represent the Pylint rule's [intended
behaviour](https://github.com/pylint-dev/pylint/issues/5224).

Full disclosure: I am not a fan of the translated name and think it
should probably be different.

## Test Plan

`cargo test`
2023-07-04 18:49:43 +00:00
Charlie Marsh 75da72bd7f
Update documentation to list double-quote preference first (#5507)
Closes https://github.com/astral-sh/ruff/issues/5496.
2023-07-04 18:06:01 +00:00
qdegraaf 93b2bd7184
[`perflint`] Add `PERF401` and `PERF402` rules (#5298)
## Summary

Adds `PERF401` and `PERF402` mirroring `W8401` and `W8402` from
https://github.com/tonybaloney/perflint

Implementation is not super smart but should be at parity with upstream
implementation judging by:
c07391c176/perflint/comprehension_checker.py (L42-L73)

It essentially checks:

- If the body of a for-loop is just one statement
- If that statement is an `if` and the if-statement contains a call to
`append()` we flag `PERF401` and suggest a list comprehension
- If that statement is a plain call to `append()` or `insert()` we flag
`PERF402` and suggest `list()` or `list.copy()`

I've set the violation to only flag the first append call in a long
`if-else` statement for `PERF401`. Happy to change this to some other
location or make it multiple violations if that makes more sense.

## Test Plan

Fixtures were added with the relevant scenarios for both rules

## Issue Links

Refers: https://github.com/astral-sh/ruff/issues/4789
2023-07-03 04:03:09 +00:00
Justin Prieto 0bff4ed4d3
[`flake8-pyi`] Implement PYI002, PYI003, PYI004, PYI005 (#5457)
## Summary

Implements flake8-pyi checks 002, 003, 004, 005. The logic is a bit
complex, as you can see in the [original
code](57921813c1/pyi.py (L1403C18-L1403C18)).

ref: #848 

## Test Plan

Updated snapshot tests. Ran flake8 to double check lints, and ran ruff
with all PYI lints enabled to check for incorrect overlapping lint
errors.
2023-07-02 23:52:16 -04:00
Charlie Marsh c8b9a46e2b
[`pyupgrade`] Restore the `keep-runtime-typing` setting (#5470)
## Summary

This PR reverts #4427. See the included documentation for a detailed
explanation.

Closes #5434.
2023-07-03 02:11:31 +00:00
Tom Kuson a0a93a636f
Implement Pylint `single-string-used-for-slots` (`C0205`) as `single-string-slots` (`PLC0205`) (#5399)
## Summary

Implement Pylint rule `single-string-used-for-slots` (`C0205`) as
`single-string-slots` (`PLC0205`). This rule checks for single strings
being assigned to `__slots__`. For example

```python
class Foo:
    __slots__: str = "bar"

    def __init__(self, bar: str) -> None:
        self.bar = bar
```

should be

```python
class Foo:
    __slots__: tuple[str, ...] = ("bar",)

    def __init__(self, bar: str) -> None:
        self.bar = bar
```

Related to #970. Includes documentation.

## Test Plan

`cargo test`
2023-06-27 18:33:58 +00:00
Evan Rittenhouse 190bed124f
[`perflint`] Implement `try-except-in-loop` (`PERF203`) (#5166)
## Summary

Implements PERF203 from #4789, which throws if a `try/except` block is
inside of a loop. Not sure if we want to extend the diagnostic to the
`except` as well, but I thought that that may get a little messy. We may
also want to just throw on the word `try` - open to suggestions though.

## Test Plan
`cargo test`
2023-06-26 17:34:37 +00:00
qdegraaf 38e618cd18
[`perflint`] Add `PERF101` with autofix (#5121)
## Summary

Adds PERF101 which checks for unnecessary casts to `list` in for loops. 

NOTE: Is not fully equal to its upstream implementation as this
implementation does not flag based on type annotations
(i.e.):
```python
def foo(x: List[str]):
    for y in list(x):
        ...
```

With the current set-up it's quite hard to get the annotation from a
function arg from its binding. Problem is best considered broader than
this implementation.

## Test Plan

Added fixture. 

## Issue links

Refers: https://github.com/astral-sh/ruff/issues/4789

---------

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-06-22 20:44:26 +00:00
Charlie Marsh 8bc7378002
Add `PythonVersion::Py312` (#5316)
Closes #5310.
2023-06-22 20:01:07 +00:00
Charlie Marsh 62e2c46f98
Move `compare-to-empty-string` to nursery (#5264)
## Summary

This rule has too many false positives. It has parity with the Pylint
version, but the Pylint version is part of an
[extension](https://pylint.readthedocs.io/en/stable/user_guide/messages/convention/compare-to-empty-string.html),
and so requires explicit opt-in.

I'm moving this rule to the nursery to require explicit opt-in, as with
Pylint.

Closes #4282.
2023-06-21 19:47:02 +00:00
Charlie Marsh 07b6b7401f
Move `copyright` rules to `flake8_copyright` module (#5236)
## Summary

I initially wanted this category to be more general and decoupled from
the plugin, but I got some feedback that the titling felt inconsistent
with others.
2023-06-21 01:56:40 +00:00
Charlie Marsh 015895bcae
Move copyright rule to nursery (#5197)
## Summary

I want this to be explicitly opted-into.
2023-06-19 21:41:47 -04:00
konstin 916f0889f8
Add pyproject.toml to include option doc (#5080)
Fixes an oversight where i didn't update this initially
2023-06-14 15:55:12 +00:00
Thomas de Zeeuw b0f89fa814
Support glob patterns in pep8_naming ignore-names (#5024)
## Summary

 Support glob patterns in pep8_naming ignore-names.

Closes #2787

## Test Plan

Added new tests.
2023-06-13 17:37:13 +02:00
Aarni Koskela 7b4dde0c6c
Add JSON Lines (NDJSON) message serialization (#5048)
## Summary

This adds `json-lines` (https://jsonlines.org/ or http://ndjson.org/) as
an output format.

I'm sure you already know, but

* JSONL is more greppable (each record is a single line) than the pretty
JSON
* JSONL is faster to ingest piecewise (and/or in parallel) than JSON

## Test Plan

Snapshot test in the new module :)
2023-06-13 14:15:55 +00:00
qdegraaf a477720f4e
[`perflint`] Add `perflint` plugin, add first rule `PERF102` (#4821)
## Summary

Adds boilerplate for implementing the
[perflint](https://github.com/tonybaloney/perflint/) plugin, plus a
first rule.

## Test Plan

Fixture added for PER8102

## Issue link

Refers: https://github.com/charliermarsh/ruff/issues/4789
2023-06-13 01:54:44 +00:00
Charlie Marsh 54e103fc99
Add a rule to remove unnecessary parentheses in class definitions (#5032)
Closes #2409.
2023-06-12 18:43:06 +00:00
Dhruv Manilawala 3470dee7d4
Add rule to disallow implicit optional with autofix (#4831)
## Summary

Add rule to disallow implicit optional with autofix.

Currently, I've added it under `RUF` category.

### Limitation

Type aliases could result in false positive:

```python
from typing import Optional

StrOptional = Optional[str]


def foo(arg: StrOptional = None):
	pass
```

## Test Plan

`cargo test`

resolves: #1983

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-06-12 18:12:10 +00:00
Adam Pauls 638c18f007
Expand RUF008 to all classes, but to a new code (RUF012) (#4390)
AFAIK, there is no reason to limit RUF008 to just dataclasses -- mutable
defaults have the same problems for regular classes.

Partially addresses https://github.com/charliermarsh/ruff/issues/4053
and broken out from https://github.com/charliermarsh/ruff/pull/4096.

---------

Co-authored-by: Micha Reiser <micha@reiser.io>
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-06-12 16:54:27 +00:00
Thomas de Zeeuw 8161757229
[flake8-pyi] Implement PYI044 (#5021)
## Summary

This implements PYI044. This rule checks if `from __future__ import
annotations` is used in stub files as it has no effect in stub files, since type
checkers automatically treat stubs as having those semantics.

Updates https://github.com/astral-sh/ruff/issues/848

## Test Plan

Added a test case and snapshots.
2023-06-12 13:20:16 +02:00
Ryan Yang ab3c02342b
Implement copyright notice detection (#4701)
## Summary

Add copyright notice detection to enforce the presence of copyright
headers in Python files.

Configurable settings include: the relevant regular expression, the
author name, and the minimum file size, similar to
[flake8-copyright](https://github.com/savoirfairelinux/flake8-copyright).

Closes https://github.com/charliermarsh/ruff/issues/3579

---------

Signed-off-by: ryan <ryang@waabi.ai>
Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-06-11 02:17:58 +00:00
qdegraaf 2bb32ee943
[`flake8-slots`] Add plugin, add `SLOT000`, `SLOT001` and `SLOT002` (#4909) 2023-06-09 04:14:16 +00:00
rodjunger ee1f094834
[`ruff`] Add a rule for static keys in dict comprehensions (#4929) 2023-06-09 02:06:34 +00:00
Tom Kuson 2c19000e4a
Add Pylint rule `comparison-with-itself` (`R0124`) (#4957) 2023-06-09 00:57:50 +00:00
Charlie Marsh 20240fc3d9
Move flake8-fixme rules to FIX prefix (#4917) 2023-06-07 21:14:49 +00:00
Charlie Marsh ec609f5c3b
Clarify requires-python inference requirements (#4918) 2023-06-07 04:18:56 +00:00
Justin Prieto b9060ea2bd
[`flake8-pyi`] Implement PYI050 (#4884) 2023-06-07 01:56:53 +00:00
Charlie Marsh c67029ded9
Move duplicate-value rule to flake8-bugbear (#4882) 2023-06-05 21:43:47 +00:00
Justin Prieto f9e82f2578
[`flake8-pyi`] Implement PYI029 (#4851) 2023-06-05 19:21:16 +00:00
Ryan Yang 72245960a1
implement E307 for pylint invalid str return type (#4854) 2023-06-05 17:54:15 +00:00
Justin Prieto e82160a83a
[`flake8-pyi`] Implement PYI035 (#4820) 2023-06-03 03:13:04 +00:00
Ville Skyttä 0a5dfcb26a
Implement S609, linux_commands_wildcard_injection (#4504) 2023-06-02 18:19:02 +00:00
Evan Rittenhouse b2498c576f
Implement `flake8_fixme` and refactor `TodoDirective` (#4681) 2023-06-02 08:18:47 +02:00
qdegraaf fcbf5c3fae
Add PYI034 for `flake8-pyi` plugin (#4764) 2023-06-02 02:15:57 +00:00
Justin Prieto c68686b1de
[`flake8-pyi`] Implement PYI054 (#4775) 2023-06-02 01:21:27 +00:00
Justin Prieto 583411a29f
[`flake8-pyi`] Implement PYI053 (#4770) 2023-06-01 23:00:15 +00:00
qdegraaf 6d94aa89e3
[`flake8-pyi`] Implement `PYI025` (#4791) 2023-06-01 22:45:31 +00:00
Jonathan Plasse edadd7814f
Add `pyflakes.extend-generics` setting (#4677) 2023-06-01 22:19:37 +00:00
Tom Kuson bdff4a66ac
Add Pylint rule `C0208` (`use-sequence-for-iteration`) as `PLC0208` (`iteration-over-set`) (#4706) 2023-06-01 21:26:23 +00:00
qdegraaf 2b2812c4f2
Add PYI024 for `flake8-pyi` plugin (#4756) 2023-05-31 16:07:04 +00:00
Aarni Koskela 0106bce02f
[`flake8-future-annotations`] Implement `FA102` (#4702) 2023-05-29 22:41:45 +00:00
Justin Prieto d0ad4be20e
[`flake8-pyi`] Implement `PYI045` (#4700) 2023-05-29 21:27:13 +00:00
Julian LaNeve 68db74b3c5
Add AIR001: task variable name should be same as task_id arg (#4687) 2023-05-29 03:25:06 +00:00
Charlie Marsh 9646bc7d7f
Add docs to clarify project root heuristics (#4697) 2023-05-29 02:50:35 +00:00
qdegraaf 0911ce4cbc
[`flake8-pyi`] Add `PYI032` rule with autofix (#4695) 2023-05-28 22:41:15 +00:00
Chris Chan 1268ddca92
Implement Pylint's `yield-inside-async-function` rule (`PLE1700`) (#4668) 2023-05-27 01:14:41 +00:00
qdegraaf 52deeb36ee
Implement PYI048 for `flake8-pyi` plugin (#4645) 2023-05-25 20:04:14 +00:00
konstin b6a382eeaf
Lint pyproject.toml (#4496)
This adds a new rule `InvalidPyprojectToml` that lints pyproject.toml by checking if https://github.com/PyO3/pyproject-toml-rs can parse it. This means the linting is currently very basic, e.g. we don't check whether the name is actually a valid python project name or appropriately normalized. It does catch errors e.g. with invalid dependency requirements or problems withs the license specifications. It is open to be extended in the future (validate name, SPDX expressions, classifiers, ...), either in ruff or in pyproject-toml-rs.

Test plan:

```
scripts/ecosystem_all_check.sh check --select RUF200
```
This lead to a bunch of 
```
RUF200 Failed to parse pyproject.toml: missing field `name`
```
(e.g. https://github.com/amitsk/fastapi-todos/blob/main/pyproject.toml) which is indeed invalid (https://packaging.python.org/en/latest/specifications/declaring-project-metadata/#specification).

Filtering those out, the following other problems were found by `cd target/ecosystem_all_results/ && rg RUF200`:
```
UCL-ARC:rred-reports.stdout.txt
1:pyproject.toml:27:16: RUF200 Failed to parse pyproject.toml: Version specifier `>='3.9'` doesn't match PEP 440 rules
EndlessTrax:python-start-project.stdout.txt
1:pyproject.toml:14:16: RUF200 Failed to parse pyproject.toml: Expected package name starting with an alphanumeric character, found '#'
redjax:gardening-api.stdout.txt
1:pyproject.toml:7:11: RUF200 Failed to parse pyproject.toml: Version `` doesn't match PEP 440 rules
ajslater:codex.stdout.txt
2:  3:17 RUF200 Failed to parse pyproject.toml: invalid type: sequence, expected a string
LDmitriy7:404_AvatarsBot.stdout.txt
1:pyproject.toml:3:11: RUF200 Failed to parse pyproject.toml: Version `` doesn't match PEP 440 rules
ajslater:comicbox.stdout.txt
1:pyproject.toml:3:17: RUF200 Failed to parse pyproject.toml: invalid type: sequence, expected a string
manueldevillena:forecast-earnings.stdout.txt
1:pyproject.toml:24:12: RUF200 Failed to parse pyproject.toml: Expected one of `@`, `(`, `<`, `=`, `>`, `~`, `!`, `;`, found `^`
redjax:ohio_utility_scraper.stdout.txt
1:pyproject.toml:11:11: RUF200 Failed to parse pyproject.toml: Version `` doesn't match PEP 440 rules
agronholm:typeguard.stdout.txt
1:pyproject.toml:40:8: RUF200 Failed to parse pyproject.toml: Expected a valid marker name, found 'python_implementation'
cyuss:decathlon-turnover.stdout.txt
1:pyproject.toml:7:12: RUF200 Failed to parse pyproject.toml: invalid type: string "Youcef", expected a table with 'name' and 'email' keys
ajslater:boilerplate.stdout.txt
1:pyproject.toml:3:17: RUF200 Failed to parse pyproject.toml: invalid type: sequence, expected a string
kaparoo:lightning-project-template.stdout.txt
1:pyproject.toml:56:16: RUF200 Failed to parse pyproject.toml: You can't mix a >= operator with a local version (`+cu117`)
dijital20:pytexas2023-decorators.stdout.txt
1:pyproject.toml:5:11: RUF200 Failed to parse pyproject.toml: Version `` doesn't match PEP 440 rules
pfouque:django-anymail-history.stdout.txt
1:pyproject.toml:137:12: RUF200 Failed to parse pyproject.toml: Version specifier `> = 1.2.0` doesn't match PEP 440 rules
pfouque:django-fakemessages.stdout.txt
1:pyproject.toml:130:12: RUF200 Failed to parse pyproject.toml: Version specifier `> = 1.2.0` doesn't match PEP 440 rules
pypa:build.stdout.txt
1:tests/packages/test-invalid-requirements/pyproject.toml:2:12: RUF200 Failed to parse pyproject.toml: Expected one of `@`, `(`, `<`, `=`, `>`, `~`, `!`, `;`, found `i`
4:tests/packages/test-no-requires/pyproject.toml:1:1: RUF200 Failed to parse pyproject.toml: missing field `requires`
UnoYakshi:FRAAND.stdout.txt
2:  3:11 RUF200 Failed to parse pyproject.toml: Version `` doesn't match PEP 440 rules
DHolmanCoding:python-template.stdout.txt
1:pyproject.toml:22:1: RUF200 Failed to parse pyproject.toml: missing field `requires`
```
Overall, this emitted errors in 43 out of 3408 projects (`rg -c RUF200 target/ecosystem_all_results/ | wc -l`)


Co-authored-by: Micha Reiser <micha@reiser.io>
2023-05-25 12:05:28 +00:00
Jonathan Plasse c6a760e298
Introduce `tab-size` to correcly calculate the line length with tabulations (#4167) 2023-05-24 08:37:24 +02:00
Charlie Marsh f22c269ccf
Point LSP, VS Code, and pre-commut URLs to Astral org (#4562) 2023-05-21 15:27:35 -04:00
Hoël Bagard fe8e2bb237
[`pylint`] Add `named_expr_without_context` (`W0131`) (#4531) 2023-05-19 18:00:01 +00:00
Aaron Cunningham 41a681531d
Support new `extend-per-file-ignores` setting (#4265) 2023-05-19 12:24:04 -04:00
Justin Prieto 837e70677b
[`flake8-pyi`] Implement `PYI013` (#4517) 2023-05-19 15:39:55 +00:00
Hoël Bagard 7ebe372122
[`pylint`] Add `duplicate-value` (`W0130`) (#4515) 2023-05-19 15:03:47 +00:00
Ville Skyttä fdb241cad2
[`flake8-bandit`] Implement `paramiko-call` (`S601`) (#4500) 2023-05-19 03:40:50 +00:00
Charlie Marsh 15cb21a6f4
Implement `--extend-fixable` option (#4297) 2023-05-18 22:20:19 -04:00
John Kelly 9c732c7946
Implement TRY302 - `raise` after `except` (#4461) 2023-05-17 01:36:10 +00:00
Charlie Marsh 6b1062ccc3
Enable `pycodestyle` rules under new "nursery" category (#4407) 2023-05-16 21:21:58 +00:00
Charlie Marsh 39fa38cb35
Enable `pycodestyle` rules (#3689) 2023-05-16 20:39:43 +00:00
Sladyn c711db11ce
[`flake8-pyi`] Implement `unannotated-assignment-in-stub` (`PY052`) (#4293) 2023-05-16 02:06:55 +00:00
qdegraaf 8ba9eb83af
Implement `flake8-async` plugin (#4432) 2023-05-15 09:15:28 -04:00
Charlie Marsh dcff515ad8
Make `extend_function_names` an `Option` type (#4434) 2023-05-15 02:15:02 +00:00
Charlie Marsh a69451ff46
[`pyupgrade`] Remove `keep-runtime-typing` setting (#4427) 2023-05-14 03:12:52 +00:00
Tyler Yep 01b372a75c
Implement `flake8-future-annotations` FA100 (#3979) 2023-05-14 03:00:06 +00:00
alm 0a68636de3
[`pylint`] Add `duplicate-bases` rule (#4411) 2023-05-13 14:28:03 +00:00
Evan Rittenhouse 2f53781a77
Implement `flake8_todos` (#3921) 2023-05-13 14:19:06 +00:00
Lotem 52f6663089
Implement `RUF010` to detect explicit type conversions within f-strings (#4387) 2023-05-12 18:12:58 +00:00
Charlie Marsh 865205d992
Implement pygrep-hook's Mock-mistake diagnostic (#4366) 2023-05-11 03:26:29 +00:00
Charlie Marsh a435c0df4b
Remove deprecated `update-check` setting (#4313) 2023-05-09 13:10:02 -04:00
Aarni Koskela efdf383f5e
Implement Flynt static string join transform as FLY002 (#4196) 2023-05-08 20:46:38 -04:00
Trevor McCulloch 3beff29026
[`pylint`] Implement `nested-min-max` (`W3301`) (#4200) 2023-05-07 03:14:14 +00:00
Chris Chan c2921e957b
[`pylint`] Implement import-self (`W0406`) (#4154) 2023-05-04 16:05:15 -04:00
Arya Kumar e9e194ab32
[`flake8-pyi`] Implement `PYI042` and `PYI043` (#4214) 2023-05-04 14:35:26 -04:00
Arya Kumar 37aae666c7
[flake8-pyi] PYI020 (#4211) 2023-05-03 22:37:32 -04:00
Moritz Sauter ee6d8f7467
Add bugbear immutable functions as allowed in dataclasses (#4122) 2023-04-27 21:23:06 -04:00
Trevor McCulloch bbf658d4c5
[`pylint`] Implement PLE0302 `unexpected-special-method-signature` (#4075) 2023-04-25 04:51:21 +00:00
Edgar R. M cfc7d8a2b5
[`flake8-import-conventions`] Implement new rule `ICN003` to ban `from ... import ...` for selected modules (#4040) 2023-04-23 04:40:36 +00:00
Charlie Marsh c457752f36
Redirect `PIE802` to `C419` (#3971) 2023-04-13 22:12:32 -04:00
Charlie Marsh 289289bfd3
Implement `unnecessary-literal-within-dict-call` (`C418`) (#3969) 2023-04-14 01:39:35 +00:00
Paul 2d2630ef07
Implement isort custom sections and ordering (#2419) (#3900) 2023-04-13 21:28:22 +00:00
Rob Young a6a7584d79
Implement `flake8-bandit` shell injection rules (#3924) 2023-04-13 14:45:27 -04:00
USER-5 860841468c
[`flake8-pyi`] Implement duplicate types in unions (`PYI016`) (#3922) 2023-04-12 04:06:09 +00:00
Charlie Marsh b999e4b1e2
Allow users to extend the set of included files via `include` (#3914) 2023-04-11 23:39:43 -04:00
Daniel Stancl 523515f936
[`flake8-import-conventions`] Add a rule for `BannedImportAlias` (#3926) 2023-04-12 03:29:24 +00:00
Moritz Sauter d4af2dd5cf
[`ruff`] Add checks for mutable defaults in `dataclass`es (#3877) 2023-04-09 02:46:28 +00:00
Charlie Marsh e0bccfd2d9
Allow legacy C and T selectors in JSON schema (#3889) 2023-04-05 17:58:36 +00:00
kyoto7250 46bcb1f725
[`flake8-simplify`] Implement `dict-get-with-none-default` (`SIM910`) (#3874) 2023-04-04 03:52:10 +00:00
Leiser Fernández Gallo 224e85c6d7
Implement `flake8-gettext` (#3785) 2023-03-28 23:32:02 +00:00
Charlie Marsh c3917eab38
Revert "Implement `flake8-i18n` (#3741)" (#3765) 2023-03-27 21:14:38 +00:00
JBLDSKY 0eb5a22dd1
[`flake8-pyi`] Implement `PYI012` (#3743) 2023-03-27 18:27:24 +00:00
Leiser Fernández Gallo 5cb120327c
Implement `flake8-i18n` (#3741) 2023-03-27 18:03:39 +00:00
Jonathan Plasse 8ac7584756
[`flake8-pyi`] Implement `PYI015` (#3728) 2023-03-25 15:48:11 +00:00
Dhruv Manilawala c1d89d8c93
[`flake8-bugbear`]: Implement rule `B031` (#3680) 2023-03-24 17:26:11 -04:00
Dhruv Manilawala 9e61956711
[`flake8-django`]: Implement rule DJ012 (#3659) 2023-03-22 03:07:58 +00:00
Colin Delahunty 41e38ffa98
[`flake8-bandit`]: Implement deny-list rules for suspicious member calls (#3239) 2023-03-21 15:11:52 -04:00
Jacob Latonis 318c2c80e2
`pylint`: Implement `binary-op-exception` (`PLW0711`) (#3639) 2023-03-21 03:33:40 +00:00
Jacob Latonis a45753f462
[`pylint`]: Implement `assert-on-string-literal` (`W0129`) (#3610) 2023-03-19 23:45:51 -04:00
tomecki 61653b9f27
[`pylint`] Implement `useless-return` (`R1711`) (#3116) 2023-03-17 18:30:32 -04:00
Tomer Chachamu 1dd3cbd047
[`pylint`] invalid-characters-* (#3552) 2023-03-17 19:30:41 +00:00
Johan bd935cbd49
[`flake8-bugbear`] Add `no-explicit-stacklevel` (`B028`) (#3550) 2023-03-17 19:20:08 +00:00
Evan Rittenhouse 33d2457909
Prefer `itertools.pairwise()` over `zip()` for successive pairs (`RUF007`) (#3501) 2023-03-16 23:50:45 -04:00
Jacob Latonis 73df267635
[`pylint`]: Implement `continue-in-finally` (`E0116`) (#3541) 2023-03-17 02:47:49 +00:00
Charlie Marsh 62ff3b62e3
Add `requires-python` inference to docs (#3495) 2023-03-13 18:14:39 -04:00
Jacob Latonis 675227db5c
pylint: E1507 invalid-envvar-value (#3467) 2023-03-12 21:43:06 +00:00
Jacob Latonis 0f78f27713
pylint: W1508 invalid-envvar-default (#3449) 2023-03-11 16:44:42 -05:00
Aryaman Marathe 952307d39d
[`pylint`] C1901: compare-to-empty-string (#3405) 2023-03-09 21:33:34 +00:00
Aaron Cunningham 3349ceb969
[`flake8-bugbear`] Add `flake8-bugbear`'s B030 rule (#3400) 2023-03-08 20:41:29 +00:00
Charlie Marsh bced58ce40
Rename `runtime-evaluated-baseclasses` to `runtime-evaluated-base-classes` (#3379) 2023-03-07 09:51:12 -05:00
Sasan Jacob Rasti 4dead7541f
Implement configuration options `runtime-evaluated-decorators` and `runtime-evaluated-baseclasses` for `flake8-type-checking` (#3292) 2023-03-06 23:34:19 -05:00
StefanBRas 30c71dc59a
Add Azure Devops as a `-format` option. (#3335) 2023-03-06 02:48:39 +00:00
Charlie Marsh 367cc43c42
Un-gate PEP 604 isinstance rewrites from keep_runtime_typing checks (#3328) 2023-03-03 17:29:41 -05:00
Charlie Marsh b5b26d5a3e
Gate PEP604 isinstance rewrites behind Python 3.10+ (#3327) 2023-03-03 22:22:14 +00:00
konstin 3bcffb5bdd
Add flake-pyi PYI033 "Do not use type comments in stubs" (#3302) 2023-03-03 10:45:34 -05:00
Charlie Marsh 3a98b68dc0
Always include `@classmethod` and `@staticmethod` in decorator lists (#3314) 2023-03-03 03:49:04 +00:00
Yaroslav Chvanov 508bc605a5
Implement `property-decorators` configuration option for pydocstyle (#3311) 2023-03-02 16:59:56 -05:00
Martin Lehoux 886992c6c2
Replace tuples with type union in isinstance or issubclass calls (#3280) 2023-03-02 15:59:15 -05:00
Charlie Marsh 310f13c7db
Redirect `RUF004` to `B026` (#3293) 2023-03-01 13:00:02 -05:00
konstin 2168404fc2
flake8-pyi PYI006 bad version info comparison (#3291)
Implement PYI006 "bad version info comparison"

## What it does

Ensures that you only `<` and `>=` for version info comparisons with
`sys.version_info` in `.pyi` files. All other comparisons such as
`<`, `<=` and `==` are banned.

## Why is this bad?

```python
>>> import sys
>>> print(sys.version_info)
sys.version_info(major=3, minor=8, micro=10, releaselevel='final', serial=0)
>>> print(sys.version_info > (3, 8))
True
>>> print(sys.version_info == (3, 8))
False
>>> print(sys.version_info <= (3, 8))
False
>>> print(sys.version_info in (3, 8))
False
```

Co-authored-by: Charlie Marsh <charlie.r.marsh@gmail.com>
2023-03-01 18:58:57 +01:00
Carlos Gonçalves e8ba9c9e21
feat(W191): add indentation_contains_tabs (#3249) 2023-02-27 10:36:03 -05:00
Jonathan Plasse d285f5c90a
Run automatically format code blocks with Black (#3191) 2023-02-27 10:14:05 -05:00
Ivan Gozali 4b5538f74e
[`pylint`] W0603: `global-statement` (#3227)
Implements pylint rule [W0603: global-statement](https://pylint.readthedocs.io/en/latest/user_guide/messages/warning/global-statement.html).

Currently checks for global statement usage in a few StmtKinds (as tested in the `pylint` `global-statement` test case [here](b70d2abd7f/tests/functional/g/globals.py)):

* Assign
* AugAssign
* ClassDef
* FunctionDef | AsyncFunctionDef
* Import
* ImportFrom
* Delete
2023-02-26 23:40:24 +00:00
Chris Chan 0b7d6b9097
Implement pylint's `else-if-used` rule (`PLR5501`) (#3231)
Attempt to implement else-if-used
https://pylint.pycqa.org/en/latest/user_guide/messages/refactor/else-if-used.html

Issue #970
2023-02-26 22:42:33 +00:00
Luc Khai Hai bc79f540e4
[flake8-django] DJ003, DJ006, DJ007 (#3236)
Implements [flake8-django](https://github.com/rocioar/flake8-django) rules:
- DJ03
- DJ06
- DJ07
2023-02-26 22:29:42 +00:00
Steve Dignam 3a78b59314
[flake8-pyi]: PYI011, PYI014 (#3238)
Implement PYI011 and PYI014 with the latest changes:

https://github.com/PyCQA/flake8-pyi/pull/326
https://github.com/PyCQA/flake8-pyi/issues/316

rel: https://github.com/charliermarsh/ruff/issues/848
rel: 4212bec43d/pyi.py (L718)
2023-02-26 22:11:58 +00:00
Edgar R. M 5f83851329
[pydocstyle]: Implement `ignore-decorators` (#3229) 2023-02-26 21:40:01 +00:00
Steve Dignam a8a312e862
[flake8-pyi]: PYI009, PYI010, PYI021 (#3230)
PYI009 and PYI010 are very similar, always use `...` in function and class bodies in stubs.

PYI021 bans doc strings in stubs.

I think all of these rules should be relatively straightforward to implement auto fixes for but can do that later once we get all the other rules added.

rel: https://github.com/charliermarsh/ruff/issues/848
2023-02-25 22:29:04 -05:00
Matt Nawara 198b301baf
[pycodestyle] trailing-whitespace, blank-line-contains-whitespace (W291, W293) (#3122) 2023-02-23 19:04:45 -05:00
Matthew Lloyd c1ddcb8a60
[flake8-pie] Unnecessary list comprehension, with autofix (PIE802) (#3149) 2023-02-22 20:58:45 -05:00
Matthieu Devlin 8fde63b323
[`pylint`] Implement E1205 and E106 (#3084) 2023-02-21 22:53:11 -05:00
Matthew Lloyd 97338e4cd6
[pylint] redefined-loop-name (W2901) (#3022)
Slightly broadens W2901 to cover `with` statements too.

Closes #2972.
2023-02-22 03:23:47 +00:00
Carlos Gonçalves 6eb014b3b2
feat(B032): add b032 flake8_bugbear (#3085) 2023-02-21 19:53:29 +00:00
Carlos Gonçalves b657468346
feat(B029): Add B029 from flake8-bugbear (#3068) 2023-02-20 15:57:13 -05:00
Colin Delahunty 9545958ad8
[`flake8-simplify`]: Implement manual-dict-lookup (#2767) 2023-02-20 20:00:59 +00:00
Colin Delahunty 41faa335d1
[`tryceratops`]: Verbose Log Messages (#3036) 2023-02-20 18:21:04 +00:00
Tomer Chachamu 4d3d04ee61
[`PLE0101`] error when `__init__` returns a value (#3007) 2023-02-19 14:54:43 +00:00
Manuel Jacob 87422ba362
Add configuration option for C408 to allow dict calls with keyword arguments. (#2977)
When creating a dict with string keys, some prefer to call dict instead of writing a dict literal.
For example: `dict(a=1, b=2, c=3)` instead of `{"a": 1, "b": 2, "c": 3}`.
2023-02-19 14:47:03 +00:00
Charlie Marsh a10a500a26
Ignore namedtuple methods in flake8-self (#2998) 2023-02-17 17:16:25 -05:00
Simon Brugman 34664a0ca0
[`numpy`] numpy-legacy-random (#2960)
The new `Generator` in NumPy uses bits provided by [PCG64](https://numpy.org/doc/stable/reference/random/bit_generators/pcg64.html#numpy.random.PCG64) which has better statistical properties than the legacy [MT19937](https://numpy.org/doc/stable/reference/random/bit_generators/mt19937.html#numpy.random.MT19937) used in [RandomState](https://numpy.org/doc/stable/reference/random/legacy.html#numpy.random.RandomState). Global random functions can also be problematic with parallel processing.

This rule is probably quite useful for data scientists (perhaps in combination with `nbqa`)

References:
- [Legacy Random Generation](https://numpy.org/doc/stable/reference/random/legacy.html#legacy)
- [Random Sampling](https://numpy.org/doc/stable/reference/random/index.html#random-quick-start)
- [Using PyTorch + NumPy? You're making a mistake.](https://tanelp.github.io/posts/a-bug-that-plagues-thousands-of-open-source-ml-projects/)
2023-02-17 02:06:30 +00:00
Florian Best a919041dda
feat(isort): Implement isort.force_to_top (#2877) 2023-02-16 19:01:59 +00:00
Simon Brugman cc30738148
Implement `flake8-module-naming` (#2855)
- Implement N999 (following flake8-module-naming) in pep8_naming
- Refactor pep8_naming: split rules.rs into file per rule
- Documentation for majority of the violations

Closes https://github.com/charliermarsh/ruff/issues/2734
2023-02-16 04:20:33 +00:00
Martin Fischer 7b09972c97 Merge convert-loop-to-any & convert-loop-to-all to reimplemented-builtin 2023-02-15 16:24:31 -05:00
Charlie Marsh f8d46d09ef
Implement `asyncio-dangling-task` to track `asyncio.create_task` calls (#2935)
This rule guards against `asyncio.create_task` usages of the form:

```py
asyncio.create_task(coordinator.ws_connect())  # Error
```

...which can lead to unexpected bugs due to the lack of a strong reference to the created task. See Will McGugan's blog post for reference: https://textual.textualize.io/blog/2023/02/11/the-heisenbug-lurking-in-your-async-code/.

Note that we can't detect issues like:

```py
def f():
    # Stored as `task`, but never used...
    task = asyncio.create_task(coordinator.ws_connect())
```

So that would be a false negative. But this catches the common case of failing to assign the task in any way.

Closes #2809.
2023-02-15 15:19:03 -05:00