Compare commits

...

321 Commits

Author SHA1 Message Date
Micha Reiser
09c50c311c Testing Macros: Add extra-traits feature (#4643) 2023-05-24 17:14:58 +00:00
Charlie Marsh
252506f8ed Remove deprecated --universal2 flag (#4640) 2023-05-24 17:00:52 +00:00
Charlie Marsh
f4572fe40b Bump version to 0.0.270 (#4637) 2023-05-24 16:34:29 +00:00
Sladyn
8c9215489e Migrate flake8_bugbear rules to unspecified to suggested (#4616) 2023-05-24 16:16:33 +00:00
qdegraaf
dcd2bfaab7 Migrate flake8_pie autofix rules from unspecified to suggested and automatic (#4621) 2023-05-24 16:08:22 +00:00
Charlie Marsh
f0e173d9fd Use BindingId copies in lieu of &BindingId in semantic model methods (#4633) 2023-05-24 15:55:45 +00:00
Charlie Marsh
f4f1b1d0ee Only run the playground release job on release (#4636) 2023-05-24 11:48:36 -04:00
Micha Reiser
edc6c4058f Move shared_traits to ruff_formatter (#4632) 2023-05-24 17:38:11 +02:00
Jonathan Plasse
4233f6ec91 Update to the new rule architecture (#4589) 2023-05-24 11:30:40 -04:00
Charlie Marsh
fcdc7bdd33 Remove separate ReferenceContext enum (#4631) 2023-05-24 15:12:38 +00:00
Micha Reiser
86ced3516b Introduce SourceCodeSlice to reduce the size of FormatElement (#4622)
Introduce `SourceCodeSlice` to reduce the size of `FormatElement`
2023-05-24 15:04:52 +00:00
Micha Reiser
6943beee66 Remove source position from FormatElement::DynamicText (#4619) 2023-05-24 16:36:14 +02:00
Micha Reiser
85f094f592 Improve Message sorting performance (#4624) 2023-05-24 16:34:48 +02:00
konstin
17d938f078 Add Checker::any_enabled shortcut (#4630)
Add Checker::any_enabled shortcut

 ## Summary

 Akin to #4625, This is a refactoring that shortens a bunch of code by replacing `checker.settings.rules.any_enabled` with `checker.any_enabled`.

 ## Test Plan

 `cargo clippy`
2023-05-24 14:32:55 +00:00
Charlie Marsh
5cedf0f724 Remove ReferenceContext::Synthetic (#4612) 2023-05-24 14:30:35 +00:00
konstin
38297c08b4 Make ecosystem all check more generic (#4629)
* Don't assume unique repo names in ecosystem checks

This fixes a bug where previously repositories with the same name would have been overwritten.

I tested with `scripts/check_ecosystem.py -v --checkouts target/checkouts_main .venv/bin/ruff target/release/ruff` and ruff 0.0.267 that changes are shown. I confirmed with `scripts/ecosystem_all_check.sh check --select RUF008` (next PR) that the checkouts are now complete.

* Make ecosystem all check more generic

This allows passing arguments to the ecosystem all check script, e.g. you can now do `scripts/ecosystem_all_check.sh check --select RUF008`.

Tested with
```
$ cat target/ecosystem_all_results/*.stdout.txt | head
src/fi_parliament_tools/parsing/data_structures.py:33:17: RUF008 Do not use mutable default values for dataclass attributes
src/fi_parliament_tools/parsing/data_structures.py:76:17: RUF008 Do not use mutable default values for dataclass attributes
src/fi_parliament_tools/parsing/data_structures.py:178:17: RUF008 Do not use mutable default values for dataclass attributes
Found 3 errors.
braid_triggers/tasks.py:46:17: RUF008 Do not use mutable default values for dataclass attributes
Found 1 error.
src/boards/RaspberryPi3.py:15:22: RUF008 Do not use mutable default values for dataclass attributes
src/boards/board.py:21:26: RUF008 Do not use mutable default values for dataclass attributes
src/boards/board.py:22:32: RUF008 Do not use mutable default values for dataclass attributes
src/boards/board.py:23:37: RUF008 Do not use mutable default values for dataclass attributes
$ cat target/ecosystem_all_results/*.stdout.txt | wc -l
115
```
2023-05-24 16:26:23 +02:00
konstin
30e90838d0 Don't assume unique repo names in ecosystem checks (#4628)
This fixes a bug where previously repositories with the same name would have been overwritten.

I tested with `scripts/check_ecosystem.py -v --checkouts target/checkouts_main .venv/bin/ruff target/release/ruff` and ruff 0.0.267 that changes are shown. I confirmed with `scripts/ecosystem_all_check.sh check --select RUF008` (next PR) that the checkouts are now complete.
2023-05-24 16:26:12 +02:00
Charlie Marsh
040fb9cef4 Use a separate PrinterFlag for including fix diffs (#4615) 2023-05-24 10:22:37 -04:00
Charlie Marsh
8961d8eb6f Track all read references in semantic model (#4610) 2023-05-24 14:14:27 +00:00
Charlie Marsh
31bddef98f Visit TypeVar and NewType name arguments (#4627) 2023-05-24 10:10:15 -04:00
konstin
a59d252246 Add Checker::enabled shortcut (#4625)
This is a refactoring that shortens a bunch of code by replacing `checker.settings.rules.enabled` with `checker.enabled`
2023-05-24 14:56:41 +02:00
konstin
5b9d4f18ae Remove outdated feature flag from Dockerfile.ecosystem (#4620) 2023-05-24 08:19:08 +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
konstin
3644695bf2 Include hidden ecosystem_ci option to show fixes without feature (#4528) 2023-05-23 22:22:23 -04:00
Evan Rittenhouse
b1d01b1950 Add a PR template (#4582) 2023-05-24 02:17:38 +00:00
Sladyn
4e84e8a8e2 Migrate some rules from Fix::unspecified (#4587) 2023-05-23 22:10:58 -04:00
Hoël Bagard
a256fdb9f4 Extend RUF005 to recursive and literal-literal concatenations (#4557) 2023-05-24 01:26:34 +00:00
Tom Kuson
7479dfd815 Add Pyflakes docs (#4588) 2023-05-24 00:45:32 +00:00
Charlie Marsh
ba4c0a21fa Rename ContextFlags to SemanticModelFlags (#4611) 2023-05-23 17:47:07 -04:00
konstin
73e179ffab Update maturin to 1.0 (#4605)
* Refactor and fix task trigger for dependent jobs in other repos

I have confirmed (https://github.com/konstin/ruff-pre-commit/actions/runs/5056928280/jobs/9075029868) that this does dispatch the workflow when running with act, `owner: 'konstin'`, `needs` commented out and personal access token. I can't properly test the actual release workflow, and i'm unsure how to best handle the next release after this was merged (should we do a beta release or will this break everything that assumes we only do stable releases?)

The command for act is
```
act -j update-dependents -s RUFF_PRE_COMMIT_PAT=<...>
```

* delete old file

* Update maturin to 1.0

A 1.0 release for maturin 🎉
2023-05-23 20:55:52 +02:00
konstin
3cbaaa4795 Refactor and fix task trigger for dependent jobs in other repos (#4598)
* Refactor and fix task trigger for dependent jobs in other repos

I have confirmed (https://github.com/konstin/ruff-pre-commit/actions/runs/5056928280/jobs/9075029868) that this does dispatch the workflow when running with act, `owner: 'konstin'`, `needs` commented out and personal access token. I can't properly test the actual release workflow, and i'm unsure how to best handle the next release after this was merged (should we do a beta release or will this break everything that assumes we only do stable releases?)

The command for act is
```
act -j update-dependents -s RUFF_PRE_COMMIT_PAT=<...>
```

* delete old file
2023-05-23 20:55:35 +02:00
Micha Reiser
2681c0e633 Add missing nodes to AnyNodeRef and AnyNode (#4608) 2023-05-23 18:30:27 +02:00
Charlie Marsh
f3bdd2e7be Make B007 fix relevance stricter (#4607) 2023-05-23 15:43:59 +00:00
Micha Reiser
652c644c2a Introduce ruff_index crate (#4597) 2023-05-23 17:40:35 +02:00
konstin
04d273bcc7 Add a script to update the schemastore (#4574)
* Add a script to update the schemastore

Hacked this together, it clones astral-sh/schemastore, updated the schema and pushes the changes
to a new branch tagged with the ruff git hash. You can see the URL to create the PR
to schemastore in the CLI. The script is separated into three blocks so you can rerun
the schema generation in the middle before committing.

* Use tempdir for schemastore

* Add comments
2023-05-23 10:41:56 +00:00
Micha Reiser
154439728a Add AnyNode and AnyNodeRef unions (#4578) 2023-05-23 08:53:22 +02:00
Jonathan Plasse
1ddc577204 Rework CST matchers (#4536)
Co-authored-by: Micha Reiser <micha@reiser.io>
2023-05-23 06:26:51 +00:00
Charlie Marsh
74effb40b9 Rename index to binding_id in a few iterators (#4594) 2023-05-23 03:56:00 +00:00
Charlie Marsh
6c3724ab98 Move get_or_import_symbol onto Importer (#4591) 2023-05-23 01:33:00 +00:00
Christopher Covington
3b8121379d Name ambiguous characters (#4448) 2023-05-22 17:16:57 +00:00
qdegraaf
5ba47c3302 Add autofix for PYI009 (#4583) 2023-05-22 16:41:18 +00:00
Charlie Marsh
b613460fe5 Fix # isort: split comment detection in nested blocks (#4584) 2023-05-22 12:31:59 -04:00
Micha Reiser
daadd24bde Include decorators in Function and Class definition ranges (#4467) 2023-05-22 17:50:42 +02:00
Charlie Marsh
9308e939f4 Avoid infinite loop for required imports with isort: off (#4581) 2023-05-22 15:49:03 +00:00
Charlie Marsh
04c9348de0 Make ambiguous-unicode detection sensitive to 'word' context (#4552) 2023-05-22 14:42:25 +00:00
Tom Kuson
2d3766d928 Add flake8-boolean-trap docs (#4572) 2023-05-22 14:11:14 +00:00
konstin
550b643e33 Add script for ecosystem wide checks of all rules and fixes (#4326)
* Add script for ecosystem wide checks of all rules and fixes

This adds my personal script for checking an entire checkout of ~2.1k packages for
panics, autofix errors and similar problems. It's not really meant to be used by anybody else but i thought it's better if it lives in the repo than if it doesn't.

For reference, this is the current output of failing autofixes: https://gist.github.com/konstin/c3fada0135af6cacec74f166adf87a00. Trimmed down to the useful information: https://gist.github.com/konstin/c864f4c300c7903a24fdda49635c5da9

* Keep github template intact

* Remove the need for ripgrep

* sort output
2023-05-22 15:23:25 +02:00
Micha Reiser
cbe344f4d5 Rename Checker::model to semantic_model (#4573) 2023-05-22 15:14:30 +02:00
Micha Reiser
063431cb0f Upgrade RustPython (#4576) 2023-05-22 14:50:49 +02:00
Evan Rittenhouse
c6e5fed658 Replace token iteration with Indexer/Locator lookups for relevant rules (#4513) 2023-05-22 09:56:19 +02:00
Charlie Marsh
f73b398776 Reduce visibility of more functions, structs, and fields (#4570) 2023-05-22 03:36:48 +00:00
Charlie Marsh
55c4020ba9 Remove regex for noqa code splitting (#4569) 2023-05-21 23:20:49 -04:00
Charlie Marsh
d70f899f71 Use SemanticModel in lieu of Checker in more methods (#4568) 2023-05-22 02:58:47 +00:00
Charlie Marsh
19c4b7bee6 Rename ruff_python_semantic's Context struct to SemanticModel (#4565) 2023-05-22 02:35:03 +00:00
Jonathan Plasse
3238743a7b Fix Flake8Todo typo (#4566) 2023-05-21 16:32:13 -04:00
Charlie Marsh
f22c269ccf Point LSP, VS Code, and pre-commut URLs to Astral org (#4562) 2023-05-21 15:27:35 -04:00
Arne de Laat
8ca3977602 Fix false-positive for TRY302 if exception cause is given (#4559) 2023-05-21 11:49:53 -04:00
Jacob Coffee
6db05d8cc6 Starlite -> Litestar (#4554) 2023-05-21 09:55:26 -04:00
Jonathan Plasse
fc63c6f2e2 Fix PLE01310 typo (#4550) 2023-05-20 19:34:03 +00:00
Jonathan Plasse
f7f5bc9085 Fix SIM401 snapshot (#4547) 2023-05-20 14:18:19 -04:00
Charlie Marsh
6b85430a14 Ignore #region code folding marks in eradicate rules (#4546) 2023-05-20 16:45:49 +00:00
Jonathan Plasse
a68c865010 Fix SIM110 and SIM111 ranges (#4545) 2023-05-20 12:40:35 -04:00
Charlie Marsh
fe7f2e2e4d Move submodule alias resolution into Context (#4543) 2023-05-20 16:34:10 +00:00
Felipe Peter
0a3cf8ba11 Fix typos in docs (#4540) 2023-05-20 07:23:17 -04:00
Charlie Marsh
bf5b463c0d Include empty success test in JUnit output (#4537) 2023-05-20 03:38:51 +00:00
Charlie Marsh
6aa9900c03 Improve handling of __qualname__, __module__, and __class__ (#4512) 2023-05-20 03:03:45 +00:00
Charlie Marsh
9e21414294 Improve reference resolution for deferred-annotations-within-classes (#4509) 2023-05-20 02:54:18 +00:00
Charlie Marsh
bb4e674415 Move reference-resolution into Context (#4510) 2023-05-20 02:47:15 +00:00
Charlie Marsh
b42ff08612 Parenthesize more sub-expressions in f-string conversion (#4535) 2023-05-19 19:41:30 +00:00
Jonathan Plasse
03fb62c174 Fix RUF010 auto-fix with parenthesis (#4524) 2023-05-19 19:05:51 +00:00
Jonathan Plasse
2dfc645ea9 Fix UP032 auto-fix with integers (#4525) 2023-05-19 18:53:50 +00:00
Hoël Bagard
fe8e2bb237 [pylint] Add named_expr_without_context (W0131) (#4531) 2023-05-19 18:00:01 +00:00
Tom Kuson
a9ed8d5391 Add Pylint docs (#4530) 2023-05-19 17:40:18 +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
konstin
625849b846 Ecosystem CI: Optionally diff fixes (#4193)
* Generate fixes when using --show-fixes

Example command: `cargo run --bin ruff -- --no-cache --select F401
--show-source --show-fixes
crates/ruff/resources/test/fixtures/pyflakes/F401_9.py`

Before, `--show-fixes` was ignored:

```
crates/ruff/resources/test/fixtures/pyflakes/F401_9.py:4:22: F401 [*] `foo.baz` imported but unused
  |
4 | __all__ = ("bar",)
5 | from foo import bar, baz
  |                      ^^^ F401
  |
  = help: Remove unused import: `foo.baz`

Found 1 error.
[*] 1 potentially fixable with the --fix option.
```

After:

```
crates/ruff/resources/test/fixtures/pyflakes/F401_9.py:4:22: F401 [*] `foo.baz` imported but unused
  |
4 | __all__ = ("bar",)
5 | from foo import bar, baz
  |                      ^^^ F401
  |
  = help: Remove unused import: `foo.baz`

ℹ Suggested fix
1 1 | """Test: late-binding of `__all__`."""
2 2 |
3 3 | __all__ = ("bar",)
4   |-from foo import bar, baz
  4 |+from foo import bar

Found 1 error.
[*] 1 potentially fixable with the --fix option.
```

Also fixes git clone
2023-05-19 09:49:57 +00:00
konstin
32f1edc555 Create dummy format CLI (#4453)
* Create dummy format CLI

* Hide format from clap, too

Missed that this is a separate option from `#[doc(hidden)]`

* Remove cargo feature and replace with warning

* No-alloc files parameter matching

* beta warning: warn -> warn_user_once

* Rephrase warning
2023-05-19 11:45:52 +02:00
Micha Reiser
2f35099f81 Remove regex dependency from ruff_python_ast (#4518) 2023-05-19 06:44:18 +00:00
Hoël Bagard
ce8fd31a8f Updated contributing documentation (#4516) 2023-05-19 08:39:15 +02:00
Ville Skyttä
fdb241cad2 [flake8-bandit] Implement paramiko-call (S601) (#4500) 2023-05-19 03:40:50 +00:00
Charlie Marsh
ab303f4e09 Gate schemars skip under feature flag (#4514) 2023-05-19 03:01:31 +00:00
Charlie Marsh
15cb21a6f4 Implement --extend-fixable option (#4297) 2023-05-18 22:20:19 -04:00
Ville Skyttä
2e2ba2cb16 Avoid some false positives in dunder variable assigments (#4508) 2023-05-19 02:11:20 +00:00
Charlie Marsh
d4c0a41b00 Bump version to 0.0.269 (#4506) 2023-05-18 19:45:20 +00:00
Charlie Marsh
8702b5a40a Bump version to 0.0.268 (#4501) 2023-05-18 15:35:46 -04:00
figsoda
bab818e801 Update RustPython dependencies (#4503) 2023-05-18 15:28:13 -04:00
konstin
a3aa841fc9 Overhaul sdist handling (#4439)
* Reduce sdist size

`maturin sdist && du -sh target/wheels/ruff-0.0.267.tar.gz`:
Before: 1,1M
After: 668K

* Test sdist before release

* Update maturin to fix the sdist
2023-05-18 19:02:22 +02:00
Ville Skyttä
fdd894145b S608 improvements (#4499) 2023-05-18 11:27:22 -04:00
Charlie Marsh
85f67b2ee3 Make the AST Checker pub(crate) (#4498) 2023-05-18 15:17:26 +00:00
Charlie Marsh
e9c6f16c56 Move unparse utility methods onto Generator (#4497) 2023-05-18 15:00:46 +00:00
Charlie Marsh
d3b18345c5 Move triple-quoted string detection into Indexer method (#4495) 2023-05-18 14:42:05 +00:00
Jonathan Plasse
0e4d174551 Fix COM812 false positive in string subscript (#4493) 2023-05-18 14:35:41 +00:00
Charlie Marsh
73efbeb581 Invert quote-style when generating code within f-strings (#4487) 2023-05-18 14:33:33 +00:00
Charlie Marsh
2fb312bb2b Fix scoping of comprehensions within classes (#4494) 2023-05-18 14:30:02 +00:00
Charlie Marsh
e8e66f3824 Remove unnecessary path prefixes (#4492) 2023-05-18 10:19:09 -04:00
Charlie Marsh
a8d080c825 Extend multi-line noqa directives to start-of-line (#4490) 2023-05-18 13:05:27 +00:00
Charlie Marsh
ddd541b198 Move Insertion into its own module (#4478) 2023-05-17 21:11:41 +00:00
Tom Kuson
3090aec97d Add PLW docs (#4469) 2023-05-17 18:30:45 +00:00
Charlie Marsh
14c6419bc1 Bring pycodestyle rules into full compatibility (on SciPy) (#4472) 2023-05-17 16:51:55 +00:00
Charlie Marsh
3bc29d6c0c Allow shebang comments at start-of-file (#4473) 2023-05-17 16:32:12 +00:00
Charlie Marsh
67c5086aba Include precise tokens for extraneous-whitespace diagnostics (#4471) 2023-05-17 16:25:17 +00:00
Charlie Marsh
cd82b83f89 Avoid triggering pd#at and friends on non-subscripts (#4474) 2023-05-17 16:20:58 +00:00
Charlie Marsh
39fb2cc732 Remove special-casing for whitespace-around-@ (#4458) 2023-05-17 15:32:08 +00:00
John Kelly
9c732c7946 Implement TRY302 - raise after except (#4461) 2023-05-17 01:36:10 +00:00
Charlie Marsh
2332ea5753 Remove type-complexity ignores from map_codes.rs (#4463) 2023-05-17 01:02:24 +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
Micha Reiser
ddf7de7e86 Prototype Black's string joining/splitting (#4449) 2023-05-16 18:42:40 +01:00
Charlie Marsh
e5101e8eac Split logical lines tests into one test per assertion (#4457) 2023-05-16 17:40:39 +00:00
Charlie Marsh
d9c3f8e249 Avoid flagging missing whitespace for decorators (#4454) 2023-05-16 13:15:01 -04:00
Charlie Marsh
7e0d018b35 Avoid emitting empty logical lines (#4452) 2023-05-16 16:33:33 +00:00
Jeong, YunWon
4b05ca1198 Specialize ConversionFlag (#4450) 2023-05-16 18:00:13 +02:00
Charlie Marsh
f0465bf106 Emit non-logical newlines for "empty" lines (#4444) 2023-05-16 14:58:56 +00:00
Charlie Marsh
8134ec25f0 Fix expected-indentation errors with end-of-line comments (#4438) 2023-05-16 10:45:54 -04:00
Jeong, YunWon
6049aabe27 Update RustPyhon and enable full-lexer feature (#4442) 2023-05-16 07:19:57 +00:00
Jeong, YunWon
badade3ccc Impl Default for SourceLocation (#4328)
Co-authored-by: Micha Reiser <micha@reiser.io>
2023-05-16 07:03:43 +00:00
Micha Reiser
fa26860296 Refactor range from Attributed to Nodes (#4422) 2023-05-16 06:36:32 +00:00
James Lamb
140e0acf54 Add LightGBM to user list (#4446) 2023-05-16 04:04:37 +00:00
Sladyn
c711db11ce [flake8-pyi] Implement unannotated-assignment-in-stub (PY052) (#4293) 2023-05-16 02:06:55 +00:00
Charlie Marsh
1fe6954150 Fix bidirectional-unicode formatting (#4445) 2023-05-15 22:36:25 +00:00
Charlie Marsh
2414469ac3 Enable automatic rewrites of typing.Deque and typing.DefaultDict (#4420) 2023-05-15 22:33:24 +00:00
Tom Kuson
838ba1ca3d Add PLE rule docs (#4437) 2023-05-15 19:48:18 +00:00
Charlie Marsh
8f3f8d3e0b Revert change to re-run release on tag update (#4441) 2023-05-15 15:48:45 +00:00
qdegraaf
8ba9eb83af Implement flake8-async plugin (#4432) 2023-05-15 09:15:28 -04:00
Zanie Adkins
2c6efc2f5f Update C419 to be a suggested fix (#4424) 2023-05-15 10:30:40 +02:00
Ben Doerry
d6930ca991 Merge subsettings when extending configurations (#4431) 2023-05-15 02:34:58 +00:00
Yanks Yoon
f70c286e6a docs: update contributing guide (#4428) 2023-05-15 02:21:37 +00:00
Charlie Marsh
dcff515ad8 Make extend_function_names an Option type (#4434) 2023-05-15 02:15:02 +00:00
Jonathan Plasse
b9e387013f Fix RUF010 autofix within f-strings (#4423) 2023-05-15 02:08:30 +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
Charlie Marsh
cd2e7fa72a Use TextSize for flake8-todos Directive methods (#4426) 2023-05-13 22:05:51 -04:00
Charlie Marsh
fdf0b999cd Replace TODO tag regex with a lexer (#4413) 2023-05-13 15:23:46 +00:00
Jonathan Plasse
45b5fa573f Ignore ANN401 for overridden methods (#4409) 2023-05-13 15:20:04 +00:00
Jonathan Plasse
a0258f2205 [pylint] Fix PLW3301 auto-fix with generators (#4412) 2023-05-13 11:17:13 -04: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
Micha Reiser
7e7be05ddf Upgrade dependencies (#4389) 2023-05-13 13:00:25 +00:00
Micha Reiser
f5afa8198c Use new rustpython_format crate over rustpython-common (#4388) 2023-05-13 12:35:02 +00:00
Charlie Marsh
eeabfd6d18 Enable autofix for split-assertions at top level (#4405) 2023-05-12 17:35:49 -04:00
Charlie Marsh
490301f9fe Replace macro_rules! visitors with dedicated methods (#4402) 2023-05-12 17:05:59 -04:00
Zanie Adkins
f5be3d8e5b Update CI to test Python wheel on Linux (#4398) 2023-05-12 16:27:18 -04:00
Charlie Marsh
7617519b4f Skip python -m ruff --help on linux-cross 2023-05-12 15:46:42 -04:00
Charlie Marsh
bc7ddd8f3a Temporarily create release on-tag 2023-05-12 15:31:48 -04:00
Charlie Marsh
e6bb5cddcf Add Astral badge to the repo (#4401) 2023-05-12 19:27:38 +00:00
Charlie Marsh
dcedd5cd9d Bump version to 0.0.267 (#4400) 2023-05-12 19:04:56 +00:00
konstin
606b6ac3df Workaround for maturin bug (#4399) 2023-05-12 18:55:55 +00:00
Zanie Adkins
ebda9b31d9 Update CI to test python -m ruff on release (#4397) 2023-05-12 18:47:30 +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
a6176d2c70 Add PyTorch to user list (#4393) 2023-05-12 18:02:13 +00:00
OMEGA_RAZER
1d165f7e9d Add linting badge that can be used to display usage (#3938) 2023-05-12 17:58:29 +00:00
Charlie Marsh
e96092291d Update Ruff badge (#4392) 2023-05-12 13:42:33 -04:00
Charlie Marsh
67076b2dcb Bump version to 0.0.266 (#4391) 2023-05-12 13:11:03 -04:00
Charlie Marsh
7e3ba7f32a Use bitflags for tracking Context flags (#4381) 2023-05-12 16:07:26 +00:00
konstin
09dbd2029c Update maturin to maturin 0.15 (#3999)
* Update maturin to maturin>=0.14.17

This allows removing the deprecated `[package.metadata.maturin]`

* Update to maturin 0.15
2023-05-12 15:43:06 +02:00
Jonathan Plasse
1380bd94da Expose more fields in rule explanation (#4367) 2023-05-11 19:22:23 -04:00
Jonathan Plasse
c10a4535b9 Disallow unreachable_pub (#4314) 2023-05-11 18:00:00 -04:00
Charlie Marsh
97802e7466 Ignore some methods on list in flake8-boolean-trap (#4385) 2023-05-11 21:54:59 +00:00
Jonathan Plasse
4fd4a65718 Isolate show statistic integration test (#4383) 2023-05-11 21:42:34 +00:00
Charlie Marsh
d78c614764 Remove special-casing for flake8-builtins rules (#4380) 2023-05-11 16:39:28 -04:00
Charlie Marsh
3f3dd7af99 Move some recursion out of the pre-visit statement phase (#4379) 2023-05-11 15:46:25 -04:00
Charlie Marsh
871b92a385 Avoid re-using imports beyond current edit site (#4378) 2023-05-11 14:47:18 -04:00
Charlie Marsh
9158f13ee6 Respect __all__ imports when determining definition visibility (#4357) 2023-05-11 17:43:51 +00:00
Charlie Marsh
72e0ffc1ac Delay computation of Definition visibility (#4339) 2023-05-11 17:14:29 +00:00
Charlie Marsh
ffcf0618c7 Avoid underflow in expected-special-method-signature (#4377) 2023-05-11 12:47:47 -04:00
Micha Reiser
1ccef5150d Remove lifetime from FormatContext (#4376) 2023-05-11 15:43:42 +00:00
konstin
6a52577630 Ecosystem CI: Allow storing checkouts locally (#4192)
* Ecosystem CI: Allow storing checkouts locally

This adds a --checkouts options to (re)use a local directory instead of checkouts into a tempdir

* Fix missing path conversion
2023-05-11 17:36:44 +02:00
konstin
3c2f41b615 Also show rule codes in autofix errors in production codes (#4327)
I needed those changes for #4326
2023-05-11 17:36:03 +02:00
Calum Young
b76b4b6016 List rule changes in ecosystem (#4371)
* Count changes for each rule

* Handle case where rule matches were found in a line

* List and sort by changes

* Remove detail from rule changes

* Add comment about leading :

* Only print rule changes if rule changes are present

* Use re.search and match group

* Remove dict().items()

* Use match group to extract rule code
2023-05-11 16:33:15 +02:00
Jeong, YunWon
bbadbb5de5 Refactor code to use the new RustPython is method (#4369) 2023-05-11 16:16:36 +02:00
Calum Young
ba6370e5d0 Move black excludes from pre-commit config to pyproject.toml (#4370) 2023-05-11 09:00:05 -04:00
Jeong, YunWon
be6e00ef6e Re-integrate RustPython parser repository (#4359)
Co-authored-by: Micha Reiser <micha@reiser.io>
2023-05-11 07:47:17 +00:00
Charlie Marsh
865205d992 Implement pygrep-hook's Mock-mistake diagnostic (#4366) 2023-05-11 03:26:29 +00:00
Charlie Marsh
572adf7994 Use target name in hardcoded-password diagnostics (#4365) 2023-05-11 02:54:27 +00:00
Charlie Marsh
3b26bf84f5 Avoid debug panic with empty indent replacement (#4364) 2023-05-11 02:42:18 +00:00
Charlie Marsh
f4f88308ae Remove Copy and destructure Snapshot (#4358) 2023-05-10 19:46:18 +00:00
Charlie Marsh
ea3d3a655d Add a Snapshot abstraction for deferring and restoring visitor context (#4353) 2023-05-10 16:50:47 +00:00
Charlie Marsh
fd34797d0f Add a specialized StatementVisitor (#4349) 2023-05-10 12:42:20 -04:00
dependabot[bot]
6532455672 Bump json5 from 1.0.1 to 1.0.2 in /playground (#4354) 2023-05-10 16:34:37 +00:00
Charlie Marsh
257c571c43 Remove pub from some Checker fields (#4352) 2023-05-10 12:33:47 -04:00
Charlie Marsh
ccdee55e6e Tweak capitalization of B021 message (#4350) 2023-05-10 15:59:00 +00:00
Charlie Marsh
6d6d7abf70 Use short-import for HashMap (#4351) 2023-05-10 15:46:55 +00:00
konstin
0096938789 Optionally show fixes when using --features ecosystem_ci with cargo and --show-fixes at runtime (#4191)
* Generate fixes when using --show-fixes

Example command: `cargo run --bin ruff -- --no-cache --select F401
--show-source --show-fixes
crates/ruff/resources/test/fixtures/pyflakes/F401_9.py`

Before, `--show-fixes` was ignored:

```
crates/ruff/resources/test/fixtures/pyflakes/F401_9.py:4:22: F401 [*] `foo.baz` imported but unused
  |
4 | __all__ = ("bar",)
5 | from foo import bar, baz
  |                      ^^^ F401
  |
  = help: Remove unused import: `foo.baz`

Found 1 error.
[*] 1 potentially fixable with the --fix option.
```

After:

```
crates/ruff/resources/test/fixtures/pyflakes/F401_9.py:4:22: F401 [*] `foo.baz` imported but unused
  |
4 | __all__ = ("bar",)
5 | from foo import bar, baz
  |                      ^^^ F401
  |
  = help: Remove unused import: `foo.baz`

ℹ Suggested fix
1 1 | """Test: late-binding of `__all__`."""
2 2 |
3 3 | __all__ = ("bar",)
4   |-from foo import bar, baz
  4 |+from foo import bar

Found 1 error.
[*] 1 potentially fixable with the --fix option.
```

* Add `--format ecosystem-ci`

* cargo dev generate-all

* Put behind cargo feature

* Regenerate docs

* Don't test ecosystem_ci feature on CI

* Use top level flag instead

* Fix

* Simplify code based on #4191

* Remove old TODO comment
2023-05-10 17:45:57 +02:00
Micha Reiser
853d8354cb JSON Emitter: Use one indexed column numbers for edits (#4007)
I noticed in the byte-offsets refactor that the `JsonEmitter` uses one indexed column numbers for the diagnostic start and end locations but not for `edits`.

This PR changes the `JsonEmitter` to emit one-indexed column numbers for edits, as we already do for `Message::location` and `Message::end_location`.

## Open questions

~We'll need to change the LSP to subtract 1 from the columns in `_parse_fix`~

6e44fadf8a/ruff_lsp/server.py (L129-L150)

~@charliermarsh is there a way to get the ruff version in that method? If not, then I recommend adding a `version` that we increment whenever we make incompatible changes to the serialized message. We can then use it in the LSP to correctly compute the column offset.~

I'll use the presence of the `Fix::applicability` field to detect if the Ruff version uses one or zero-based column indices.

See https://github.com/charliermarsh/ruff-lsp/pull/103
2023-05-10 17:21:02 +02:00
Charlie Marsh
5f64d2346f Enforce max-doc-length for multi-line docstrings (#4347) 2023-05-10 11:06:07 -04:00
Micha Reiser
ddbe5a1243 Add Fix::applicability to JSON output (#4341) 2023-05-10 14:34:53 +00:00
Evan Rittenhouse
04097d194c Fix false positives in PD002 (#4337) 2023-05-10 16:04:28 +02:00
Micha Reiser
a2b8487ae3 Remove functor from autofix title (#4245) 2023-05-10 07:21:15 +00:00
Micha Reiser
8969ad5879 Always generate fixes (#4239) 2023-05-10 07:06:14 +00:00
Micha Reiser
bfa1c28c00 Use non-empty ranges for logical-lines diagnostics (#4133) 2023-05-10 06:44:33 +00:00
Zanie Adkins
cf7aa26aa4 Add Applicability to Fix (#4303)
Co-authored-by: Micha Reiser <micha@reiser.io>
2023-05-10 08:42:46 +02:00
Micha Reiser
d66ce76691 Truncate SyntaxErrors before newline character (#4124) 2023-05-10 08:37:57 +02:00
Tom Kuson
b8bb9e8b92 Add docs for flake8-simplify rules (#4334) 2023-05-10 03:03:24 +00:00
Charlie Marsh
5e46dcbf21 Handle .encode calls on parenthesized expressions (#4338) 2023-05-09 22:57:10 -04:00
trag1c
045449ab12 Improved E713 & E714 code examples (#4336) 2023-05-09 22:27:44 -04:00
Tom Kuson
d5ff8d7c43 Add flake8-pie documentation (#4332) 2023-05-09 22:11:30 +00:00
Charlie Marsh
d92fb11e80 Include positional- and keyword-only arguments in too-many-arguments (#4329) 2023-05-09 18:05:53 -04:00
Charlie Marsh
3d947196f8 Make violation struct fields private (#4331) 2023-05-09 18:00:20 -04:00
Charlie Marsh
e846f2688b Avoid SIM105 autofixes that would remove comments (#4330) 2023-05-09 21:30:56 +00:00
Charlie Marsh
7b91a162c6 Remove current_ prefix from some Context methods (#4325) 2023-05-09 19:40:12 +00:00
Charlie Marsh
8c2cfade90 Move show_source onto CLI settings group (#4317) 2023-05-09 17:26:25 +00:00
Charlie Marsh
a435c0df4b Remove deprecated update-check setting (#4313) 2023-05-09 13:10:02 -04:00
Aaron Cunningham
48e1852893 Revert the B027 autofix logic (#4310) 2023-05-09 13:08:20 -04:00
Calum Young
03f141f53d Check that all rules have descriptions (#4315) 2023-05-09 16:53:23 +00:00
Calum Young
8dea47afc1 Update mkdocs unformatted example error message (#4312) 2023-05-09 12:36:13 -04:00
Charlie Marsh
d3b71f1e04 Run autofix on initial watcher pass (#4311) 2023-05-09 12:35:32 -04:00
Mikko Leppänen
04e8e74499 Feat: detect changes also in configuration files (#4169) 2023-05-09 16:22:52 +00:00
konstin
318653c427 Write diagnostic name when failing to create fix (#4309) 2023-05-09 17:46:40 +02:00
Marti Raudsepp
f08fd5cbf0 Tweak package metadata URLs, add changelog and docs (#4304) 2023-05-09 11:32:47 -04:00
Micha Reiser
99a755f936 Add schemars feature (#4305) 2023-05-09 16:15:18 +02:00
Aurelio Jargas
e7dfb35778 UP011: Fix typo in rule description (#4306) 2023-05-09 08:49:15 -04:00
Dhruv Manilawala
085fd37209 Preserve whitespace around ListComp brackets in C419 (#4099) 2023-05-09 08:43:05 +02:00
Charlie Marsh
83536cf87b Ignore TRY301 exceptions without except handlers (#4301) 2023-05-09 03:38:02 +00:00
Charlie Marsh
9366eb919d Specify exact command in incorrect parentheses suggestion (#4300) 2023-05-09 02:21:54 +00:00
Charlie Marsh
8be51942dd Use ruff_python_semantic abstract utility in flake8-pytest-style (#4299) 2023-05-08 22:12:28 -04:00
Charlie Marsh
d365dab904 Include static and class methods in in abstract decorator list (#4298) 2023-05-08 21:54:02 -04:00
Charlie Marsh
f23851130a Add flynt to documentation (#4295) 2023-05-09 00:52:41 +00:00
Aarni Koskela
efdf383f5e Implement Flynt static string join transform as FLY002 (#4196) 2023-05-08 20:46:38 -04:00
Charlie Marsh
61f21a6513 Rewrite not not a as bool(a) in boolean contexts (#4294) 2023-05-08 23:38:24 +00:00
Charlie Marsh
43d6aa9173 Clarify some docstring-related docs (#4292) 2023-05-08 22:24:53 +00:00
Charlie Marsh
c54e48dce5 Avoid panics for f-string rewrites at start-of-file (#4291) 2023-05-08 19:44:57 +00:00
Charlie Marsh
b913e99bde Explicitly support ASCII-only for capitalization checks (#4290) 2023-05-08 15:41:11 -04:00
Dhruv Manilawala
4ac506526b Avoid D403 if first char cannot be uppercased (#4283) 2023-05-08 15:33:24 -04:00
Calum Young
cd41de2588 Check docs formatting check (#4270) 2023-05-08 19:03:22 +00:00
Dhruv Manilawala
3344d367f5 Avoid fixing PD002 in a lambda expression (#4286) 2023-05-08 18:24:27 +00:00
Aarni Koskela
d7a369e7dc Update confusable character mapping (#4274) 2023-05-08 14:20:44 -04:00
Jonathan Plasse
1b1788c8ad Fix replace_whitespace() tabulation to space (#4226)
Co-authored-by: Micha Reiser <micha@reiser.io>
2023-05-08 12:03:04 +00:00
Micha Reiser
4d5a339d9e Remove Fix::from(Edit) and add deprecated replacement methods to Diagnostics (#4275) 2023-05-08 10:25:50 +00:00
Zanie Adkins
0801f14046 Refactor Fix and Edit API (#4198) 2023-05-08 11:57:03 +02:00
Micha Reiser
edaf891042 Fix jemalloc page size on aarch64 (#4247)
Co-authored-by: konstin <konstin@mailbox.org>
2023-05-08 08:10:03 +02:00
Trevor McCulloch
3beff29026 [pylint] Implement nested-min-max (W3301) (#4200) 2023-05-07 03:14:14 +00:00
Jerome Leclanche
5ac2c7d293 Add .git-rewrite folder to default ignored folder paths (#4261) 2023-05-06 22:40:38 -04:00
Charlie Marsh
e66fdb83d0 Respect insertion location when importing symbols (#4258) 2023-05-07 02:32:40 +00:00
Charlie Marsh
a95bafefb0 Fix RET504 example in docs (#4260) 2023-05-06 16:56:52 -04:00
Charlie Marsh
539af34f58 Add a utility method to detect top-level state (#4259) 2023-05-06 20:24:27 +00:00
Charlie Marsh
983bb31577 Remove RefEquality usages from Context (#4257) 2023-05-06 15:55:14 -04:00
Charlie Marsh
b98b604071 Remove some deferred &Stmt references (#4256) 2023-05-06 18:42:35 +00:00
Charlie Marsh
cd27b39aff Re-order some code in scope.rs (#4255) 2023-05-06 16:36:20 +00:00
Charlie Marsh
a9fc648faf Use NodeId for Binding source (#4234) 2023-05-06 16:20:08 +00:00
Charlie Marsh
c1f0661225 Replace parents statement stack with a Nodes abstraction (#4233) 2023-05-06 16:12:41 +00:00
Dhruv Manilawala
2c91412321 Consider Flask app logger as logger candidate (#4253) 2023-05-06 11:31:10 -04:00
Charlie Marsh
11e1380df4 Bump version to 0.0.265 (#4248) 2023-05-05 13:16:05 -04:00
Micha Reiser
e93f378635 Refactor whitespace around operator (#4223) 2023-05-05 09:37:56 +02:00
Micha Reiser
2124feb0e7 Fail lint tests if the fix creates a syntax error (#4202) 2023-05-05 07:59:33 +02:00
Charlie Marsh
c0e7269b07 Update doc defaults for section-order (#4232) 2023-05-04 21:35:27 +00:00
Chris Chan
c2921e957b [pylint] Implement import-self (W0406) (#4154) 2023-05-04 16:05:15 -04:00
Charlie Marsh
93cfce674a Ignore __debuggerskip__ in unused variable checks (#4229) 2023-05-04 15:45:49 -04:00
Charlie Marsh
b71cc3789f Change --fix-only exit semantics to mirror --fix (#4146) 2023-05-04 19:03:15 +00:00
Zanie Adkins
717128112d Fix panic in pydocstyle D214 when docstring indentation is empty (#4216) 2023-05-04 14:42:34 -04:00
Arya Kumar
e9e194ab32 [flake8-pyi] Implement PYI042 and PYI043 (#4214) 2023-05-04 14:35:26 -04:00
Calum Young
890e630c41 Allow linking to individual rules (#4158) 2023-05-04 13:43:53 -04:00
Aaron Cunningham
d78287540d Update B027 to support autofixing (#4178) 2023-05-04 16:36:32 +00:00
Charlie Marsh
494e807315 Add space when joining rule codes for debug messages (#4225) 2023-05-04 15:34:34 +00:00
Tom Kuson
6db1a32eb9 Add docs for PLC rules (#4224) 2023-05-04 10:56:00 -04:00
Dhruv Manilawala
bb2cbf1f25 End of statement insertion should occur after newline (#4215) 2023-05-04 16:17:41 +02:00
konstin
badfdab61a Show rule codes on autofix failure (#4220) 2023-05-04 15:25:07 +02:00
Dhruv Manilawala
59d40f9f81 Show settings path in --show-settings output (#4199) 2023-05-04 08:22:31 +02:00
Arya Kumar
37aae666c7 [flake8-pyi] PYI020 (#4211) 2023-05-03 22:37:32 -04:00
Leiser Fernández Gallo
460023a959 Fix era panic caused by out of bound edition (#4206) 2023-05-03 15:48:43 +02:00
Aarni Koskela
d0e3ca29d9 Print out autofix-broken or non-converging code when debugging (#4201) 2023-05-03 13:50:03 +02:00
Christian Clauss
ccfc78e2d5 faq: Clarify how Ruff and Black treat line-length. (#4180) 2023-05-02 23:19:38 +00:00
Micha Reiser
b14358fbfe Render tabs as 4 spaces in diagnostics (#4132) 2023-05-02 13:14:02 +00:00
wookie184
ac600bb3da Warn on PEP 604 syntax not in an annotation, but don't autofix (#4170) 2023-05-01 23:49:20 -07:00
Charlie Marsh
8cb76f85eb Bump version to 0.0.264 (#4179) 2023-05-01 23:33:38 -07:00
Charlie Marsh
56c45013c2 Allow boolean parameters for pytest.param (#4176) 2023-05-02 01:07:50 +00:00
Calum Young
a4ce746892 Reference related settings in rules (#4157) 2023-05-02 00:59:00 +00:00
Calum Young
2d6d51f3a1 Add flake8-return docs (#4164) 2023-05-02 00:53:46 +00:00
Jonathan Plasse
814731364a Fix UP032 auto-fix (#4165) 2023-04-30 16:57:41 -04:00
Jonathan Plasse
8c97e7922b Fix F811 false positive with match (#4161) 2023-04-30 14:39:45 -04:00
Jonathan Plasse
a32617911a Use --filter=blob:none to clone CPython faster (#4156) 2023-04-30 13:39:22 +02:00
Charlie Marsh
64b7280eb8 Respect parent-scoping rules for NamedExpr assignments (#4145) 2023-04-29 22:45:30 +00:00
Evan Rittenhouse
8d64747d34 Remove pyright comment prefix from PYI033 checks (#4152) 2023-04-29 18:41:04 -04:00
Charlie Marsh
2115d99c43 Remove ScopeStack in favor of child-parent ScopeId pointers (#4138) 2023-04-29 18:23:51 -04:00
Calum Young
39ed75f643 Document flake8-unused-arguments (#4147) 2023-04-29 19:17:50 +00:00
Calum Young
8f61eae1e7 Add remaining pep8-naming docs (#4149) 2023-04-29 15:13:10 -04:00
Calum Young
f0f4bf2929 Move typos to pre-commit config (#4148) 2023-04-29 12:13:35 -04:00
Calum Young
03144b2fad Document flake8-commas (#4142) 2023-04-29 03:24:15 +00:00
Calum Young
0172cc51a7 Document flake8-print (#4144) 2023-04-29 03:19:00 +00:00
Calum Young
12d64a223b Document RUF100 (#4141) 2023-04-28 22:14:15 +00:00
Charlie Marsh
432ea6f2e2 Tweak rule documentation for B008 (#4137) 2023-04-28 01:29:03 +00:00
Evan Rittenhouse
b34804ceb5 Make D410/D411 autofixes mutually exclusive (#4110) 2023-04-28 01:24:35 +00:00
Moritz Sauter
ee6d8f7467 Add bugbear immutable functions as allowed in dataclasses (#4122) 2023-04-27 21:23:06 -04:00
Dhruv Manilawala
089b64e9c1 Autofix EM101, EM102, EM103 if possible (#4123) 2023-04-27 18:53:27 +00:00
Tom Kuson
3e81403fbe Add pygrep-hooks documentation (#4131) 2023-04-27 18:33:07 +00:00
Charlie Marsh
3c9f5e2fdc Preserve star-handling special-casing for force-single-line (#4129) 2023-04-27 00:02:17 -04:00
Micha Reiser
17db2e2a62 Fix B023 shadowed variables in nested functions (#4111) 2023-04-26 22:01:31 +01:00
Micha Reiser
e04ef42334 Use memchr to speedup newline search on x86 (#3985) 2023-04-26 20:15:47 +01:00
Micha Reiser
f3e6ddda62 perf(logical-lines): Various small perf improvements (#4022) 2023-04-26 20:10:35 +01:00
Micha Reiser
cab65b25da Replace row/column based Location with byte-offsets. (#3931) 2023-04-26 18:11:02 +00:00
Charlie Marsh
ee91598835 Tweak --show-fixes documentation (#4117) 2023-04-26 15:15:56 +00:00
Calum Young
ab65eaea7f Add docs build validation stage to CI (#4116)
Nice. Thank you
2023-04-26 14:57:59 +01:00
konstin
19d8913e32 Use musl in ecosystem docker (#3998)
This prevents errors when the host glibc is newer than the one in the docker container
2023-04-26 05:54:53 +02:00
Dhruv Manilawala
b9c06b48e1 Document that --diff implies --fix-only (#4098) 2023-04-25 21:19:44 -06:00
Charlie Marsh
7266eb0d69 Add support for providing command-line arguments via argfile (#4087) 2023-04-25 17:58:21 -06:00
Jonathan Plasse
4df7bc0bcd Fix E713 and E714 false positives for multiple comparisons (#4083) 2023-04-25 11:37:56 -06:00
Calum Young
464a0ff483 Fix docs failure (#4097) 2023-04-25 11:30:37 -06:00
Charlie Marsh
fd7ccb4c9e Bump version to 0.0.263 (#4086) 2023-04-24 23:32:29 -06:00
Evan Rittenhouse
ae6f38344a Unify positional and keyword arguments when checking for missing arguments in docstring (#4067) 2023-04-25 05:32:15 +00:00
Trevor McCulloch
bbf658d4c5 [pylint] Implement PLE0302 unexpected-special-method-signature (#4075) 2023-04-25 04:51:21 +00:00
Jonathan Plasse
1f3b0fd602 Fix SIM222 and SIM223 false positives and auto-fix (#4063) 2023-04-25 04:44:02 +00:00
Dhruv Manilawala
37483f3ac9 Ignore ClassVar annotation for RUF008, RUF009 (#4081) 2023-04-24 23:58:30 +00:00
Zanie Adkins
4d3a1e0581 Add PrefectHQ/prefect to list of ruff users (#4084) 2023-04-24 17:49:12 -06:00
Bartosz Sokorski
9e5f348a17 Add Poetry to the list of projects using Ruff (#4085) 2023-04-24 17:48:35 -06:00
Jonathan Plasse
5e91211e6d Add in_boolean_test to Context (#4072) 2023-04-23 23:18:23 -06:00
Jonathan Plasse
df77595426 Move Truthiness into ruff_python_ast (#4071) 2023-04-24 04:54:31 +00:00
Charlie Marsh
407af6e0ae Avoid infinite-propagation of inline comments when force-splitting imports (#4074) 2023-04-23 22:39:51 -06:00
Dhruv Manilawala
d64146683e Increment priority should be (branch-local, global) (#4070) 2023-04-23 00:04:15 -06:00
Charlie Marsh
0e7914010f Misc. small clean-up of flake8-import-conventions rules (#4069) 2023-04-23 04:57:15 +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
Tom Kuson
f5cd659292 Add docs for tryceratops rules (#4042) 2023-04-23 04:35:56 +00:00
Charlie Marsh
260138b427 Use Context for pep8-naming helpers (#4068) 2023-04-22 18:44:54 -04:00
Jonathan Plasse
2da149fd7e Ignore N815 for TypedDict fields (#4066) 2023-04-22 18:17:14 -04:00
Micha Reiser
e33887718d Use Rust 1.69 (#4065) 2023-04-22 23:04:17 +01:00
Micha Reiser
ba4f4f4672 Upgrade dependencies (#4064) 2023-04-22 18:04:01 +01:00
Pronoy Mandal
b7a57ce120 Update tutorial.md (#4055) 2023-04-21 10:56:31 -06:00
Alan Du
82abbc7234 [flake8-bugbear] Add pytest.raises(Exception) support to B017 (#4052) 2023-04-21 03:43:01 +00:00
Dhruv Manilawala
ba98149022 Avoid RUF008 if field annotation is immutable (#4039) 2023-04-20 16:02:12 -04:00
Dhruv Manilawala
7fd44a3e12 Avoid PYI015 for valid default value without annotation (#4043) 2023-04-20 15:45:47 -04:00
Evan Rittenhouse
6e8d561090 Support --fix in watch mode (#4035) 2023-04-19 23:33:12 -04:00
Jacob Coffee
cb762f4cad Add Astral announcement to README (#4010) 2023-04-19 20:28:45 +00:00
1159 changed files with 52121 additions and 29145 deletions

View File

@@ -33,4 +33,5 @@ rustflags = [
"-Wclippy::rc_buffer",
"-Wclippy::rc_mutex",
"-Wclippy::rest_pat_in_fully_bound_structs",
"-Wunreachable_pub"
]

View File

@@ -12,3 +12,6 @@ indent_size = 2
[*.{rs,py}]
indent_size = 4
[*.snap]
trim_trailing_whitespace = false

15
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,15 @@
<!--
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? -->
## Test Plan
<!-- How was it tested? -->

View File

@@ -15,6 +15,8 @@ env:
CARGO_NET_RETRY: 10
CARGO_TERM_COLOR: always
RUSTUP_MAX_RETRIES: 10
PACKAGE_NAME: ruff
PYTHON_VERSION: "3.7" # to build abi3 wheels
jobs:
cargo-fmt:
@@ -121,15 +123,6 @@ jobs:
- run: cargo check
- run: cargo fmt --all --check
typos:
name: "spell check"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: crate-ci/typos@master
with:
files: .
ecosystem:
name: "ecosystem"
runs-on: ubuntu-latest
@@ -190,18 +183,30 @@ jobs:
- name: "Install cargo-udeps"
uses: taiki-e/install-action@cargo-udeps
- name: "Run cargo-udeps"
run: cargo +nightly-2023-03-30 udeps
python-package:
name: "python package"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION }}
architecture: x64
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build wheels"
uses: PyO3/maturin-action@v1
with:
manylinux: auto
args: --out dist
- name: "Test wheel"
run: |
unused_dependencies=$(cargo +nightly-2023-03-30 udeps > unused.txt && cat unused.txt | cut -d $'\n' -f 2-)
if [ -z "$unused_dependencies" ]; then
echo "No unused dependencies found" > $GITHUB_STEP_SUMMARY
exit 0
else
echo "Found unused dependencies" > $GITHUB_STEP_SUMMARY
echo '```console' >> $GITHUB_STEP_SUMMARY
echo "$unused_dependencies" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
exit 1
fi
pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
ruff --help
python -m ruff --help
pre-commit:
name: "pre-commit"
@@ -230,3 +235,23 @@ jobs:
exit_code=${PIPESTATUS[0]}
echo '```' >> $GITHUB_STEP_SUMMARY
exit $exit_code
docs:
name: "mkdocs"
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
- name: "Install Rust toolchain"
run: rustup show
- uses: Swatinem/rust-cache@v2
- name: "Install dependencies"
run: pip install -r docs/requirements.txt
- name: "Update README File"
run: python scripts/transform_readme.py --target mkdocs
- name: "Generate docs"
run: python scripts/generate_mkdocs.py
- name: "Check docs formatting"
run: python scripts/check_docs_formatted.py
- name: "Build docs"
run: mkdocs build --strict

View File

@@ -1,9 +1,9 @@
name: mkdocs
on:
release:
types: [published]
workflow_dispatch:
release:
types: [ published ]
jobs:
mkdocs:

View File

@@ -52,7 +52,7 @@ jobs:
- name: "Build wheels - universal2"
uses: PyO3/maturin-action@v1
with:
args: --release --universal2 --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
args: --release --target universal2-apple-darwin --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
- name: "Install built wheel - universal2"
run: |
pip install dist/${{ env.CRATE_NAME }}-*universal2.whl --force-reinstall

View File

@@ -2,8 +2,8 @@ name: "[Playground] Release"
on:
workflow_dispatch:
push:
branches: [main]
release:
types: [ published ]
env:
CARGO_INCREMENTAL: 0

View File

@@ -3,7 +3,7 @@ name: "[ruff] Release"
on:
workflow_dispatch:
release:
types: [published]
types: [ published ]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -18,6 +18,31 @@ env:
RUSTUP_MAX_RETRIES: 10
jobs:
sdist:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION }}
- name: "Prep README.md"
run: python scripts/transform_readme.py --target pypi
- name: "Build sdist"
uses: PyO3/maturin-action@v1
with:
command: sdist
args: --out dist
- name: "Test sdist"
run: |
pip install dist/${{ env.PACKAGE_NAME }}-*.tar.gz --force-reinstall
ruff --help
python -m ruff --help
- name: "Upload sdist"
uses: actions/upload-artifact@v3
with:
name: wheels
path: dist
macos-x86_64:
runs-on: macos-latest
steps:
@@ -32,10 +57,12 @@ jobs:
uses: PyO3/maturin-action@v1
with:
target: x86_64
args: --release --out dist --sdist
- name: "Install built wheel - x86_64"
args: --release --out dist
- name: "Test wheel - x86_64"
run: |
pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
ruff --help
python -m ruff --help
- name: "Upload wheels"
uses: actions/upload-artifact@v3
with:
@@ -43,9 +70,9 @@ jobs:
path: dist
- name: "Archive binary"
run: |
ARCHIVE_FILE=ruff-x86_64-apple-darwin.tar.gz
tar czvf $ARCHIVE_FILE -C target/x86_64-apple-darwin/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
ARCHIVE_FILE=ruff-x86_64-apple-darwin.tar.gz
tar czvf $ARCHIVE_FILE -C target/x86_64-apple-darwin/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@v3
with:
@@ -67,10 +94,12 @@ jobs:
- name: "Build wheels - universal2"
uses: PyO3/maturin-action@v1
with:
args: --release --universal2 --out dist
- name: "Install built wheel - universal2"
args: --release --target universal2-apple-darwin --out dist
- name: "Test wheel - universal2"
run: |
pip install dist/${{ env.PACKAGE_NAME }}-*universal2.whl --force-reinstall
ruff --help
python -m ruff --help
- name: "Upload wheels"
uses: actions/upload-artifact@v3
with:
@@ -78,9 +107,9 @@ jobs:
path: dist
- name: "Archive binary"
run: |
ARCHIVE_FILE=ruff-aarch64-apple-darwin.tar.gz
tar czvf $ARCHIVE_FILE -C target/aarch64-apple-darwin/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
ARCHIVE_FILE=ruff-aarch64-apple-darwin.tar.gz
tar czvf $ARCHIVE_FILE -C target/aarch64-apple-darwin/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@v3
with:
@@ -113,11 +142,13 @@ jobs:
with:
target: ${{ matrix.platform.target }}
args: --release --out dist
- name: "Install built wheel"
- name: "Test wheel"
if: ${{ !startsWith(matrix.platform.target, 'aarch64') }}
shell: bash
run: |
python -m pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
ruff --help
python -m ruff --help
- name: "Upload wheels"
uses: actions/upload-artifact@v3
with:
@@ -126,9 +157,9 @@ jobs:
- name: "Archive binary"
shell: bash
run: |
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.zip
7z a $ARCHIVE_FILE ./target/${{ matrix.platform.target }}/release/ruff.exe
sha256sum $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.zip
7z a $ARCHIVE_FILE ./target/${{ matrix.platform.target }}/release/ruff.exe
sha256sum $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@v3
with:
@@ -158,10 +189,12 @@ jobs:
target: ${{ matrix.target }}
manylinux: auto
args: --release --out dist
- name: "Install built wheel"
- name: "Test wheel"
if: ${{ startsWith(matrix.target, 'x86_64') }}
run: |
pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
ruff --help
python -m ruff --help
- name: "Upload wheels"
uses: actions/upload-artifact@v3
with:
@@ -169,9 +202,9 @@ jobs:
path: dist
- name: "Archive binary"
run: |
ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz
tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz
tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@v3
with:
@@ -187,6 +220,9 @@ jobs:
platform:
- target: aarch64-unknown-linux-gnu
arch: aarch64
# see https://github.com/charliermarsh/ruff/issues/3791
# and https://github.com/gnzlbg/jemallocator/issues/170#issuecomment-1503228963
maturin_docker_options: -e JEMALLOC_SYS_WITH_LG_PAGE=16
- target: armv7-unknown-linux-gnueabihf
arch: armv7
- target: s390x-unknown-linux-gnu
@@ -195,6 +231,7 @@ jobs:
arch: ppc64le
- target: powerpc64-unknown-linux-gnu
arch: ppc64
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
@@ -207,10 +244,11 @@ jobs:
with:
target: ${{ matrix.platform.target }}
manylinux: auto
docker-options: ${{ matrix.platform.maturin_docker_options }}
args: --release --out dist
- uses: uraimo/run-on-arch-action@v2
if: matrix.platform.arch != 'ppc64'
name: Install built wheel
name: Test wheel
with:
arch: ${{ matrix.platform.arch }}
distro: ubuntu20.04
@@ -221,6 +259,7 @@ jobs:
pip3 install -U pip
run: |
pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
ruff --help
- name: "Upload wheels"
uses: actions/upload-artifact@v3
with:
@@ -228,9 +267,9 @@ jobs:
path: dist
- name: "Archive binary"
run: |
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz
tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz
tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@v3
with:
@@ -260,7 +299,7 @@ jobs:
target: ${{ matrix.target }}
manylinux: musllinux_1_2
args: --release --out dist
- name: "Install built wheel"
- name: "Test wheel"
if: matrix.target == 'x86_64-unknown-linux-musl'
uses: addnab/docker-run-action@v3
with:
@@ -269,6 +308,8 @@ jobs:
run: |
apk add py3-pip
pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links /io/dist/ --force-reinstall
ruff --help
python -m ruff --help
- name: "Upload wheels"
uses: actions/upload-artifact@v3
with:
@@ -276,9 +317,9 @@ jobs:
path: dist
- name: "Archive binary"
run: |
ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz
tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
ARCHIVE_FILE=ruff-${{ matrix.target }}.tar.gz
tar czvf $ARCHIVE_FILE -C target/${{ matrix.target }}/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@v3
with:
@@ -294,8 +335,10 @@ jobs:
platform:
- target: aarch64-unknown-linux-musl
arch: aarch64
maturin_docker_options: -e JEMALLOC_SYS_WITH_LG_PAGE=16
- target: armv7-unknown-linux-musleabihf
arch: armv7
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
@@ -309,8 +352,9 @@ jobs:
target: ${{ matrix.platform.target }}
manylinux: musllinux_1_2
args: --release --out dist
docker-options: ${{ matrix.platform.maturin_docker_options }}
- uses: uraimo/run-on-arch-action@v2
name: Install built wheel
name: Test wheel
with:
arch: ${{ matrix.platform.arch }}
distro: alpine_latest
@@ -319,6 +363,7 @@ jobs:
apk add py3-pip
run: |
pip3 install ${{ env.PACKAGE_NAME }} --no-index --find-links dist/ --force-reinstall
ruff check --help
- name: "Upload wheels"
uses: actions/upload-artifact@v3
with:
@@ -326,9 +371,9 @@ jobs:
path: dist
- name: "Archive binary"
run: |
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz
tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
ARCHIVE_FILE=ruff-${{ matrix.platform.target }}.tar.gz
tar czvf $ARCHIVE_FILE -C target/${{ matrix.platform.target }}/release ruff
shasum -a 256 $ARCHIVE_FILE > $ARCHIVE_FILE.sha256
- name: "Upload binary"
uses: actions/upload-artifact@v3
with:
@@ -361,9 +406,6 @@ jobs:
run: |
pip install --upgrade twine
twine upload --skip-existing *
- name: "Update pre-commit mirror"
run: |
curl -X POST -H "Accept: application/vnd.github+json" -H "Authorization: Bearer ${{ secrets.RUFF_PRE_COMMIT_PAT }}" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/charliermarsh/ruff-pre-commit/dispatches --data '{"event_type": "pypi_release"}'
- uses: actions/download-artifact@v3
with:
name: binaries
@@ -372,3 +414,22 @@ jobs:
uses: softprops/action-gh-release@v1
with:
files: binaries/*
# After the release has been published, we update downstream repositories
# This is separate because if this fails the release is still fine, we just need to do some manual workflow triggers
update-dependents:
name: Release
runs-on: ubuntu-latest
needs: release
steps:
- name: "Update pre-commit mirror"
uses: actions/github-script@v6
with:
github-token: ${{ secrets.RUFF_PRE_COMMIT_PAT }}
script: |
github.rest.actions.createWorkflowDispatch({
owner: 'astral-sh',
repo: 'ruff-pre-commit',
workflow_id: 'main.yml',
ref: 'main',
})

7
.gitignore vendored
View File

@@ -1,9 +1,10 @@
# Local cache
.ruff_cache
crates/ruff/resources/test/cpython
mkdocs.yml
.overrides
github_search.jsonl
ruff-old
github_search*.jsonl
schemastore
.venv*
###
# Rust.gitignore

View File

@@ -21,8 +21,14 @@ repos:
- --disable
- MD013 # line-length
- MD033 # no-inline-html
- MD041 # first-line-h1
- --
- repo: https://github.com/crate-ci/typos
rev: v1.14.8
hooks:
- id: typos
- repo: local
hooks:
- id: cargo-fmt
@@ -58,11 +64,6 @@ repos:
rev: 23.1.0
hooks:
- id: black
exclude: |
(?x)^(
crates/ruff/resources/.*|
crates/ruff_python_formatter/resources/.*
)$
ci:
skip: [cargo-fmt, clippy, dev-generate-all]

View File

@@ -1,5 +1,36 @@
# Breaking Changes
## 0.0.268
### The `keep-runtime-typing` setting has been removed ([#4427](https://github.com/charliermarsh/ruff/pull/4427))
Enabling the `keep-runtime-typing` option, located under the `pyupgrade` section, is equivalent
to ignoring the `UP006` and `UP007` rules via Ruff's standard `ignore` mechanism. As there's no
need for a dedicated setting to disable these rules, the `keep-runtime-typing` option has been
removed.
## 0.0.267
### `update-check` is no longer a valid configuration option ([#4313](https://github.com/charliermarsh/ruff/pull/4313))
The `update-check` functionality was deprecated in [#2530](https://github.com/charliermarsh/ruff/pull/2530),
in that the behavior itself was removed, and Ruff was changed to warn when that option was enabled.
Now, Ruff will throw an error when `update-check` is provided via a configuration file (e.g.,
`update-check = false`) or through the command-line, since it has no effect. Users should remove
this option from their configuration.
## 0.0.265
### `--fix-only` now exits with a zero exit code, unless `--exit-non-zero-on-fix` is specified ([#4146](https://github.com/charliermarsh/ruff/pull/4146))
Previously, `--fix-only` would exit with a non-zero exit code if any fixes were applied. This
behavior was inconsistent with `--fix`, and further, meant that `--exit-non-zero-on-fix` was
effectively ignored when `--fix-only` was specified.
Now, `--fix-only` will exit with a zero exit code, unless `--exit-non-zero-on-fix` is specified,
in which case it will exit with a non-zero exit code if any fixes were applied.
## 0.0.260
### Fixes are now represented as a list of edits ([#3709](https://github.com/charliermarsh/ruff/pull/3709))

View File

@@ -106,7 +106,7 @@ At a high level, the steps involved in adding a new lint rule are as follows:
1. Create a file for your rule (e.g., `crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs`).
1. In that file, define a violation struct. You can grep for `#[violation]` to see examples.
1. Map the violation struct to a rule code in `crates/ruff/src/registry.rs` (e.g., `E402`).
1. Define the logic for triggering the violation in `crates/ruff/src/checkers/ast.rs` (for AST-based
1. Define the logic for triggering the violation in `crates/ruff/src/checkers/ast/mod.rs` (for AST-based
checks), `crates/ruff/src/checkers/tokens.rs` (for token-based checks), `crates/ruff/src/checkers/lines.rs`
(for text-based checks), or `crates/ruff/src/checkers/filesystem.rs` (for filesystem-based
checks).
@@ -134,7 +134,7 @@ Run `cargo dev generate-all` to generate the code for your new fixture. Then run
locally with (e.g.) `cargo run -p ruff_cli -- check crates/ruff/resources/test/fixtures/pycodestyle/E402.py --no-cache --select E402`.
Once you're satisfied with the output, codify the behavior as a snapshot test by adding a new
`test_case` macro in the relevant `crates/ruff/src/[linter]/mod.rs` file. Then, run `cargo test`.
`test_case` macro in the relevant `crates/ruff/src/rules/[linter]/mod.rs` file. Then, run `cargo test`.
Your test will fail, but you'll be prompted to follow-up with `cargo insta review`. Accept the
generated snapshot, then commit the snapshot file alongside the rest of your changes.
@@ -148,7 +148,7 @@ This implies that rule names:
- should state the bad thing being checked for
- should not contain instructions on what you what you should use instead
- should not contain instructions on what you should use instead
(these belong in the rule documentation and the `autofix_title` for rules that have autofix)
When re-implementing rules from other linters, this convention is given more importance than
@@ -225,7 +225,7 @@ python scripts/check_ecosystem.py path/to/your/ruff path/to/older/ruff
You can also run the Ecosystem CI check in a Docker container across a larger set of projects by
downloading the [`known-github-tomls.json`](https://github.com/akx/ruff-usage-aggregate/blob/master/data/known-github-tomls.jsonl)
as `github_search.jsonl` and following the instructions in [scripts/Dockerfile.ecosystem](scripts/Dockerfile.ecosystem).
as `github_search.jsonl` and following the instructions in [scripts/Dockerfile.ecosystem](https://github.com/charliermarsh/ruff/blob/main/scripts/Dockerfile.ecosystem).
Note that this check will take a while to run.
## Benchmarks

1224
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -3,7 +3,7 @@ members = ["crates/*"]
[workspace.package]
edition = "2021"
rust-version = "1.67"
rust-version = "1.69"
homepage = "https://beta.ruff.rs/docs/"
documentation = "https://beta.ruff.rs/docs/"
repository = "https://github.com/charliermarsh/ruff"
@@ -11,7 +11,7 @@ authors = ["Charlie Marsh <charlie.r.marsh@gmail.com>"]
[workspace.dependencies]
anyhow = { version = "1.0.69" }
bitflags = { version = "1.3.2" }
bitflags = { version = "2.3.1" }
chrono = { version = "0.4.23", default-features = false, features = ["clock"] }
clap = { version = "4.1.8", features = ["derive"] }
colored = { version = "2.0.0" }
@@ -31,11 +31,11 @@ proc-macro2 = { version = "1.0.51" }
quote = { version = "1.0.23" }
regex = { version = "1.7.1" }
rustc-hash = { version = "1.1.0" }
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "c15f670f2c30cfae6b41a1874893590148c74bc4" }
rustpython-parser = { features = [
"lalrpop",
"serde",
], git = "https://github.com/RustPython/RustPython.git", rev = "c15f670f2c30cfae6b41a1874893590148c74bc4" }
ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65" }
rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65", default-features = false, features = ["all-nodes-with-ranges"]}
rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65" }
rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65" }
rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "335780aeeac1e6fcd85994ba001d7b8ce99fcf65", default-features = false, features = ["full-lexer", "all-nodes-with-ranges"] }
schemars = { version = "0.8.12" }
serde = { version = "1.0.152", features = ["derive"] }
serde_json = { version = "1.0.93", features = ["preserve_order"] }
@@ -44,7 +44,7 @@ similar = { version = "2.2.1" }
smallvec = { version = "1.10.0" }
strum = { version = "0.24.1", features = ["strum_macros"] }
strum_macros = { version = "0.24.3" }
syn = { version = "1.0.109" }
syn = { version = "2.0.15" }
test-case = { version = "3.0.0" }
textwrap = { version = "0.16.0" }
toml = { version = "0.7.2" }

80
LICENSE
View File

@@ -354,6 +354,37 @@ are:
SOFTWARE.
"""
- flake8-todos, licensed as follows:
"""
Copyright (c) 2019 EclecticIQ. All rights reserved.
Copyright (c) 2020 Gram <gram@orsinium.dev>. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""
- flake8-unused-arguments, licensed as follows:
"""
MIT License
@@ -550,6 +581,30 @@ are:
THE SOFTWARE.
"""
- flynt, licensed as follows:
"""
MIT License
Copyright (c) 2019-2022 Ilya Kamenshchikov
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
- isort, licensed as follows:
"""
@@ -759,6 +814,31 @@ are:
SOFTWARE.
"""
- flake8-async, licensed as follows:
"""
MIT License
Copyright (c) 2022 Cooper Lees
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"""
- flake8-type-checking, licensed as follows:
"""
Copyright (c) 2021, Sondre Lillebø Gundersen

View File

@@ -2,7 +2,7 @@
# Ruff
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v1.json)](https://github.com/charliermarsh/ruff)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/charliermarsh/ruff)
[![image](https://img.shields.io/pypi/v/ruff.svg)](https://pypi.python.org/pypi/ruff)
[![image](https://img.shields.io/pypi/l/ruff.svg)](https://pypi.python.org/pypi/ruff)
[![image](https://img.shields.io/pypi/pyversions/ruff.svg)](https://pypi.python.org/pypi/ruff)
@@ -33,7 +33,7 @@ An extremely fast Python linter, written in Rust.
- 📏 Over [500 built-in rules](https://beta.ruff.rs/docs/rules/)
- ⚖️ [Near-parity](https://beta.ruff.rs/docs/faq/#how-does-ruff-compare-to-flake8) with the built-in Flake8 rule set
- 🔌 Native re-implementations of dozens of Flake8 plugins, like flake8-bugbear
- ⌨️ First-party editor integrations for [VS Code](https://github.com/charliermarsh/ruff-vscode) and [more](https://github.com/charliermarsh/ruff-lsp)
- ⌨️ First-party editor integrations for [VS Code](https://github.com/astral-sh/ruff-vscode) and [more](https://github.com/astral-sh/ruff-lsp)
- 🌎 Monorepo-friendly, with [hierarchical and cascading configuration](https://beta.ruff.rs/docs/configuration/#pyprojecttoml-discovery)
Ruff aims to be orders of magnitude faster than alternative tools while integrating more
@@ -55,8 +55,8 @@ Ruff is extremely actively developed and used in major open-source projects like
...and many more.
Read the [launch blog post](https://notes.crmarsh.com/python-tooling-could-be-much-much-faster) or
the most recent [project update](https://notes.crmarsh.com/ruff-the-first-200-releases).
Ruff is backed by [Astral](https://astral.sh). Read the [launch post](https://astral.sh/blog/announcing-astral-the-company-behind-ruff),
or the original [project announcement](https://notes.crmarsh.com/python-tooling-could-be-much-much-faster).
## Testimonials
@@ -135,15 +135,15 @@ ruff check path/to/code/to/file.py # Lint `file.py`
Ruff can also be used as a [pre-commit](https://pre-commit.com) hook:
```yaml
- repo: https://github.com/charliermarsh/ruff-pre-commit
- repo: https://github.com/astral-sh/ruff-pre-commit
# Ruff version.
rev: 'v0.0.262'
rev: v0.0.270
hooks:
- id: ruff
```
Ruff can also be used as a [VS Code extension](https://github.com/charliermarsh/ruff-vscode) or
alongside any other editor through the [Ruff LSP](https://github.com/charliermarsh/ruff-lsp).
Ruff can also be used as a [VS Code extension](https://github.com/astral-sh/ruff-vscode) or
alongside any other editor through the [Ruff LSP](https://github.com/astral-sh/ruff-lsp).
Ruff can also be used as a [GitHub Action](https://github.com/features/actions) via
[`ruff-action`](https://github.com/chartboost/ruff-action):
@@ -183,6 +183,7 @@ exclude = [
".direnv",
".eggs",
".git",
".git-rewrite",
".hg",
".mypy_cache",
".nox",
@@ -248,6 +249,7 @@ quality tools, including:
- [eradicate](https://pypi.org/project/eradicate/)
- [flake8-2020](https://pypi.org/project/flake8-2020/)
- [flake8-annotations](https://pypi.org/project/flake8-annotations/)
- [flake8-async](https://pypi.org/project/flake8-async)
- [flake8-bandit](https://pypi.org/project/flake8-bandit/) ([#1646](https://github.com/charliermarsh/ruff/issues/1646))
- [flake8-blind-except](https://pypi.org/project/flake8-blind-except/)
- [flake8-boolean-trap](https://pypi.org/project/flake8-boolean-trap/)
@@ -262,6 +264,7 @@ quality tools, including:
- [flake8-eradicate](https://pypi.org/project/flake8-eradicate/)
- [flake8-errmsg](https://pypi.org/project/flake8-errmsg/)
- [flake8-executable](https://pypi.org/project/flake8-executable/)
- [flake8-future-annotations](https://pypi.org/project/flake8-future-annotations/)
- [flake8-gettext](https://pypi.org/project/flake8-gettext/)
- [flake8-implicit-str-concat](https://pypi.org/project/flake8-implicit-str-concat/)
- [flake8-import-conventions](https://github.com/joaopalmeiro/flake8-import-conventions)
@@ -278,14 +281,16 @@ quality tools, including:
- [flake8-simplify](https://pypi.org/project/flake8-simplify/)
- [flake8-super](https://pypi.org/project/flake8-super/)
- [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/)
- [flake8-todos](https://pypi.org/project/flake8-todos/)
- [flake8-type-checking](https://pypi.org/project/flake8-type-checking/)
- [flake8-use-pathlib](https://pypi.org/project/flake8-use-pathlib/)
- [flynt](https://pypi.org/project/flynt/) ([#2102](https://github.com/charliermarsh/ruff/issues/2102))
- [isort](https://pypi.org/project/isort/)
- [mccabe](https://pypi.org/project/mccabe/)
- [pandas-vet](https://pypi.org/project/pandas-vet/)
- [pep8-naming](https://pypi.org/project/pep8-naming/)
- [pydocstyle](https://pypi.org/project/pydocstyle/)
- [pygrep-hooks](https://github.com/pre-commit/pygrep-hooks) ([#980](https://github.com/charliermarsh/ruff/issues/980))
- [pygrep-hooks](https://github.com/pre-commit/pygrep-hooks)
- [pyupgrade](https://pypi.org/project/pyupgrade/)
- [tryceratops](https://pypi.org/project/tryceratops/)
- [yesqa](https://pypi.org/project/yesqa/)
@@ -341,9 +346,9 @@ Ruff is used by a number of major open-source projects and companies, including:
- [Babel](https://github.com/python-babel/babel)
- [Bokeh](https://github.com/bokeh/bokeh)
- [Cryptography (PyCA)](https://github.com/pyca/cryptography)
- [DVC](https://github.com/iterative/dvc)
- [Dagger](https://github.com/dagger/dagger)
- [Dagster](https://github.com/dagster-io/dagster)
- [DVC](https://github.com/iterative/dvc)
- [FastAPI](https://github.com/tiangolo/fastapi)
- [Gradio](https://github.com/gradio-app/gradio)
- [Great Expectations](https://github.com/great-expectations/great_expectations)
@@ -359,7 +364,7 @@ Ruff is used by a number of major open-source projects and companies, including:
- Modern Treasury ([Python SDK](https://github.com/Modern-Treasury/modern-treasury-python-sdk))
- Mozilla ([Firefox](https://github.com/mozilla/gecko-dev))
- [MegaLinter](https://github.com/oxsecurity/megalinter)
- Microsoft ([Semantic Kernel](https://github.com/microsoft/semantic-kernel), [ONNX Runtime](https://github.com/microsoft/onnxruntime))
- Microsoft ([Semantic Kernel](https://github.com/microsoft/semantic-kernel), [ONNX Runtime](https://github.com/microsoft/onnxruntime), [LightGBM](https://github.com/microsoft/LightGBM))
- Netflix ([Dispatch](https://github.com/Netflix/dispatch))
- [Neon](https://github.com/neondatabase/neon)
- [ONNX](https://github.com/onnx/onnx)
@@ -367,11 +372,13 @@ Ruff is used by a number of major open-source projects and companies, including:
- [PDM](https://github.com/pdm-project/pdm)
- [PaddlePaddle](https://github.com/PaddlePaddle/Paddle)
- [Pandas](https://github.com/pandas-dev/pandas)
- [Poetry](https://github.com/python-poetry/poetry)
- [Polars](https://github.com/pola-rs/polars)
- [PostHog](https://github.com/PostHog/posthog)
- Prefect ([Marvin](https://github.com/PrefectHQ/marvin))
- [Pydantic](https://github.com/pydantic/pydantic)
- Prefect ([Python SDK](https://github.com/PrefectHQ/prefect), [Marvin](https://github.com/PrefectHQ/marvin))
- [PyInstaller](https://github.com/pyinstaller/pyinstaller)
- [PyTorch](https://github.com/pytorch/pytorch)
- [Pydantic](https://github.com/pydantic/pydantic)
- [Pylint](https://github.com/PyCQA/pylint)
- [Pynecone](https://github.com/pynecone-io/pynecone)
- [Robyn](https://github.com/sansyrox/robyn)
@@ -381,7 +388,7 @@ Ruff is used by a number of major open-source projects and companies, including:
- [SciPy](https://github.com/scipy/scipy)
- [Sphinx](https://github.com/sphinx-doc/sphinx)
- [Stable Baselines3](https://github.com/DLR-RM/stable-baselines3)
- [Starlite](https://github.com/starlite-api/starlite)
- [Litestar](https://litestar.dev/)
- [The Algorithms](https://github.com/TheAlgorithms/Python)
- [Vega-Altair](https://github.com/altair-viz/altair)
- WordPress ([Openverse](https://github.com/WordPress/openverse))
@@ -394,6 +401,34 @@ Ruff is used by a number of major open-source projects and companies, including:
- [meson-python](https://github.com/mesonbuild/meson-python)
- [nox](https://github.com/wntrblm/nox)
### Show Your Support
If you're using Ruff, consider adding the Ruff badge to project's `README.md`:
```md
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/charliermarsh/ruff)
```
...or `README.rst`:
```rst
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json
:target: https://github.com/charliermarsh/ruff
:alt: Ruff
```
...or, as HTML:
```html
<a href="https://github.com/charliermarsh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json" alt="Ruff" style="max-width:100%;"></a>
```
## License
MIT
<div align="center">
<a target="_blank" href="https://astral.sh" style="background:none">
<img src="https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/svg/Astral.svg">
</a>
</div>

View File

@@ -6,3 +6,5 @@ trivias = "trivias"
hel = "hel"
whos = "whos"
spawnve = "spawnve"
ned = "ned"
poit = "poit"

8
assets/badge/v2.json Normal file
View File

@@ -0,0 +1,8 @@
{
"label": "",
"message": "Ruff",
"logoSvg": "<svg width=\"510\" height=\"622\" viewBox=\"0 0 510 622\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><path fill-rule=\"evenodd\" clip-rule=\"evenodd\" d=\"M206.701 0C200.964 0 196.314 4.64131 196.314 10.3667V41.4667C196.314 47.192 191.663 51.8333 185.927 51.8333H156.843C151.107 51.8333 146.456 56.4746 146.456 62.2V145.133C146.456 150.859 141.806 155.5 136.069 155.5H106.986C101.249 155.5 96.5988 160.141 96.5988 165.867V222.883C96.5988 228.609 91.9484 233.25 86.2118 233.25H57.1283C51.3917 233.25 46.7413 237.891 46.7413 243.617V300.633C46.7413 306.359 42.0909 311 36.3544 311H10.387C4.6504 311 0 315.641 0 321.367V352.467C0 358.192 4.6504 362.833 10.387 362.833H145.418C151.154 362.833 155.804 367.475 155.804 373.2V430.217C155.804 435.942 151.154 440.583 145.418 440.583H116.334C110.597 440.583 105.947 445.225 105.947 450.95V507.967C105.947 513.692 101.297 518.333 95.5601 518.333H66.4766C60.74 518.333 56.0896 522.975 56.0896 528.7V611.633C56.0896 617.359 60.74 622 66.4766 622H149.572C155.309 622 159.959 617.359 159.959 611.633V570.167H201.507C207.244 570.167 211.894 565.525 211.894 559.8V528.7C211.894 522.975 216.544 518.333 222.281 518.333H251.365C257.101 518.333 261.752 513.692 261.752 507.967V476.867C261.752 471.141 266.402 466.5 272.138 466.5H301.222C306.959 466.5 311.609 461.859 311.609 456.133V425.033C311.609 419.308 316.259 414.667 321.996 414.667H351.079C356.816 414.667 361.466 410.025 361.466 404.3V373.2C361.466 367.475 366.117 362.833 371.853 362.833H400.937C406.673 362.833 411.324 358.192 411.324 352.467V321.367C411.324 315.641 415.974 311 421.711 311H450.794C456.531 311 461.181 306.359 461.181 300.633V217.7C461.181 211.975 456.531 207.333 450.794 207.333H420.672C414.936 207.333 410.285 202.692 410.285 196.967V165.867C410.285 160.141 414.936 155.5 420.672 155.5H449.756C455.492 155.5 460.143 150.859 460.143 145.133V114.033C460.143 108.308 464.793 103.667 470.53 103.667H499.613C505.35 103.667 510 99.0253 510 93.3V10.3667C510 4.64132 505.35 0 499.613 0H206.701ZM168.269 440.583C162.532 440.583 157.882 445.225 157.882 450.95V507.967C157.882 513.692 153.231 518.333 147.495 518.333H118.411C112.675 518.333 108.024 522.975 108.024 528.7V559.8C108.024 565.525 112.675 570.167 118.411 570.167H159.959V528.7C159.959 522.975 164.61 518.333 170.346 518.333H199.43C205.166 518.333 209.817 513.692 209.817 507.967V476.867C209.817 471.141 214.467 466.5 220.204 466.5H249.287C255.024 466.5 259.674 461.859 259.674 456.133V425.033C259.674 419.308 264.325 414.667 270.061 414.667H299.145C304.881 414.667 309.532 410.025 309.532 404.3V373.2C309.532 367.475 314.182 362.833 319.919 362.833H349.002C354.739 362.833 359.389 358.192 359.389 352.467V321.367C359.389 315.641 364.039 311 369.776 311H398.859C404.596 311 409.246 306.359 409.246 300.633V269.533C409.246 263.808 404.596 259.167 398.859 259.167H318.88C313.143 259.167 308.493 254.525 308.493 248.8V217.7C308.493 211.975 313.143 207.333 318.88 207.333H347.963C353.7 207.333 358.35 202.692 358.35 196.967V165.867C358.35 160.141 363.001 155.5 368.737 155.5H397.821C403.557 155.5 408.208 150.859 408.208 145.133V114.033C408.208 108.308 412.858 103.667 418.595 103.667H447.678C453.415 103.667 458.065 99.0253 458.065 93.3V62.2C458.065 56.4746 453.415 51.8333 447.678 51.8333H208.778C203.041 51.8333 198.391 56.4746 198.391 62.2V145.133C198.391 150.859 193.741 155.5 188.004 155.5H158.921C153.184 155.5 148.534 160.141 148.534 165.867V222.883C148.534 228.609 143.883 233.25 138.147 233.25H109.063C103.327 233.25 98.6762 237.891 98.6762 243.617V300.633C98.6762 306.359 103.327 311 109.063 311H197.352C203.089 311 207.739 315.641 207.739 321.367V430.217C207.739 435.942 203.089 440.583 197.352 440.583H168.269Z\" fill=\"#D7FF64\"/></svg>",
"logoWidth": 10,
"labelColor": "grey",
"color": "#261230"
}

24
assets/svg/Astral.svg Normal file
View File

@@ -0,0 +1,24 @@
<svg width="139" height="24" viewBox="0 0 139 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect width="138.764" height="24" rx="2.18182" fill="#261230"/>
<path
d="M8.72798 15.2726H9.91316V11.8697L9.6887 10.4062L9.8952 10.3343L12.1309 15.1649L14.3486 10.3343L14.5461 10.4062L14.3486 11.8607V15.2726H15.5248V8.72714H13.9535L12.2117 12.7137H12.0142L10.2723 8.72714H8.72798V15.2726Z"
fill="#D7FF64"/>
<path
d="M22.3432 15.2726H23.6631L21.3017 8.72714H19.7574L17.4589 15.2726H18.7069L19.1558 13.9797H21.9033L22.3432 15.2726ZM19.497 13.0279L19.901 11.8607L20.4308 10.0021H20.6463L21.176 11.8607L21.5711 13.0279H19.497Z"
fill="#D7FF64"/>
<path
d="M25.4209 15.2726H28.1234C30.1077 15.2726 30.9876 14.1413 30.9876 12.0044C30.9876 9.92131 30.1706 8.72714 28.1234 8.72714H25.4209V15.2726ZM26.624 14.2131V9.77765H28.0965C29.147 9.77765 29.7306 10.1907 29.7306 11.4477V12.5521C29.7306 13.6923 29.2817 14.2131 28.0965 14.2131H26.624Z"
fill="#D7FF64"/>
<path
d="M33.079 15.2726H37.6491V14.2131H34.2822V12.3815H37.2002V11.3938H34.2822V9.77765H37.6491V8.72714H33.079V15.2726Z"
fill="#D7FF64"/>
<path
d="M42.923 15.2726H46.2451C47.4572 15.2726 48.2025 14.5812 48.2025 13.5487C48.2025 12.7675 47.8343 12.175 47.0532 11.9954V11.7799C47.6637 11.5734 48.0319 11.0436 48.0319 10.3433C48.0319 9.38259 47.4572 8.72714 46.281 8.72714H42.923V15.2726ZM44.0992 11.4746V9.65195H45.9578C46.4875 9.65195 46.7928 9.92131 46.7928 10.3523V10.7653C46.7928 11.1873 46.4965 11.4746 45.9758 11.4746H44.0992ZM44.0992 14.3388V12.3904H46.0296C46.5863 12.3904 46.9365 12.6418 46.9365 13.1806V13.5666C46.9365 14.0425 46.5684 14.3388 45.9309 14.3388H44.0992Z"
fill="#D7FF64"/>
<path
d="M49.6959 8.72714L52.174 12.579V14.1952H50.1898V15.2726H53.3772V12.579L55.8553 8.72714H54.4456L53.5119 10.2535L52.8744 11.3759H52.6679L52.0483 10.2715L51.1056 8.72714H49.6959Z"
fill="#D7FF64"/>
<path fill-rule="evenodd" clip-rule="evenodd"
d="M74.1824 7.63626C74.1824 7.03377 74.6708 6.54535 75.2733 6.54535H84.0006C84.6031 6.54535 85.0915 7.03377 85.0915 7.63626V9.81808H80.0733V8.94535H79.2006V10.6908H84.0006C84.6031 10.6908 85.0915 11.1792 85.0915 11.7817V16.3635C85.0915 16.966 84.6031 17.4544 84.0006 17.4544H75.2733C74.6708 17.4544 74.1824 16.966 74.1824 16.3635V14.1817L79.2006 14.1817V15.0544H80.0733V13.309L75.2733 13.309C74.6708 13.309 74.1824 12.8206 74.1824 12.2181V7.63626ZM63.4912 6.54545C62.8887 6.54545 62.4003 7.03387 62.4003 7.63636V17.4545H67.4185V14.1818H68.2912V17.4545H73.3094V7.63636C73.3094 7.03387 72.821 6.54545 72.2185 6.54545H63.4912ZM69.164 10.6909V11.5636H66.5458V10.6909H69.164ZM110.619 6.54545C110.016 6.54545 109.528 7.03387 109.528 7.63636V17.4545H114.546V14.1818H115.419V17.4545H120.437V7.63636C120.437 7.03387 119.948 6.54545 119.346 6.54545H110.619ZM116.291 10.6909V11.5636H113.673V10.6909H116.291ZM91.8549 8.29091H96.8731V11.3455C96.8731 11.9479 96.3847 12.4364 95.7822 12.4364H91.8549V13.3091H96.8731V17.4545H87.9276C87.3251 17.4545 86.8367 16.9661 86.8367 16.3636V12.4364H85.964V8.29091H86.8367V6.54545H91.8549V8.29091ZM108.655 7.63636C108.655 7.03387 108.166 6.54545 107.564 6.54545H97.7458V17.4545H102.764V14.1818H103.637V17.4545H108.655V13.3091H106.473V12.4364H107.564C108.166 12.4364 108.655 11.9479 108.655 11.3455V7.63636ZM104.509 10.6909V11.5636H101.891V10.6909H104.509ZM132.218 13.3091L126.327 13.3091V6.54547L121.309 6.54547V17.4546H132.218V13.3091Z"
fill="#D7FF64"/>
</svg>

After

Width:  |  Height:  |  Size: 3.4 KiB

View File

@@ -1,6 +1,6 @@
[package]
name = "flake8-to-ruff"
version = "0.0.262"
version = "0.0.270"
edition = { workspace = true }
rust-version = { workspace = true }

View File

@@ -26,7 +26,7 @@ requires-python = ">=3.7"
repository = "https://github.com/charliermarsh/ruff#subdirectory=crates/flake8_to_ruff"
[build-system]
requires = ["maturin>=0.14,<0.15"]
requires = ["maturin>=1.0,<2.0"]
build-backend = "maturin"
[tool.maturin]

View File

@@ -1,6 +1,6 @@
[package]
name = "ruff"
version = "0.0.262"
version = "0.0.270"
authors.workspace = true
edition.workspace = true
rust-version.workspace = true
@@ -17,11 +17,11 @@ name = "ruff"
ruff_cache = { path = "../ruff_cache" }
ruff_diagnostics = { path = "../ruff_diagnostics", features = ["serde"] }
ruff_macros = { path = "../ruff_macros" }
ruff_python_ast = { path = "../ruff_python_ast" }
ruff_python_ast = { path = "../ruff_python_ast", features = ["serde"] }
ruff_python_semantic = { path = "../ruff_python_semantic" }
ruff_python_stdlib = { path = "../ruff_python_stdlib" }
ruff_rustpython = { path = "../ruff_rustpython" }
ruff_text_size = { path = "../ruff_text_size" }
ruff_text_size = { workspace = true }
annotate-snippets = { version = "0.9.1", features = ["color"] }
anyhow = { workspace = true }
@@ -29,7 +29,7 @@ bitflags = { workspace = true }
chrono = { workspace = true }
clap = { workspace = true, features = ["derive", "string"], optional = true }
colored = { workspace = true }
dirs = { version = "4.0.0" }
dirs = { version = "5.0.0" }
fern = { version = "0.6.1" }
glob = { workspace = true }
globset = { workspace = true }
@@ -54,9 +54,9 @@ quick-junit = { version = "0.3.2" }
regex = { workspace = true }
result-like = { version = "0.4.6" }
rustc-hash = { workspace = true }
rustpython-common = { workspace = true }
rustpython-format = { workspace = true }
rustpython-parser = { workspace = true }
schemars = { workspace = true }
schemars = { workspace = true, optional = true }
semver = { version = "1.0.16" }
serde = { workspace = true }
serde_json = { workspace = true }
@@ -70,6 +70,7 @@ thiserror = { version = "1.0.38" }
toml = { workspace = true }
typed-arena = { version = "2.0.2" }
unicode-width = { version = "0.1.10" }
unicode_names2 = { version = "0.6.0", git = "https://github.com/youknowone/unicode_names2.git", rev = "4ce16aa85cbcdd9cc830410f1a72ef9a235f2fde" }
[dev-dependencies]
insta = { workspace = true }
@@ -80,5 +81,5 @@ colored = { workspace = true, features = ["no-color"] }
[features]
default = []
logical_lines = []
schemars = ["dep:schemars"]
jupyter_notebook = []

View File

@@ -14,3 +14,8 @@ def foo(x, y, z):
return False
#import os # noqa: ERA001
class A():
pass
# b = c

View File

@@ -1,4 +1,5 @@
from typing import Any, Type
from typing_extensions import override
# Error
def foo(a, b):
@@ -94,6 +95,31 @@ class Foo:
def foo(self: "Foo", a: int, *params: str, **options: Any) -> int:
pass
# ANN401
@override
def foo(self: "Foo", a: Any, *params: str, **options: str) -> int:
pass
# ANN401
@override
def foo(self: "Foo", a: int, *params: str, **options: str) -> Any:
pass
# ANN401
@override
def foo(self: "Foo", a: int, *params: Any, **options: Any) -> int:
pass
# ANN401
@override
def foo(self: "Foo", a: int, *params: Any, **options: str) -> int:
pass
# ANN401
@override
def foo(self: "Foo", a: int, *params: str, **options: Any) -> int:
pass
# OK
@classmethod
def foo(cls: Type["Foo"], a: int, b: int) -> int:

View File

@@ -0,0 +1,23 @@
import urllib.request
import requests
import httpx
async def foo():
urllib.request.urlopen("http://example.com/foo/bar").read()
async def foo():
requests.get()
async def foo():
httpx.get()
async def foo():
requests.post()
async def foo():
httpx.post()

View File

@@ -0,0 +1,31 @@
import os
import subprocess
import time
async def foo():
open("foo")
async def foo():
time.sleep(1)
async def foo():
subprocess.run("foo")
async def foo():
subprocess.call("foo")
async def foo():
subprocess.foo(0)
async def foo():
os.wait4(10)
async def foo():
os.wait(12)

View File

@@ -0,0 +1,13 @@
import os
async def foo():
os.popen()
async def foo():
os.spawnl()
async def foo():
os.fspath("foo")

View File

@@ -0,0 +1,3 @@
import paramiko
paramiko.exec_command('something; really; unsafe')

View File

@@ -74,8 +74,8 @@ def query40():
def query41():
return (
"SELECT *"
"FROM table"
"SELECT * "
"FROM table "
f"WHERE var = {var}"
)
@@ -84,7 +84,7 @@ query42 = cursor.execute("SELECT * FROM table WHERE var = %s" % var)
query43 = cursor.execute(f"SELECT * FROM table WHERE var = {var}")
query44 = cursor.execute("SELECT * FROM table WHERE var = {}".format(var))
query45 = cursor.executemany("SELECT * FROM table WHERE var = %s" % var, [])
# # pass
query = "SELECT * FROM table WHERE id = 1"
query = "DELETE FROM table WHERE id = 1"
@@ -93,3 +93,12 @@ query = "UPDATE table SET id = 1"
cursor.execute('SELECT * FROM table WHERE id = %s', var)
cursor.execute('SELECT * FROM table WHERE id = 1')
cursor.executemany('SELECT * FROM table WHERE id = %s', [var, var2])
# # INSERT without INTO (e.g. MySQL and derivatives)
query = "INSERT table VALUES (%s)" % (var,)
# # REPLACE (e.g. MySQL and derivatives, SQLite)
query = "REPLACE INTO table VALUES (%s)" % (var,)
query = "REPLACE table VALUES (%s)" % (var,)
query = "Deselect something that is not SQL even though it has a ' from ' somewhere in %s." % "there"

View File

@@ -73,7 +73,18 @@ def f():
def f():
# Fixable.
# Unfixable.
for foo, bar, baz in (["1", "2", "3"],):
if foo or baz:
break
else:
bar = 1
print(bar)
def f():
# Unfixable (false negative) due to usage of `bar` outside of loop.
for foo, bar, baz in (["1", "2", "3"],):
if foo or baz:
break
@@ -85,4 +96,4 @@ def f():
# Unfixable due to trailing underscore (`_line_` wouldn't be considered an ignorable
# variable name).
for line_ in range(self.header_lines):
fp.readline()
fp.readline()

View File

@@ -1,9 +1,10 @@
"""
Should emit:
B017 - on lines 20
B017 - on lines 23 and 41
"""
import asyncio
import unittest
import pytest
CONSTANT = True
@@ -34,3 +35,14 @@ class Foobar(unittest.TestCase):
def raises_with_absolute_reference(self):
with self.assertRaises(asyncio.CancelledError):
Foo()
def test_pytest_raises():
with pytest.raises(Exception):
raise ValueError("Hello")
with pytest.raises(Exception, "hello"):
raise ValueError("This is fine")
with pytest.raises(Exception, match="hello"):
raise ValueError("This is also fine")

View File

@@ -172,3 +172,14 @@ def iter_f(names):
if False:
return [lambda: i for i in range(3)] # error
for val in range(3):
def make_func(val=val):
def tmp():
return print(val)
return tmp
funcs.append(make_func())

View File

@@ -4,7 +4,12 @@ B027 - on lines 13, 16, 19, 23
"""
import abc
from abc import ABC
from abc import abstractmethod, abstractproperty
from abc import (
abstractmethod,
abstractproperty,
abstractclassmethod,
abstractstaticmethod,
)
from abc import abstractmethod as notabstract
from abc import abstractproperty as notabstract_property
@@ -55,6 +60,22 @@ class AbstractClass(ABC):
def abstract_6(self):
...
@abstractclassmethod
def abstract_7(self):
pass
@abc.abstractclassmethod
def abstract_8(self):
...
@abstractstaticmethod
def abstract_9(self):
pass
@abc.abstractstaticmethod
def abstract_10(self):
...
def body_1(self):
print("foo")
...

View File

@@ -149,6 +149,16 @@ for group in groupby(items, key=lambda p: p[1]):
collect_shop_items("Joe", group[1])
# https://github.com/charliermarsh/ruff/issues/4050
for _section, section_items in itertools.groupby(items, key=lambda p: p[1]):
if _section == "greens":
for item in section_items:
collect_shop_items(shopper, item)
elif _section == "frozen items":
_ = [item for item in section_items]
else:
collect_shop_items(shopper, section_items)
# Make sure we ignore - but don't fail on more complicated invocations
for _key, (_value1, _value2) in groupby(
[("a", (1, 2)), ("b", (3, 4)), ("a", (5, 6))], key=lambda p: p[1]

View File

@@ -631,3 +631,11 @@ result = function(
the_first_one = next(
(i for i in range(10) if i // 2 == 0) # COM812 fix should include the final bracket
)
foo = namedtuple(
name="foo",
status="bar",
message="sfdsdfsdgs fsdfsdf output!dsfdfsdjkg ghfskdjghkdssd sd fsdf s\n"[
:20
],
)

View File

@@ -17,3 +17,23 @@ all((x.id for x in bar))
async def f() -> bool:
return all([await use_greeting(greeting) for greeting in await greetings()])
# Special comment handling
any(
[ # lbracket comment
# second line comment
i.bit_count()
# random middle comment
for i in range(5) # rbracket comment
] # rpar comment
# trailing comment
)
# Weird case where the function call, opening bracket, and comment are all
# on the same line.
any([ # lbracket comment
# second line comment
i.bit_count() for i in range(5) # rbracket comment
] # rpar comment
)

View File

@@ -21,3 +21,36 @@ def f_c():
def f_ok():
msg = "hello"
raise RuntimeError(msg)
def f_unfixable():
msg = "hello"
raise RuntimeError("This is an example exception")
def f_msg_in_nested_scope():
def nested():
msg = "hello"
raise RuntimeError("This is an example exception")
def f_msg_in_parent_scope():
msg = "hello"
def nested():
raise RuntimeError("This is an example exception")
def f_fix_indentation_check(foo):
if foo:
raise RuntimeError("This is an example exception")
else:
if foo == "foo":
raise RuntimeError(f"This is an exception: {foo}")
raise RuntimeError("This is an exception: {}".format(foo))
# Report these, but don't fix them
if foo: raise RuntimeError("This is an example exception")
if foo: x = 1; raise RuntimeError("This is an example exception")

View File

@@ -0,0 +1,7 @@
from typing import List
import typing as t
def main(_: List[int]) -> None:
a_list: t.List[str] = []
a_list.append("hello")

View File

@@ -0,0 +1,6 @@
from typing import List
def main() -> None:
a_list: List[str] = []
a_list.append("hello")

View File

@@ -0,0 +1,8 @@
from typing import Dict, List, Optional, Set, Union, cast
def main() -> None:
a_list: List[Optional[str]] = []
a_list.append("hello")
a_dict = cast(Dict[int | None, Union[int, Set[bool]]], {})
a_dict[1] = {True, False}

View File

@@ -0,0 +1,6 @@
import typing
def main() -> None:
a_list: typing.List[str] = []
a_list.append("hello")

View File

@@ -0,0 +1,6 @@
import typing as t
def main() -> None:
a_list: t.List[str] = []
a_list.append("hello")

View File

@@ -0,0 +1,7 @@
def main() -> None:
a_list: list[str] = []
a_list.append("hello")
def hello(y: dict[str, int]) -> None:
del y

View File

@@ -0,0 +1,7 @@
def main() -> None:
a_list: list[str] | None = []
a_list.append("hello")
def hello(y: dict[str, int] | None) -> None:
del y

View File

@@ -0,0 +1,8 @@
def main() -> None:
a_list: list[str | None] = []
a_list.append("hello")
def hello(y: dict[str | None, int]) -> None:
z: tuple[str, str | None, str] = tuple(y)
del z

View File

@@ -0,0 +1,3 @@
def main() -> str:
a_str = "hello"
return a_str

View File

@@ -0,0 +1,10 @@
from typing import NamedTuple
class Stuff(NamedTuple):
x: int
def main() -> None:
a_list = Stuff(5)
print(a_list)

View File

@@ -0,0 +1,6 @@
from __future__ import annotations
def main() -> None:
a_list: list[str] = []
a_list.append("hello")

View File

@@ -0,0 +1,8 @@
import typing
IRRELEVANT = typing.TypeVar
def main() -> None:
List: list[str] = []
List.append("hello")

View File

@@ -0,0 +1,10 @@
from logging.config import BaseConfigurator # banned
from typing import Any, Dict # banned
from typing import * # banned
from pandas import DataFrame # banned
from pandas import * # banned
import logging.config # ok
import typing # ok
import pandas # ok

View File

@@ -7,3 +7,12 @@ foo.info("Hello {}".format("World!"))
logging.log(logging.INFO, msg="Hello {}".format("World!"))
logging.log(level=logging.INFO, msg="Hello {}".format("World!"))
logging.log(msg="Hello {}".format("World!"), level=logging.INFO)
# Flask support
import flask
from flask import current_app
from flask import current_app as app
flask.current_app.logger.info("Hello {}".format("World!"))
current_app.logger.info("Hello {}".format("World!"))
app.logger.log(logging.INFO, "Hello {}".format("World!"))

View File

@@ -0,0 +1,65 @@
class OneAttributeClass:
value: int
...
class OneAttributeClass2:
...
value: int
class TwoEllipsesClass:
...
...
class DocstringClass:
"""
My body only contains an ellipsis.
"""
...
class NonEmptyChild(Exception):
value: int
...
class NonEmptyChild2(Exception):
...
value: int
class NonEmptyWithInit:
value: int
...
def __init__():
pass
class EmptyClass:
...
class EmptyEllipsis:
...
class Dog:
eyes: int = 2
class WithInit:
value: int = 0
def __init__():
...
def function():
...
...

View File

@@ -0,0 +1,56 @@
# Violations of PYI013
class OneAttributeClass:
value: int
... # Error
class OneAttributeClass2:
... # Error
value: int
class MyClass:
...
value: int
class TwoEllipsesClass:
...
... # Error
class DocstringClass:
"""
My body only contains an ellipsis.
"""
... # Error
class NonEmptyChild(Exception):
value: int
... # Error
class NonEmptyChild2(Exception):
... # Error
value: int
class NonEmptyWithInit:
value: int
... # Error
def __init__():
pass
# Not violations
class EmptyClass: ...
class EmptyEllipsis: ...
class Dog:
eyes: int = 2
class WithInit:
value: int = 0
def __init__(): ...
def function(): ...
...

View File

@@ -84,3 +84,10 @@ class Class1:
# We shouldn't emit Y015 for __all__
__all__ = ["Class1"]
# Ignore the following for PYI015
field26 = typing.Sequence[int]
field27 = list[str]
field28 = builtins.str
field29 = str
field30 = str | bytes | None

View File

@@ -91,3 +91,10 @@ class Class1:
# We shouldn't emit Y015 for __all__
__all__ = ["Class1"]
# Ignore the following for PYI015
field26 = typing.Sequence[int]
field27 = list[str]
field28 = builtins.str
field29 = str
field30 = str | bytes | None

View File

@@ -0,0 +1,28 @@
import sys
import typing
from typing import Annotated, Literal, TypeAlias, TypeVar
import typing_extensions
def f(x: "int"): ... # Y020 Quoted annotations should never be used in stubs
def g(x: list["int"]): ... # Y020 Quoted annotations should never be used in stubs
_T = TypeVar("_T", bound="int") # Y020 Quoted annotations should never be used in stubs
def h(w: Literal["a", "b"], x: typing.Literal["c"], y: typing_extensions.Literal["d"], z: _T) -> _T: ...
def j() -> "int": ... # Y020 Quoted annotations should never be used in stubs
Alias: TypeAlias = list["int"] # Y020 Quoted annotations should never be used in stubs
class Child(list["int"]): # Y020 Quoted annotations should never be used in stubs
"""Documented and guaranteed useful.""" # Y021 Docstrings should not be included in stubs
if sys.platform == "linux":
f: "int" # Y020 Quoted annotations should never be used in stubs
elif sys.platform == "win32":
f: "str" # Y020 Quoted annotations should never be used in stubs
else:
f: "bytes" # Y020 Quoted annotations should never be used in stubs
# These two shouldn't trigger Y020 -- empty strings can't be "quoted annotations"
k = "" # Y052 Need type annotation for "k"
el = r"" # Y052 Need type annotation for "el"

View File

@@ -0,0 +1,28 @@
import sys
import typing
from typing import Annotated, Literal, TypeAlias, TypeVar
import typing_extensions
def f(x: "int"): ... # Y020 Quoted annotations should never be used in stubs
def g(x: list["int"]): ... # Y020 Quoted annotations should never be used in stubs
_T = TypeVar("_T", bound="int") # Y020 Quoted annotations should never be used in stubs
def h(w: Literal["a", "b"], x: typing.Literal["c"], y: typing_extensions.Literal["d"], z: _T) -> _T: ...
def j() -> "int": ... # Y020 Quoted annotations should never be used in stubs
Alias: TypeAlias = list["int"] # Y020 Quoted annotations should never be used in stubs
class Child(list["int"]): # Y020 Quoted annotations should never be used in stubs
"""Documented and guaranteed useful.""" # Y021 Docstrings should not be included in stubs
if sys.platform == "linux":
f: "int" # Y020 Quoted annotations should never be used in stubs
elif sys.platform == "win32":
f: "str" # Y020 Quoted annotations should never be used in stubs
else:
f: "bytes" # Y020 Quoted annotations should never be used in stubs
# These two shouldn't trigger Y020 -- empty strings can't be "quoted annotations"
k = "" # Y052 Need type annotation for "k"
el = r"" # Y052 Need type annotation for "el"

View File

@@ -0,0 +1,24 @@
import typing
from collections.abc import Mapping
from typing import (
Annotated,
TypeAlias,
Union,
Literal,
)
just_literals_pipe_union: TypeAlias = (
Literal[True] | Literal["idk"]
) # not PYI042 (not a stubfile)
PublicAliasT: TypeAlias = str | int
PublicAliasT2: TypeAlias = Union[str, bytes]
_ABCDEFGHIJKLMNOPQRST: TypeAlias = typing.Any
_PrivateAliasS: TypeAlias = Literal["I", "guess", "this", "is", "okay"]
_PrivateAliasS2: TypeAlias = Annotated[str, "also okay"]
snake_case_alias1: TypeAlias = str | int # not PYI042 (not a stubfile)
_snake_case_alias2: TypeAlias = Literal["whatever"] # not PYI042 (not a stubfile)
Snake_case_alias: TypeAlias = int | float # not PYI042 (not a stubfile)
# check that this edge case doesn't crash
_: TypeAlias = str | int

View File

@@ -0,0 +1,24 @@
import typing
from collections.abc import Mapping
from typing import (
Annotated,
TypeAlias,
Union,
Literal,
)
just_literals_pipe_union: TypeAlias = (
Literal[True] | Literal["idk"]
) # PYI042, since not camel case
PublicAliasT: TypeAlias = str | int
PublicAliasT2: TypeAlias = Union[str, bytes]
_ABCDEFGHIJKLMNOPQRST: TypeAlias = typing.Any
_PrivateAliasS: TypeAlias = Literal["I", "guess", "this", "is", "okay"]
_PrivateAliasS2: TypeAlias = Annotated[str, "also okay"]
snake_case_alias1: TypeAlias = str | int # PYI042, since not camel case
_snake_case_alias2: TypeAlias = Literal["whatever"] # PYI042, since not camel case
Snake_case_alias: TypeAlias = int | float # PYI042, since not camel case
# check that this edge case doesn't crash
_: TypeAlias = str | int

View File

@@ -0,0 +1,23 @@
import typing
from collections.abc import Mapping
from typing import (
Annotated,
TypeAlias,
Union,
Literal,
)
_PrivateAliasT: TypeAlias = str | int # not PYI043 (not a stubfile)
_PrivateAliasT2: TypeAlias = typing.Any # not PYI043 (not a stubfile)
_PrivateAliasT3: TypeAlias = Literal[
"not", "a", "chance"
] # not PYI043 (not a stubfile)
just_literals_pipe_union: TypeAlias = Literal[True] | Literal["idk"]
PublicAliasT: TypeAlias = str | int
PublicAliasT2: TypeAlias = Union[str, bytes]
_ABCDEFGHIJKLMNOPQRST: TypeAlias = typing.Any
_PrivateAliasS: TypeAlias = Literal["I", "guess", "this", "is", "okay"]
_PrivateAliasS2: TypeAlias = Annotated[str, "also okay"]
# check that this edge case doesn't crash
_: TypeAlias = str | int

View File

@@ -0,0 +1,23 @@
import typing
from collections.abc import Mapping
from typing import (
Annotated,
TypeAlias,
Union,
Literal,
)
_PrivateAliasT: TypeAlias = str | int # PYI043, since this ends in a T
_PrivateAliasT2: TypeAlias = typing.Any # PYI043, since this ends in a T
_PrivateAliasT3: TypeAlias = Literal[
"not", "a", "chance"
] # PYI043, since this ends in a T
just_literals_pipe_union: TypeAlias = Literal[True] | Literal["idk"]
PublicAliasT: TypeAlias = str | int
PublicAliasT2: TypeAlias = Union[str, bytes]
_ABCDEFGHIJKLMNOPQRST: TypeAlias = typing.Any
_PrivateAliasS: TypeAlias = Literal["I", "guess", "this", "is", "okay"]
_PrivateAliasS2: TypeAlias = Annotated[str, "also okay"]
# check that this edge case doesn't crash
_: TypeAlias = str | int

View File

@@ -0,0 +1,93 @@
import builtins
import typing
from typing import TypeAlias, Final
field1: int
field2: int = ...
field3 = ... # type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
field4: int = 0
field41: int = 0xFFFFFFFF
field42: int = 1234567890
field43: int = -0xFFFFFFFF
field44: int = -1234567890
field5 = 0 # type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int") # Y052 Need type annotation for "field5"
field6 = 0 # Y052 Need type annotation for "field6"
field7 = b"" # Y052 Need type annotation for "field7"
field71 = "foo" # Y052 Need type annotation for "field71"
field72: str = "foo"
field8 = False # Y052 Need type annotation for "field8"
field81 = -1 # Y052 Need type annotation for "field81"
field82: float = -98.43
field83 = -42j # Y052 Need type annotation for "field83"
field84 = 5 + 42j # Y052 Need type annotation for "field84"
field85 = -5 - 42j # Y052 Need type annotation for "field85"
field9 = None # Y026 Use typing_extensions.TypeAlias for type aliases, e.g. "field9: TypeAlias = None"
Field95: TypeAlias = None
Field96: TypeAlias = int | None
Field97: TypeAlias = None | typing.SupportsInt | builtins.str | float | bool
field19 = [1, 2, 3] # Y052 Need type annotation for "field19"
field191: list[int] = [1, 2, 3]
field20 = (1, 2, 3) # Y052 Need type annotation for "field20"
field201: tuple[int, ...] = (1, 2, 3)
field21 = {1, 2, 3} # Y052 Need type annotation for "field21"
field211: set[int] = {1, 2, 3}
field212 = {"foo": "bar"} # Y052 Need type annotation for "field212"
field213: dict[str, str] = {"foo": "bar"}
field22: Final = {"foo": 5}
field221: list[int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] # Y015 Only simple default values are allowed for assignments
field223: list[int] = [*range(10)] # Y015 Only simple default values are allowed for assignments
field224: list[int] = list(range(10)) # Y015 Only simple default values are allowed for assignments
field225: list[object] = [{}, 1, 2] # Y015 Only simple default values are allowed for assignments
field226: tuple[str | tuple[str, ...], ...] = ("foo", ("foo", "bar")) # Y015 Only simple default values are allowed for assignments
field227: dict[str, object] = {"foo": {"foo": "bar"}} # Y015 Only simple default values are allowed for assignments
field228: dict[str, list[object]] = {"foo": []} # Y015 Only simple default values are allowed for assignments
# When parsed, this case results in `None` being placed in the `.keys` list for the `ast.Dict` node
field229: dict[int, int] = {1: 2, **{3: 4}} # Y015 Only simple default values are allowed for assignments
field23 = "foo" + "bar" # Y015 Only simple default values are allowed for assignments
field24 = b"foo" + b"bar" # Y015 Only simple default values are allowed for assignments
field25 = 5 * 5 # Y015 Only simple default values are allowed for assignments
# We shouldn't emit Y015 within functions
def f():
field26: list[int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
# We shouldn't emit Y015 for __slots__ or __match_args__
class Class1:
__slots__ = (
'_one',
'_two',
'_three',
'_four',
'_five',
'_six',
'_seven',
'_eight',
'_nine',
'_ten',
'_eleven',
)
__match_args__ = (
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
'eleven',
)
# We shouldn't emit Y015 for __all__
__all__ = ["Class1"]
# Ignore the following for PYI015
field26 = typing.Sequence[int]
field27 = list[str]
field28 = builtins.str
field29 = str
field30 = str | bytes | None

View File

@@ -0,0 +1,100 @@
import builtins
import typing
from typing import TypeAlias, Final, NewType, TypeVar, TypeVarTuple, ParamSpec
# We shouldn't emit Y015 for simple default values
field1: int
field2: int = ...
field3 = ... # type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int")
field4: int = 0
field41: int = 0xFFFFFFFF
field42: int = 1234567890
field43: int = -0xFFFFFFFF
field44: int = -1234567890
field5 = 0 # type: int # Y033 Do not use type comments in stubs (e.g. use "x: int" instead of "x = ... # type: int") # Y052 Need type annotation for "field5"
field6 = 0 # Y052 Need type annotation for "field6"
field7 = b"" # Y052 Need type annotation for "field7"
field71 = "foo" # Y052 Need type annotation for "field71"
field72: str = "foo"
field8 = False # Y052 Need type annotation for "field8"
field81 = -1 # Y052 Need type annotation for "field81"
field82: float = -98.43
field83 = -42j # Y052 Need type annotation for "field83"
field84 = 5 + 42j # Y052 Need type annotation for "field84"
field85 = -5 - 42j # Y052 Need type annotation for "field85"
field9 = None # Y026 Use typing_extensions.TypeAlias for type aliases, e.g. "field9: TypeAlias = None"
Field95: TypeAlias = None
Field96: TypeAlias = int | None
Field97: TypeAlias = None | typing.SupportsInt | builtins.str | float | bool
Field98 = NewType('MyInt', int)
Field99 = TypeVar('Field99')
Field100 = TypeVarTuple('Field100')
Field101 = ParamSpec('Field101')
field19 = [1, 2, 3] # Y052 Need type annotation for "field19"
field191: list[int] = [1, 2, 3]
field20 = (1, 2, 3) # Y052 Need type annotation for "field20"
field201: tuple[int, ...] = (1, 2, 3)
field21 = {1, 2, 3} # Y052 Need type annotation for "field21"
field211: set[int] = {1, 2, 3}
field212 = {"foo": "bar"} # Y052 Need type annotation for "field212"
field213: dict[str, str] = {"foo": "bar"}
field22: Final = {"foo": 5}
# We *should* emit Y015 for more complex default values
field221: list[int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] # Y015 Only simple default values are allowed for assignments
field223: list[int] = [*range(10)] # Y015 Only simple default values are allowed for assignments
field224: list[int] = list(range(10)) # Y015 Only simple default values are allowed for assignments
field225: list[object] = [{}, 1, 2] # Y015 Only simple default values are allowed for assignments
field226: tuple[str | tuple[str, ...], ...] = ("foo", ("foo", "bar")) # Y015 Only simple default values are allowed for assignments
field227: dict[str, object] = {"foo": {"foo": "bar"}} # Y015 Only simple default values are allowed for assignments
field228: dict[str, list[object]] = {"foo": []} # Y015 Only simple default values are allowed for assignments
# When parsed, this case results in `None` being placed in the `.keys` list for the `ast.Dict` node
field229: dict[int, int] = {1: 2, **{3: 4}} # Y015 Only simple default values are allowed for assignments
field23 = "foo" + "bar" # Y015 Only simple default values are allowed for assignments
field24 = b"foo" + b"bar" # Y015 Only simple default values are allowed for assignments
field25 = 5 * 5 # Y015 Only simple default values are allowed for assignments
# We shouldn't emit Y015 within functions
def f():
field26: list[int] = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]
# We shouldn't emit Y015 for __slots__ or __match_args__
class Class1:
__slots__ = (
'_one',
'_two',
'_three',
'_four',
'_five',
'_six',
'_seven',
'_eight',
'_nine',
'_ten',
'_eleven',
)
__match_args__ = (
'one',
'two',
'three',
'four',
'five',
'six',
'seven',
'eight',
'nine',
'ten',
'eleven',
)
# We shouldn't emit Y015 for __all__
__all__ = ["Class1"]
# Ignore the following for PYI015
field26 = typing.Sequence[int]
field27 = list[str]
field28 = builtins.str
field29 = str
field30 = str | bytes | None

View File

@@ -39,3 +39,8 @@ def test_error():
message
"""
)
assert something # OK
assert something and something_else # Error
assert something and something_else and something_third # Error

View File

@@ -86,9 +86,16 @@ while x > 0:
):
print("Bad module!")
# SIM102
if node.module:
if node.module == "multiprocessing" or node.module.startswith(
# SIM102 (auto-fixable)
if node.module012345678:
if node.module == "multiprocß9💣2" or node.module.startswith(
"multiprocessing."
):
print("Bad module!")
# SIM102 (not auto-fixable)
if node.module0123456789:
if node.module == "multiprocß9💣2" or node.module.startswith(
"multiprocessing."
):
print("Bad module!")

View File

@@ -1,73 +1,96 @@
def foo():
pass
try:
foo()
except ValueError: # SIM105
pass
try:
foo()
except (ValueError, OSError): # SIM105
pass
try:
foo()
except: # SIM105
pass
try:
foo()
except (a.Error, b.Error): # SIM105
pass
# SIM105
try:
foo()
except ValueError:
print('foo')
pass
# SIM105
try:
foo()
except (ValueError, OSError):
pass
# SIM105
try:
foo()
except:
pass
# SIM105
try:
foo()
except (a.Error, b.Error):
pass
# OK
try:
foo()
except ValueError:
print("foo")
except OSError:
pass
# OK
try:
foo()
except ValueError:
pass
else:
print('bar')
print("bar")
# OK
try:
foo()
except ValueError:
pass
finally:
print('bar')
print("bar")
# OK
try:
foo()
foo()
except ValueError:
pass
# OK
try:
for i in range(3):
foo()
except ValueError:
pass
def bar():
# OK
try:
return foo()
except ValueError:
pass
def with_ellipsis():
# OK
try:
foo()
except ValueError:
...
def with_ellipsis_and_return():
# OK
try:
return foo()
except ValueError:
...
def with_comment():
try:
foo()
except (ValueError, OSError):
pass # Trailing comment.

View File

@@ -0,0 +1,8 @@
"""Case: There's a random import, so it should add `contextlib` after it."""
import math
# SIM105
try:
math.sqrt(-1)
except ValueError:
pass

View File

@@ -0,0 +1,13 @@
"""Case: `contextlib` already imported."""
import contextlib
def foo():
pass
# SIM105
try:
foo()
except ValueError:
pass

View File

@@ -0,0 +1,16 @@
"""Case: `contextlib` is imported after the call site."""
def foo():
pass
def bar():
# SIM105
try:
foo()
except ValueError:
pass
import contextlib

View File

@@ -80,17 +80,25 @@ else:
# SIM108
if a:
b = cccccccccccccccccccccccccccccccccccc
b = "cccccccccccccccccccccccccccccccccß"
else:
b = ddddddddddddddddddddddddddddddddddddd
b = "ddddddddddddddddddddddddddddddddd💣"
# OK (too long)
if True:
if a:
b = cccccccccccccccccccccccccccccccccccc
b = ccccccccccccccccccccccccccccccccccc
else:
b = ddddddddddddddddddddddddddddddddddddd
b = ddddddddddddddddddddddddddddddddddd
# OK (too long with tabs)
if True:
if a:
b = ccccccccccccccccccccccccccccccccccc
else:
b = ddddddddddddddddddddddddddddddddddd
# SIM108 (without fix due to trailing comment)

View File

@@ -155,3 +155,19 @@ def f():
if check(x):
return False
return True
def f():
# SIM110
for x in "012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß9💣2":
if x.isdigit():
return True
return False
def f():
# OK (too long)
for x in "012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß9💣29":
if x.isdigit():
return True
return False

View File

@@ -171,3 +171,19 @@ def f():
if x > y:
return False
return True
def f():
# SIM111
for x in "012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß9":
if x.isdigit():
return False
return True
def f():
# OK (too long)
for x in "012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß90":
if x.isdigit():
return False
return True

View File

@@ -90,3 +90,13 @@ with (
D() as d,
):
print("hello")
# SIM117 (auto-fixable)
with A("01ß9💣28901ß9💣28901ß9💣289") as a:
with B("01ß9💣28901ß9💣28901ß9💣289") as b:
print("hello")
# SIM117 (not auto-fixable too long)
with A("01ß9💣28901ß9💣28901ß9💣2890") as a:
with B("01ß9💣28901ß9💣28901ß9💣289") as b:
print("hello")

View File

@@ -12,3 +12,10 @@ if not a == b: # OK
if not a != b: # OK
pass
a = not not b # SIM208
f(not not a) # SIM208
if 1 + (not (not a)): # SIM208
pass

View File

@@ -6,6 +6,7 @@ a = True if b + c else False # SIM210
a = False if b else True # OK
def f():
# OK
def bool():

View File

@@ -42,3 +42,113 @@ if False and f() and a and g() and b: # OK
if a and False and f() and b and g(): # OK
pass
a or "" or True # SIM222
a or "foo" or True or "bar" # SIM222
a or 0 or True # SIM222
a or 1 or True or 2 # SIM222
a or 0.0 or True # SIM222
a or 0.1 or True or 0.2 # SIM222
a or [] or True # SIM222
a or list([]) or True # SIM222
a or [1] or True or [2] # SIM222
a or list([1]) or True or list([2]) # SIM222
a or {} or True # SIM222
a or dict() or True # SIM222
a or {1: 1} or True or {2: 2} # SIM222
a or dict({1: 1}) or True or dict({2: 2}) # SIM222
a or set() or True # SIM222
a or set(set()) or True # SIM222
a or {1} or True or {2} # SIM222
a or set({1}) or True or set({2}) # SIM222
a or () or True # SIM222
a or tuple(()) or True # SIM222
a or (1,) or True or (2,) # SIM222
a or tuple((1,)) or True or tuple((2,)) # SIM222
a or frozenset() or True # SIM222
a or frozenset(frozenset()) or True # SIM222
a or frozenset({1}) or True or frozenset({2}) # SIM222
a or frozenset(frozenset({1})) or True or frozenset(frozenset({2})) # SIM222
# Inside test `a` is simplified.
bool(a or [1] or True or [2]) # SIM222
assert a or [1] or True or [2] # SIM222
if (a or [1] or True or [2]) and (a or [1] or True or [2]): # SIM222
pass
0 if a or [1] or True or [2] else 1 # SIM222
while a or [1] or True or [2]: # SIM222
pass
[
0
for a in range(10)
for b in range(10)
if a or [1] or True or [2] # SIM222
if b or [1] or True or [2] # SIM222
]
{
0
for a in range(10)
for b in range(10)
if a or [1] or True or [2] # SIM222
if b or [1] or True or [2] # SIM222
}
{
0: 0
for a in range(10)
for b in range(10)
if a or [1] or True or [2] # SIM222
if b or [1] or True or [2] # SIM222
}
(
0
for a in range(10)
for b in range(10)
if a or [1] or True or [2] # SIM222
if b or [1] or True or [2] # SIM222
)
# Outside test `a` is not simplified.
a or [1] or True or [2] # SIM222
if (a or [1] or True or [2]) == (a or [1]): # SIM222
pass
if f(a or [1] or True or [2]): # SIM222
pass

View File

@@ -37,3 +37,113 @@ if True or f() or a or g() or b: # OK
if a or True or f() or b or g(): # OK
pass
a and "" and False # SIM223
a and "foo" and False and "bar" # SIM223
a and 0 and False # SIM223
a and 1 and False and 2 # SIM223
a and 0.0 and False # SIM223
a and 0.1 and False and 0.2 # SIM223
a and [] and False # SIM223
a and list([]) and False # SIM223
a and [1] and False and [2] # SIM223
a and list([1]) and False and list([2]) # SIM223
a and {} and False # SIM223
a and dict() and False # SIM223
a and {1: 1} and False and {2: 2} # SIM223
a and dict({1: 1}) and False and dict({2: 2}) # SIM223
a and set() and False # SIM223
a and set(set()) and False # SIM223
a and {1} and False and {2} # SIM223
a and set({1}) and False and set({2}) # SIM223
a and () and False # SIM222
a and tuple(()) and False # SIM222
a and (1,) and False and (2,) # SIM222
a and tuple((1,)) and False and tuple((2,)) # SIM222
a and frozenset() and False # SIM222
a and frozenset(frozenset()) and False # SIM222
a and frozenset({1}) and False and frozenset({2}) # SIM222
a and frozenset(frozenset({1})) and False and frozenset(frozenset({2})) # SIM222
# Inside test `a` is simplified.
bool(a and [] and False and []) # SIM223
assert a and [] and False and [] # SIM223
if (a and [] and False and []) or (a and [] and False and []): # SIM223
pass
0 if a and [] and False and [] else 1 # SIM222
while a and [] and False and []: # SIM223
pass
[
0
for a in range(10)
for b in range(10)
if a and [] and False and [] # SIM223
if b and [] and False and [] # SIM223
]
{
0
for a in range(10)
for b in range(10)
if a and [] and False and [] # SIM223
if b and [] and False and [] # SIM223
}
{
0: 0
for a in range(10)
for b in range(10)
if a and [] and False and [] # SIM223
if b and [] and False and [] # SIM223
}
(
0
for a in range(10)
for b in range(10)
if a and [] and False and [] # SIM223
if b and [] and False and [] # SIM223
)
# Outside test `a` is not simplified.
a and [] and False and [] # SIM223
if (a and [] and False and []) == (a and []): # SIM223
pass
if f(a and [] and False and []): # SIM223
pass

View File

@@ -14,7 +14,7 @@ if key not in a_dict:
else:
var = a_dict[key]
# SIM401 (default with a complex expression)
# OK (default contains effect)
if key in a_dict:
var = a_dict[key]
else:
@@ -36,12 +36,18 @@ else:
if key in a_dict:
vars[idx] = a_dict[key]
else:
vars[idx] = "default"
vars[idx] = "defaultß9💣26789ß9💣26789ß9💣26789ß9💣26789ß9💣26789"
###
# Negative cases
###
# OK (too long)
if key in a_dict:
vars[idx] = a_dict[key]
else:
vars[idx] = "defaultß9💣26789ß9💣26789ß9💣26789ß9💣26789ß9💣26789ß"
# OK (false negative)
if not key in a_dict:
var = "default"

View File

@@ -0,0 +1,8 @@
# T001 - accepted
# TODO (evanrittenhouse): this is a valid TODO
# SOME_OTHER_TAG: this is impossible to determine
# this is not a TODO
# T001 - errors
# XXX (evanrittenhouse): this is not fine
# FIXME (evanrittenhouse): this is not fine

View File

@@ -0,0 +1,7 @@
# T002 - accepted
# TODO (evanrittenhouse): this has an author
# TODO(evanrittenhouse): this also has an author
# T002 - errors
# TODO: this has no author
# FIXME: neither does this
# TODO : and neither does this

View File

@@ -0,0 +1,29 @@
# TDO003 - accepted
# TODO: this comment has a link
# https://github.com/charliermarsh/ruff/issues/3870
# TODO: this comment has an issue
# TDO-3870
# TDO003 - errors
# TODO: this comment has no
# link after it
# TODO: here's a TODO with no link after it
def foo(x):
return x
# TODO: here's a TODO on the last line with no link
# Here's more content.
# TDO-3870
# TODO: here's a TODO on the last line with no link
# Here's more content, with a space.
# TDO-3870
# TODO: here's a TODO without an issue link
# TODO: followed by a new TODO with an issue link
# TDO-3870
# TODO: here's a TODO on the last line with no link

View File

@@ -0,0 +1,6 @@
# T004 - accepted
# TODO(evanrittenhouse): this has a colon
# T004 - errors
# TODO this has no colon
# TODO(evanrittenhouse 😀) this has no colon
# FIXME add a colon

View File

@@ -0,0 +1,6 @@
# T005 - accepted
# TODO(evanrittenhouse): this has text, while the errors do not
# T005 - errors
# TODO(evanrittenhouse):
# TODO(evanrittenhouse)
# FIXME

View File

@@ -0,0 +1,5 @@
# TDO006 - accepted
# TODO (evanrittenhouse): this is a valid TODO
# TDO006 - error
# ToDo (evanrittenhouse): invalid capitalization
# todo (evanrittenhouse): another invalid capitalization

View File

@@ -0,0 +1,8 @@
# T007 - accepted
# TODO(evanrittenhouse): this has a space after a colon
# TODO: so does this
# T007 - errors
# TODO(evanrittenhouse):this has no space after a colon
# TODO (evanrittenhouse):this doesn't either
# TODO:neither does this
# FIXME:and lastly neither does this

View File

@@ -146,3 +146,7 @@ def f():
import pandas as pd
x = dict[pd.DataFrame, pd.DataFrame]
def f():
import pandas as pd

View File

@@ -0,0 +1,18 @@
import secrets
from random import random, choice
a = "Hello"
ok1 = " ".join([a, " World"]) # OK
ok2 = "".join(["Finally, ", a, " World"]) # OK
ok3 = "x".join(("1", "2", "3")) # OK
ok4 = "y".join([1, 2, 3]) # Technically OK, though would've been an error originally
ok5 = "a".join([random(), random()]) # OK (simple calls)
ok6 = "a".join([secrets.token_urlsafe(), secrets.token_hex()]) # OK (attr calls)
nok1 = "x".join({"4", "5", "yee"}) # Not OK (set)
nok2 = a.join(["1", "2", "3"]) # Not OK (not a static joiner)
nok3 = "a".join(a) # Not OK (not a static joinee)
nok4 = "a".join([a, a, *a]) # Not OK (not a static length)
nok5 = "a".join([choice("flarp")]) # Not OK (not a simple call)
nok6 = "a".join(x for x in "feefoofum") # Not OK (generator)
nok7 = "a".join([f"foo{8}", "bar"]) # Not OK (contains an f-string)

View File

@@ -2,3 +2,7 @@ import a
# Don't take this comment into account when determining whether the next import can fit on one line.
from b import c
from d import e # Do take this comment into account when determining whether the next import can fit on one line.
# The next import fits on one line.
from f import g # 012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß9💣2
# The next import doesn't fit on one line.
from h import i # 012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß9💣29012ß9💣29

View File

@@ -22,3 +22,6 @@ from bar import (
a, # comment 7
b, # comment 8
)
# comment 9
from baz import * # comment 10

View File

@@ -0,0 +1,4 @@
from mypackage.subpackage import ( # long comment that seems to be a problem
a_long_variable_name_that_causes_problems,
items,
)

View File

@@ -0,0 +1,4 @@
# isort: off
x = 1
# isort: on

View File

@@ -6,7 +6,16 @@ import f
import c
import d
# isort: split
# isort: split
import a
import b
if True:
import C
import A
# isort: split
import D
import B

View File

@@ -22,3 +22,7 @@ if True:
x.drop(["a"], axis=1, **kwargs, inplace=True)
x.drop(["a"], axis=1, inplace=True, **kwargs)
f(x.drop(["a"], axis=1, inplace=True))
x.apply(lambda x: x.sort_values('a', inplace=True))
import torch
torch.m.ReLU(inplace=True) # safe because this isn't a pandas call

View File

@@ -13,3 +13,11 @@ class C:
myObj2 = namedtuple("MyObj2", ["a", "b"])
Employee = NamedTuple('Employee', [('name', str), ('id', int)])
Point2D = TypedDict('Point2D', {'in': int, 'x-y': int})
class D(TypedDict):
lower: int
CONSTANT: str
mixedCase: bool
_mixedCase: list
mixed_Case: set

View File

@@ -40,3 +40,27 @@ def start():
#: E117 W191
def start():
print()
#: E112
if False: #
print()
#:
if False:
print()
#:
if False: #
print()
#:
if False:
print()
print()
#:
if False:
print()
if False:
print()
#:
if False:
print()

View File

@@ -76,3 +76,11 @@ if x == 4:
a[b1, :] == a[b1, ...]
b = a[:, b1]
#:
#: E201:1:6
spam[ ~ham]
#: Okay
x = [ #
'some value',
]

View File

@@ -160,6 +160,7 @@ if alpha[:-i]:
*a, b = (1, 2, 3)
@decorator
def squares(n):
return (i**2 for i in range(n))
@@ -168,4 +169,14 @@ ENG_PREFIXES = {
-6: "\u03bc", # Greek letter mu
-3: "m",
}
i = (
i + #
1
)
x[~y]
if i == -1:
pass
#:

View File

@@ -18,3 +18,13 @@ def foo() -> None:
#: E231
if (1,2):
pass
#: Okay
a = (1,\
2)
#: E231:2:20
mdtypes_template = {
'tag_full': [('mdtype', 'u4'), ('byte_count', 'u4')],
'tag_smalldata':[('byte_count_mdtype', 'u4'), ('data', 'S4')],
}

View File

@@ -64,3 +64,11 @@ a = 42 #  (One space one NBSP)
#: E262:2:9
# (Two spaces) Ok for block comment
a = 42 # (Two spaces)
#: E265:5:1
### Means test is not done yet
# E Means test is giving error (E)
# F Means test is failing (F)
# EF Means test is giving error and Failing
#! Means test is segfaulting
# 8 Means test runs forever

View File

@@ -56,3 +56,7 @@ if True:
def f():
print((yield))
x = (yield)
#: Okay
if (a and
b):
pass

Some files were not shown because too many files have changed in this diff Show More