Compare commits

..

1 Commits

Author SHA1 Message Date
Charlie Marsh
c8cbf45ec2 Ignore precedence when identifying explicit concatenations 2023-07-25 21:11:00 -04:00
908 changed files with 4111 additions and 111532 deletions

View File

@@ -122,9 +122,9 @@ At time of writing, the repository includes the following crates:
intermediate representation. The backend for `ruff_python_formatter`.
- `crates/ruff_index`: library crate inspired by `rustc_index`.
- `crates/ruff_macros`: proc macro crate containing macros used by Ruff.
- `crates/ruff_python_ast`: library crate containing Python-specific AST types and utilities.
- `crates/ruff_python_codegen`: library crate containing utilities for generating Python source code.
- `crates/ruff_python_codegen`: library crate containing utilities for generating Python source code.
- `crates/ruff_python_ast`: library crate containing Python-specific AST types and utilities. Note
that the AST schema itself is defined in the
[rustpython-ast](https://github.com/astral-sh/RustPython-Parser) crate.
- `crates/ruff_python_formatter`: library crate implementing the Python formatter. Emits an
intermediate representation for each node, which `ruff_formatter` prints based on the configured
line length.
@@ -135,7 +135,8 @@ At time of writing, the repository includes the following crates:
the names of all built-in exceptions and which standard library types are immutable.
- `crates/ruff_python_trivia`: library crate containing Python-specific trivia utilities (e.g.,
for analyzing indentation, newlines, etc.).
- `crates/ruff_python_parser`: library crate containing the Python parser.
- `crates/ruff_rustpython`: library crate containing `RustPython`-specific utilities.
- `crates/ruff_textwrap`: library crate to indent and dedent Python source code.
- `crates/ruff_wasm`: library crate for exposing Ruff as a WebAssembly module. Powers the
[Ruff Playground](https://play.ruff.rs/).
@@ -223,12 +224,9 @@ Once you've completed the code for the rule itself, you can define tests with th
For example, if you're adding a new rule named `E402`, you would run:
```shell
cargo run -p ruff_cli -- check crates/ruff/resources/test/fixtures/pycodestyle/E402.py --no-cache --select E402
cargo run -p ruff_cli -- check crates/ruff/resources/test/fixtures/pycodestyle/E402.py --no-cache
```
**Note:** Only a subset of rules are enabled by default. When testing a new rule, ensure that
you activate it by adding `--select ${rule_code}` to the command.
1. Add the test to the relevant `crates/ruff/src/rules/[linter]/mod.rs` file. If you're contributing
a rule to a pre-existing set, you should be able to find a similar example to pattern-match
against. If you're adding a new linter, you'll need to create a new `mod.rs` file (see,
@@ -315,7 +313,7 @@ even patch releases may contain [non-backwards-compatible changes](https://semve
1. Run the release workflow with the version number (without starting `v`) as input. Make sure
main has your merged PR as last commit
1. The release workflow will do the following:
1. Build all the assets. If this fails (even though we tested in step 4), we haven't tagged or
1. Build all the assets. If this fails (even though we tested in step 4), we havent tagged or
uploaded anything, you can restart after pushing a fix.
1. Upload to PyPI.
1. Create and push the Git tag (as extracted from `pyproject.toml`). We create the Git tag only
@@ -728,9 +726,9 @@ diagnostics, then our current compilation pipeline proceeds as follows:
1. **File discovery**: Given paths like `foo/`, locate all Python files in any specified subdirectories, taking into account our hierarchical settings system and any `exclude` options.
1. **Package resolution**: Determine the "package root" for every file by traversing over its parent directories and looking for `__init__.py` files.
1. **Package resolution**: Determine the package root for every file by traversing over its parent directories and looking for `__init__.py` files.
1. **Cache initialization**: For every "package root", initialize an empty cache.
1. **Cache initialization**: For every package root, initialize an empty cache.
1. **Analysis**: For every file, in parallel:
@@ -738,7 +736,7 @@ diagnostics, then our current compilation pipeline proceeds as follows:
1. **Tokenization**: Run the lexer over the file to generate a token stream.
1. **Indexing**: Extract metadata from the token stream, such as: comment ranges, `# noqa` locations, `# isort: off` locations, "doc lines", etc.
1. **Indexing**: Extract metadata from the token stream, such as: comment ranges, `# noqa` locations, `# isort: off` locations, doc lines, etc.
1. **Token-based rule evaluation**: Run any lint rules that are based on the contents of the token stream (e.g., commented-out code).
@@ -748,9 +746,9 @@ diagnostics, then our current compilation pipeline proceeds as follows:
1. **Parsing**: Run the parser over the token stream to produce an AST. (This consumes the token stream, so anything that relies on the token stream needs to happen before parsing.)
1. **AST-based rule evaluation**: Run any lint rules that are based on the AST. This includes the vast majority of lint rules. As part of this step, we also build the semantic model for the current file as we traverse over the AST. Some lint rules are evaluated eagerly, as we iterate over the AST, while others are evaluated in a deferred manner (e.g., unused imports, since we can't determine whether an import is unused until we've finished analyzing the entire file), after we've finished the initial traversal.
1. **AST-based rule evaluation**: Run any lint rules that are based on the AST. This includes the vast majority of lint rules. As part of this step, we also build the semantic model for the current file as we traverse over the AST. Some lint rules are evaluated eagerly, as we iterate over the AST, while others are evaluated in a deferred manner (e.g., unused imports, since we cant determine whether an import is unused until weve finished analyzing the entire file), after weve finished the initial traversal.
1. **Import-based rule evaluation**: Run any lint rules that are based on the module's imports (e.g., import sorting). These could, in theory, be included in the AST-based rule evaluation phase — they're just separated for simplicity.
1. **Import-based rule evaluation**: Run any lint rules that are based on the modules imports (e.g., import sorting). These could, in theory, be included in the AST-based rule evaluation phase — theyre just separated for simplicity.
1. **Physical line-based rule evaluation**: Run any lint rules that are based on physical lines (e.g., line-length).
@@ -759,116 +757,3 @@ diagnostics, then our current compilation pipeline proceeds as follows:
1. **Cache write**: Write the generated diagnostics to the package cache using the file as a key.
1. **Reporting**: Print diagnostics in the specified format (text, JSON, etc.), to the specified output channel (stdout, a file, etc.).
### Import Categorization
To understand Ruff's import categorization system, we first need to define two concepts:
- "Project root": The directory containing the `pyproject.toml`, `ruff.toml`, or `.ruff.toml` file,
discovered by identifying the "closest" such directory for each Python file. (If you're running
via `ruff --config /path/to/pyproject.toml`, then the current working directory is used as the
"project root".)
- "Package root": The top-most directory defining the Python package that includes a given Python
file. To find the package root for a given Python file, traverse up its parent directories until
you reach a parent directory that doesn't contain an `__init__.py` file (and isn't marked as
a [namespace package](https://beta.ruff.rs/docs/settings/#namespace-packages)); take the directory
just before that, i.e., the first directory in the package.
For example, given:
```text
my_project
├── pyproject.toml
└── src
└── foo
├── __init__.py
└── bar
├── __init__.py
└── baz.py
```
Then when analyzing `baz.py`, the project root would be the top-level directory (`./my_project`),
and the package root would be `./my_project/src/foo`.
#### Project root
The project root does not have a significant impact beyond that all relative paths within the loaded
configuration file are resolved relative to the project root.
For example, to indicate that `bar` above is a namespace package (it isn't, but let's run with it),
the `pyproject.toml` would list `namespace-packages = ["./src/bar"]`, which would resolve
to `my_project/src/bar`.
The same logic applies when providing a configuration file via `--config`. In that case, the
_current working directory_ is used as the project root, and so all paths in that configuration file
are resolved relative to the current working directory. (As a general rule, we want to avoid relying
on the current working directory as much as possible, to ensure that Ruff exhibits the same behavior
regardless of where and how you invoke it — but that's hard to avoid in this case.)
Additionally, if a `pyproject.toml` file _extends_ another configuration file, Ruff will still use
the directory containing that `pyproject.toml` file as the project root. For example, if
`./my_project/pyproject.toml` contains:
```toml
[tool.ruff]
extend = "/path/to/pyproject.toml"
```
Then Ruff will use `./my_project` as the project root, even though the configuration file extends
`/path/to/pyproject.toml`. As such, if the configuration file at `/path/to/pyproject.toml` contains
any relative paths, they will be resolved relative to `./my_project`.
If a project uses nested configuration files, then Ruff would detect multiple project roots, one for
each configuration file.
#### Package root
The package root is used to determine a file's "module path". Consider, again, `baz.py`. In that
case, `./my_project/src/foo` was identified as the package root, so the module path for `baz.py`
would resolve to `foo.bar.baz` — as computed by taking the relative path from the package root
(inclusive of the root itself). The module path can be thought of as "the path you would use to
import the module" (e.g., `import foo.bar.baz`).
The package root and module path are used to, e.g., convert relative to absolute imports, and for
import categorization, as described below.
#### Import categorization
When sorting and formatting import blocks, Ruff categorizes every import into one of five
categories:
1. **"Future"**: the import is a `__future__` import. That's easy: just look at the name of the
imported module!
1. **"Standard library"**: the import comes from the Python standard library (e.g., `import os`).
This is easy too: we include a list of all known standard library modules in Ruff itself, so it's
a simple lookup.
1. **"Local folder"**: the import is a relative import (e.g., `from .foo import bar`). This is easy
too: just check if the import includes a `level` (i.e., a dot-prefix).
1. **"First party"**: the import is part of the current project. (More on this below.)
1. **"Third party"**: everything else.
The real challenge lies in determining whether an import is first-party — everything else is either
trivial, or (as in the case of third-party) merely defined as "not first-party".
There are three ways in which an import can be categorized as "first-party":
1. **Explicit settings**: the import is marked as such via the `known-first-party` setting. (This
should generally be seen as an escape hatch.)
1. **Same-package**: the imported module is in the same package as the current file. This gets back
to the importance of the "package root" and the file's "module path". Imagine that we're
analyzing `baz.py` above. If `baz.py` contains any imports that appear to come from the `foo`
package (e.g., `from foo import bar` or `import foo.bar`), they'll be classified as first-party
automatically. This check is as simple as comparing the first segment of the current file's
module path to the first segment of the import.
1. **Source roots**: Ruff supports a `[src](https://beta.ruff.rs/docs/settings/#src)` setting, which
sets the directories to scan when identifying first-party imports. The algorithm is
straightforward: given an import, like `import foo`, iterate over the directories enumerated in
the `src` setting and, for each directory, check for the existence of a subdirectory `foo` or a
file `foo.py`.
By default, `src` is set to the project root. In the above example, we'd want to set
`src = ["./src"]` to ensure that we locate `./my_project/src/foo` and thus categorize `import foo`
as first-party in `baz.py`. In practice, for this limited example, setting `src = ["./src"]` is
unnecessary, as all imports within `./my_project/src/foo` would be categorized as first-party via
the same-package heuristic; but your project contains multiple packages, you'll want to set `src`
explicitly.

415
Cargo.lock generated
View File

@@ -133,15 +133,6 @@ dependencies = [
"os_str_bytes",
]
[[package]]
name = "ascii-canvas"
version = "3.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6"
dependencies = [
"term",
]
[[package]]
name = "assert_cmd"
version = "2.0.11"
@@ -178,21 +169,6 @@ dependencies = [
"serde",
]
[[package]]
name = "bit-set"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
dependencies = [
"bit-vec",
]
[[package]]
name = "bit-vec"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -633,16 +609,6 @@ dependencies = [
"dirs-sys 0.4.1",
]
[[package]]
name = "dirs-next"
version = "2.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
dependencies = [
"cfg-if",
"dirs-sys-next",
]
[[package]]
name = "dirs-sys"
version = "0.3.7"
@@ -666,17 +632,6 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "dirs-sys-next"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
dependencies = [
"libc",
"redox_users",
"winapi",
]
[[package]]
name = "doc-comment"
version = "0.3.3"
@@ -701,15 +656,6 @@ version = "1.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
[[package]]
name = "ena"
version = "0.14.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1"
dependencies = [
"log",
]
[[package]]
name = "encode_unicode"
version = "0.3.6"
@@ -786,12 +732,6 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "fixedbitset"
version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
[[package]]
name = "flake8-to-ruff"
version = "0.0.280"
@@ -1159,28 +1099,6 @@ dependencies = [
"libc",
]
[[package]]
name = "lalrpop"
version = "0.20.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da4081d44f4611b66c6dd725e6de3169f9f63905421e8626fcb86b6a898998b8"
dependencies = [
"ascii-canvas",
"bit-set",
"diff",
"ena",
"is-terminal",
"itertools",
"lalrpop-util",
"petgraph",
"regex",
"regex-syntax 0.7.3",
"string_cache",
"term",
"tiny-keccak",
"unicode-xid",
]
[[package]]
name = "lalrpop-util"
version = "0.20.0"
@@ -1281,16 +1199,6 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0"
[[package]]
name = "lock_api"
version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c1cc9717a20b1bb222f333e6a92fd32f7d8a18ddc5a3191a11af45dcbf4dcd16"
dependencies = [
"autocfg",
"scopeguard",
]
[[package]]
name = "log"
version = "0.4.19"
@@ -1369,12 +1277,6 @@ version = "1.0.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "308d96db8debc727c3fd9744aac51751243420e46edf401010908da7f8d5e57c"
[[package]]
name = "new_debug_unreachable"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
[[package]]
name = "nextest-workspace-hack"
version = "0.1.0"
@@ -1519,29 +1421,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
[[package]]
name = "parking_lot"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447"
dependencies = [
"cfg-if",
"libc",
"redox_syscall 0.3.5",
"smallvec",
"windows-targets 0.48.1",
]
[[package]]
name = "paste"
version = "1.0.13"
@@ -1633,23 +1512,13 @@ version = "2.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94"
[[package]]
name = "petgraph"
version = "0.6.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4"
dependencies = [
"fixedbitset",
"indexmap 1.9.3",
]
[[package]]
name = "phf"
version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc"
dependencies = [
"phf_shared 0.11.2",
"phf_shared",
]
[[package]]
@@ -1659,7 +1528,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a"
dependencies = [
"phf_generator",
"phf_shared 0.11.2",
"phf_shared",
]
[[package]]
@@ -1668,19 +1537,10 @@ version = "0.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0"
dependencies = [
"phf_shared 0.11.2",
"phf_shared",
"rand",
]
[[package]]
name = "phf_shared"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
dependencies = [
"siphasher",
]
[[package]]
name = "phf_shared"
version = "0.11.2"
@@ -1741,18 +1601,6 @@ version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "767eb9f07d4a5ebcb39bbf2d452058a93c011373abf6832e24194a1c3f004794"
[[package]]
name = "ppv-lite86"
version = "0.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
[[package]]
name = "predicates"
version = "3.0.3"
@@ -1877,18 +1725,6 @@ version = "0.8.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
]
[[package]]
name = "rand_chacha"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
]
@@ -1897,9 +1733,6 @@ name = "rand_core"
version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
dependencies = [
"getrandom",
]
[[package]]
name = "rayon"
@@ -2072,16 +1905,15 @@ dependencies = [
"ruff_index",
"ruff_macros",
"ruff_python_ast",
"ruff_python_codegen",
"ruff_python_index",
"ruff_python_literal",
"ruff_python_parser",
"ruff_python_semantic",
"ruff_python_stdlib",
"ruff_python_trivia",
"ruff_source_file",
"ruff_rustpython",
"ruff_text_size",
"ruff_textwrap",
"rustc-hash",
"rustpython-format",
"rustpython-parser",
"schemars",
"semver",
"serde",
@@ -2112,7 +1944,7 @@ dependencies = [
"ruff",
"ruff_python_ast",
"ruff_python_formatter",
"ruff_python_parser",
"rustpython-parser",
"serde",
"serde_json",
"tikv-jemallocator",
@@ -2167,9 +1999,8 @@ dependencies = [
"ruff_python_ast",
"ruff_python_formatter",
"ruff_python_stdlib",
"ruff_python_trivia",
"ruff_source_file",
"ruff_text_size",
"ruff_textwrap",
"rustc-hash",
"serde",
"serde_json",
@@ -2203,13 +2034,11 @@ dependencies = [
"ruff_cli",
"ruff_diagnostics",
"ruff_formatter",
"ruff_python_ast",
"ruff_python_codegen",
"ruff_python_formatter",
"ruff_python_literal",
"ruff_python_parser",
"ruff_python_stdlib",
"ruff_python_trivia",
"ruff_textwrap",
"rustpython-format",
"rustpython-parser",
"schemars",
"serde",
"serde_json",
@@ -2260,7 +2089,7 @@ dependencies = [
"itertools",
"proc-macro2",
"quote",
"ruff_python_trivia",
"ruff_textwrap",
"syn 2.0.23",
]
@@ -2268,33 +2097,26 @@ dependencies = [
name = "ruff_python_ast"
version = "0.0.0"
dependencies = [
"anyhow",
"bitflags 2.3.3",
"insta",
"is-macro",
"itertools",
"log",
"memchr",
"num-bigint",
"num-traits",
"once_cell",
"ruff_python_parser",
"ruff_python_trivia",
"ruff_source_file",
"ruff_text_size",
"rustc-hash",
"rustpython-ast",
"rustpython-literal",
"rustpython-parser",
"serde",
"smallvec",
]
[[package]]
name = "ruff_python_codegen"
version = "0.0.0"
dependencies = [
"once_cell",
"ruff_python_ast",
"ruff_python_literal",
"ruff_python_parser",
"ruff_source_file",
]
[[package]]
name = "ruff_python_formatter"
version = "0.0.0"
@@ -2309,12 +2131,10 @@ dependencies = [
"once_cell",
"ruff_formatter",
"ruff_python_ast",
"ruff_python_index",
"ruff_python_parser",
"ruff_python_trivia",
"ruff_source_file",
"ruff_text_size",
"rustc-hash",
"rustpython-parser",
"serde",
"serde_json",
"similar",
@@ -2322,55 +2142,6 @@ dependencies = [
"thiserror",
]
[[package]]
name = "ruff_python_index"
version = "0.0.0"
dependencies = [
"itertools",
"ruff_python_ast",
"ruff_python_parser",
"ruff_python_trivia",
"ruff_source_file",
"ruff_text_size",
]
[[package]]
name = "ruff_python_literal"
version = "0.0.0"
dependencies = [
"bitflags 2.3.3",
"hexf-parse",
"is-macro",
"itertools",
"lexical-parse-float",
"num-bigint",
"num-traits",
"rand",
"unic-ucd-category",
]
[[package]]
name = "ruff_python_parser"
version = "0.0.0"
dependencies = [
"anyhow",
"insta",
"is-macro",
"itertools",
"lalrpop",
"lalrpop-util",
"num-bigint",
"num-traits",
"ruff_python_ast",
"ruff_text_size",
"rustc-hash",
"static_assertions",
"tiny-keccak",
"unic-emoji-char",
"unic-ucd-ident",
"unicode_names2",
]
[[package]]
name = "ruff_python_resolver"
version = "0.0.0"
@@ -2391,9 +2162,9 @@ dependencies = [
"ruff_index",
"ruff_python_ast",
"ruff_python_stdlib",
"ruff_source_file",
"ruff_text_size",
"rustc-hash",
"rustpython-parser",
"smallvec",
]
@@ -2407,14 +2178,19 @@ version = "0.0.0"
dependencies = [
"insta",
"memchr",
"ruff_python_ast",
"ruff_python_parser",
"ruff_source_file",
"ruff_text_size",
"smallvec",
"unic-ucd-ident",
]
[[package]]
name = "ruff_rustpython"
version = "0.0.0"
dependencies = [
"anyhow",
"rustpython-parser",
]
[[package]]
name = "ruff_shrinking"
version = "0.1.0"
@@ -2424,32 +2200,28 @@ dependencies = [
"fs-err",
"regex",
"ruff_python_ast",
"ruff_python_parser",
"ruff_text_size",
"ruff_rustpython",
"rustpython-ast",
"shlex",
"tracing",
"tracing-subscriber",
]
[[package]]
name = "ruff_source_file"
name = "ruff_text_size"
version = "0.0.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=4d03b9b5b212fc869e4cfda151414438186a7779#4d03b9b5b212fc869e4cfda151414438186a7779"
dependencies = [
"insta",
"memchr",
"once_cell",
"ruff_text_size",
"schemars",
"serde",
]
[[package]]
name = "ruff_text_size"
name = "ruff_textwrap"
version = "0.0.0"
dependencies = [
"schemars",
"serde",
"serde_test",
"static_assertions",
"ruff_python_trivia",
"ruff_text_size",
]
[[package]]
@@ -2463,11 +2235,9 @@ dependencies = [
"ruff",
"ruff_diagnostics",
"ruff_python_ast",
"ruff_python_codegen",
"ruff_python_formatter",
"ruff_python_index",
"ruff_python_parser",
"ruff_source_file",
"ruff_rustpython",
"rustpython-parser",
"serde",
"serde-wasm-bindgen",
"wasm-bindgen",
@@ -2539,6 +2309,74 @@ dependencies = [
"untrusted",
]
[[package]]
name = "rustpython-ast"
version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=4d03b9b5b212fc869e4cfda151414438186a7779#4d03b9b5b212fc869e4cfda151414438186a7779"
dependencies = [
"is-macro",
"num-bigint",
"rustpython-parser-core",
"static_assertions",
]
[[package]]
name = "rustpython-format"
version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=4d03b9b5b212fc869e4cfda151414438186a7779#4d03b9b5b212fc869e4cfda151414438186a7779"
dependencies = [
"bitflags 2.3.3",
"itertools",
"num-bigint",
"num-traits",
"rustpython-literal",
]
[[package]]
name = "rustpython-literal"
version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=4d03b9b5b212fc869e4cfda151414438186a7779#4d03b9b5b212fc869e4cfda151414438186a7779"
dependencies = [
"hexf-parse",
"is-macro",
"lexical-parse-float",
"num-traits",
"unic-ucd-category",
]
[[package]]
name = "rustpython-parser"
version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=4d03b9b5b212fc869e4cfda151414438186a7779#4d03b9b5b212fc869e4cfda151414438186a7779"
dependencies = [
"anyhow",
"is-macro",
"itertools",
"lalrpop-util",
"log",
"num-bigint",
"num-traits",
"phf",
"phf_codegen",
"rustc-hash",
"rustpython-ast",
"rustpython-parser-core",
"tiny-keccak",
"unic-emoji-char",
"unic-ucd-ident",
"unicode_names2",
]
[[package]]
name = "rustpython-parser-core"
version = "0.2.0"
source = "git+https://github.com/astral-sh/RustPython-Parser.git?rev=4d03b9b5b212fc869e4cfda151414438186a7779#4d03b9b5b212fc869e4cfda151414438186a7779"
dependencies = [
"is-macro",
"memchr",
"ruff_text_size",
]
[[package]]
name = "rustversion"
version = "1.0.13"
@@ -2674,15 +2512,6 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_test"
version = "1.0.176"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a2f49ace1498612d14f7e0b8245519584db8299541dfe31a06374a828d620ab"
dependencies = [
"serde",
]
[[package]]
name = "serde_with"
version = "3.0.0"
@@ -2765,19 +2594,6 @@ version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
[[package]]
name = "string_cache"
version = "0.8.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
dependencies = [
"new_debug_unreachable",
"once_cell",
"parking_lot",
"phf_shared 0.10.0",
"precomputed-hash",
]
[[package]]
name = "strsim"
version = "0.10.0"
@@ -2851,17 +2667,6 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "term"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
dependencies = [
"dirs-next",
"rustversion",
"winapi",
]
[[package]]
name = "termcolor"
version = "1.2.0"
@@ -3241,12 +3046,6 @@ version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
[[package]]
name = "unicode-xid"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
[[package]]
name = "unicode_names2"
version = "0.6.0"

View File

@@ -51,6 +51,12 @@ wsl = { version = "0.1.0" }
# v1.0.1
libcst = { git = "https://github.com/Instagram/LibCST.git", rev = "3cacca1a1029f05707e50703b49fe3dd860aa839", default-features = false }
ruff_text_size = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "4d03b9b5b212fc869e4cfda151414438186a7779" }
rustpython-ast = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "4d03b9b5b212fc869e4cfda151414438186a7779" , default-features = false, features = ["num-bigint"]}
rustpython-format = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "4d03b9b5b212fc869e4cfda151414438186a7779", default-features = false, features = ["num-bigint"] }
rustpython-literal = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "4d03b9b5b212fc869e4cfda151414438186a7779", default-features = false }
rustpython-parser = { git = "https://github.com/astral-sh/RustPython-Parser.git", rev = "4d03b9b5b212fc869e4cfda151414438186a7779" , default-features = false, features = ["full-lexer", "num-bigint"] }
[profile.release]
lto = "fat"
codegen-units = 1
@@ -63,7 +69,7 @@ opt-level = 3
# Reduce complexity of a parser function that would trigger a locals limit in a wasm tool.
# https://github.com/bytecodealliance/wasm-tools/blob/b5c3d98e40590512a3b12470ef358d5c7b983b15/crates/wasmparser/src/limits.rs#L29
[profile.dev.package.ruff_python_parser]
[profile.dev.package.rustpython-parser]
opt-level = 1
# Use the `--profile release-debug` flag to show symbols in release mode.

View File

@@ -2,7 +2,7 @@
# Ruff
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/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)
@@ -424,13 +424,13 @@ Ruff is used by a number of major open-source projects and companies, including:
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/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
[![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
```
...or `README.rst`:
```rst
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json
.. image:: https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/badge/v2.json
:target: https://github.com/astral-sh/ruff
:alt: Ruff
```
@@ -438,7 +438,7 @@ If you're using Ruff, consider adding the Ruff badge to project's `README.md`:
...or, as HTML:
```html
<a href="https://github.com/astral-sh/ruff"><img src="https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json" alt="Ruff" style="max-width:100%;"></a>
<a href="https://github.com/astral-sh/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
@@ -447,6 +447,6 @@ MIT
<div align="center">
<a target="_blank" href="https://astral.sh" style="background:none">
<img src="https://raw.githubusercontent.com/astral-sh/ruff/main/assets/svg/Astral.svg">
<img src="https://raw.githubusercontent.com/charliermarsh/ruff/main/assets/svg/Astral.svg">
</a>
</div>

View File

@@ -19,16 +19,13 @@ ruff_cache = { path = "../ruff_cache" }
ruff_diagnostics = { path = "../ruff_diagnostics", features = ["serde"] }
ruff_index = { path = "../ruff_index" }
ruff_macros = { path = "../ruff_macros" }
ruff_python_trivia = { path = "../ruff_python_trivia" }
ruff_python_ast = { path = "../ruff_python_ast", features = ["serde"] }
ruff_python_codegen = { path = "../ruff_python_codegen" }
ruff_python_index = { path = "../ruff_python_index" }
ruff_python_literal = { path = "../ruff_python_literal" }
ruff_python_semantic = { path = "../ruff_python_semantic" }
ruff_python_stdlib = { path = "../ruff_python_stdlib" }
ruff_python_trivia = { path = "../ruff_python_trivia" }
ruff_python_parser = { path = "../ruff_python_parser" }
ruff_source_file = { path = "../ruff_source_file", features = ["serde"] }
ruff_text_size = { path = "../ruff_text_size" }
ruff_rustpython = { path = "../ruff_rustpython" }
ruff_text_size = { workspace = true }
ruff_textwrap = { path = "../ruff_textwrap" }
annotate-snippets = { version = "0.9.1", features = ["color"] }
anyhow = { workspace = true }
@@ -62,8 +59,8 @@ quick-junit = { version = "0.3.2" }
regex = { workspace = true }
result-like = { version = "0.4.6" }
rustc-hash = { workspace = true }
rustpython-format = { workspace = true }
rustpython-parser = { workspace = true }
schemars = { workspace = true, optional = true }
semver = { version = "1.0.16" }
serde = { workspace = true }

View File

@@ -59,3 +59,13 @@ _ = "abc" + "def" + foo
_ = foo + bar + "abc"
_ = "abc" + foo + bar
_ = foo + "abc" + bar
_ = (
a + f"abc" +
"def"
)
_ = (
f"abc" +
"def" + a
)

View File

@@ -1,12 +0,0 @@
import typing
from typing import TypeVar
_T = typing.TypeVar("_T")
_P = TypeVar("_P")
# OK
_UsedTypeVar = TypeVar("_UsedTypeVar")
def func(arg: _UsedTypeVar) -> _UsedTypeVar: ...
_A, _B = TypeVar("_A"), TypeVar("_B")
_C = _D = TypeVar("_C")

View File

@@ -1,12 +0,0 @@
import typing
from typing import TypeVar
_T = typing.TypeVar("_T")
_P = TypeVar("_P")
# OK
_UsedTypeVar = TypeVar("_UsedTypeVar")
def func(arg: _UsedTypeVar) -> _UsedTypeVar: ...
_A, _B = TypeVar("_A"), TypeVar("_B")
_C = _D = TypeVar("_C")

View File

@@ -1,18 +0,0 @@
import typing
from typing import Protocol
class _Foo(Protocol):
bar: int
class _Bar(typing.Protocol):
bar: int
# OK
class _UsedPrivateProtocol(Protocol):
bar: int
def uses__UsedPrivateProtocol(arg: _UsedPrivateProtocol) -> None: ...

View File

@@ -1,18 +0,0 @@
import typing
from typing import Protocol
class _Foo(object, Protocol):
bar: int
class _Bar(typing.Protocol):
bar: int
# OK
class _UsedPrivateProtocol(Protocol):
bar: int
def uses__UsedPrivateProtocol(arg: _UsedPrivateProtocol) -> None: ...

View File

@@ -11,10 +11,6 @@ async def test_ok_trivial_with():
with context_manager_under_test():
pass
with pytest.raises(ValueError):
with context_manager_under_test():
raise ValueError
with pytest.raises(AttributeError):
async with context_manager_under_test():
pass
@@ -28,16 +24,6 @@ def test_ok_complex_single_call():
)
def test_ok_func_and_class():
with pytest.raises(AttributeError):
class A:
pass
with pytest.raises(AttributeError):
def f():
pass
def test_error_multiple_statements():
with pytest.raises(AttributeError):
len([])
@@ -61,10 +47,13 @@ async def test_error_complex_statement():
while True:
[].size
with pytest.raises(AttributeError):
with context_manager_under_test():
[].size
with pytest.raises(AttributeError):
async with context_manager_under_test():
if True:
raise Exception
[].size
def test_error_try():

View File

@@ -156,12 +156,3 @@ if False:
if True:
if a:
pass
# SIM102
def f():
if a:
pass
elif b:
if c:
d

View File

@@ -5,7 +5,6 @@ from pathlib import Path as pth
_ = Path(".")
_ = pth(".")
_ = PurePath(".")
_ = Path("")
# no match
_ = Path()

View File

@@ -1,11 +0,0 @@
import os
import glob
from glob import glob as search
extensions_dir = "./extensions"
# PTH207
glob.glob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp"))
list(glob.iglob(os.path.join(extensions_dir, "ops", "autograd", "*.cpp")))
search("*.png")

View File

@@ -1 +1 @@
broken "§=($/=()
broken "§=($/=(")

View File

@@ -1,4 +0,0 @@
print('Hello world')
#!/usr/bin/python
# -*- coding: utf-8 -*-

View File

@@ -4,10 +4,9 @@ use anyhow::{bail, Result};
use libcst_native::{
Codegen, CodegenState, ImportNames, ParenthesizableWhitespace, SmallStatement, Statement,
};
use ruff_python_ast::{Ranged, Stmt};
use rustpython_parser::ast::{Ranged, Stmt};
use ruff_python_codegen::Stylist;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::{Locator, Stylist};
use crate::cst::helpers::compose_module_path;
use crate::cst::matchers::match_statement;

View File

@@ -1,14 +1,13 @@
//! Interface for generating autofix edits from higher-level actions (e.g., "remove an argument").
use anyhow::{bail, Result};
use ruff_python_ast::{self as ast, ExceptHandler, Expr, Keyword, Ranged, Stmt};
use ruff_python_parser::{lexer, Mode};
use ruff_text_size::{TextLen, TextRange, TextSize};
use rustpython_parser::ast::{self, ExceptHandler, Expr, Keyword, Ranged, Stmt};
use rustpython_parser::{lexer, Mode};
use ruff_diagnostics::Edit;
use ruff_python_codegen::Stylist;
use ruff_python_index::Indexer;
use ruff_python_trivia::{has_leading_content, is_python_whitespace, PythonWhitespace};
use ruff_source_file::{Locator, NewlineWithTrailingNewline};
use ruff_python_ast::helpers;
use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
use ruff_python_trivia::{is_python_whitespace, NewlineWithTrailingNewline, PythonWhitespace};
use crate::autofix::codemods;
@@ -42,9 +41,11 @@ pub(crate) fn delete_stmt(
if let Some(semicolon) = trailing_semicolon(stmt.end(), locator) {
let next = next_stmt_break(semicolon, locator);
Edit::deletion(stmt.start(), next)
} else if has_leading_content(stmt.start(), locator) {
} else if helpers::has_leading_content(stmt.start(), locator) {
Edit::range_deletion(stmt.range())
} else if let Some(start) = indexer.preceded_by_continuations(stmt.start(), locator) {
} else if let Some(start) =
helpers::preceded_by_continuations(stmt.start(), locator, indexer)
{
Edit::range_deletion(TextRange::new(start, stmt.end()))
} else {
let range = locator.full_lines_range(stmt.range());
@@ -294,11 +295,11 @@ fn next_stmt_break(semicolon: TextSize, locator: &Locator) -> TextSize {
#[cfg(test)]
mod tests {
use anyhow::Result;
use ruff_python_ast::{Ranged, Suite};
use ruff_python_parser::Parse;
use ruff_text_size::TextSize;
use rustpython_parser::ast::{Ranged, Suite};
use rustpython_parser::Parse;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::Locator;
use crate::autofix::edits::{next_stmt_break, trailing_semicolon};

View File

@@ -5,7 +5,7 @@ use ruff_text_size::{TextLen, TextRange, TextSize};
use rustc_hash::{FxHashMap, FxHashSet};
use ruff_diagnostics::{Diagnostic, Edit, Fix, IsolationLevel};
use ruff_source_file::Locator;
use ruff_python_ast::source_code::Locator;
use crate::autofix::source_map::SourceMap;
use crate::linter::FixTable;
@@ -146,7 +146,7 @@ mod tests {
use ruff_diagnostics::Diagnostic;
use ruff_diagnostics::Edit;
use ruff_diagnostics::Fix;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::Locator;
use crate::autofix::source_map::SourceMarker;
use crate::autofix::{apply_fixes, FixResult};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Arg, Ranged};
use rustpython_parser::ast::{Arg, Ranged};
use crate::checkers::ast::Checker;
use crate::codes::Rule;

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::Arguments;
use rustpython_parser::ast::Arguments;
use crate::checkers::ast::Checker;
use crate::codes::Rule;

View File

@@ -10,9 +10,7 @@ pub(crate) fn bindings(checker: &mut Checker) {
Rule::InvalidAllObject,
Rule::UnaliasedCollectionsAbcSetImport,
Rule::UnconventionalImportAlias,
Rule::UnusedPrivateTypeVar,
Rule::UnusedVariable,
Rule::UnusedPrivateProtocol,
]) {
return;
}
@@ -65,20 +63,6 @@ pub(crate) fn bindings(checker: &mut Checker) {
checker.diagnostics.push(diagnostic);
}
}
if checker.enabled(Rule::UnusedPrivateTypeVar) {
if let Some(diagnostic) =
flake8_pyi::rules::unused_private_type_var(checker, binding)
{
checker.diagnostics.push(diagnostic);
}
}
if checker.enabled(Rule::UnusedPrivateProtocol) {
if let Some(diagnostic) =
flake8_pyi::rules::unused_private_protocol(checker, binding)
{
checker.diagnostics.push(diagnostic);
}
}
}
}
}

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::Comprehension;
use rustpython_parser::ast::Comprehension;
use crate::checkers::ast::Checker;
use crate::codes::Rule;

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Stmt};
use rustpython_parser::ast::{self, Stmt};
use crate::checkers::ast::Checker;
use crate::codes::Rule;

View File

@@ -1,6 +1,6 @@
use ruff_python_ast::str::raw_contents_range;
use ruff_python_ast::Ranged;
use ruff_text_size::TextRange;
use rustpython_parser::ast::Ranged;
use ruff_python_semantic::{BindingKind, ContextualizedDefinition, Export};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, ExceptHandler, Ranged};
use rustpython_parser::ast::{self, ExceptHandler, Ranged};
use crate::checkers::ast::Checker;
use crate::registry::Rule;

View File

@@ -1,5 +1,5 @@
use ruff_python_ast::{self as ast, Constant, Expr, ExprContext, Operator, Ranged};
use ruff_python_literal::cformat::{CFormatError, CFormatErrorType};
use rustpython_format::cformat::{CFormatError, CFormatErrorType};
use rustpython_parser::ast::{self, Constant, Expr, ExprContext, Operator, Ranged};
use ruff_diagnostics::Diagnostic;
@@ -12,10 +12,10 @@ use crate::registry::Rule;
use crate::rules::{
flake8_2020, flake8_async, flake8_bandit, flake8_boolean_trap, flake8_bugbear, flake8_builtins,
flake8_comprehensions, flake8_datetimez, flake8_debugger, flake8_django,
flake8_future_annotations, flake8_gettext, flake8_implicit_str_concat, flake8_logging_format,
flake8_pie, flake8_print, flake8_pyi, flake8_pytest_style, flake8_self, flake8_simplify,
flake8_tidy_imports, flake8_use_pathlib, flynt, numpy, pandas_vet, pep8_naming, pycodestyle,
pyflakes, pygrep_hooks, pylint, pyupgrade, ruff,
flake8_future_annotations, flake8_gettext, flake8_logging_format, flake8_pie, flake8_print,
flake8_pyi, flake8_pytest_style, flake8_self, flake8_simplify, flake8_tidy_imports,
flake8_use_pathlib, flynt, numpy, pandas_vet, pep8_naming, pycodestyle, pyflakes, pygrep_hooks,
pylint, pyupgrade, ruff,
};
use crate::settings::types::PythonVersion;
@@ -849,7 +849,6 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
Rule::OsPathGetatime,
Rule::OsPathGetmtime,
Rule::OsPathGetctime,
Rule::Glob,
]) {
flake8_use_pathlib::rules::replaceable_by_pathlib(checker, func);
}
@@ -1056,13 +1055,6 @@ pub(crate) fn expression(expr: &Expr, checker: &mut Checker) {
Expr::BinOp(ast::ExprBinOp {
op: Operator::Add, ..
}) => {
if checker.enabled(Rule::ExplicitStringConcatenation) {
if let Some(diagnostic) =
flake8_implicit_str_concat::rules::explicit(expr, checker.locator)
{
checker.diagnostics.push(diagnostic);
}
}
if checker.enabled(Rule::CollectionLiteralConcatenation) {
ruff::rules::collection_literal_concatenation(checker, expr);
}

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::Suite;
use rustpython_parser::ast::Suite;
use crate::checkers::ast::Checker;
use crate::codes::Rule;

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Expr, Ranged, Stmt};
use rustpython_parser::ast::{self, Expr, Ranged, Stmt};
use ruff_diagnostics::Diagnostic;
use ruff_python_ast::helpers;

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::Stmt;
use rustpython_parser::ast::Stmt;
use crate::checkers::ast::Checker;
use crate::codes::Rule;

View File

@@ -1,5 +1,5 @@
use ruff_python_ast::Expr;
use ruff_text_size::TextRange;
use rustpython_parser::ast::Expr;
use ruff_python_semantic::{ScopeId, Snapshot};

View File

@@ -30,22 +30,21 @@ use std::path::Path;
use itertools::Itertools;
use log::error;
use ruff_python_ast::{
self as ast, Arg, ArgWithDefault, Arguments, Comprehension, Constant, ElifElseClause,
ExceptHandler, Expr, ExprContext, Keyword, Pattern, Ranged, Stmt, Suite, UnaryOp,
};
use ruff_text_size::{TextRange, TextSize};
use rustpython_parser::ast::{
self, Arg, ArgWithDefault, Arguments, Comprehension, Constant, ElifElseClause, ExceptHandler,
Expr, ExprContext, Keyword, Pattern, Ranged, Stmt, Suite, UnaryOp,
};
use ruff_diagnostics::{Diagnostic, IsolationLevel};
use ruff_python_ast::all::{extract_all_names, DunderAllFlags};
use ruff_python_ast::helpers::{extract_handled_exceptions, to_module_path};
use ruff_python_ast::identifier::Identifier;
use ruff_python_ast::source_code::{Generator, Indexer, Locator, Quote, Stylist};
use ruff_python_ast::str::trailing_quote;
use ruff_python_ast::typing::{parse_type_annotation, AnnotationKind};
use ruff_python_ast::visitor::{walk_except_handler, walk_pattern, Visitor};
use ruff_python_ast::{helpers, str, visitor};
use ruff_python_codegen::{Generator, Quote, Stylist};
use ruff_python_index::Indexer;
use ruff_python_parser::typing::{parse_type_annotation, AnnotationKind};
use ruff_python_semantic::analyze::{typing, visibility};
use ruff_python_semantic::{
BindingFlags, BindingId, BindingKind, Exceptions, Export, FromImport, Globals, Import, Module,
@@ -53,7 +52,6 @@ use ruff_python_semantic::{
};
use ruff_python_stdlib::builtins::{BUILTINS, MAGIC_GLOBALS};
use ruff_python_stdlib::path::is_python_stub_file;
use ruff_source_file::Locator;
use crate::checkers::ast::deferred::Deferred;
use crate::docstrings::extraction::ExtractionTarget;
@@ -1474,11 +1472,6 @@ impl<'a> Checker<'a> {
// Create the `Binding`.
let binding_id = self.semantic.push_binding(range, kind, flags);
// If the name is private, mark is as such.
if name.starts_with('_') {
self.semantic.bindings[binding_id].flags |= BindingFlags::PRIVATE_DECLARATION;
}
// If there's an existing binding in this scope, copy its references.
if let Some(shadowed_id) = self.semantic.scopes[scope_id].get(name) {
// If this is an annotation, and we already have an existing value in the same scope,
@@ -1697,9 +1690,7 @@ impl<'a> Checker<'a> {
while !self.deferred.string_type_definitions.is_empty() {
let type_definitions = std::mem::take(&mut self.deferred.string_type_definitions);
for (range, value, snapshot) in type_definitions {
if let Ok((expr, kind)) =
parse_type_annotation(value, range, self.locator.contents())
{
if let Ok((expr, kind)) = parse_type_annotation(value, range, self.locator) {
let expr = allocator.alloc(expr);
self.semantic.restore(snapshot);

View File

@@ -2,16 +2,14 @@
use std::borrow::Cow;
use std::path::Path;
use ruff_python_ast::{self as ast, Ranged, Stmt, Suite};
use rustpython_parser::ast::{self, Ranged, Stmt, Suite};
use ruff_diagnostics::Diagnostic;
use ruff_python_ast::helpers::to_module_path;
use ruff_python_ast::imports::{ImportMap, ModuleImport};
use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
use ruff_python_ast::statement_visitor::StatementVisitor;
use ruff_python_codegen::Stylist;
use ruff_python_index::Indexer;
use ruff_python_stdlib::path::is_python_stub_file;
use ruff_source_file::Locator;
use crate::directives::IsortDirectives;
use crate::registry::Rule;

View File

@@ -1,10 +1,9 @@
use ruff_python_parser::lexer::LexResult;
use ruff_text_size::TextRange;
use rustpython_parser::lexer::LexResult;
use ruff_diagnostics::{Diagnostic, DiagnosticKind};
use ruff_python_codegen::Stylist;
use ruff_python_parser::TokenKind;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::{Locator, Stylist};
use ruff_python_ast::token_kind::TokenKind;
use crate::registry::{AsRule, Rule};
use crate::rules::pycodestyle::rules::logical_lines::{

View File

@@ -3,11 +3,11 @@
use std::path::Path;
use itertools::Itertools;
use ruff_python_ast::Ranged;
use ruff_text_size::{TextLen, TextRange, TextSize};
use rustpython_parser::ast::Ranged;
use ruff_diagnostics::{Diagnostic, Edit, Fix};
use ruff_source_file::Locator;
use ruff_python_ast::source_code::Locator;
use crate::noqa;
use crate::noqa::{Directive, FileExemption, NoqaDirectives, NoqaMapping};

View File

@@ -2,9 +2,8 @@
use ruff_text_size::TextSize;
use ruff_diagnostics::Diagnostic;
use ruff_python_codegen::Stylist;
use ruff_python_index::Indexer;
use ruff_source_file::{Locator, UniversalNewlines};
use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
use ruff_python_trivia::UniversalNewlines;
use crate::registry::Rule;
use crate::rules::flake8_copyright::rules::missing_copyright_notice;
@@ -13,6 +12,7 @@ use crate::rules::pycodestyle::rules::{
tab_indentation, trailing_whitespace,
};
use crate::rules::pylint;
use crate::rules::pyupgrade::rules::unnecessary_coding_comment;
use crate::settings::Settings;
pub(crate) fn check_physical_lines(
@@ -27,6 +27,7 @@ pub(crate) fn check_physical_lines(
let enforce_doc_line_too_long = settings.rules.enabled(Rule::DocLineTooLong);
let enforce_line_too_long = settings.rules.enabled(Rule::LineTooLong);
let enforce_no_newline_at_end_of_file = settings.rules.enabled(Rule::MissingNewlineAtEndOfFile);
let enforce_unnecessary_coding_comment = settings.rules.enabled(Rule::UTF8EncodingDeclaration);
let enforce_mixed_spaces_and_tabs = settings.rules.enabled(Rule::MixedSpacesAndTabs);
let enforce_bidirectional_unicode = settings.rules.enabled(Rule::BidirectionalUnicode);
let enforce_trailing_whitespace = settings.rules.enabled(Rule::TrailingWhitespace);
@@ -35,9 +36,27 @@ pub(crate) fn check_physical_lines(
let enforce_tab_indentation = settings.rules.enabled(Rule::TabIndentation);
let enforce_copyright_notice = settings.rules.enabled(Rule::MissingCopyrightNotice);
let fix_unnecessary_coding_comment = settings.rules.should_fix(Rule::UTF8EncodingDeclaration);
let mut commented_lines_iter = indexer.comment_ranges().iter().peekable();
let mut doc_lines_iter = doc_lines.iter().peekable();
for line in locator.contents().universal_newlines() {
for (index, line) in locator.contents().universal_newlines().enumerate() {
while commented_lines_iter
.next_if(|comment_range| line.range().contains_range(**comment_range))
.is_some()
{
if enforce_unnecessary_coding_comment {
if index < 2 {
if let Some(diagnostic) =
unnecessary_coding_comment(&line, fix_unnecessary_coding_comment)
{
diagnostics.push(diagnostic);
}
}
}
}
while doc_lines_iter
.next_if(|doc_line_start| line.range().contains_inclusive(**doc_line_start))
.is_some()
@@ -99,12 +118,10 @@ pub(crate) fn check_physical_lines(
#[cfg(test)]
mod tests {
use ruff_python_parser::lexer::lex;
use ruff_python_parser::Mode;
use rustpython_parser::lexer::lex;
use rustpython_parser::Mode;
use ruff_python_codegen::Stylist;
use ruff_python_index::Indexer;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
use crate::line_width::LineLength;
use crate::registry::Rule;

View File

@@ -2,12 +2,11 @@
use std::path::Path;
use ruff_python_parser::lexer::LexResult;
use ruff_python_parser::Tok;
use rustpython_parser::lexer::LexResult;
use rustpython_parser::Tok;
use ruff_diagnostics::Diagnostic;
use ruff_python_index::Indexer;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::{Indexer, Locator};
use crate::directives::TodoComment;
use crate::lex::docstring_detection::StateMachine;
@@ -69,10 +68,6 @@ pub(crate) fn check_tokens(
eradicate::rules::commented_out_code(&mut diagnostics, locator, indexer, settings);
}
if settings.rules.enabled(Rule::UTF8EncodingDeclaration) {
pyupgrade::rules::unnecessary_coding_comment(&mut diagnostics, locator, indexer, settings);
}
if settings.rules.enabled(Rule::InvalidEscapeSequence) {
for (tok, range) in tokens.iter().flatten() {
if tok.is_string() {
@@ -124,8 +119,8 @@ pub(crate) fn check_tokens(
}
if settings.rules.any_enabled(&[
Rule::SingleLineImplicitStringConcatenation,
Rule::MultiLineImplicitStringConcatenation,
Rule::SingleLineImplicitStringConcatenation,
]) {
flake8_implicit_str_concat::rules::implicit(
&mut diagnostics,
@@ -135,6 +130,10 @@ pub(crate) fn check_tokens(
);
}
if settings.rules.enabled(Rule::ExplicitStringConcatenation) {
flake8_implicit_str_concat::rules::explicit(&mut diagnostics, tokens);
}
if settings.rules.any_enabled(&[
Rule::MissingTrailingComma,
Rule::TrailingCommaOnBareTuple,

View File

@@ -632,7 +632,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Flake8Pyi, "015") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::AssignmentDefaultInStub),
(Flake8Pyi, "016") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::DuplicateUnionMember),
(Flake8Pyi, "017") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::ComplexAssignmentInStub),
(Flake8Pyi, "018") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnusedPrivateTypeVar),
(Flake8Pyi, "020") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::QuotedAnnotationInStub),
(Flake8Pyi, "021") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::DocstringInStub),
(Flake8Pyi, "024") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::CollectionsNamedTuple),
@@ -650,7 +649,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Flake8Pyi, "043") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::TSuffixedTypeAlias),
(Flake8Pyi, "044") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::FutureAnnotationsInStub),
(Flake8Pyi, "045") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::IterMethodReturnIterable),
(Flake8Pyi, "046") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnusedPrivateProtocol),
(Flake8Pyi, "048") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::StubBodyMultipleStatements),
(Flake8Pyi, "050") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::NoReturnArgumentAnnotationInStub),
(Flake8Pyi, "052") => (RuleGroup::Unspecified, rules::flake8_pyi::rules::UnannotatedAssignmentInStub),
@@ -761,7 +759,6 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<(RuleGroup, Rule)> {
(Flake8UsePathlib, "204") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetmtime),
(Flake8UsePathlib, "205") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsPathGetctime),
(Flake8UsePathlib, "206") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::OsSepSplit),
(Flake8UsePathlib, "207") => (RuleGroup::Unspecified, rules::flake8_use_pathlib::rules::Glob),
// flake8-logging-format
(Flake8LoggingFormat, "001") => (RuleGroup::Unspecified, rules::flake8_logging_format::violations::LoggingStringFormat),

View File

@@ -3,12 +3,11 @@
use std::str::FromStr;
use bitflags::bitflags;
use ruff_python_parser::lexer::LexResult;
use ruff_python_parser::Tok;
use ruff_text_size::{TextLen, TextRange, TextSize};
use rustpython_parser::lexer::LexResult;
use rustpython_parser::Tok;
use ruff_python_index::Indexer;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::{Indexer, Locator};
use crate::noqa::NoqaMapping;
use crate::settings::Settings;
@@ -349,12 +348,11 @@ impl TodoDirectiveKind {
#[cfg(test)]
mod tests {
use ruff_python_parser::lexer::LexResult;
use ruff_python_parser::{lexer, Mode};
use ruff_text_size::{TextLen, TextRange, TextSize};
use rustpython_parser::lexer::LexResult;
use rustpython_parser::{lexer, Mode};
use ruff_python_index::Indexer;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::{Indexer, Locator};
use crate::directives::{
extract_isort_directives, extract_noqa_line_for, TodoDirective, TodoDirectiveKind,

View File

@@ -3,13 +3,14 @@
use std::iter::FusedIterator;
use ruff_python_ast::{self as ast, Constant, Expr, Ranged, Stmt, Suite};
use ruff_python_parser::lexer::LexResult;
use ruff_python_parser::Tok;
use ruff_text_size::TextSize;
use rustpython_parser::ast::{self, Constant, Expr, Ranged, Stmt, Suite};
use rustpython_parser::lexer::LexResult;
use rustpython_parser::Tok;
use ruff_python_ast::source_code::Locator;
use ruff_python_ast::statement_visitor::{walk_stmt, StatementVisitor};
use ruff_source_file::{Locator, UniversalNewlineIterator};
use ruff_python_trivia::UniversalNewlineIterator;
/// Extract doc lines (standalone comments) from a token sequence.
pub(crate) fn doc_lines_from_tokens(lxr: &[LexResult]) -> DocLines {

View File

@@ -1,6 +1,6 @@
//! Extract docstrings from an AST.
use ruff_python_ast::{self as ast, Constant, Expr, Stmt};
use rustpython_parser::ast::{self, Constant, Expr, Stmt};
use ruff_python_semantic::{Definition, DefinitionId, Definitions, Member, MemberKind};

View File

@@ -1,8 +1,8 @@
use std::fmt::{Debug, Formatter};
use std::ops::Deref;
use ruff_python_ast::{Expr, Ranged};
use ruff_text_size::{TextRange, TextSize};
use rustpython_parser::ast::{Expr, Ranged};
use ruff_python_semantic::Definition;

View File

@@ -5,7 +5,7 @@ use ruff_python_ast::docstrings::{leading_space, leading_words};
use ruff_text_size::{TextLen, TextRange, TextSize};
use strum_macros::EnumIter;
use ruff_source_file::{Line, UniversalNewlineIterator, UniversalNewlines};
use ruff_python_trivia::{Line, UniversalNewlineIterator, UniversalNewlines};
use crate::docstrings::styles::SectionStyle;
use crate::docstrings::{Docstring, DocstringBody};

View File

@@ -1,15 +1,15 @@
//! Insert statements into Python code.
use std::ops::Add;
use ruff_python_ast::{Ranged, Stmt};
use ruff_python_parser::{lexer, Mode, Tok};
use ruff_text_size::TextSize;
use rustpython_parser::ast::{Ranged, Stmt};
use rustpython_parser::{lexer, Mode, Tok};
use ruff_diagnostics::Edit;
use ruff_python_ast::helpers::is_docstring_stmt;
use ruff_python_codegen::Stylist;
use ruff_python_trivia::{textwrap::indent, PythonWhitespace};
use ruff_source_file::{Locator, UniversalNewlineIterator};
use ruff_python_ast::source_code::{Locator, Stylist};
use ruff_python_trivia::{PythonWhitespace, UniversalNewlineIterator};
use ruff_textwrap::indent;
#[derive(Debug, Clone, PartialEq, Eq)]
pub(super) enum Placement<'a> {
@@ -299,13 +299,13 @@ fn match_leading_semicolon(s: &str) -> Option<TextSize> {
#[cfg(test)]
mod tests {
use anyhow::Result;
use ruff_python_ast::Suite;
use ruff_python_parser::lexer::LexResult;
use ruff_python_parser::Parse;
use ruff_text_size::TextSize;
use rustpython_parser::ast::Suite;
use rustpython_parser::lexer::LexResult;
use rustpython_parser::Parse;
use ruff_python_codegen::Stylist;
use ruff_source_file::{LineEnding, Locator};
use ruff_python_ast::source_code::{Locator, Stylist};
use ruff_python_trivia::LineEnding;
use super::Insertion;
@@ -313,7 +313,7 @@ mod tests {
fn start_of_file() -> Result<()> {
fn insert(contents: &str) -> Result<Insertion> {
let program = Suite::parse(contents, "<filename>")?;
let tokens: Vec<LexResult> = ruff_python_parser::tokenize(contents);
let tokens: Vec<LexResult> = ruff_rustpython::tokenize(contents);
let locator = Locator::new(contents);
let stylist = Stylist::from_tokens(&tokens, &locator);
Ok(Insertion::start_of_file(&program, &locator, &stylist))
@@ -424,7 +424,7 @@ x = 1
#[test]
fn start_of_block() {
fn insert(contents: &str, offset: TextSize) -> Insertion {
let tokens: Vec<LexResult> = ruff_python_parser::tokenize(contents);
let tokens: Vec<LexResult> = ruff_rustpython::tokenize(contents);
let locator = Locator::new(contents);
let stylist = Stylist::from_tokens(&tokens, &locator);
Insertion::start_of_block(offset, &locator, &stylist)

View File

@@ -7,15 +7,14 @@ use std::error::Error;
use anyhow::Result;
use libcst_native::{ImportAlias, Name, NameOrAttribute};
use ruff_python_ast::{self as ast, Ranged, Stmt, Suite};
use ruff_text_size::TextSize;
use rustpython_parser::ast::{self, Ranged, Stmt, Suite};
use ruff_diagnostics::Edit;
use ruff_python_ast::imports::{AnyImport, Import, ImportFrom};
use ruff_python_codegen::Stylist;
use ruff_python_ast::source_code::{Locator, Stylist};
use ruff_python_semantic::SemanticModel;
use ruff_python_trivia::textwrap::indent;
use ruff_source_file::Locator;
use ruff_textwrap::indent;
use crate::autofix;
use crate::autofix::codemods::CodegenStylist;

View File

@@ -10,9 +10,7 @@ use serde::Serialize;
use serde_json::error::Category;
use ruff_diagnostics::Diagnostic;
use ruff_python_parser::lexer::lex;
use ruff_python_parser::Mode;
use ruff_source_file::{NewlineWithTrailingNewline, UniversalNewlineIterator};
use ruff_python_trivia::{NewlineWithTrailingNewline, UniversalNewlineIterator};
use ruff_text_size::{TextRange, TextSize};
use crate::autofix::source_map::{SourceMap, SourceMarker};
@@ -160,7 +158,10 @@ impl Notebook {
)
})?;
// Check if tokenizing was successful and the file is non-empty
if lex(&contents, Mode::Module).any(|result| result.is_err()) {
if (ruff_rustpython::tokenize(&contents))
.last()
.map_or(true, Result::is_err)
{
Diagnostic::new(
SyntaxError {
message: format!(

View File

@@ -4,7 +4,7 @@
//!
//! TODO(charlie): Consolidate with the existing AST-based docstring extraction.
use ruff_python_parser::Tok;
use rustpython_parser::Tok;
#[derive(Default, Copy, Clone)]
enum State {

View File

@@ -5,6 +5,7 @@
//!
//! [Ruff]: https://github.com/astral-sh/ruff
pub use ruff_python_ast::source_code::round_trip;
pub use rule_selector::RuleSelector;
pub use rules::pycodestyle::rules::IOError;

View File

@@ -6,16 +6,14 @@ use anyhow::{anyhow, Result};
use colored::Colorize;
use itertools::Itertools;
use log::error;
use ruff_python_parser::lexer::LexResult;
use ruff_python_parser::ParseError;
use rustc_hash::FxHashMap;
use rustpython_parser::lexer::LexResult;
use rustpython_parser::ParseError;
use ruff_diagnostics::Diagnostic;
use ruff_python_ast::imports::ImportMap;
use ruff_python_codegen::Stylist;
use ruff_python_index::Indexer;
use ruff_python_ast::source_code::{Indexer, Locator, SourceFileBuilder, Stylist};
use ruff_python_stdlib::path::is_python_stub_file;
use ruff_source_file::{Locator, SourceFileBuilder};
use crate::autofix::{fix_file, FixResult};
use crate::checkers::ast::check_ast;
@@ -138,7 +136,7 @@ pub fn check_path(
.iter_enabled()
.any(|rule_code| rule_code.lint_source().is_imports());
if use_ast || use_imports || use_doc_lines {
match ruff_python_parser::parse_program_tokens(tokens, &path.to_string_lossy()) {
match ruff_rustpython::parse_program_tokens(tokens, &path.to_string_lossy()) {
Ok(python_ast) => {
if use_ast {
diagnostics.extend(check_ast(
@@ -260,7 +258,7 @@ pub fn add_noqa_to_path(path: &Path, package: Option<&Path>, settings: &Settings
let contents = std::fs::read_to_string(path)?;
// Tokenize once.
let tokens: Vec<LexResult> = ruff_python_parser::tokenize(&contents);
let tokens: Vec<LexResult> = ruff_rustpython::tokenize(&contents);
// Map row and column locations to byte slices (lazily).
let locator = Locator::new(&contents);
@@ -328,7 +326,7 @@ pub fn lint_only(
source_kind: Option<&SourceKind>,
) -> LinterResult<(Vec<Message>, Option<ImportMap>)> {
// Tokenize once.
let tokens: Vec<LexResult> = ruff_python_parser::tokenize(contents);
let tokens: Vec<LexResult> = ruff_rustpython::tokenize(contents);
// Map row and column locations to byte slices (lazily).
let locator = Locator::new(contents);
@@ -420,7 +418,7 @@ pub fn lint_fix<'a>(
// Continuously autofix until the source code stabilizes.
loop {
// Tokenize once.
let tokens: Vec<LexResult> = ruff_python_parser::tokenize(&transformed);
let tokens: Vec<LexResult> = ruff_rustpython::tokenize(&transformed);
// Map row and column locations to byte slices (lazily).
let locator = Locator::new(&transformed);

View File

@@ -7,9 +7,9 @@ use colored::Colorize;
use fern;
use log::Level;
use once_cell::sync::Lazy;
use ruff_python_parser::{ParseError, ParseErrorType};
use rustpython_parser::{ParseError, ParseErrorType};
use ruff_source_file::{OneIndexed, SourceCode, SourceLocation};
use ruff_python_ast::source_code::{OneIndexed, SourceCode, SourceLocation};
use crate::fs;
use crate::jupyter::Notebook;

View File

@@ -1,6 +1,6 @@
use std::io::Write;
use ruff_source_file::SourceLocation;
use ruff_python_ast::source_code::SourceLocation;
use crate::message::{Emitter, EmitterContext, Message};
use crate::registry::AsRule;

View File

@@ -7,7 +7,7 @@ use ruff_text_size::{TextRange, TextSize};
use similar::{ChangeTag, TextDiff};
use ruff_diagnostics::{Applicability, Fix};
use ruff_source_file::{OneIndexed, SourceFile};
use ruff_python_ast::source_code::{OneIndexed, SourceFile};
use crate::message::Message;

View File

@@ -1,6 +1,6 @@
use std::io::Write;
use ruff_source_file::SourceLocation;
use ruff_python_ast::source_code::SourceLocation;
use crate::fs::relativize_path;
use crate::message::{Emitter, EmitterContext, Message};

View File

@@ -6,7 +6,7 @@ use serde::ser::SerializeSeq;
use serde::{Serialize, Serializer};
use serde_json::json;
use ruff_source_file::SourceLocation;
use ruff_python_ast::source_code::SourceLocation;
use crate::fs::{relativize_path, relativize_path_to};
use crate::message::{Emitter, EmitterContext, Message};

View File

@@ -4,7 +4,7 @@ use std::num::NonZeroUsize;
use colored::Colorize;
use ruff_source_file::OneIndexed;
use ruff_python_ast::source_code::OneIndexed;
use crate::fs::relativize_path;
use crate::jupyter::{JupyterIndex, Notebook};

View File

@@ -5,7 +5,7 @@ use serde::{Serialize, Serializer};
use serde_json::{json, Value};
use ruff_diagnostics::Edit;
use ruff_source_file::SourceCode;
use ruff_python_ast::source_code::SourceCode;
use crate::message::{Emitter, EmitterContext, Message};
use crate::registry::AsRule;

View File

@@ -3,7 +3,7 @@ use std::path::Path;
use quick_junit::{NonSuccessKind, Report, TestCase, TestCaseStatus, TestSuite};
use ruff_source_file::SourceLocation;
use ruff_python_ast::source_code::SourceLocation;
use crate::message::{
group_messages_by_filename, Emitter, EmitterContext, Message, MessageWithLocation,

View File

@@ -16,7 +16,7 @@ pub use json_lines::JsonLinesEmitter;
pub use junit::JunitEmitter;
pub use pylint::PylintEmitter;
use ruff_diagnostics::{Diagnostic, DiagnosticKind, Fix};
use ruff_source_file::{SourceFile, SourceLocation};
use ruff_python_ast::source_code::{SourceFile, SourceLocation};
pub use text::TextEmitter;
mod azure;
@@ -155,7 +155,7 @@ mod tests {
use rustc_hash::FxHashMap;
use ruff_diagnostics::{Diagnostic, DiagnosticKind, Edit, Fix};
use ruff_source_file::SourceFileBuilder;
use ruff_python_ast::source_code::SourceFileBuilder;
use crate::message::{Emitter, EmitterContext, Message};

View File

@@ -1,6 +1,6 @@
use std::io::Write;
use ruff_source_file::OneIndexed;
use ruff_python_ast::source_code::OneIndexed;
use crate::fs::relativize_path;
use crate::message::{Emitter, EmitterContext, Message};

View File

@@ -8,7 +8,7 @@ use bitflags::bitflags;
use colored::Colorize;
use ruff_text_size::{TextRange, TextSize};
use ruff_source_file::{OneIndexed, SourceLocation};
use ruff_python_ast::source_code::{OneIndexed, SourceLocation};
use crate::fs::relativize_path;
use crate::jupyter::{JupyterIndex, Notebook};

View File

@@ -8,11 +8,12 @@ use std::path::Path;
use anyhow::Result;
use itertools::Itertools;
use log::warn;
use ruff_python_ast::Ranged;
use ruff_text_size::{TextLen, TextRange, TextSize};
use rustpython_parser::ast::Ranged;
use ruff_diagnostics::Diagnostic;
use ruff_source_file::{LineEnding, Locator};
use ruff_python_ast::source_code::Locator;
use ruff_python_trivia::LineEnding;
use crate::codes::NoqaCode;
use crate::fs::relativize_path;
@@ -781,7 +782,8 @@ mod tests {
use ruff_text_size::{TextRange, TextSize};
use ruff_diagnostics::Diagnostic;
use ruff_source_file::{LineEnding, Locator};
use ruff_python_ast::source_code::Locator;
use ruff_python_trivia::LineEnding;
use crate::noqa::{add_noqa_inner, Directive, NoqaMapping, ParsedFileExemption};
use crate::rules::pycodestyle::rules::AmbiguousVariableName;

View File

@@ -5,7 +5,7 @@ use ruff_text_size::{TextRange, TextSize};
use serde::{Deserialize, Serialize};
use ruff_diagnostics::Diagnostic;
use ruff_source_file::SourceFile;
use ruff_python_ast::source_code::SourceFile;
use crate::message::Message;
use crate::registry::Rule;

View File

@@ -246,7 +246,8 @@ impl Rule {
| Rule::MissingNewlineAtEndOfFile
| Rule::MixedSpacesAndTabs
| Rule::TabIndentation
| Rule::TrailingWhitespace => LintSource::PhysicalLines,
| Rule::TrailingWhitespace
| Rule::UTF8EncodingDeclaration => LintSource::PhysicalLines,
Rule::AmbiguousUnicodeCharacterComment
| Rule::AmbiguousUnicodeCharacterDocstring
| Rule::AmbiguousUnicodeCharacterString
@@ -257,6 +258,7 @@ impl Rule {
| Rule::BlanketNOQA
| Rule::BlanketTypeIgnore
| Rule::CommentedOutCode
| Rule::ExplicitStringConcatenation
| Rule::ExtraneousParentheses
| Rule::InvalidCharacterBackspace
| Rule::InvalidCharacterEsc
@@ -288,8 +290,7 @@ impl Rule {
| Rule::SingleLineImplicitStringConcatenation
| Rule::TrailingCommaOnBareTuple
| Rule::TypeCommentInStub
| Rule::UselessSemicolon
| Rule::UTF8EncodingDeclaration => LintSource::Tokens,
| Rule::UselessSemicolon => LintSource::Tokens,
Rule::IOError => LintSource::Io,
Rule::UnsortedImports | Rule::MissingRequiredImport => LintSource::Imports,
Rule::ImplicitNamespacePackage | Rule::InvalidModuleName => LintSource::Filesystem,

View File

@@ -1,10 +1,10 @@
use ruff_python_ast as ast;
use ruff_python_ast::{Expr, Ranged};
use rustpython_parser::ast;
use rustpython_parser::ast::{Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_ast::helpers::find_keyword;
use ruff_python_ast::Constant;
use rustpython_parser::ast::Constant;
use crate::checkers::ast::Checker;

View File

@@ -1,8 +1,8 @@
/// See: [eradicate.py](https://github.com/myint/eradicate/blob/98f199940979c94447a461d50d27862b118b282d/eradicate.py)
use once_cell::sync::Lazy;
use regex::Regex;
use ruff_python_ast::Suite;
use ruff_python_parser::Parse;
use rustpython_parser::ast::Suite;
use rustpython_parser::Parse;
static ALLOWLIST_REGEX: Lazy<Regex> = Lazy::new(|| {
Regex::new(

View File

@@ -1,7 +1,6 @@
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
use ruff_macros::{derive_message_formats, violation};
use ruff_python_index::Indexer;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::{Indexer, Locator};
use crate::registry::Rule;
use crate::settings::Settings;

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::Expr;
use rustpython_parser::ast::Expr;
use ruff_python_semantic::SemanticModel;

View File

@@ -1,5 +1,5 @@
use num_bigint::BigInt;
use ruff_python_ast::{self as ast, CmpOp, Constant, Expr, Ranged};
use rustpython_parser::ast::{self, CmpOp, Constant, Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Expr, Ranged};
use rustpython_parser::ast::{Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,5 +1,5 @@
use num_bigint::BigInt;
use ruff_python_ast::{self as ast, Constant, Expr, Ranged};
use rustpython_parser::ast::{self, Constant, Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,9 +1,9 @@
use anyhow::{bail, Result};
use ruff_python_ast::{Ranged, Stmt};
use ruff_python_parser::{lexer, Mode, Tok};
use rustpython_parser::ast::{Ranged, Stmt};
use rustpython_parser::{lexer, Mode, Tok};
use ruff_diagnostics::Edit;
use ruff_source_file::Locator;
use ruff_python_ast::source_code::Locator;
/// ANN204
pub(crate) fn add_return_annotation(

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Arguments, Expr, Stmt};
use rustpython_parser::ast::{self, Arguments, Expr, Stmt};
use ruff_python_ast::cast;
use ruff_python_semantic::analyze::visibility;

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, ArgWithDefault, Constant, Expr, Ranged, Stmt};
use rustpython_parser::ast::{self, ArgWithDefault, Constant, Expr, Ranged, Stmt};
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix, Violation};
use ruff_macros::{derive_message_formats, violation};
@@ -6,7 +6,7 @@ use ruff_python_ast::cast;
use ruff_python_ast::helpers::ReturnStatementVisitor;
use ruff_python_ast::identifier::Identifier;
use ruff_python_ast::statement_visitor::StatementVisitor;
use ruff_python_parser::typing::parse_type_annotation;
use ruff_python_ast::typing::parse_type_annotation;
use ruff_python_semantic::analyze::visibility;
use ruff_python_semantic::{Definition, Member, MemberKind};
use ruff_python_stdlib::typing::simple_magic_return_type;
@@ -462,8 +462,7 @@ fn check_dynamically_typed<F>(
}) = annotation
{
// Quoted annotations
if let Ok((parsed_annotation, _)) =
parse_type_annotation(string, *range, checker.locator().contents())
if let Ok((parsed_annotation, _)) = parse_type_annotation(string, *range, checker.locator())
{
if type_hint_resolves_to_any(
&parsed_annotation,

View File

@@ -1,5 +1,5 @@
use ruff_python_ast as ast;
use ruff_python_ast::{Expr, Ranged};
use rustpython_parser::ast;
use rustpython_parser::ast::{Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,5 +1,5 @@
use ruff_python_ast as ast;
use ruff_python_ast::{Expr, Ranged};
use rustpython_parser::ast;
use rustpython_parser::ast::{Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,5 +1,5 @@
use ruff_python_ast as ast;
use ruff_python_ast::{Expr, Ranged};
use rustpython_parser::ast;
use rustpython_parser::ast::{Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,6 +1,6 @@
use once_cell::sync::Lazy;
use regex::Regex;
use ruff_python_ast::{self as ast, Constant, Expr};
use rustpython_parser::ast::{self, Constant, Expr};
use ruff_python_semantic::SemanticModel;

View File

@@ -1,5 +1,5 @@
use ruff_python_ast::{Ranged, Stmt};
use ruff_text_size::{TextLen, TextRange};
use rustpython_parser::ast::{Ranged, Stmt};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,5 +1,5 @@
use num_traits::ToPrimitive;
use ruff_python_ast::{self as ast, Constant, Expr, Keyword, Operator, Ranged};
use rustpython_parser::ast::{self, Constant, Expr, Keyword, Operator, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Expr, Ranged};
use rustpython_parser::ast::{Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Arg, ArgWithDefault, Arguments, Expr, Ranged};
use rustpython_parser::ast::{Arg, ArgWithDefault, Arguments, Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Keyword, Ranged};
use rustpython_parser::ast::{Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Constant, Expr, Ranged};
use rustpython_parser::ast::{self, Constant, Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,6 +1,6 @@
use once_cell::sync::Lazy;
use regex::Regex;
use ruff_python_ast::{self as ast, Expr, Operator, Ranged};
use rustpython_parser::ast::{self, Expr, Operator, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Expr, Ranged};
use rustpython_parser::ast::{Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Expr, Keyword, Ranged};
use rustpython_parser::ast::{Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,5 +1,5 @@
use ruff_python_ast::helpers::find_keyword;
use ruff_python_ast::{self as ast, Constant, Expr, Keyword, Ranged};
use rustpython_parser::ast::{self, Constant, Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Expr, Keyword, Ranged};
use rustpython_parser::ast::{Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Expr, Ranged};
use rustpython_parser::ast::{Expr, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Expr, Keyword, Ranged};
use rustpython_parser::ast::{Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Expr, Keyword, Ranged};
use rustpython_parser::ast::{Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,6 +1,6 @@
//! Checks relating to shell injection.
use ruff_python_ast::{self as ast, Constant, Expr, Keyword, Ranged};
use rustpython_parser::ast::{self, Constant, Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,5 +1,5 @@
use num_traits::{One, Zero};
use ruff_python_ast::{self as ast, Constant, Expr, Keyword, Ranged};
use rustpython_parser::ast::{self, Constant, Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{Expr, Keyword, Ranged};
use rustpython_parser::ast::{Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,7 +1,7 @@
//! Check for calls to suspicious functions, or calls into suspicious modules.
//!
//! See: <https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html>
use ruff_python_ast::{self as ast, Expr, Ranged};
use rustpython_parser::ast::{self, Expr, Ranged};
use ruff_diagnostics::{Diagnostic, DiagnosticKind, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{ExceptHandler, Expr, Ranged, Stmt};
use rustpython_parser::ast::{ExceptHandler, Expr, Ranged, Stmt};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{ExceptHandler, Expr, Ranged, Stmt};
use rustpython_parser::ast::{ExceptHandler, Expr, Ranged, Stmt};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Expr, Keyword, Ranged};
use rustpython_parser::ast::{self, Expr, Keyword, Ranged};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Expr, Ranged, Stmt};
use rustpython_parser::ast::{self, Expr, Ranged, Stmt};
use ruff_diagnostics::{Diagnostic, Violation};
use ruff_macros::{derive_message_formats, violation};

View File

@@ -1,4 +1,4 @@
use ruff_python_ast::{self as ast, Constant, Expr, Ranged};
use rustpython_parser::ast::{self, Constant, Expr, Ranged};
use ruff_diagnostics::{Diagnostic, DiagnosticKind};

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