Compare commits
98 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e636c5fcf0 | ||
|
|
12dfd57211 | ||
|
|
d188d242a0 | ||
|
|
57796c5e59 | ||
|
|
2545869797 | ||
|
|
58353a4bf4 | ||
|
|
a36139ae21 | ||
|
|
7e904111b1 | ||
|
|
344daebb1b | ||
|
|
432059de35 | ||
|
|
c50d6da8b4 | ||
|
|
1b738f88c4 | ||
|
|
1eff3dffa5 | ||
|
|
8c7317eb8d | ||
|
|
106a93eab0 | ||
|
|
78c2b0ac47 | ||
|
|
d5700d7c69 | ||
|
|
3a7bdb39c9 | ||
|
|
a82fe4a139 | ||
|
|
62ff3b62e3 | ||
|
|
1e5db58b7b | ||
|
|
a6e998d639 | ||
|
|
a8c1915e2e | ||
|
|
c515a1b31a | ||
|
|
aa97a092bd | ||
|
|
685c242761 | ||
|
|
b540407b74 | ||
|
|
3a5fbd6d74 | ||
|
|
227679b5cb | ||
|
|
c2750a59ab | ||
|
|
2a4d6ab3b2 | ||
|
|
7a80bcec58 | ||
|
|
297749a3a8 | ||
|
|
8955e32b5c | ||
|
|
cd192eddf9 | ||
|
|
675227db5c | ||
|
|
a65c6806a6 | ||
|
|
6c576872d4 | ||
|
|
9858df1ac9 | ||
|
|
7fb7268e8a | ||
|
|
0f78f27713 | ||
|
|
12a6fc7041 | ||
|
|
d2988043af | ||
|
|
cc8b13d3a7 | ||
|
|
1e081cf9a6 | ||
|
|
841bcf1cdd | ||
|
|
7062d1db16 | ||
|
|
8b561313aa | ||
|
|
cfa2924664 | ||
|
|
a3aeec6377 | ||
|
|
b983d5eb3f | ||
|
|
bb3bb24b59 | ||
|
|
872829ca72 | ||
|
|
2383228709 | ||
|
|
952307d39d | ||
|
|
024caca233 | ||
|
|
08ec11a31e | ||
|
|
bd05a8a74d | ||
|
|
229f1c34cb | ||
|
|
a7f3532395 | ||
|
|
3349ceb969 | ||
|
|
da1f83fe32 | ||
|
|
0a9d259f9c | ||
|
|
130e733023 | ||
|
|
ff2c0dd491 | ||
|
|
dfe1cad928 | ||
|
|
ffad0bcdaa | ||
|
|
bc869d4f52 | ||
|
|
a3de791f0a | ||
|
|
d9dfec30eb | ||
|
|
3f04def3a5 | ||
|
|
98177754de | ||
|
|
8d5374762c | ||
|
|
bad6bdda1f | ||
|
|
a5d302fcbf | ||
|
|
bced58ce40 | ||
|
|
10e252e2fb | ||
|
|
4dead7541f | ||
|
|
fea1af5a63 | ||
|
|
c0ad875339 | ||
|
|
8437399496 | ||
|
|
074f5634a5 | ||
|
|
694d41897a | ||
|
|
e1ebd9130d | ||
|
|
fc8ca6edd2 | ||
|
|
709dba2e71 | ||
|
|
d1c48016eb | ||
|
|
348a38d261 | ||
|
|
22e6778e17 | ||
|
|
30c71dc59a | ||
|
|
5d8591fec4 | ||
|
|
673aa6e90f | ||
|
|
51fe9f7d4b | ||
|
|
d7767b2bad | ||
|
|
40d3b40c14 | ||
|
|
376ef929b1 | ||
|
|
8828e12283 | ||
|
|
f13633cc9f |
@@ -1,5 +1,6 @@
|
||||
[alias]
|
||||
dev = "run --package ruff_dev --bin ruff_dev"
|
||||
benchmark = "bench -p ruff_benchmark --"
|
||||
|
||||
[target.'cfg(all())']
|
||||
rustflags = [
|
||||
|
||||
11
.github/dependabot.yml
vendored
Normal file
11
.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
day: "monday"
|
||||
time: "12:00"
|
||||
timezone: "America/New_York"
|
||||
commit-message:
|
||||
prefix: "ci(deps)"
|
||||
86
.github/workflows/ci.yaml
vendored
86
.github/workflows/ci.yaml
vendored
@@ -17,20 +17,6 @@ env:
|
||||
RUSTUP_MAX_RETRIES: 10
|
||||
|
||||
jobs:
|
||||
cargo-build:
|
||||
name: "cargo build"
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- run: cargo build --all
|
||||
- run: ./target/debug/ruff_dev generate-all
|
||||
- run: git diff --quiet README.md || echo "::error file=README.md::This file is outdated. Run 'cargo dev generate-all'."
|
||||
- run: git diff --quiet ruff.schema.json || echo "::error file=ruff.schema.json::This file is outdated. Run 'cargo dev generate-all'."
|
||||
- run: git diff --exit-code -- README.md ruff.schema.json docs
|
||||
|
||||
cargo-fmt:
|
||||
name: "cargo fmt"
|
||||
runs-on: ubuntu-latest
|
||||
@@ -48,7 +34,7 @@ jobs:
|
||||
- name: "Install Rust toolchain"
|
||||
run: |
|
||||
rustup component add clippy
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: cargo clippy --workspace --all-targets --all-features -- -D warnings
|
||||
|
||||
cargo-clippy-wasm:
|
||||
@@ -60,8 +46,8 @@ jobs:
|
||||
run: |
|
||||
rustup component add clippy
|
||||
rustup target add wasm32-unknown-unknown
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- run: cargo clippy -p ruff --target wasm32-unknown-unknown --all-features -- -D warnings
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: cargo clippy -p ruff_wasm --target wasm32-unknown-unknown --all-features -- -D warnings
|
||||
|
||||
cargo-test:
|
||||
strategy:
|
||||
@@ -73,9 +59,9 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: cargo install cargo-insta
|
||||
- run: pip install black[d]==22.12.0
|
||||
- run: pip install black[d]==23.1.0
|
||||
- name: "Run tests (Ubuntu)"
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
run: |
|
||||
@@ -93,6 +79,30 @@ jobs:
|
||||
env:
|
||||
# Setting RUSTDOCFLAGS because `cargo doc --check` isn't yet implemented (https://github.com/rust-lang/cargo/issues/10025).
|
||||
RUSTDOCFLAGS: "-D warnings"
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ruff
|
||||
path: target/debug/ruff
|
||||
|
||||
|
||||
cargo-test-wasm:
|
||||
runs-on: ubuntu-latest
|
||||
name: "cargo test (wasm)"
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup target add wasm32-unknown-unknown
|
||||
- uses: actions/setup-node@v3
|
||||
with:
|
||||
node-version: 18
|
||||
cache: "npm"
|
||||
cache-dependency-path: playground/package-lock.json
|
||||
- uses: jetli/wasm-pack-action@v0.4.0
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: "Run wasm-pack"
|
||||
run: |
|
||||
cd crates/ruff_wasm
|
||||
wasm-pack test --node
|
||||
|
||||
scripts:
|
||||
name: "test scripts"
|
||||
@@ -101,7 +111,7 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- run: ./scripts/add_rule.py --name DoTheThing --code PLC999 --linter pylint
|
||||
- run: cargo check
|
||||
- run: |
|
||||
@@ -117,3 +127,39 @@ jobs:
|
||||
- uses: crate-ci/typos@master
|
||||
with:
|
||||
files: .
|
||||
|
||||
ecosystem:
|
||||
name: "ecosystem"
|
||||
runs-on: ubuntu-latest
|
||||
needs: cargo-test
|
||||
# Only runs on pull requests, since that is the only we way we can find the base version for comparison.
|
||||
if: github.event_name == 'pull_request'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: "3.11"
|
||||
- uses: actions/download-artifact@v3
|
||||
id: ruff-target
|
||||
with:
|
||||
name: ruff
|
||||
path: target/debug
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
with:
|
||||
name: ruff
|
||||
branch: ${{ github.event.pull_request.base.ref }}
|
||||
check_artifacts: true
|
||||
- name: Run ecosystem check
|
||||
run: |
|
||||
# Make executable, since artifact download doesn't preserve this
|
||||
chmod +x ruff ${{ steps.ruff-target.outputs.download-path }}/ruff
|
||||
|
||||
scripts/check_ecosystem.py ruff ${{ steps.ruff-target.outputs.download-path }}/ruff | tee ecosystem-result
|
||||
|
||||
echo ${{ github.event.number }} > pr-number
|
||||
- uses: actions/upload-artifact@v3
|
||||
with:
|
||||
name: ecosystem-result
|
||||
path: |
|
||||
ecosystem-result
|
||||
pr-number
|
||||
|
||||
2
.github/workflows/docs.yaml
vendored
2
.github/workflows/docs.yaml
vendored
@@ -15,7 +15,7 @@ jobs:
|
||||
- uses: actions/setup-python@v4
|
||||
- name: "Install Rust toolchain"
|
||||
run: rustup show
|
||||
- uses: Swatinem/rust-cache@v1
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
- name: "Install dependencies"
|
||||
run: |
|
||||
pip install -r docs/requirements.txt
|
||||
|
||||
31
.github/workflows/ecosystem-comment.yaml
vendored
Normal file
31
.github/workflows/ecosystem-comment.yaml
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
on:
|
||||
workflow_run:
|
||||
workflows: [CI]
|
||||
types: [completed]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
comment:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dawidd6/action-download-artifact@v2
|
||||
id: download-result
|
||||
with:
|
||||
name: ecosystem-result
|
||||
workflow: ci.yaml
|
||||
run_id: ${{ github.event.workflow_run.id }}
|
||||
if_no_artifact_found: ignore
|
||||
- if: steps.download-result.outputs.found_artifact
|
||||
id: result
|
||||
run: |
|
||||
echo "pr-number=$(<pr-number)" >> $GITHUB_OUTPUT
|
||||
- name: Create comment
|
||||
if: steps.download-result.outputs.found_artifact
|
||||
uses: thollander/actions-comment-pull-request@v2
|
||||
with:
|
||||
pr_number: ${{ steps.result.outputs.pr-number }}
|
||||
filePath: ecosystem-result
|
||||
comment_tag: ecosystem-results
|
||||
4
.github/workflows/flake8-to-ruff.yaml
vendored
4
.github/workflows/flake8-to-ruff.yaml
vendored
@@ -133,7 +133,7 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --no-default-features --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
- uses: uraimo/run-on-arch-action@v2.5.0
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
if: matrix.target != 'ppc64'
|
||||
name: Install built wheel
|
||||
with:
|
||||
@@ -206,7 +206,7 @@ jobs:
|
||||
target: ${{ matrix.platform.target }}
|
||||
manylinux: musllinux_1_2
|
||||
args: --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
- uses: uraimo/run-on-arch-action@master
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
name: Install built wheel
|
||||
with:
|
||||
arch: ${{ matrix.platform.arch }}
|
||||
|
||||
2
.github/workflows/playground.yaml
vendored
2
.github/workflows/playground.yaml
vendored
@@ -28,7 +28,7 @@ jobs:
|
||||
- uses: jetli/wasm-pack-action@v0.4.0
|
||||
- uses: jetli/wasm-bindgen-action@v0.2.0
|
||||
- name: "Run wasm-pack"
|
||||
run: wasm-pack build --target web --out-dir ../../playground/src/pkg crates/ruff
|
||||
run: wasm-pack build --target web --out-dir ../../playground/src/pkg crates/ruff_wasm
|
||||
- name: "Install Node dependencies"
|
||||
run: npm ci
|
||||
working-directory: playground
|
||||
|
||||
4
.github/workflows/ruff.yaml
vendored
4
.github/workflows/ruff.yaml
vendored
@@ -208,7 +208,7 @@ jobs:
|
||||
target: ${{ matrix.platform.target }}
|
||||
manylinux: auto
|
||||
args: --release --out dist
|
||||
- uses: uraimo/run-on-arch-action@v2.5.0
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
if: matrix.platform.arch != 'ppc64'
|
||||
name: Install built wheel
|
||||
with:
|
||||
@@ -309,7 +309,7 @@ jobs:
|
||||
target: ${{ matrix.platform.target }}
|
||||
manylinux: musllinux_1_2
|
||||
args: --release --out dist
|
||||
- uses: uraimo/run-on-arch-action@master
|
||||
- uses: uraimo/run-on-arch-action@v2
|
||||
name: Install built wheel
|
||||
with:
|
||||
arch: ${{ matrix.platform.arch }}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
fail_fast: true
|
||||
repos:
|
||||
- repo: https://github.com/abravalheri/validate-pyproject
|
||||
rev: v0.10.1
|
||||
rev: v0.12.1
|
||||
hooks:
|
||||
- id: validate-pyproject
|
||||
|
||||
|
||||
@@ -104,7 +104,7 @@ At a high level, the steps involved in adding a new lint rule are as follows:
|
||||
|
||||
1. Determine a name for the new rule as per our [rule naming convention](#rule-naming-convention).
|
||||
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 `define_violation!` to see examples.
|
||||
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
|
||||
checks), `crates/ruff/src/checkers/tokens.rs` (for token-based checks), `crates/ruff/src/checkers/lines.rs`
|
||||
@@ -115,7 +115,7 @@ At a high level, the steps involved in adding a new lint rule are as follows:
|
||||
|
||||
To define the violation, start by creating a dedicated file for your rule under the appropriate
|
||||
rule linter (e.g., `crates/ruff/src/rules/flake8_bugbear/rules/abstract_base_class.rs`). That file should
|
||||
contain a struct defined via `define_violation!`, along with a function that creates the violation
|
||||
contain a struct defined via `#[violation]`, along with a function that creates the violation
|
||||
based on any required inputs. (Many of the existing examples live in `crates/ruff/src/violations.rs`,
|
||||
but we're looking to place new rules in their own files.)
|
||||
|
||||
|
||||
301
Cargo.lock
generated
301
Cargo.lock
generated
@@ -289,9 +289,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.1.6"
|
||||
version = "4.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec0b0588d44d4d63a87dbd75c136c166bbfd9a86a31cb89e09906521c7d3f5e3"
|
||||
checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
@@ -308,18 +308,19 @@ version = "4.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd125be87bf4c255ebc50de0b7f4d2a6201e8ac3dc86e39c0ad081dc5e7236fe"
|
||||
dependencies = [
|
||||
"clap 4.1.6",
|
||||
"clap 4.1.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete_command"
|
||||
version = "0.4.0"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4160b4a4f72ef58bd766bad27c09e6ef1cc9d82a22f6a0f55d152985a4a48e31"
|
||||
checksum = "183495371ea78d4c9ff638bfc6497d46fed2396e4f9c50aebc1278a4a9919a3d"
|
||||
dependencies = [
|
||||
"clap 4.1.6",
|
||||
"clap 4.1.8",
|
||||
"clap_complete",
|
||||
"clap_complete_fig",
|
||||
"clap_complete_nushell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -328,15 +329,25 @@ version = "4.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "63a06158a72dbb088f864887b4409fd22600ba379f3cee3040f842234cc5c2d0"
|
||||
dependencies = [
|
||||
"clap 4.1.6",
|
||||
"clap 4.1.8",
|
||||
"clap_complete",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_complete_nushell"
|
||||
version = "0.1.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7fa41f5e6aa83bd151b70fd0ceaee703d68cd669522795dc812df9edad1252c"
|
||||
dependencies = [
|
||||
"clap 4.1.8",
|
||||
"clap_complete",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_derive"
|
||||
version = "4.1.0"
|
||||
version = "4.1.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "684a277d672e91966334af371f1a7b5833f9aa00b07c84e92fbce95e00208ce8"
|
||||
checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0"
|
||||
dependencies = [
|
||||
"heck",
|
||||
"proc-macro-error",
|
||||
@@ -427,9 +438,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "console_log"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "501a375961cef1a0d44767200e66e4a559283097e91d0730b1d75dfb2f8a1494"
|
||||
checksum = "878ad067d4089144a36ee412d665916c665430eb84c0057b9987f424a5d15c03"
|
||||
dependencies = [
|
||||
"log",
|
||||
"web-sys",
|
||||
@@ -554,6 +565,16 @@ dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctor"
|
||||
version = "0.1.26"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6d2301688392eb071b0bf1a37be05c469d3cc4dbbd95df672fe28ab021e6a096"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.91"
|
||||
@@ -598,17 +619,6 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "derivative"
|
||||
version = "2.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "diff"
|
||||
version = "0.1.13"
|
||||
@@ -770,10 +780,10 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.254"
|
||||
version = "0.0.256"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.1.6",
|
||||
"clap 4.1.8",
|
||||
"colored",
|
||||
"configparser",
|
||||
"once_cell",
|
||||
@@ -1363,15 +1373,6 @@ dependencies = [
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom8"
|
||||
version = "0.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae01545c9c7fc4486ab7debaf2aad7003ac19431791868fb2e8066df97fad2f8"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "5.1.0"
|
||||
@@ -1457,6 +1458,15 @@ version = "6.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "output_vt100"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "628223faebab4e3e40667ee0b2336d34a5b960ff60ea743ddfdbcf7770bcfb66"
|
||||
dependencies = [
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
@@ -1504,6 +1514,12 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pathdiff"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||
|
||||
[[package]]
|
||||
name = "peg"
|
||||
version = "0.8.1"
|
||||
@@ -1531,6 +1547,18 @@ version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9fa00462b37ead6d11a82c9d568b26682d78e0477dc02d1966c013af80969739"
|
||||
|
||||
[[package]]
|
||||
name = "pep440_rs"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/konstin/pep440-rs.git?rev=a8fef4ec47f4c25b070b39cdbe6a0b9847e49941#a8fef4ec47f4c25b070b39cdbe6a0b9847e49941"
|
||||
dependencies = [
|
||||
"lazy_static",
|
||||
"regex",
|
||||
"serde",
|
||||
"tracing",
|
||||
"unicode-width",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "percent-encoding"
|
||||
version = "2.2.0"
|
||||
@@ -1728,6 +1756,18 @@ dependencies = [
|
||||
"termtree",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pretty_assertions"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a25e9bcb20aa780fd0bb16b72403a9064d6b3f22f026946029acb941a50af755"
|
||||
dependencies = [
|
||||
"ctor",
|
||||
"diff",
|
||||
"output_vt100",
|
||||
"yansi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro-error"
|
||||
version = "1.0.4"
|
||||
@@ -1831,9 +1871,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.6.1"
|
||||
version = "1.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6db3a213adf02b3bcfd2d3846bb41cb22857d131789e01df434fb7e7bc0759b7"
|
||||
checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b"
|
||||
dependencies = [
|
||||
"either",
|
||||
"rayon-core",
|
||||
@@ -1841,9 +1881,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.10.2"
|
||||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "356a0625f1954f730c0201cdab48611198dc6ce21f4acff55089b5a78e6e835b"
|
||||
checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
@@ -1942,22 +1982,17 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.254"
|
||||
version = "0.0.256"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bisection",
|
||||
"bitflags",
|
||||
"cfg-if",
|
||||
"chrono",
|
||||
"clap 4.1.6",
|
||||
"clap 4.1.8",
|
||||
"colored",
|
||||
"console_error_panic_hook",
|
||||
"console_log",
|
||||
"criterion",
|
||||
"derivative",
|
||||
"dirs",
|
||||
"fern",
|
||||
"getrandom",
|
||||
"glob",
|
||||
"globset",
|
||||
"ignore",
|
||||
@@ -1965,7 +2000,6 @@ dependencies = [
|
||||
"insta",
|
||||
"is-macro",
|
||||
"itertools",
|
||||
"js-sys",
|
||||
"libcst",
|
||||
"log",
|
||||
"natord",
|
||||
@@ -1974,11 +2008,16 @@ dependencies = [
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"path-absolutize",
|
||||
"pathdiff",
|
||||
"pep440_rs",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
"result-like",
|
||||
"ruff_cache",
|
||||
"ruff_diagnostics",
|
||||
"ruff_macros",
|
||||
"ruff_python",
|
||||
"ruff_python_ast",
|
||||
"ruff_python_stdlib",
|
||||
"ruff_rustpython",
|
||||
"rustc-hash",
|
||||
"rustpython-common",
|
||||
@@ -1986,7 +2025,6 @@ dependencies = [
|
||||
"schemars",
|
||||
"semver",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
"shellexpand",
|
||||
"smallvec",
|
||||
"strum",
|
||||
@@ -1995,8 +2033,18 @@ dependencies = [
|
||||
"textwrap",
|
||||
"thiserror",
|
||||
"toml",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff_benchmark"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"criterion",
|
||||
"mimalloc",
|
||||
"ruff",
|
||||
"tikv-jemallocator",
|
||||
"ureq",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2012,7 +2060,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_cli"
|
||||
version = "0.0.254"
|
||||
version = "0.0.256"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.9.1",
|
||||
"anyhow",
|
||||
@@ -2022,7 +2070,7 @@ dependencies = [
|
||||
"bitflags",
|
||||
"cachedir",
|
||||
"chrono",
|
||||
"clap 4.1.6",
|
||||
"clap 4.1.8",
|
||||
"clap_complete_command",
|
||||
"clearscreen",
|
||||
"colored",
|
||||
@@ -2039,6 +2087,7 @@ dependencies = [
|
||||
"regex",
|
||||
"ruff",
|
||||
"ruff_cache",
|
||||
"ruff_diagnostics",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -2056,13 +2105,15 @@ name = "ruff_dev"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.1.6",
|
||||
"clap 4.1.8",
|
||||
"itertools",
|
||||
"libcst",
|
||||
"once_cell",
|
||||
"pretty_assertions",
|
||||
"regex",
|
||||
"ruff",
|
||||
"ruff_cli",
|
||||
"ruff_diagnostics",
|
||||
"rustpython-common",
|
||||
"rustpython-parser",
|
||||
"schemars",
|
||||
@@ -2072,6 +2123,15 @@ dependencies = [
|
||||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff_diagnostics"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"ruff_python_ast",
|
||||
"rustpython-parser",
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff_formatter"
|
||||
version = "0.0.0"
|
||||
@@ -2098,12 +2158,25 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff_python"
|
||||
name = "ruff_python_ast"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags",
|
||||
"is-macro",
|
||||
"itertools",
|
||||
"log",
|
||||
"nohash-hasher",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"ruff_python_stdlib",
|
||||
"ruff_rustpython",
|
||||
"rustc-hash",
|
||||
"rustpython-common",
|
||||
"rustpython-parser",
|
||||
"smallvec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2111,13 +2184,14 @@ name = "ruff_python_formatter"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.1.6",
|
||||
"clap 4.1.8",
|
||||
"insta",
|
||||
"is-macro",
|
||||
"itertools",
|
||||
"once_cell",
|
||||
"ruff_formatter",
|
||||
"ruff_python",
|
||||
"ruff_python_ast",
|
||||
"ruff_python_stdlib",
|
||||
"ruff_rustpython",
|
||||
"ruff_testing_macros",
|
||||
"ruff_text_size",
|
||||
@@ -2128,6 +2202,15 @@ dependencies = [
|
||||
"test-case",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff_python_stdlib"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff_rustpython"
|
||||
version = "0.0.0"
|
||||
@@ -2143,7 +2226,6 @@ name = "ruff_testing_macros"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
@@ -2159,6 +2241,25 @@ dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff_wasm"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"console_error_panic_hook",
|
||||
"console_log",
|
||||
"getrandom",
|
||||
"js-sys",
|
||||
"log",
|
||||
"ruff",
|
||||
"ruff_python_ast",
|
||||
"ruff_rustpython",
|
||||
"rustpython-parser",
|
||||
"serde",
|
||||
"serde-wasm-bindgen",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-test",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rust-stemmers"
|
||||
version = "1.2.0"
|
||||
@@ -2204,7 +2305,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-ast"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=822f6a9fa6b9142413634858c4c6908f678ce887#822f6a9fa6b9142413634858c4c6908f678ce887"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=c15f670f2c30cfae6b41a1874893590148c74bc4#c15f670f2c30cfae6b41a1874893590148c74bc4"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"rustpython-compiler-core",
|
||||
@@ -2213,7 +2314,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-common"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=822f6a9fa6b9142413634858c4c6908f678ce887#822f6a9fa6b9142413634858c4c6908f678ce887"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=c15f670f2c30cfae6b41a1874893590148c74bc4#c15f670f2c30cfae6b41a1874893590148c74bc4"
|
||||
dependencies = [
|
||||
"ascii",
|
||||
"bitflags",
|
||||
@@ -2238,7 +2339,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-compiler-core"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=822f6a9fa6b9142413634858c4c6908f678ce887#822f6a9fa6b9142413634858c4c6908f678ce887"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=c15f670f2c30cfae6b41a1874893590148c74bc4#c15f670f2c30cfae6b41a1874893590148c74bc4"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bstr 0.2.17",
|
||||
@@ -2252,7 +2353,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-parser"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=822f6a9fa6b9142413634858c4c6908f678ce887#822f6a9fa6b9142413634858c4c6908f678ce887"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=c15f670f2c30cfae6b41a1874893590148c74bc4#c15f670f2c30cfae6b41a1874893590148c74bc4"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
@@ -2297,9 +2398,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schemars"
|
||||
version = "0.8.11"
|
||||
version = "0.8.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a5fb6c61f29e723026dc8e923d94c694313212abbecbbe5f55a7748eec5b307"
|
||||
checksum = "02c613288622e5f0c3fdc5dbd4db1c5fbe752746b1d1a56a0630b78fd00de44f"
|
||||
dependencies = [
|
||||
"dyn-clone",
|
||||
"schemars_derive",
|
||||
@@ -2309,9 +2410,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "schemars_derive"
|
||||
version = "0.8.11"
|
||||
version = "0.8.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f188d036977451159430f3b8dc82ec76364a42b7e289c2b18a9a18f4470058e9"
|
||||
checksum = "109da1e6b197438deb6db99952990c7f959572794b80ff93707d55a232545e7c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2364,9 +2465,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde-wasm-bindgen"
|
||||
version = "0.4.5"
|
||||
version = "0.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b4c031cd0d9014307d82b8abf653c0290fbdaeb4c02d00c63cf52f728628bf"
|
||||
checksum = "f3b143e2833c57ab9ad3ea280d21fd34e285a42837aeb0ee301f4f41890fa00e"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"serde",
|
||||
@@ -2523,9 +2624,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.108"
|
||||
version = "1.0.109"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d56e159d99e6c2b93995d171050271edb50ecc5288fbc7cc17de8fdce4e58c14"
|
||||
checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2596,18 +2697,18 @@ checksum = "95059e91184749cb66be6dc994f67f182b6d897cb3df74a5bf66b5e709295fd8"
|
||||
|
||||
[[package]]
|
||||
name = "test-case"
|
||||
version = "2.2.2"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "21d6cf5a7dffb3f9dceec8e6b8ca528d9bd71d36c9f074defb548ce161f598c0"
|
||||
checksum = "679b019fb241da62cc449b33b224d19ebe1c6767b495569765115dd7f7f9fba4"
|
||||
dependencies = [
|
||||
"test-case-macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test-case-macros"
|
||||
version = "2.2.2"
|
||||
name = "test-case-core"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e45b7bf6e19353ddd832745c8fcf77a17a93171df7151187f26623f2b75b5b26"
|
||||
checksum = "72dc21b5887f4032c4656502d085dc28f2afbb686f25f216472bb0526f4b1b88"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"proc-macro-error",
|
||||
@@ -2616,6 +2717,19 @@ dependencies = [
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "test-case-macros"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3786898e0be151a96f730fd529b0e8a10f5990fa2a7ea14e37ca27613c05190"
|
||||
dependencies = [
|
||||
"proc-macro-error",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"test-case-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "textwrap"
|
||||
version = "0.16.0"
|
||||
@@ -2724,9 +2838,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.6.0"
|
||||
version = "0.7.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4fb9d890e4dc9298b70f740f615f2e05b9db37dce531f6b24fb77ac993f9f217"
|
||||
checksum = "f7afcae9e3f0fe2c370fd4657108972cbb2fa9db1b9f84849cefd80741b01cb6"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
@@ -2736,24 +2850,24 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.5.1"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4553f467ac8e3d374bc9a177a26801e5d0f9b211aa1673fb137a403afd1c9cf5"
|
||||
checksum = "3ab8ed2edee10b50132aed5f331333428b011c99402b5a534154ed15746f9622"
|
||||
dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.18.1"
|
||||
version = "0.19.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56c59d8dd7d0dcbc6428bf7aa2f0e823e26e43b3c9aca15bbc9475d23e5fa12b"
|
||||
checksum = "9a1eb0622d28f4b9c90adc4ea4b2b46b47663fde9ac5fafcb14a1369d5508825"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"nom8",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2764,9 +2878,21 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"pin-project-lite",
|
||||
"tracing-attributes",
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.30"
|
||||
@@ -3244,6 +3370,15 @@ version = "0.42.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd"
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "faf09497b8f8b5ac5d3bb4d05c0a99be20f26fd3d5f2db7b0716e946d5103658"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
@@ -3253,6 +3388,12 @@ dependencies = [
|
||||
"linked-hash-map",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yansi"
|
||||
version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
|
||||
|
||||
[[package]]
|
||||
name = "yansi-term"
|
||||
version = "0.1.2"
|
||||
|
||||
54
Cargo.toml
54
Cargo.toml
@@ -3,25 +3,49 @@ members = ["crates/*"]
|
||||
|
||||
[workspace.package]
|
||||
edition = "2021"
|
||||
rust-version = "1.67.0"
|
||||
rust-version = "1.67"
|
||||
homepage = "https://beta.ruff.rs/docs/"
|
||||
documentation = "https://beta.ruff.rs/docs/"
|
||||
repository = "https://github.com/charliermarsh/ruff"
|
||||
authors = ["Charlie Marsh <charlie.r.marsh@gmail.com>"]
|
||||
|
||||
[workspace.dependencies]
|
||||
anyhow = { version = "1.0.66" }
|
||||
clap = { version = "4.0.1", features = ["derive"] }
|
||||
itertools = { version = "0.10.5" }
|
||||
anyhow = { version = "1.0.69" }
|
||||
bitflags = { version = "1.3.2" }
|
||||
chrono = { version = "0.4.23", default-features = false, features = ["clock"] }
|
||||
clap = { version = "4.1.8", features = ["derive"] }
|
||||
colored = { version = "2.0.0" }
|
||||
filetime = { version = "0.2.20" }
|
||||
glob = { version = "0.3.1" }
|
||||
globset = { version = "0.4.10" }
|
||||
ignore = { version = "0.4.20" }
|
||||
insta = { version = "1.28.0" }
|
||||
is-macro = { version = "0.2.2" }
|
||||
itertools = { version = "0.10.5" }
|
||||
libcst = { git = "https://github.com/charliermarsh/LibCST", rev = "80e4c1399f95e5beb532fdd1e209ad2dbb470438" }
|
||||
once_cell = { version = "1.16.0" }
|
||||
regex = { version = "1.6.0" }
|
||||
log = { version = "0.4.17" }
|
||||
once_cell = { version = "1.17.1" }
|
||||
path-absolutize = { version = "3.0.14" }
|
||||
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 = "822f6a9fa6b9142413634858c4c6908f678ce887" }
|
||||
rustpython-parser = { features = ["lalrpop", "serde"], git = "https://github.com/RustPython/RustPython.git", rev = "822f6a9fa6b9142413634858c4c6908f678ce887" }
|
||||
schemars = { version = "0.8.11" }
|
||||
serde = { version = "1.0.147", features = ["derive"] }
|
||||
serde_json = { version = "1.0.87" }
|
||||
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" }
|
||||
schemars = { version = "0.8.12" }
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
serde_json = { version = "1.0.93" }
|
||||
shellexpand = { version = "3.0.0" }
|
||||
similar = { version = "2.2.1" }
|
||||
strum = { version = "0.24.1", features = ["strum_macros"] }
|
||||
strum_macros = { version = "0.24.3" }
|
||||
toml = { version = "0.6.0" }
|
||||
syn = { version = "1.0.109" }
|
||||
test-case = { version = "3.0.0" }
|
||||
textwrap = { version = "0.16.0" }
|
||||
toml = { version = "0.7.2" }
|
||||
|
||||
[profile.release]
|
||||
panic = "abort"
|
||||
@@ -39,3 +63,9 @@ opt-level = 3
|
||||
# https://github.com/bytecodealliance/wasm-tools/blob/b5c3d98e40590512a3b12470ef358d5c7b983b15/crates/wasmparser/src/limits.rs#L29
|
||||
[profile.dev.package.rustpython-parser]
|
||||
opt-level = 1
|
||||
|
||||
# Use the `--profile release-debug` flag to show symbols in release mode.
|
||||
# e.g. `cargo build --profile release-debug`
|
||||
[profile.release-debug]
|
||||
inherits = "release"
|
||||
debug = 1
|
||||
|
||||
@@ -137,7 +137,7 @@ Ruff can also be used as a [pre-commit](https://pre-commit.com) hook:
|
||||
```yaml
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
# Ruff version.
|
||||
rev: 'v0.0.254'
|
||||
rev: 'v0.0.256'
|
||||
hooks:
|
||||
- id: ruff
|
||||
```
|
||||
@@ -306,6 +306,9 @@ Ruff is used in a number of major open-source projects, including:
|
||||
- [meson-python](https://github.com/mesonbuild/meson-python)
|
||||
- [ZenML](https://github.com/zenml-io/zenml)
|
||||
- [delta-rs](https://github.com/delta-io/delta-rs)
|
||||
- [Starlite](https://github.com/starlite-api/starlite)
|
||||
- [telemetry-airflow (Mozilla)](https://github.com/mozilla/telemetry-airflow)
|
||||
- [Stable Baselines3](https://github.com/DLR-RM/stable-baselines3)
|
||||
|
||||
## License
|
||||
|
||||
|
||||
@@ -1,17 +1,18 @@
|
||||
[package]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.254"
|
||||
version = "0.0.256"
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
ruff = { path = "../ruff", default-features = false }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
colored = { version = "2.0.0" }
|
||||
colored = { workspace = true }
|
||||
configparser = { version = "3.0.2" }
|
||||
once_cell = { workspace = true }
|
||||
regex = { workspace = true }
|
||||
ruff = { path = "../ruff", default-features = false }
|
||||
rustc-hash = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -46,8 +46,15 @@ fn main() -> Result<()> {
|
||||
.map(|tool| ExternalConfig {
|
||||
black: tool.black.as_ref(),
|
||||
isort: tool.isort.as_ref(),
|
||||
..Default::default()
|
||||
})
|
||||
.unwrap_or_default();
|
||||
let external_config = ExternalConfig {
|
||||
project: pyproject
|
||||
.as_ref()
|
||||
.and_then(|pyproject| pyproject.project.as_ref()),
|
||||
..external_config
|
||||
};
|
||||
|
||||
// Create Ruff's pyproject.toml section.
|
||||
let pyproject = flake8_to_ruff::convert(&config, &external_config, args.plugin)?;
|
||||
|
||||
@@ -1,82 +1,76 @@
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.0.254"
|
||||
authors = ["Charlie Marsh <charlie.r.marsh@gmail.com>"]
|
||||
edition = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
documentation = "https://github.com/charliermarsh/ruff"
|
||||
homepage = "https://github.com/charliermarsh/ruff"
|
||||
repository = "https://github.com/charliermarsh/ruff"
|
||||
version = "0.0.256"
|
||||
authors.workspace = true
|
||||
edition.workspace = true
|
||||
rust-version.workspace = true
|
||||
documentation.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
readme = "README.md"
|
||||
license = "MIT"
|
||||
|
||||
[lib]
|
||||
name = "ruff"
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
doctest = false
|
||||
|
||||
[dependencies]
|
||||
ruff_macros = { path = "../ruff_macros" }
|
||||
ruff_python = { path = "../ruff_python" }
|
||||
ruff_rustpython = { path = "../ruff_rustpython" }
|
||||
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_stdlib = { path = "../ruff_python_stdlib" }
|
||||
ruff_rustpython = { path = "../ruff_rustpython" }
|
||||
|
||||
anyhow = { workspace = true }
|
||||
bisection = { version = "0.1.0" }
|
||||
bitflags = { version = "1.3.2" }
|
||||
cfg-if = { version = "1.0.0" }
|
||||
chrono = { version = "0.4.21", default-features = false, features = ["clock"] }
|
||||
clap = { workspace = true, features = ["derive", "env", "string"] }
|
||||
colored = { version = "2.0.0" }
|
||||
derivative = { version = "2.2.0" }
|
||||
bitflags = { workspace = true }
|
||||
chrono = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive", "string"], optional = true }
|
||||
colored = { workspace = true }
|
||||
dirs = { version = "4.0.0" }
|
||||
fern = { version = "0.6.1" }
|
||||
glob = { version = "0.3.0" }
|
||||
globset = { version = "0.4.9" }
|
||||
ignore = { version = "0.4.18" }
|
||||
imperative = { version = "1.0.3" }
|
||||
glob = { workspace = true }
|
||||
globset = { workspace = true }
|
||||
ignore = { workspace = true }
|
||||
imperative = { version = "1.0.4" }
|
||||
is-macro = { workspace = true }
|
||||
itertools = { workspace = true }
|
||||
libcst = { workspace = true }
|
||||
log = { version = "0.4.17" }
|
||||
log = { workspace = true }
|
||||
natord = { version = "1.0.9" }
|
||||
nohash-hasher = { version = "0.2.0" }
|
||||
num-bigint = { version = "0.4.3" }
|
||||
num-traits = "0.2.15"
|
||||
num-traits = { version = "0.2.15" }
|
||||
once_cell = { workspace = true }
|
||||
path-absolutize = { version = "3.0.14", features = ["once_cell_cache", "use_unix_paths_on_wasm"] }
|
||||
path-absolutize = { workspace = true, features = [
|
||||
"once_cell_cache",
|
||||
"use_unix_paths_on_wasm",
|
||||
] }
|
||||
pathdiff = { version = "0.2.1" }
|
||||
pep440_rs = { git = "https://github.com/konstin/pep440-rs.git", features = [
|
||||
"serde",
|
||||
], rev = "a8fef4ec47f4c25b070b39cdbe6a0b9847e49941" }
|
||||
regex = { workspace = true }
|
||||
result-like = "0.4.6"
|
||||
result-like = { version = "0.4.6" }
|
||||
rustc-hash = { workspace = true }
|
||||
rustpython-common = { workspace = true }
|
||||
rustpython-parser = { workspace = true }
|
||||
schemars = { workspace = true }
|
||||
semver = { version = "1.0.16" }
|
||||
serde = { workspace = true }
|
||||
shellexpand = { version = "3.0.0" }
|
||||
shellexpand = { workspace = true }
|
||||
smallvec = { version = "1.10.0" }
|
||||
strum = { workspace = true }
|
||||
strum_macros = { workspace = true }
|
||||
textwrap = { version = "0.16.0" }
|
||||
thiserror = { version = "1.0" }
|
||||
textwrap = { workspace = true }
|
||||
thiserror = { version = "1.0.38" }
|
||||
toml = { workspace = true }
|
||||
|
||||
# https://docs.rs/getrandom/0.2.7/getrandom/#webassembly-support
|
||||
[target.'cfg(all(target_family = "wasm", target_os = "unknown"))'.dependencies]
|
||||
getrandom = { version = "0.2.7", features = ["js"] }
|
||||
console_error_panic_hook = { version = "0.1.7" }
|
||||
console_log = { version = "0.2.0" }
|
||||
serde-wasm-bindgen = { version = "0.4" }
|
||||
js-sys = { version = "0.3.60" }
|
||||
wasm-bindgen = { version = "0.2.83" }
|
||||
|
||||
[dev-dependencies]
|
||||
insta = { version = "1.19.0", features = ["yaml", "redactions"] }
|
||||
test-case = { version = "2.2.2" }
|
||||
wasm-bindgen-test = { version = "0.3.33" }
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dev-dependencies]
|
||||
criterion = { version = "0.4.0" }
|
||||
insta = { workspace = true, features = ["yaml", "redactions"] }
|
||||
pretty_assertions = "1.3.0"
|
||||
test-case = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = []
|
||||
|
||||
47
crates/ruff/resources/test/fixtures/flake8_bugbear/B030.py
vendored
Normal file
47
crates/ruff/resources/test/fixtures/flake8_bugbear/B030.py
vendored
Normal file
@@ -0,0 +1,47 @@
|
||||
"""
|
||||
Should emit:
|
||||
B030:
|
||||
- line 12, column 8
|
||||
- line 17, column 9
|
||||
- line 22, column 21
|
||||
- line 27, column 37
|
||||
"""
|
||||
|
||||
try:
|
||||
pass
|
||||
except 1: # error
|
||||
pass
|
||||
|
||||
try:
|
||||
pass
|
||||
except (1, ValueError): # error
|
||||
pass
|
||||
|
||||
try:
|
||||
pass
|
||||
except (ValueError, (RuntimeError, (KeyError, TypeError))): # error
|
||||
pass
|
||||
|
||||
try:
|
||||
pass
|
||||
except (ValueError, *(RuntimeError, (KeyError, TypeError))): # error
|
||||
pass
|
||||
|
||||
|
||||
try:
|
||||
pass
|
||||
except (ValueError, *(RuntimeError, TypeError)): # ok
|
||||
pass
|
||||
|
||||
try:
|
||||
pass
|
||||
except (ValueError, *[RuntimeError, *(TypeError,)]): # ok
|
||||
pass
|
||||
|
||||
def what_to_catch():
|
||||
return ...
|
||||
|
||||
try:
|
||||
pass
|
||||
except what_to_catch(): # ok
|
||||
pass
|
||||
@@ -8,3 +8,9 @@ any({x.id for x in bar})
|
||||
# PIE 802
|
||||
any([x.id for x in bar])
|
||||
all([x.id for x in bar])
|
||||
any( # first comment
|
||||
[x.id for x in bar], # second comment
|
||||
) # third comment
|
||||
all( # first comment
|
||||
[x.id for x in bar], # second comment
|
||||
) # third comment
|
||||
|
||||
@@ -6,6 +6,8 @@ obj.endswith("foo") or obj.endswith("bar")
|
||||
obj.startswith(foo) or obj.startswith(bar)
|
||||
# error
|
||||
obj.startswith(foo) or obj.startswith("foo")
|
||||
# error
|
||||
obj.endswith(foo) or obj.startswith(foo) or obj.startswith("foo")
|
||||
|
||||
# ok
|
||||
obj.startswith(("foo", "bar"))
|
||||
|
||||
@@ -1,3 +1,10 @@
|
||||
import math
|
||||
import os
|
||||
import sys
|
||||
from math import inf
|
||||
|
||||
import numpy as np
|
||||
|
||||
def f12(
|
||||
x,
|
||||
y: str = os.pathsep, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
@@ -61,3 +68,49 @@ def f22(
|
||||
x: complex = -42.5j # Error PYI011 Only simple default values allowed for typed arguments
|
||||
+ 4.3j,
|
||||
) -> None: ...
|
||||
def f23(
|
||||
x: bool = True, # OK
|
||||
) -> None: ...
|
||||
def f24(
|
||||
x: float = 3.14, # OK
|
||||
) -> None: ...
|
||||
def f25(
|
||||
x: float = -3.14, # OK
|
||||
) -> None: ...
|
||||
def f26(
|
||||
x: complex = -3.14j, # OK
|
||||
) -> None: ...
|
||||
def f27(
|
||||
x: complex = -3 - 3.14j, # OK
|
||||
) -> None: ...
|
||||
def f28(
|
||||
x: float = math.tau, # OK
|
||||
) -> None: ...
|
||||
def f29(
|
||||
x: float = math.inf, # OK
|
||||
) -> None: ...
|
||||
def f30(
|
||||
x: float = -math.inf, # OK
|
||||
) -> None: ...
|
||||
def f31(
|
||||
x: float = inf, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
def f32(
|
||||
x: float = np.inf, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
def f33(
|
||||
x: float = math.nan, # OK
|
||||
) -> None: ...
|
||||
def f34(
|
||||
x: float = -math.nan, # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
def f35(
|
||||
x: complex = math.inf # Error PYI011 Only simple default values allowed for typed arguments
|
||||
+ 1j,
|
||||
) -> None: ...
|
||||
def f36(
|
||||
*, x: str = sys.version, # OK
|
||||
) -> None: ...
|
||||
def f37(
|
||||
*, x: str = "" + "", # Error PYI011 Only simple default values allowed for typed arguments
|
||||
) -> None: ...
|
||||
|
||||
@@ -43,3 +43,6 @@ def f21(
|
||||
def f22(
|
||||
x=-42.5j + 4.3j, # Error PYI014
|
||||
) -> None: ...
|
||||
def f23(
|
||||
x=True, # OK
|
||||
) -> None: ...
|
||||
|
||||
@@ -6,22 +6,6 @@ def x():
|
||||
return a # error
|
||||
|
||||
|
||||
def x():
|
||||
a = 1
|
||||
print(a)
|
||||
a = 2
|
||||
return a # error
|
||||
|
||||
|
||||
def x():
|
||||
a = 1
|
||||
if True:
|
||||
return a # error
|
||||
a = 2
|
||||
print(a)
|
||||
return a
|
||||
|
||||
|
||||
# Can be refactored false positives
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issuecomment-1122571066
|
||||
def get_bar_if_exists(obj):
|
||||
@@ -165,44 +149,6 @@ def my_func():
|
||||
return foo
|
||||
|
||||
|
||||
# Refactored incorrect false positives
|
||||
# See test cases above marked: "Can be refactored false positives"
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issuecomment-1122571066
|
||||
def get_bar_if_exists(obj):
|
||||
if hasattr(obj, "bar"):
|
||||
return str(obj.bar)
|
||||
return ""
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issue-641117366
|
||||
def x():
|
||||
formatted = _USER_AGENT_FORMATTER.format(format_string, **values)
|
||||
# clean up after any blank components
|
||||
return formatted.replace("()", "").replace(" ", " ").strip()
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issue-641117366
|
||||
def user_agent_username(username=None):
|
||||
|
||||
if not username:
|
||||
return ""
|
||||
|
||||
username = username.replace(" ", "_") # Avoid spaces or %20.
|
||||
try:
|
||||
username.encode("ascii") # just test,
|
||||
# but not actually use it
|
||||
except UnicodeEncodeError:
|
||||
username = quote(username.encode("utf-8"))
|
||||
else:
|
||||
# % is legal in the default $wgLegalTitleChars
|
||||
# This is so that ops know the real pywikibot will not
|
||||
# allow a useragent in the username to allow through a
|
||||
# hand-coded percent-encoded value.
|
||||
if "%" in username:
|
||||
username = quote(username)
|
||||
return username
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/116#issue-1367575481
|
||||
def no_exception_loop():
|
||||
success = False
|
||||
@@ -260,3 +206,44 @@ def nonlocal_assignment():
|
||||
nonlocal X
|
||||
X = 1
|
||||
return X
|
||||
|
||||
|
||||
def decorator() -> Flask:
|
||||
app = Flask(__name__)
|
||||
|
||||
@app.route('/hello')
|
||||
def hello() -> str:
|
||||
"""Hello endpoint."""
|
||||
return 'Hello, World!'
|
||||
|
||||
return app
|
||||
|
||||
|
||||
def default():
|
||||
y = 1
|
||||
|
||||
def f(x = y) -> X:
|
||||
return x
|
||||
|
||||
return y
|
||||
|
||||
|
||||
def get_queryset(option_1, option_2):
|
||||
queryset: Any = None
|
||||
queryset = queryset.filter(a=1)
|
||||
if option_1:
|
||||
queryset = queryset.annotate(b=Value(2))
|
||||
if option_2:
|
||||
queryset = queryset.filter(c=3)
|
||||
return queryset
|
||||
|
||||
|
||||
def get_queryset():
|
||||
queryset = Model.filter(a=1)
|
||||
queryset = queryset.filter(c=3)
|
||||
return queryset
|
||||
|
||||
|
||||
def get_queryset():
|
||||
queryset = Model.filter(a=1)
|
||||
return queryset # error
|
||||
|
||||
@@ -6,6 +6,8 @@
|
||||
"yoda" <= compare # SIM300
|
||||
"yoda" < compare # SIM300
|
||||
42 > age # SIM300
|
||||
-42 > age # SIM300
|
||||
+42 > age # SIM300
|
||||
YODA == age # SIM300
|
||||
YODA > age # SIM300
|
||||
YODA >= age # SIM300
|
||||
|
||||
3
crates/ruff/resources/test/fixtures/flake8_type_checking/TCH004_14.pyi
vendored
Normal file
3
crates/ruff/resources/test/fixtures/flake8_type_checking/TCH004_14.pyi
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from typing import Tuple
|
||||
|
||||
x: Tuple
|
||||
38
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_1.py
vendored
Normal file
38
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_1.py
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pydantic
|
||||
from pydantic import BaseModel
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import datetime # TCH004
|
||||
from array import array # TCH004
|
||||
|
||||
import pandas # TCH004
|
||||
import pyproj
|
||||
|
||||
|
||||
class A(pydantic.BaseModel):
|
||||
x: datetime.datetime
|
||||
|
||||
|
||||
class B(BaseModel):
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
class C(BaseModel):
|
||||
x: pathlib.Path
|
||||
|
||||
|
||||
class E:
|
||||
pass
|
||||
|
||||
|
||||
class F(E):
|
||||
x: pyproj.Transformer
|
||||
|
||||
|
||||
class G(BaseModel):
|
||||
x: array
|
||||
28
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_2.py
vendored
Normal file
28
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_2.py
vendored
Normal file
@@ -0,0 +1,28 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import geopandas as gpd # TCH002
|
||||
import pydantic
|
||||
import pyproj # TCH002
|
||||
from pydantic import BaseModel
|
||||
|
||||
import numpy
|
||||
|
||||
|
||||
class A(BaseModel):
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
class B(pydantic.BaseModel):
|
||||
x: numpy.ndarray
|
||||
|
||||
|
||||
class C:
|
||||
pass
|
||||
|
||||
|
||||
class D(C):
|
||||
x: pyproj.Transformer
|
||||
|
||||
|
||||
class E(C):
|
||||
x: gpd.GeoDataFrame
|
||||
24
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py
vendored
Normal file
24
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_base_classes_3.py
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
import pathlib
|
||||
from uuid import UUID # TCH003
|
||||
|
||||
import pydantic
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class A(pydantic.BaseModel):
|
||||
x: datetime.datetime
|
||||
|
||||
|
||||
class B(BaseModel):
|
||||
x: pathlib.Path
|
||||
|
||||
|
||||
class C:
|
||||
pass
|
||||
|
||||
|
||||
class D(C):
|
||||
x: UUID
|
||||
46
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_1.py
vendored
Normal file
46
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_1.py
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import pathlib
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import attrs
|
||||
from attrs import frozen
|
||||
|
||||
import numpy
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import datetime # TCH004
|
||||
from array import array # TCH004
|
||||
|
||||
import pandas # TCH004
|
||||
import pyproj
|
||||
|
||||
|
||||
@attrs.define(auto_attribs=True)
|
||||
class A:
|
||||
x: datetime.datetime
|
||||
|
||||
|
||||
@attrs.define
|
||||
class B:
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
@frozen(auto_attribs=True)
|
||||
class C:
|
||||
x: pathlib.Path
|
||||
|
||||
|
||||
@frozen
|
||||
class D:
|
||||
x: array
|
||||
|
||||
|
||||
@dataclass
|
||||
class E:
|
||||
x: pyproj.Transformer
|
||||
|
||||
|
||||
@attrs.define
|
||||
class F:
|
||||
x: numpy.ndarray
|
||||
30
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_2.py
vendored
Normal file
30
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_2.py
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
|
||||
import attrs
|
||||
import pandas
|
||||
import pyproj
|
||||
from attrs import frozen
|
||||
|
||||
import numpy # TCH002
|
||||
|
||||
|
||||
@attrs.define(auto_attribs=True)
|
||||
class A:
|
||||
x: pyproj.Transformer
|
||||
|
||||
|
||||
@attrs.define
|
||||
class B:
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
@frozen
|
||||
class C:
|
||||
x: pandas.DataFrame
|
||||
|
||||
|
||||
@dataclass
|
||||
class D:
|
||||
x: numpy.ndarray
|
||||
24
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_3.py
vendored
Normal file
24
crates/ruff/resources/test/fixtures/flake8_type_checking/runtime_evaluated_decorators_3.py
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import datetime
|
||||
from array import array
|
||||
from dataclasses import dataclass
|
||||
from uuid import UUID # TCH003
|
||||
|
||||
import attrs
|
||||
from attrs import frozen
|
||||
|
||||
|
||||
@attrs.define(auto_attribs=True)
|
||||
class A:
|
||||
x: datetime.datetime
|
||||
|
||||
|
||||
@frozen
|
||||
class B:
|
||||
x: array
|
||||
|
||||
|
||||
@dataclass
|
||||
class C:
|
||||
x: UUID
|
||||
@@ -1,5 +1,10 @@
|
||||
import sys, math
|
||||
from os import path, uname
|
||||
from json import detect_encoding
|
||||
from json import dump
|
||||
from json import dumps as json_dumps
|
||||
from json import load
|
||||
from json import loads as json_loads
|
||||
from logging.handlers import StreamHandler, FileHandler
|
||||
|
||||
# comment 1
|
||||
@@ -10,9 +15,10 @@ from third_party import lib4
|
||||
|
||||
from foo import bar # comment 3
|
||||
from foo2 import bar2 # comment 4
|
||||
from foo3 import bar3, baz3 # comment 5
|
||||
|
||||
# comment 5
|
||||
# comment 6
|
||||
from bar import (
|
||||
a, # comment 6
|
||||
b, # comment 7
|
||||
)
|
||||
a, # comment 7
|
||||
b, # comment 8
|
||||
)
|
||||
|
||||
10
crates/ruff/resources/test/fixtures/isort/ruff_skip_file.py
vendored
Normal file
10
crates/ruff/resources/test/fixtures/isort/ruff_skip_file.py
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# ruff: isort: skip_file
|
||||
import e
|
||||
import f
|
||||
|
||||
# isort: split
|
||||
|
||||
import a
|
||||
import b
|
||||
import c
|
||||
import d
|
||||
@@ -6,6 +6,14 @@ def f():
|
||||
# isort: on
|
||||
|
||||
|
||||
def f():
|
||||
# ruff: isort: off
|
||||
import sys
|
||||
import os
|
||||
import collections
|
||||
# ruff: isort: on
|
||||
|
||||
|
||||
def f():
|
||||
import sys
|
||||
import os # isort: skip
|
||||
|
||||
15
crates/ruff/resources/test/fixtures/pycodestyle/E23.py
vendored
Normal file
15
crates/ruff/resources/test/fixtures/pycodestyle/E23.py
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
#: E231
|
||||
a = (1,2)
|
||||
#: E231
|
||||
a[b1,:]
|
||||
#: E231
|
||||
a = [{'a':''}]
|
||||
#: Okay
|
||||
a = (4,)
|
||||
b = (5, )
|
||||
c = {'text': text[5:]}
|
||||
|
||||
result = {
|
||||
'key1': 'value',
|
||||
'key2': 'value',
|
||||
}
|
||||
1
crates/ruff/resources/test/fixtures/pydocstyle/bom.py
vendored
Normal file
1
crates/ruff/resources/test/fixtures/pydocstyle/bom.py
vendored
Normal file
@@ -0,0 +1 @@
|
||||
''' SAM macro definitions '''
|
||||
19
crates/ruff/resources/test/fixtures/pylint/compare_to_empty_string.py
vendored
Normal file
19
crates/ruff/resources/test/fixtures/pylint/compare_to_empty_string.py
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
x = "a string"
|
||||
y = "another string"
|
||||
z = ""
|
||||
|
||||
|
||||
def errors():
|
||||
if x is "" or x == "":
|
||||
print("x is an empty string")
|
||||
|
||||
if y is not "" or y != "":
|
||||
print("y is not an empty string")
|
||||
|
||||
if "" != z:
|
||||
print("z is an empty string")
|
||||
|
||||
|
||||
def ok():
|
||||
if x and not y:
|
||||
print("x is not an empty string, but y is an empty string")
|
||||
12
crates/ruff/resources/test/fixtures/pylint/invalid_envvar_default.py
vendored
Normal file
12
crates/ruff/resources/test/fixtures/pylint/invalid_envvar_default.py
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import os
|
||||
|
||||
tempVar = os.getenv("TEST", 12) # [invalid-envvar-default]
|
||||
goodVar = os.getenv("TESTING", None)
|
||||
dictVarBad = os.getenv("AAA", {"a", 7}) # [invalid-envvar-default]
|
||||
print(os.getenv("TEST", False)) # [invalid-envvar-default]
|
||||
os.getenv("AA", "GOOD")
|
||||
os.getenv("AA", f"GOOD")
|
||||
os.getenv("AA", "GOOD" + "BAD")
|
||||
os.getenv("AA", "GOOD" + 1)
|
||||
os.getenv("AA", "GOOD %s" % "BAD")
|
||||
os.getenv("B", Z)
|
||||
15
crates/ruff/resources/test/fixtures/pylint/invalid_envvar_value.py
vendored
Normal file
15
crates/ruff/resources/test/fixtures/pylint/invalid_envvar_value.py
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
import os
|
||||
|
||||
os.getenv(1) # [invalid-envvar-value]
|
||||
os.getenv("a")
|
||||
os.getenv("test")
|
||||
os.getenv(key="testingAgain")
|
||||
os.getenv(key=11) # [invalid-envvar-value]
|
||||
os.getenv(["hello"]) # [invalid-envvar-value]
|
||||
os.getenv(key="foo", default="bar")
|
||||
os.getenv(key=f"foo", default="bar")
|
||||
os.getenv(key="foo" + "bar", default=1)
|
||||
os.getenv(key=1 + "bar", default=1) # [invalid-envvar-value]
|
||||
|
||||
AA = "aa"
|
||||
os.getenv(AA)
|
||||
@@ -11,6 +11,9 @@ if 10 == 100: # [comparison-of-constants] R0133
|
||||
if 1 == 3: # [comparison-of-constants] R0133
|
||||
pass
|
||||
|
||||
if 1 == -3: # [comparison-of-constants] R0133
|
||||
pass
|
||||
|
||||
x = 0
|
||||
if 4 == 3 == x: # [comparison-of-constants] R0133
|
||||
pass
|
||||
@@ -35,6 +38,12 @@ if argc != 1: # correct
|
||||
if argc != 2: # [magic-value-comparison]
|
||||
pass
|
||||
|
||||
if argc != -2: # [magic-value-comparison]
|
||||
pass
|
||||
|
||||
if argc != +2: # [magic-value-comparison]
|
||||
pass
|
||||
|
||||
if __name__ == "__main__": # correct
|
||||
pass
|
||||
|
||||
|
||||
@@ -12,11 +12,17 @@ Ipsum
|
||||
""".encode(
|
||||
"utf-8"
|
||||
)
|
||||
# b"""
|
||||
# Lorem
|
||||
#
|
||||
# Ipsum
|
||||
# """
|
||||
(
|
||||
"Lorem "
|
||||
"Ipsum".encode()
|
||||
)
|
||||
(
|
||||
"Lorem " # Comment
|
||||
"Ipsum".encode() # Comment
|
||||
)
|
||||
(
|
||||
"Lorem " "Ipsum".encode()
|
||||
)
|
||||
|
||||
# `encode` on variables should not be processed.
|
||||
string = "hello there"
|
||||
|
||||
10
crates/ruff/resources/test/fixtures/pyupgrade/UP024_4.py
vendored
Normal file
10
crates/ruff/resources/test/fixtures/pyupgrade/UP024_4.py
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import socket
|
||||
|
||||
from kombu import Connection, exceptions
|
||||
|
||||
try:
|
||||
conn = Connection(settings.CELERY_BROKER_URL)
|
||||
conn.ensure_connection(max_retries=2)
|
||||
conn._close()
|
||||
except (socket.error, exceptions.OperationalError):
|
||||
return HttpResponseServerError("cache: cannot connect to broker.")
|
||||
@@ -41,7 +41,7 @@ if True:
|
||||
Good,
|
||||
)
|
||||
|
||||
from typing import Callable, Match, Pattern, List
|
||||
from typing import Callable, Match, Pattern, List, OrderedDict, AbstractSet, ContextManager
|
||||
|
||||
if True: from collections import (
|
||||
Mapping, Counter)
|
||||
|
||||
@@ -5,3 +5,5 @@ isinstance(1, int) # OK
|
||||
issubclass("yes", int) # OK
|
||||
isinstance(1, int | float) # OK
|
||||
issubclass("yes", int | str) # OK
|
||||
isinstance(1, ()) # OK
|
||||
isinstance(1, (int, *(str, bytes))) # OK
|
||||
|
||||
13
crates/ruff/resources/test/fixtures/ruff/RUF100_3.py
vendored
Normal file
13
crates/ruff/resources/test/fixtures/ruff/RUF100_3.py
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
# noqa
|
||||
# noqa # comment
|
||||
print() # noqa
|
||||
print() # noqa # comment
|
||||
print(a) # noqa
|
||||
print(a) # noqa # comment
|
||||
|
||||
# noqa: E501, F821
|
||||
# noqa: E501, F821 # comment
|
||||
print() # noqa: E501, F821
|
||||
print() # noqa: E501, F821 # comment
|
||||
print(a) # noqa: E501, F821
|
||||
print(a) # noqa: E501, F821 # comment
|
||||
@@ -6,14 +6,14 @@ use libcst_native::{
|
||||
use rustpython_parser::ast::{ExcepthandlerKind, Expr, Keyword, Location, Stmt, StmtKind};
|
||||
use rustpython_parser::{lexer, Mode, Tok};
|
||||
|
||||
use crate::ast::helpers;
|
||||
use crate::ast::helpers::to_absolute;
|
||||
use crate::ast::types::Range;
|
||||
use crate::ast::whitespace::LinesWithTrailingNewline;
|
||||
use ruff_diagnostics::Fix;
|
||||
use ruff_python_ast::helpers;
|
||||
use ruff_python_ast::helpers::to_absolute;
|
||||
use ruff_python_ast::newlines::NewlineWithTrailingNewline;
|
||||
use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
|
||||
|
||||
use crate::cst::helpers::compose_module_path;
|
||||
use crate::cst::matchers::match_module;
|
||||
use crate::fix::Fix;
|
||||
use crate::source_code::{Indexer, Locator, Stylist};
|
||||
|
||||
/// Determine if a body contains only a single statement, taking into account
|
||||
/// deleted.
|
||||
@@ -100,7 +100,7 @@ fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result<bool>
|
||||
/// of a multi-statement line.
|
||||
fn trailing_semicolon(stmt: &Stmt, locator: &Locator) -> Option<Location> {
|
||||
let contents = locator.skip(stmt.end_location.unwrap());
|
||||
for (row, line) in LinesWithTrailingNewline::from(contents).enumerate() {
|
||||
for (row, line) in NewlineWithTrailingNewline::from(contents).enumerate() {
|
||||
let trimmed = line.trim();
|
||||
if trimmed.starts_with(';') {
|
||||
let column = line
|
||||
@@ -123,7 +123,7 @@ fn trailing_semicolon(stmt: &Stmt, locator: &Locator) -> Option<Location> {
|
||||
fn next_stmt_break(semicolon: Location, locator: &Locator) -> Location {
|
||||
let start_location = Location::new(semicolon.row(), semicolon.column() + 1);
|
||||
let contents = locator.skip(start_location);
|
||||
for (row, line) in LinesWithTrailingNewline::from(contents).enumerate() {
|
||||
for (row, line) in NewlineWithTrailingNewline::from(contents).enumerate() {
|
||||
let trimmed = line.trim();
|
||||
// Skip past any continuations.
|
||||
if trimmed.starts_with('\\') {
|
||||
@@ -227,7 +227,7 @@ pub fn remove_unused_imports<'a>(
|
||||
indexer: &Indexer,
|
||||
stylist: &Stylist,
|
||||
) -> Result<Fix> {
|
||||
let module_text = locator.slice(&Range::from_located(stmt));
|
||||
let module_text = locator.slice(stmt);
|
||||
let mut tree = match_module(module_text)?;
|
||||
|
||||
let Some(Statement::Simple(body)) = tree.body.first_mut() else {
|
||||
@@ -450,8 +450,9 @@ mod tests {
|
||||
use rustpython_parser as parser;
|
||||
use rustpython_parser::ast::Location;
|
||||
|
||||
use ruff_python_ast::source_code::Locator;
|
||||
|
||||
use crate::autofix::helpers::{next_stmt_break, trailing_semicolon};
|
||||
use crate::source_code::Locator;
|
||||
|
||||
#[test]
|
||||
fn find_semicolon() -> Result<()> {
|
||||
|
||||
@@ -4,11 +4,12 @@ use itertools::Itertools;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_parser::ast::Location;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::fix::Fix;
|
||||
use ruff_diagnostics::{Diagnostic, Fix};
|
||||
use ruff_python_ast::source_code::Locator;
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
use crate::linter::FixTable;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::source_code::Locator;
|
||||
use crate::registry::AsRule;
|
||||
|
||||
pub mod helpers;
|
||||
|
||||
@@ -54,7 +55,7 @@ fn apply_fixes<'a>(
|
||||
}
|
||||
|
||||
// Add all contents from `last_pos` to `fix.location`.
|
||||
let slice = locator.slice(&Range::new(last_pos, fix.location));
|
||||
let slice = locator.slice(Range::new(last_pos, fix.location));
|
||||
output.push_str(slice);
|
||||
|
||||
// Add the patch itself.
|
||||
@@ -78,7 +79,7 @@ pub(crate) fn apply_fix(fix: &Fix, locator: &Locator) -> String {
|
||||
let mut output = String::with_capacity(locator.len());
|
||||
|
||||
// Add all contents from `last_pos` to `fix.location`.
|
||||
let slice = locator.slice(&Range::new(Location::new(1, 0), fix.location));
|
||||
let slice = locator.slice(Range::new(Location::new(1, 0), fix.location));
|
||||
output.push_str(slice);
|
||||
|
||||
// Add the patch itself.
|
||||
@@ -95,43 +96,38 @@ pub(crate) fn apply_fix(fix: &Fix, locator: &Locator) -> String {
|
||||
mod tests {
|
||||
use rustpython_parser::ast::Location;
|
||||
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_diagnostics::Fix;
|
||||
use ruff_python_ast::source_code::Locator;
|
||||
|
||||
use crate::autofix::{apply_fix, apply_fixes};
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::rules::pycodestyle::rules::NoNewLineAtEndOfFile;
|
||||
|
||||
use crate::source_code::Locator;
|
||||
|
||||
#[test]
|
||||
fn empty_file() {
|
||||
let fixes: Vec<Diagnostic> = vec![];
|
||||
let locator = Locator::new(r#""#);
|
||||
let (contents, fixed) = apply_fixes(fixes.iter(), &locator);
|
||||
assert_eq!(contents, "");
|
||||
assert_eq!(fixed.values().sum::<usize>(), 0);
|
||||
}
|
||||
|
||||
impl From<Fix> for Diagnostic {
|
||||
fn from(fix: Fix) -> Self {
|
||||
Diagnostic {
|
||||
fn create_diagnostics(fixes: impl IntoIterator<Item = Fix>) -> Vec<Diagnostic> {
|
||||
fixes
|
||||
.into_iter()
|
||||
.map(|fix| Diagnostic {
|
||||
// The choice of rule here is arbitrary.
|
||||
kind: NoNewLineAtEndOfFile.into(),
|
||||
location: fix.location,
|
||||
end_location: fix.end_location,
|
||||
fix: Some(fix),
|
||||
parent: None,
|
||||
}
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_file() {
|
||||
let locator = Locator::new(r#""#);
|
||||
let diagnostics = create_diagnostics([]);
|
||||
let (contents, fixed) = apply_fixes(diagnostics.iter(), &locator);
|
||||
assert_eq!(contents, "");
|
||||
assert_eq!(fixed.values().sum::<usize>(), 0);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn apply_one_replacement() {
|
||||
let fixes: Vec<Diagnostic> = vec![Fix {
|
||||
content: "Bar".to_string(),
|
||||
location: Location::new(1, 8),
|
||||
end_location: Location::new(1, 14),
|
||||
}
|
||||
.into()];
|
||||
let locator = Locator::new(
|
||||
r#"
|
||||
class A(object):
|
||||
@@ -139,7 +135,12 @@ class A(object):
|
||||
"#
|
||||
.trim(),
|
||||
);
|
||||
let (contents, fixed) = apply_fixes(fixes.iter(), &locator);
|
||||
let diagnostics = create_diagnostics([Fix {
|
||||
content: "Bar".to_string(),
|
||||
location: Location::new(1, 8),
|
||||
end_location: Location::new(1, 14),
|
||||
}]);
|
||||
let (contents, fixed) = apply_fixes(diagnostics.iter(), &locator);
|
||||
assert_eq!(
|
||||
contents,
|
||||
r#"
|
||||
@@ -153,12 +154,6 @@ class A(Bar):
|
||||
|
||||
#[test]
|
||||
fn apply_one_removal() {
|
||||
let fixes: Vec<Diagnostic> = vec![Fix {
|
||||
content: String::new(),
|
||||
location: Location::new(1, 7),
|
||||
end_location: Location::new(1, 15),
|
||||
}
|
||||
.into()];
|
||||
let locator = Locator::new(
|
||||
r#"
|
||||
class A(object):
|
||||
@@ -166,7 +161,12 @@ class A(object):
|
||||
"#
|
||||
.trim(),
|
||||
);
|
||||
let (contents, fixed) = apply_fixes(fixes.iter(), &locator);
|
||||
let diagnostics = create_diagnostics([Fix {
|
||||
content: String::new(),
|
||||
location: Location::new(1, 7),
|
||||
end_location: Location::new(1, 15),
|
||||
}]);
|
||||
let (contents, fixed) = apply_fixes(diagnostics.iter(), &locator);
|
||||
assert_eq!(
|
||||
contents,
|
||||
r#"
|
||||
@@ -180,20 +180,6 @@ class A:
|
||||
|
||||
#[test]
|
||||
fn apply_two_removals() {
|
||||
let fixes: Vec<Diagnostic> = vec![
|
||||
Fix {
|
||||
content: String::new(),
|
||||
location: Location::new(1, 7),
|
||||
end_location: Location::new(1, 16),
|
||||
}
|
||||
.into(),
|
||||
Fix {
|
||||
content: String::new(),
|
||||
location: Location::new(1, 16),
|
||||
end_location: Location::new(1, 23),
|
||||
}
|
||||
.into(),
|
||||
];
|
||||
let locator = Locator::new(
|
||||
r#"
|
||||
class A(object, object):
|
||||
@@ -201,7 +187,19 @@ class A(object, object):
|
||||
"#
|
||||
.trim(),
|
||||
);
|
||||
let (contents, fixed) = apply_fixes(fixes.iter(), &locator);
|
||||
let diagnostics = create_diagnostics([
|
||||
Fix {
|
||||
content: String::new(),
|
||||
location: Location::new(1, 7),
|
||||
end_location: Location::new(1, 16),
|
||||
},
|
||||
Fix {
|
||||
content: String::new(),
|
||||
location: Location::new(1, 16),
|
||||
end_location: Location::new(1, 23),
|
||||
},
|
||||
]);
|
||||
let (contents, fixed) = apply_fixes(diagnostics.iter(), &locator);
|
||||
|
||||
assert_eq!(
|
||||
contents,
|
||||
@@ -216,20 +214,6 @@ class A:
|
||||
|
||||
#[test]
|
||||
fn ignore_overlapping_fixes() {
|
||||
let fixes: Vec<Diagnostic> = vec![
|
||||
Fix {
|
||||
content: String::new(),
|
||||
location: Location::new(1, 7),
|
||||
end_location: Location::new(1, 15),
|
||||
}
|
||||
.into(),
|
||||
Fix {
|
||||
content: "ignored".to_string(),
|
||||
location: Location::new(1, 9),
|
||||
end_location: Location::new(1, 11),
|
||||
}
|
||||
.into(),
|
||||
];
|
||||
let locator = Locator::new(
|
||||
r#"
|
||||
class A(object):
|
||||
@@ -237,7 +221,19 @@ class A(object):
|
||||
"#
|
||||
.trim(),
|
||||
);
|
||||
let (contents, fixed) = apply_fixes(fixes.iter(), &locator);
|
||||
let diagnostics = create_diagnostics([
|
||||
Fix {
|
||||
content: String::new(),
|
||||
location: Location::new(1, 7),
|
||||
end_location: Location::new(1, 15),
|
||||
},
|
||||
Fix {
|
||||
content: "ignored".to_string(),
|
||||
location: Location::new(1, 9),
|
||||
end_location: Location::new(1, 11),
|
||||
},
|
||||
]);
|
||||
let (contents, fixed) = apply_fixes(diagnostics.iter(), &locator);
|
||||
assert_eq!(
|
||||
contents,
|
||||
r#"
|
||||
|
||||
24
crates/ruff/src/checkers/ast/deferred.rs
Normal file
24
crates/ruff/src/checkers/ast/deferred.rs
Normal file
@@ -0,0 +1,24 @@
|
||||
use rustpython_parser::ast::{Expr, Stmt};
|
||||
|
||||
use ruff_python_ast::types::Range;
|
||||
use ruff_python_ast::types::RefEquality;
|
||||
use ruff_python_ast::visibility::{Visibility, VisibleScope};
|
||||
|
||||
use crate::checkers::ast::AnnotationContext;
|
||||
use crate::docstrings::definition::Definition;
|
||||
|
||||
type Context<'a> = (Vec<usize>, Vec<RefEquality<'a, Stmt>>);
|
||||
|
||||
/// A collection of AST nodes that are deferred for later analysis.
|
||||
/// Used to, e.g., store functions, whose bodies shouldn't be analyzed until all
|
||||
/// module-level definitions have been analyzed.
|
||||
#[derive(Default)]
|
||||
pub struct Deferred<'a> {
|
||||
pub definitions: Vec<(Definition<'a>, Visibility, Context<'a>)>,
|
||||
pub string_type_definitions: Vec<(Range, &'a str, AnnotationContext, Context<'a>)>,
|
||||
pub type_definitions: Vec<(&'a Expr, AnnotationContext, Context<'a>)>,
|
||||
pub functions: Vec<(&'a Stmt, Context<'a>, VisibleScope)>,
|
||||
pub lambdas: Vec<(&'a Expr, Context<'a>)>,
|
||||
pub for_loops: Vec<(&'a Stmt, Context<'a>)>,
|
||||
pub assignments: Vec<Context<'a>>,
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,8 @@
|
||||
use std::path::Path;
|
||||
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::flake8_no_pep420::rules::implicit_namespace_package;
|
||||
use crate::rules::pep8_naming::rules::invalid_module_name;
|
||||
use crate::settings::Settings;
|
||||
|
||||
@@ -4,13 +4,15 @@ use std::path::Path;
|
||||
|
||||
use rustpython_parser::ast::Suite;
|
||||
|
||||
use crate::ast::visitor::Visitor;
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
|
||||
use ruff_python_ast::visitor::Visitor;
|
||||
|
||||
use crate::directives::IsortDirectives;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::isort;
|
||||
use crate::rules::isort::track::{Block, ImportTracker};
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::{Indexer, Locator, Stylist};
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn check_imports(
|
||||
|
||||
@@ -5,17 +5,19 @@ use itertools::Itertools;
|
||||
use rustpython_parser::ast::Location;
|
||||
use rustpython_parser::lexer::LexResult;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::source_code::{Locator, Stylist};
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
use crate::registry::{AsRule, Rule};
|
||||
use crate::rules::pycodestyle::logical_lines::{iter_logical_lines, TokenFlags};
|
||||
use crate::rules::pycodestyle::rules::{
|
||||
extraneous_whitespace, indentation, missing_whitespace_after_keyword,
|
||||
extraneous_whitespace, indentation, missing_whitespace, missing_whitespace_after_keyword,
|
||||
missing_whitespace_around_operator, space_around_operator, whitespace_around_keywords,
|
||||
whitespace_around_named_parameter_equals, whitespace_before_comment,
|
||||
whitespace_before_parameters,
|
||||
};
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::{Locator, Stylist};
|
||||
|
||||
/// Return the amount of indentation, expanding tabs to the next multiple of 8.
|
||||
fn expand_indent(mut line: &str) -> usize {
|
||||
@@ -57,7 +59,7 @@ pub fn check_logical_lines(
|
||||
|
||||
// Extract the indentation level.
|
||||
let start_loc = line.mapping[0].1;
|
||||
let start_line = locator.slice(&Range::new(Location::new(start_loc.row(), 0), start_loc));
|
||||
let start_line = locator.slice(Range::new(Location::new(start_loc.row(), 0), start_loc));
|
||||
let indent_level = expand_indent(start_line);
|
||||
let indent_size = 4;
|
||||
|
||||
@@ -162,6 +164,18 @@ pub fn check_logical_lines(
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "logical_lines")]
|
||||
let should_fix = autofix.into() && settings.rules.should_fix(&Rule::MissingWhitespace);
|
||||
|
||||
#[cfg(not(feature = "logical_lines"))]
|
||||
let should_fix = false;
|
||||
|
||||
for diagnostic in missing_whitespace(&line.text, start_loc.row(), should_fix) {
|
||||
if settings.rules.enabled(diagnostic.kind.rule()) {
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if line.flags.contains(TokenFlags::BRACKET) {
|
||||
@@ -213,8 +227,9 @@ mod tests {
|
||||
use rustpython_parser::lexer::LexResult;
|
||||
use rustpython_parser::{lexer, Mode};
|
||||
|
||||
use ruff_python_ast::source_code::Locator;
|
||||
|
||||
use crate::checkers::logical_lines::iter_logical_lines;
|
||||
use crate::source_code::Locator;
|
||||
|
||||
#[test]
|
||||
fn split_logical_lines() {
|
||||
@@ -291,7 +306,7 @@ f()"#;
|
||||
.into_iter()
|
||||
.map(|line| line.text)
|
||||
.collect();
|
||||
let expected = vec!["def f():", "\"xxx\"", "", "x = 1", "f()"];
|
||||
let expected = vec!["def f():", "\"xxxxxxxxxxxxxxxxxxxx\"", "", "x = 1", "f()"];
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,12 +4,14 @@ use log::warn;
|
||||
use nohash_hasher::IntMap;
|
||||
use rustpython_parser::ast::Location;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use ruff_diagnostics::{Diagnostic, Fix};
|
||||
use ruff_python_ast::newlines::StrExt;
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
use crate::codes::NoqaCode;
|
||||
use crate::fix::Fix;
|
||||
use crate::noqa;
|
||||
use crate::noqa::{extract_file_exemption, Directive, Exemption};
|
||||
use crate::registry::{Diagnostic, DiagnosticKind, Rule};
|
||||
use crate::registry::{AsRule, Rule};
|
||||
use crate::rule_redirects::get_redirect_target;
|
||||
use crate::rules::ruff::rules::{UnusedCodes, UnusedNOQA};
|
||||
use crate::settings::{flags, Settings};
|
||||
@@ -21,7 +23,7 @@ pub fn check_noqa(
|
||||
noqa_line_for: &IntMap<usize, usize>,
|
||||
settings: &Settings,
|
||||
autofix: flags::Autofix,
|
||||
) {
|
||||
) -> Vec<usize> {
|
||||
let enforce_noqa = settings.rules.enabled(&Rule::UnusedNOQA);
|
||||
|
||||
// Whether the file is exempted from all checks.
|
||||
@@ -37,7 +39,7 @@ pub fn check_noqa(
|
||||
// Indices of diagnostics that were ignored by a `noqa` directive.
|
||||
let mut ignored_diagnostics = vec![];
|
||||
|
||||
let lines: Vec<&str> = contents.lines().collect();
|
||||
let lines: Vec<&str> = contents.universal_newlines().collect();
|
||||
for lineno in commented_lines {
|
||||
match extract_file_exemption(lines[lineno - 1]) {
|
||||
Exemption::All => {
|
||||
@@ -65,7 +67,7 @@ pub fn check_noqa(
|
||||
|
||||
// Remove any ignored diagnostics.
|
||||
for (index, diagnostic) in diagnostics.iter().enumerate() {
|
||||
if matches!(diagnostic.kind, DiagnosticKind::BlanketNOQA(..)) {
|
||||
if matches!(diagnostic.kind.rule(), Rule::BlanketNOQA) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -96,7 +98,7 @@ pub fn check_noqa(
|
||||
ignored_diagnostics.push(index);
|
||||
continue;
|
||||
}
|
||||
(Directive::Codes(.., codes), matches) => {
|
||||
(Directive::Codes(.., codes, _), matches) => {
|
||||
if noqa::includes(diagnostic.kind.rule(), codes) {
|
||||
matches.push(diagnostic.kind.rule().noqa_code());
|
||||
ignored_diagnostics.push(index);
|
||||
@@ -123,7 +125,7 @@ pub fn check_noqa(
|
||||
ignored_diagnostics.push(index);
|
||||
continue;
|
||||
}
|
||||
(Directive::Codes(.., codes), matches) => {
|
||||
(Directive::Codes(.., codes, _), matches) => {
|
||||
if noqa::includes(diagnostic.kind.rule(), codes) {
|
||||
matches.push(diagnostic.kind.rule().noqa_code());
|
||||
ignored_diagnostics.push(index);
|
||||
@@ -139,7 +141,7 @@ pub fn check_noqa(
|
||||
if enforce_noqa {
|
||||
for (row, (directive, matches)) in noqa_directives {
|
||||
match directive {
|
||||
Directive::All(spaces, start_byte, end_byte) => {
|
||||
Directive::All(leading_spaces, start_byte, end_byte, trailing_spaces) => {
|
||||
if matches.is_empty() {
|
||||
let start = lines[row][..start_byte].chars().count();
|
||||
let end = start + lines[row][start_byte..end_byte].chars().count();
|
||||
@@ -149,15 +151,27 @@ pub fn check_noqa(
|
||||
Range::new(Location::new(row + 1, start), Location::new(row + 1, end)),
|
||||
);
|
||||
if autofix.into() && settings.rules.should_fix(diagnostic.kind.rule()) {
|
||||
diagnostic.amend(Fix::deletion(
|
||||
Location::new(row + 1, start - spaces),
|
||||
Location::new(row + 1, lines[row].chars().count()),
|
||||
));
|
||||
if start - leading_spaces == 0 && end == lines[row].chars().count() {
|
||||
diagnostic.amend(Fix::deletion(
|
||||
Location::new(row + 1, 0),
|
||||
Location::new(row + 2, 0),
|
||||
));
|
||||
} else if end == lines[row].chars().count() {
|
||||
diagnostic.amend(Fix::deletion(
|
||||
Location::new(row + 1, start - leading_spaces),
|
||||
Location::new(row + 1, end + trailing_spaces),
|
||||
));
|
||||
} else {
|
||||
diagnostic.amend(Fix::deletion(
|
||||
Location::new(row + 1, start),
|
||||
Location::new(row + 1, end + trailing_spaces),
|
||||
));
|
||||
}
|
||||
}
|
||||
diagnostics.push(diagnostic);
|
||||
}
|
||||
}
|
||||
Directive::Codes(spaces, start_byte, end_byte, codes) => {
|
||||
Directive::Codes(leading_spaces, start_byte, end_byte, codes, trailing_spaces) => {
|
||||
let mut disabled_codes = vec![];
|
||||
let mut unknown_codes = vec![];
|
||||
let mut unmatched_codes = vec![];
|
||||
@@ -217,15 +231,28 @@ pub fn check_noqa(
|
||||
);
|
||||
if autofix.into() && settings.rules.should_fix(diagnostic.kind.rule()) {
|
||||
if valid_codes.is_empty() {
|
||||
diagnostic.amend(Fix::deletion(
|
||||
Location::new(row + 1, start - spaces),
|
||||
Location::new(row + 1, lines[row].chars().count()),
|
||||
));
|
||||
if start - leading_spaces == 0 && end == lines[row].chars().count()
|
||||
{
|
||||
diagnostic.amend(Fix::deletion(
|
||||
Location::new(row + 1, 0),
|
||||
Location::new(row + 2, 0),
|
||||
));
|
||||
} else if end == lines[row].chars().count() {
|
||||
diagnostic.amend(Fix::deletion(
|
||||
Location::new(row + 1, start - leading_spaces),
|
||||
Location::new(row + 1, end + trailing_spaces),
|
||||
));
|
||||
} else {
|
||||
diagnostic.amend(Fix::deletion(
|
||||
Location::new(row + 1, start),
|
||||
Location::new(row + 1, end + trailing_spaces),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
diagnostic.amend(Fix::replacement(
|
||||
format!("# noqa: {}", valid_codes.join(", ")),
|
||||
Location::new(row + 1, start),
|
||||
Location::new(row + 1, lines[row].chars().count()),
|
||||
Location::new(row + 1, end),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -238,7 +265,5 @@ pub fn check_noqa(
|
||||
}
|
||||
|
||||
ignored_diagnostics.sort_unstable();
|
||||
for index in ignored_diagnostics.iter().rev() {
|
||||
diagnostics.swap_remove(*index);
|
||||
}
|
||||
ignored_diagnostics
|
||||
}
|
||||
|
||||
@@ -2,7 +2,11 @@
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::newlines::StrExt;
|
||||
use ruff_python_ast::source_code::{Locator, Stylist};
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::rules::flake8_executable::helpers::{extract_shebang, ShebangDirective};
|
||||
use crate::rules::flake8_executable::rules::{
|
||||
shebang_missing, shebang_newline, shebang_not_executable, shebang_python, shebang_whitespace,
|
||||
@@ -15,12 +19,11 @@ use crate::rules::pygrep_hooks::rules::{blanket_noqa, blanket_type_ignore};
|
||||
use crate::rules::pylint;
|
||||
use crate::rules::pyupgrade::rules::unnecessary_coding_comment;
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::Stylist;
|
||||
|
||||
pub fn check_physical_lines(
|
||||
path: &Path,
|
||||
locator: &Locator,
|
||||
stylist: &Stylist,
|
||||
contents: &str,
|
||||
commented_lines: &[usize],
|
||||
doc_lines: &[usize],
|
||||
settings: &Settings,
|
||||
@@ -54,7 +57,7 @@ pub fn check_physical_lines(
|
||||
|
||||
let mut commented_lines_iter = commented_lines.iter().peekable();
|
||||
let mut doc_lines_iter = doc_lines.iter().peekable();
|
||||
for (index, line) in contents.lines().enumerate() {
|
||||
for (index, line) in locator.contents().universal_newlines().enumerate() {
|
||||
while commented_lines_iter
|
||||
.next_if(|lineno| &(index + 1) == *lineno)
|
||||
.is_some()
|
||||
@@ -160,8 +163,8 @@ pub fn check_physical_lines(
|
||||
|
||||
if enforce_no_newline_at_end_of_file {
|
||||
if let Some(diagnostic) = no_newline_at_end_of_file(
|
||||
locator,
|
||||
stylist,
|
||||
contents,
|
||||
autofix.into() && settings.rules.should_fix(&Rule::NoNewLineAtEndOfFile),
|
||||
) {
|
||||
diagnostics.push(diagnostic);
|
||||
@@ -179,13 +182,14 @@ pub fn check_physical_lines(
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use std::path::Path;
|
||||
|
||||
use super::check_physical_lines;
|
||||
use ruff_python_ast::source_code::{Locator, Stylist};
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::{Locator, Stylist};
|
||||
|
||||
use super::check_physical_lines;
|
||||
|
||||
#[test]
|
||||
fn e501_non_ascii_char() {
|
||||
@@ -196,8 +200,8 @@ mod tests {
|
||||
let check_with_max_line_length = |line_length: usize| {
|
||||
check_physical_lines(
|
||||
Path::new("foo.py"),
|
||||
&locator,
|
||||
&stylist,
|
||||
line,
|
||||
&[],
|
||||
&[],
|
||||
&Settings {
|
||||
|
||||
@@ -4,21 +4,22 @@ use rustpython_parser::lexer::LexResult;
|
||||
use rustpython_parser::Tok;
|
||||
|
||||
use crate::lex::docstring_detection::StateMachine;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::registry::{AsRule, Rule};
|
||||
use crate::rules::ruff::rules::Context;
|
||||
use crate::rules::{
|
||||
eradicate, flake8_commas, flake8_implicit_str_concat, flake8_pyi, flake8_quotes, pycodestyle,
|
||||
pyupgrade, ruff,
|
||||
};
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::Locator;
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::source_code::Locator;
|
||||
|
||||
pub fn check_tokens(
|
||||
locator: &Locator,
|
||||
tokens: &[LexResult],
|
||||
settings: &Settings,
|
||||
autofix: flags::Autofix,
|
||||
is_interface_definition: bool,
|
||||
is_stub: bool,
|
||||
) -> Vec<Diagnostic> {
|
||||
let mut diagnostics: Vec<Diagnostic> = vec![];
|
||||
|
||||
@@ -164,7 +165,7 @@ pub fn check_tokens(
|
||||
}
|
||||
|
||||
// PYI033
|
||||
if enforce_type_comment_in_stub && is_interface_definition {
|
||||
if enforce_type_comment_in_stub && is_stub {
|
||||
diagnostics.extend(flake8_pyi::rules::type_comment_in_stub(tokens));
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,23 @@
|
||||
use crate::registry::{Linter, Rule};
|
||||
|
||||
#[derive(PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub struct NoqaCode(&'static str, &'static str);
|
||||
|
||||
impl std::fmt::Display for NoqaCode {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
|
||||
write!(f, "{}{}", self.0, self.1)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<&str> for NoqaCode {
|
||||
fn eq(&self, other: &&str) -> bool {
|
||||
match other.strip_prefix(self.0) {
|
||||
Some(suffix) => suffix == self.1,
|
||||
None => false,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[ruff_macros::map_codes]
|
||||
pub fn code_to_rule(linter: Linter, code: &str) -> Option<Rule> {
|
||||
#[allow(clippy::enum_glob_use)]
|
||||
@@ -47,6 +65,8 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<Rule> {
|
||||
#[cfg(feature = "logical_lines")]
|
||||
(Pycodestyle, "E228") => Rule::MissingWhitespaceAroundModuloOperator,
|
||||
#[cfg(feature = "logical_lines")]
|
||||
(Pycodestyle, "E231") => Rule::MissingWhitespace,
|
||||
#[cfg(feature = "logical_lines")]
|
||||
(Pycodestyle, "E251") => Rule::UnexpectedSpacesAroundKeywordParameterEquals,
|
||||
#[cfg(feature = "logical_lines")]
|
||||
(Pycodestyle, "E252") => Rule::MissingWhitespaceAroundParameterEquals,
|
||||
@@ -141,34 +161,37 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<Rule> {
|
||||
(Pyflakes, "901") => Rule::RaiseNotImplemented,
|
||||
|
||||
// pylint
|
||||
(Pylint, "C0414") => Rule::UselessImportAlias,
|
||||
(Pylint, "C1901") => Rule::CompareToEmptyString,
|
||||
(Pylint, "C3002") => Rule::UnnecessaryDirectLambdaCall,
|
||||
(Pylint, "E0100") => Rule::YieldInInit,
|
||||
(Pylint, "E0101") => Rule::ReturnInInit,
|
||||
(Pylint, "E0117") => Rule::NonlocalWithoutBinding,
|
||||
(Pylint, "E0118") => Rule::UsedPriorGlobalDeclaration,
|
||||
(Pylint, "E0604") => Rule::InvalidAllObject,
|
||||
(Pylint, "E0605") => Rule::InvalidAllFormat,
|
||||
(Pylint, "W1508") => Rule::InvalidEnvvarDefault,
|
||||
(Pylint, "E1142") => Rule::AwaitOutsideAsync,
|
||||
(Pylint, "E1205") => Rule::LoggingTooManyArgs,
|
||||
(Pylint, "E1206") => Rule::LoggingTooFewArgs,
|
||||
(Pylint, "E1307") => Rule::BadStringFormatType,
|
||||
(Pylint, "E2502") => Rule::BidirectionalUnicode,
|
||||
(Pylint, "E1310") => Rule::BadStrStripCall,
|
||||
(Pylint, "C0414") => Rule::UselessImportAlias,
|
||||
(Pylint, "C3002") => Rule::UnnecessaryDirectLambdaCall,
|
||||
(Pylint, "E0117") => Rule::NonlocalWithoutBinding,
|
||||
(Pylint, "E0118") => Rule::UsedPriorGlobalDeclaration,
|
||||
(Pylint, "E1142") => Rule::AwaitOutsideAsync,
|
||||
(Pylint, "E1507") => Rule::InvalidEnvvarValue,
|
||||
(Pylint, "E2502") => Rule::BidirectionalUnicode,
|
||||
(Pylint, "R0133") => Rule::ComparisonOfConstant,
|
||||
(Pylint, "R0206") => Rule::PropertyWithParameters,
|
||||
(Pylint, "R0402") => Rule::ConsiderUsingFromImport,
|
||||
(Pylint, "R0133") => Rule::ComparisonOfConstant,
|
||||
(Pylint, "R0911") => Rule::TooManyReturnStatements,
|
||||
(Pylint, "R0912") => Rule::TooManyBranches,
|
||||
(Pylint, "R0913") => Rule::TooManyArguments,
|
||||
(Pylint, "R0915") => Rule::TooManyStatements,
|
||||
(Pylint, "R1701") => Rule::ConsiderMergingIsinstance,
|
||||
(Pylint, "R1722") => Rule::ConsiderUsingSysExit,
|
||||
(Pylint, "R5501") => Rule::CollapsibleElseIf,
|
||||
(Pylint, "R2004") => Rule::MagicValueComparison,
|
||||
(Pylint, "R5501") => Rule::CollapsibleElseIf,
|
||||
(Pylint, "W0120") => Rule::UselessElseOnLoop,
|
||||
(Pylint, "W0602") => Rule::GlobalVariableNotAssigned,
|
||||
(Pylint, "W0603") => Rule::GlobalStatement,
|
||||
(Pylint, "R0911") => Rule::TooManyReturnStatements,
|
||||
(Pylint, "R0913") => Rule::TooManyArguments,
|
||||
(Pylint, "R0912") => Rule::TooManyBranches,
|
||||
(Pylint, "R0915") => Rule::TooManyStatements,
|
||||
(Pylint, "W2901") => Rule::RedefinedLoopName,
|
||||
|
||||
// flake8-builtins
|
||||
@@ -204,6 +227,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<Rule> {
|
||||
(Flake8Bugbear, "026") => Rule::StarArgUnpackingAfterKeywordArg,
|
||||
(Flake8Bugbear, "027") => Rule::EmptyMethodWithoutAbstractDecorator,
|
||||
(Flake8Bugbear, "029") => Rule::ExceptWithEmptyTuple,
|
||||
(Flake8Bugbear, "030") => Rule::ExceptWithNonExceptionClasses,
|
||||
(Flake8Bugbear, "032") => Rule::UnintentionalTypeAnnotation,
|
||||
(Flake8Bugbear, "904") => Rule::RaiseWithoutFromInsideExcept,
|
||||
(Flake8Bugbear, "905") => Rule::ZipWithoutExplicitStrict,
|
||||
@@ -351,7 +375,7 @@ pub fn code_to_rule(linter: Linter, code: &str) -> Option<Rule> {
|
||||
(Pyupgrade, "032") => Rule::FString,
|
||||
(Pyupgrade, "033") => Rule::FunctoolsCache,
|
||||
(Pyupgrade, "034") => Rule::ExtraneousParentheses,
|
||||
(Pyupgrade, "035") => Rule::ImportReplacements,
|
||||
(Pyupgrade, "035") => Rule::DeprecatedImport,
|
||||
(Pyupgrade, "036") => Rule::OutdatedVersionBlock,
|
||||
(Pyupgrade, "037") => Rule::QuotedAnnotation,
|
||||
(Pyupgrade, "038") => Rule::IsinstanceWithTuple,
|
||||
|
||||
@@ -107,15 +107,21 @@ pub fn extract_isort_directives(lxr: &[LexResult]) -> IsortDirectives {
|
||||
// omit a space after the colon. The remaining action comments are
|
||||
// required to include the space, and must appear on their own lines.
|
||||
let comment_text = comment_text.trim_end();
|
||||
if comment_text == "# isort: split" {
|
||||
if matches!(comment_text, "# isort: split" | "# ruff: isort: split") {
|
||||
splits.push(start.row());
|
||||
} else if comment_text == "# isort: skip_file" || comment_text == "# isort:skip_file" {
|
||||
} else if matches!(
|
||||
comment_text,
|
||||
"# isort: skip_file"
|
||||
| "# isort:skip_file"
|
||||
| "# ruff: isort: skip_file"
|
||||
| "# ruff: isort:skip_file"
|
||||
) {
|
||||
return IsortDirectives {
|
||||
skip_file: true,
|
||||
..IsortDirectives::default()
|
||||
};
|
||||
} else if off.is_some() {
|
||||
if comment_text == "# isort: on" {
|
||||
if comment_text == "# isort: on" || comment_text == "# ruff: isort: on" {
|
||||
if let Some(start) = off {
|
||||
for row in start.row() + 1..=end.row() {
|
||||
exclusions.insert(row);
|
||||
@@ -126,7 +132,7 @@ pub fn extract_isort_directives(lxr: &[LexResult]) -> IsortDirectives {
|
||||
} else {
|
||||
if comment_text.contains("isort: skip") || comment_text.contains("isort:skip") {
|
||||
exclusions.insert(start.row());
|
||||
} else if comment_text == "# isort: off" {
|
||||
} else if comment_text == "# isort: off" || comment_text == "# ruff: isort: off" {
|
||||
off = Some(start);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@ use rustpython_parser::ast::{Constant, ExprKind, Stmt, StmtKind, Suite};
|
||||
use rustpython_parser::lexer::LexResult;
|
||||
use rustpython_parser::Tok;
|
||||
|
||||
use crate::ast::visitor;
|
||||
use crate::ast::visitor::Visitor;
|
||||
use ruff_python_ast::visitor;
|
||||
use ruff_python_ast::visitor::Visitor;
|
||||
|
||||
/// Extract doc lines (standalone comments) from a token sequence.
|
||||
pub fn doc_lines_from_tokens(lxr: &[LexResult]) -> DocLines {
|
||||
|
||||
@@ -1,3 +1,6 @@
|
||||
use ruff_python_ast::visibility::{
|
||||
class_visibility, function_visibility, method_visibility, Modifier, Visibility, VisibleScope,
|
||||
};
|
||||
use rustpython_parser::ast::{Expr, Stmt};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -30,3 +33,36 @@ pub enum Documentable {
|
||||
Class,
|
||||
Function,
|
||||
}
|
||||
|
||||
pub fn transition_scope(scope: &VisibleScope, stmt: &Stmt, kind: &Documentable) -> VisibleScope {
|
||||
match kind {
|
||||
Documentable::Function => VisibleScope {
|
||||
modifier: Modifier::Function,
|
||||
visibility: match scope {
|
||||
VisibleScope {
|
||||
modifier: Modifier::Module,
|
||||
visibility: Visibility::Public,
|
||||
} => function_visibility(stmt),
|
||||
VisibleScope {
|
||||
modifier: Modifier::Class,
|
||||
visibility: Visibility::Public,
|
||||
} => method_visibility(stmt),
|
||||
_ => Visibility::Private,
|
||||
},
|
||||
},
|
||||
Documentable::Class => VisibleScope {
|
||||
modifier: Modifier::Class,
|
||||
visibility: match scope {
|
||||
VisibleScope {
|
||||
modifier: Modifier::Module,
|
||||
visibility: Visibility::Public,
|
||||
} => class_visibility(stmt),
|
||||
VisibleScope {
|
||||
modifier: Modifier::Class,
|
||||
visibility: Visibility::Public,
|
||||
} => class_visibility(stmt),
|
||||
_ => Visibility::Private,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use crate::docstrings::definition::{Definition, DefinitionKind, Documentable};
|
||||
use crate::visibility::{Modifier, VisibleScope};
|
||||
use ruff_python_ast::visibility::{Modifier, VisibleScope};
|
||||
|
||||
/// Extract a docstring from a function or class body.
|
||||
pub fn docstring_from(suite: &[Stmt]) -> Option<&Expr> {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use strum_macros::EnumIter;
|
||||
|
||||
use crate::ast::whitespace;
|
||||
use crate::docstrings::styles::SectionStyle;
|
||||
use ruff_python_ast::whitespace;
|
||||
|
||||
#[derive(EnumIter, PartialEq, Eq, Debug, Clone, Copy)]
|
||||
pub enum SectionKind {
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
use rustpython_parser::ast::Location;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, Copy, Clone, Hash)]
|
||||
pub enum FixMode {
|
||||
Generate,
|
||||
@@ -18,40 +15,3 @@ impl From<bool> for FixMode {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)]
|
||||
pub struct Fix {
|
||||
pub content: String,
|
||||
pub location: Location,
|
||||
pub end_location: Location,
|
||||
}
|
||||
|
||||
impl Fix {
|
||||
pub const fn deletion(start: Location, end: Location) -> Self {
|
||||
Self {
|
||||
content: String::new(),
|
||||
location: start,
|
||||
end_location: end,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn replacement(content: String, start: Location, end: Location) -> Self {
|
||||
debug_assert!(!content.is_empty(), "Prefer `Fix::deletion`");
|
||||
|
||||
Self {
|
||||
content,
|
||||
location: start,
|
||||
end_location: end,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insertion(content: String, at: Location) -> Self {
|
||||
debug_assert!(!content.is_empty(), "Insert content is empty");
|
||||
|
||||
Self {
|
||||
content,
|
||||
location: at,
|
||||
end_location: at,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,7 @@ use crate::rules::{
|
||||
};
|
||||
use crate::settings::options::Options;
|
||||
use crate::settings::pyproject::Pyproject;
|
||||
use crate::settings::types::PythonVersion;
|
||||
use crate::warn_user;
|
||||
|
||||
const DEFAULT_SELECTORS: &[RuleSelector] = &[
|
||||
@@ -424,6 +425,15 @@ pub fn convert(
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(project) = &external_config.project {
|
||||
if let Some(requires_python) = &project.requires_python {
|
||||
if options.target_version.is_none() {
|
||||
options.target_version =
|
||||
PythonVersion::get_minimum_supported_version(requires_python);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Create the pyproject.toml.
|
||||
Ok(Pyproject::new(options))
|
||||
}
|
||||
@@ -439,13 +449,17 @@ fn resolve_select(plugins: &[Plugin]) -> HashSet<RuleSelector> {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::collections::HashMap;
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
use itertools::Itertools;
|
||||
use pep440_rs::VersionSpecifiers;
|
||||
use pretty_assertions::assert_eq;
|
||||
|
||||
use super::super::plugin::Plugin;
|
||||
use super::convert;
|
||||
use crate::flake8_to_ruff::converter::DEFAULT_SELECTORS;
|
||||
use crate::flake8_to_ruff::pep621::Project;
|
||||
use crate::flake8_to_ruff::ExternalConfig;
|
||||
use crate::registry::Linter;
|
||||
use crate::rule_selector::RuleSelector;
|
||||
@@ -453,6 +467,7 @@ mod tests {
|
||||
use crate::rules::{flake8_quotes, pydocstyle};
|
||||
use crate::settings::options::Options;
|
||||
use crate::settings::pyproject::Pyproject;
|
||||
use crate::settings::types::PythonVersion;
|
||||
|
||||
fn default_options(plugins: impl IntoIterator<Item = RuleSelector>) -> Options {
|
||||
Options {
|
||||
@@ -609,4 +624,25 @@ mod tests {
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn it_converts_project_requires_python() -> Result<()> {
|
||||
let actual = convert(
|
||||
&HashMap::from([("flake8".to_string(), HashMap::default())]),
|
||||
&ExternalConfig {
|
||||
project: Some(&Project {
|
||||
requires_python: Some(VersionSpecifiers::from_str(">=3.8.16, <3.11")?),
|
||||
}),
|
||||
..ExternalConfig::default()
|
||||
},
|
||||
Some(vec![]),
|
||||
)?;
|
||||
let expected = Pyproject::new(Options {
|
||||
target_version: Some(PythonVersion::Py38),
|
||||
..default_options([])
|
||||
});
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
use super::black::Black;
|
||||
use super::isort::Isort;
|
||||
use super::pep621::Project;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct ExternalConfig<'a> {
|
||||
pub black: Option<&'a Black>,
|
||||
pub isort: Option<&'a Isort>,
|
||||
pub project: Option<&'a Project>,
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ mod converter;
|
||||
mod external_config;
|
||||
mod isort;
|
||||
mod parser;
|
||||
pub mod pep621;
|
||||
mod plugin;
|
||||
mod pyproject;
|
||||
|
||||
|
||||
10
crates/ruff/src/flake8_to_ruff/pep621.rs
Normal file
10
crates/ruff/src/flake8_to_ruff/pep621.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
//! Extract PEP 621 configuration settings from a pyproject.toml.
|
||||
|
||||
use pep440_rs::VersionSpecifiers;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||
pub struct Project {
|
||||
#[serde(alias = "requires-python", alias = "requires_python")]
|
||||
pub requires_python: Option<VersionSpecifiers>,
|
||||
}
|
||||
@@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use super::black::Black;
|
||||
use super::isort::Isort;
|
||||
use super::pep621::Project;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Tools {
|
||||
@@ -15,6 +16,7 @@ pub struct Tools {
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Pyproject {
|
||||
pub tool: Option<Tools>,
|
||||
pub project: Option<Project>,
|
||||
}
|
||||
|
||||
pub fn parse<P: AsRef<Path>>(path: P) -> Result<Pyproject> {
|
||||
|
||||
@@ -74,10 +74,20 @@ pub fn normalize_path_to<P: AsRef<Path>, R: AsRef<Path>>(path: P, project_root:
|
||||
}
|
||||
|
||||
/// Convert an absolute path to be relative to the current working directory.
|
||||
pub fn relativize_path(path: impl AsRef<Path>) -> String {
|
||||
pub fn relativize_path<P: AsRef<Path>>(path: P) -> String {
|
||||
let path = path.as_ref();
|
||||
if let Ok(path) = path.strip_prefix(&*path_dedot::CWD) {
|
||||
return format!("{}", path.display());
|
||||
}
|
||||
format!("{}", path.display())
|
||||
}
|
||||
|
||||
/// Convert an absolute path to be relative to the specified project root.
|
||||
pub fn relativize_path_to<P: AsRef<Path>, R: AsRef<Path>>(path: P, project_root: R) -> String {
|
||||
format!(
|
||||
"{}",
|
||||
pathdiff::diff_paths(&path, project_root)
|
||||
.expect("Could not diff paths")
|
||||
.display()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,18 +5,16 @@
|
||||
//!
|
||||
//! [Ruff]: https://github.com/charliermarsh/ruff
|
||||
|
||||
pub use ast::types::Range;
|
||||
use cfg_if::cfg_if;
|
||||
pub use ruff_python_ast::source_code::round_trip;
|
||||
pub use ruff_python_ast::types::Range;
|
||||
pub use rule_selector::RuleSelector;
|
||||
pub use rules::pycodestyle::rules::IOError;
|
||||
pub use violation::{AutofixKind, Availability as AutofixAvailability};
|
||||
|
||||
mod ast;
|
||||
mod autofix;
|
||||
mod checkers;
|
||||
mod codes;
|
||||
mod cst;
|
||||
mod directives;
|
||||
pub mod directives;
|
||||
mod doc_lines;
|
||||
mod docstrings;
|
||||
pub mod fix;
|
||||
@@ -27,24 +25,13 @@ pub mod linter;
|
||||
pub mod logging;
|
||||
pub mod message;
|
||||
mod noqa;
|
||||
pub mod packaging;
|
||||
pub mod registry;
|
||||
pub mod resolver;
|
||||
mod rule_redirects;
|
||||
mod rule_selector;
|
||||
mod rules;
|
||||
pub mod rules;
|
||||
pub mod settings;
|
||||
pub mod source_code;
|
||||
mod violation;
|
||||
mod visibility;
|
||||
|
||||
cfg_if! {
|
||||
if #[cfg(target_family = "wasm")] {
|
||||
mod lib_wasm;
|
||||
pub use lib_wasm::check;
|
||||
} else {
|
||||
pub mod packaging;
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
||||
@@ -8,6 +8,10 @@ use rustc_hash::FxHashMap;
|
||||
use rustpython_parser::lexer::LexResult;
|
||||
use rustpython_parser::ParseError;
|
||||
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::source_code::{Indexer, Locator, Stylist};
|
||||
use ruff_python_stdlib::path::is_python_stub_file;
|
||||
|
||||
use crate::autofix::fix_file;
|
||||
use crate::checkers::ast::check_ast;
|
||||
use crate::checkers::filesystem::check_file_path;
|
||||
@@ -20,11 +24,9 @@ use crate::directives::Directives;
|
||||
use crate::doc_lines::{doc_lines_from_ast, doc_lines_from_tokens};
|
||||
use crate::message::{Message, Source};
|
||||
use crate::noqa::{add_noqa, rule_is_ignored};
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::resolver::is_interface_definition_path;
|
||||
use crate::registry::{AsRule, Rule};
|
||||
use crate::rules::pycodestyle;
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::{Indexer, Locator, Stylist};
|
||||
use crate::{directives, fs};
|
||||
|
||||
const CARGO_PKG_NAME: &str = env!("CARGO_PKG_NAME");
|
||||
@@ -84,14 +86,8 @@ pub fn check_path(
|
||||
.iter_enabled()
|
||||
.any(|rule_code| rule_code.lint_source().is_tokens())
|
||||
{
|
||||
let is_interface_definition = is_interface_definition_path(path);
|
||||
diagnostics.extend(check_tokens(
|
||||
locator,
|
||||
&tokens,
|
||||
settings,
|
||||
autofix,
|
||||
is_interface_definition,
|
||||
));
|
||||
let is_stub = is_python_stub_file(path);
|
||||
diagnostics.extend(check_tokens(locator, &tokens, settings, autofix, is_stub));
|
||||
}
|
||||
|
||||
// Run the filesystem-based rules.
|
||||
@@ -195,8 +191,8 @@ pub fn check_path(
|
||||
{
|
||||
diagnostics.extend(check_physical_lines(
|
||||
path,
|
||||
locator,
|
||||
stylist,
|
||||
contents,
|
||||
indexer.commented_lines(),
|
||||
&doc_lines,
|
||||
settings,
|
||||
@@ -208,7 +204,7 @@ pub fn check_path(
|
||||
if !diagnostics.is_empty() && !settings.per_file_ignores.is_empty() {
|
||||
let ignores = fs::ignores_from_path(path, &settings.per_file_ignores);
|
||||
if !ignores.is_empty() {
|
||||
diagnostics.retain(|diagnostic| !ignores.contains(&diagnostic.kind.rule()));
|
||||
diagnostics.retain(|diagnostic| !ignores.contains(diagnostic.kind.rule()));
|
||||
}
|
||||
};
|
||||
|
||||
@@ -219,7 +215,7 @@ pub fn check_path(
|
||||
.iter_enabled()
|
||||
.any(|rule_code| rule_code.lint_source().is_noqa())
|
||||
{
|
||||
check_noqa(
|
||||
let ignored = check_noqa(
|
||||
&mut diagnostics,
|
||||
contents,
|
||||
indexer.commented_lines(),
|
||||
@@ -227,6 +223,11 @@ pub fn check_path(
|
||||
settings,
|
||||
error.as_ref().map_or(autofix, |_| flags::Autofix::Disabled),
|
||||
);
|
||||
if noqa.into() {
|
||||
for index in ignored.iter().rev() {
|
||||
diagnostics.swap_remove(*index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LinterResult::new(diagnostics, error)
|
||||
|
||||
@@ -1,8 +1,31 @@
|
||||
use std::sync::Mutex;
|
||||
|
||||
use anyhow::Result;
|
||||
use colored::Colorize;
|
||||
use fern;
|
||||
use log::Level;
|
||||
use once_cell::sync::Lazy;
|
||||
|
||||
pub(crate) static WARNINGS: Lazy<Mutex<Vec<&'static str>>> = Lazy::new(Mutex::default);
|
||||
|
||||
/// Warn a user once, with uniqueness determined by the given ID.
|
||||
#[macro_export]
|
||||
macro_rules! warn_user_once_by_id {
|
||||
($id:expr, $($arg:tt)*) => {
|
||||
use colored::Colorize;
|
||||
use log::warn;
|
||||
|
||||
if let Ok(mut states) = $crate::logging::WARNINGS.lock() {
|
||||
if !states.contains(&$id) {
|
||||
let message = format!("{}", format_args!($($arg)*));
|
||||
warn!("{}", message.bold());
|
||||
states.push($id);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/// Warn a user once, with uniqueness determined by the calling location itself.
|
||||
#[macro_export]
|
||||
macro_rules! warn_user_once {
|
||||
($($arg:tt)*) => {
|
||||
|
||||
@@ -3,10 +3,9 @@ use std::cmp::Ordering;
|
||||
pub use rustpython_parser::ast::Location;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::{Diagnostic, DiagnosticKind};
|
||||
use crate::source_code::Locator;
|
||||
use ruff_diagnostics::{Diagnostic, DiagnosticKind, Fix};
|
||||
use ruff_python_ast::source_code::Locator;
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Message {
|
||||
@@ -74,9 +73,9 @@ impl Source {
|
||||
} else {
|
||||
Location::new(diagnostic.end_location.row() + 1, 0)
|
||||
};
|
||||
let source = locator.slice(&Range::new(location, end_location));
|
||||
let source = locator.slice(Range::new(location, end_location));
|
||||
let num_chars_in_range = locator
|
||||
.slice(&Range::new(diagnostic.location, diagnostic.end_location))
|
||||
.slice(Range::new(diagnostic.location, diagnostic.end_location))
|
||||
.chars()
|
||||
.count();
|
||||
Source {
|
||||
|
||||
@@ -11,15 +11,18 @@ use regex::Regex;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_parser::ast::Location;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::newlines::StrExt;
|
||||
use ruff_python_ast::source_code::{LineEnding, Locator};
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
use crate::codes::NoqaCode;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::registry::{AsRule, Rule};
|
||||
use crate::rule_redirects::get_redirect_target;
|
||||
use crate::source_code::{LineEnding, Locator};
|
||||
|
||||
static NOQA_LINE_REGEX: Lazy<Regex> = Lazy::new(|| {
|
||||
Regex::new(
|
||||
r"(?P<spaces>\s*)(?P<noqa>(?i:# noqa)(?::\s?(?P<codes>([A-Z]+[0-9]+(?:[,\s]+)?)+))?)",
|
||||
r"(?P<leading_spaces>\s*)(?P<noqa>(?i:# noqa)(?::\s?(?P<codes>(?:[A-Z]+[0-9]+)(?:[,\s]+[A-Z]+[0-9]+)*))?)(?P<trailing_spaces>\s*)",
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
@@ -71,35 +74,42 @@ pub fn extract_file_exemption(line: &str) -> Exemption {
|
||||
#[derive(Debug)]
|
||||
pub enum Directive<'a> {
|
||||
None,
|
||||
All(usize, usize, usize),
|
||||
Codes(usize, usize, usize, Vec<&'a str>),
|
||||
All(usize, usize, usize, usize),
|
||||
Codes(usize, usize, usize, Vec<&'a str>, usize),
|
||||
}
|
||||
|
||||
/// Extract the noqa `Directive` from a line of Python source code.
|
||||
pub fn extract_noqa_directive(line: &str) -> Directive {
|
||||
match NOQA_LINE_REGEX.captures(line) {
|
||||
Some(caps) => match caps.name("spaces") {
|
||||
Some(spaces) => match caps.name("noqa") {
|
||||
Some(noqa) => match caps.name("codes") {
|
||||
Some(codes) => {
|
||||
let codes: Vec<&str> = SPLIT_COMMA_REGEX
|
||||
.split(codes.as_str().trim())
|
||||
.map(str::trim)
|
||||
.filter(|code| !code.is_empty())
|
||||
.collect();
|
||||
if codes.is_empty() {
|
||||
warn!("Expected rule codes on `noqa` directive: \"{line}\"");
|
||||
Some(caps) => match caps.name("leading_spaces") {
|
||||
Some(leading_spaces) => match caps.name("trailing_spaces") {
|
||||
Some(trailing_spaces) => match caps.name("noqa") {
|
||||
Some(noqa) => match caps.name("codes") {
|
||||
Some(codes) => {
|
||||
let codes: Vec<&str> = SPLIT_COMMA_REGEX
|
||||
.split(codes.as_str().trim())
|
||||
.map(str::trim)
|
||||
.filter(|code| !code.is_empty())
|
||||
.collect();
|
||||
if codes.is_empty() {
|
||||
warn!("Expected rule codes on `noqa` directive: \"{line}\"");
|
||||
}
|
||||
Directive::Codes(
|
||||
leading_spaces.as_str().chars().count(),
|
||||
noqa.start(),
|
||||
noqa.end(),
|
||||
codes,
|
||||
trailing_spaces.as_str().chars().count(),
|
||||
)
|
||||
}
|
||||
Directive::Codes(
|
||||
spaces.as_str().chars().count(),
|
||||
None => Directive::All(
|
||||
leading_spaces.as_str().chars().count(),
|
||||
noqa.start(),
|
||||
noqa.end(),
|
||||
codes,
|
||||
)
|
||||
}
|
||||
None => {
|
||||
Directive::All(spaces.as_str().chars().count(), noqa.start(), noqa.end())
|
||||
}
|
||||
trailing_spaces.as_str().chars().count(),
|
||||
),
|
||||
},
|
||||
None => Directive::None,
|
||||
},
|
||||
None => Directive::None,
|
||||
},
|
||||
@@ -126,14 +136,14 @@ pub fn rule_is_ignored(
|
||||
locator: &Locator,
|
||||
) -> bool {
|
||||
let noqa_lineno = noqa_line_for.get(&lineno).unwrap_or(&lineno);
|
||||
let line = locator.slice(&Range::new(
|
||||
let line = locator.slice(Range::new(
|
||||
Location::new(*noqa_lineno, 0),
|
||||
Location::new(noqa_lineno + 1, 0),
|
||||
));
|
||||
match extract_noqa_directive(line) {
|
||||
Directive::None => false,
|
||||
Directive::All(..) => true,
|
||||
Directive::Codes(.., codes) => includes(code, &codes),
|
||||
Directive::Codes(.., codes, _) => includes(code, &codes),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -172,7 +182,7 @@ fn add_noqa_inner(
|
||||
// Codes that are globally exempted (within the current file).
|
||||
let mut file_exemptions: Vec<NoqaCode> = vec![];
|
||||
|
||||
let lines: Vec<&str> = contents.lines().collect();
|
||||
let lines: Vec<&str> = contents.universal_newlines().collect();
|
||||
for lineno in commented_lines {
|
||||
match extract_file_exemption(lines[lineno - 1]) {
|
||||
Exemption::All => {
|
||||
@@ -214,7 +224,7 @@ fn add_noqa_inner(
|
||||
Directive::All(..) => {
|
||||
continue;
|
||||
}
|
||||
Directive::Codes(.., codes) => {
|
||||
Directive::Codes(.., codes, _) => {
|
||||
if includes(diagnostic.kind.rule(), &codes) {
|
||||
continue;
|
||||
}
|
||||
@@ -234,7 +244,7 @@ fn add_noqa_inner(
|
||||
Directive::All(..) => {
|
||||
continue;
|
||||
}
|
||||
Directive::Codes(.., codes) => {
|
||||
Directive::Codes(.., codes, _) => {
|
||||
if includes(diagnostic.kind.rule(), &codes) {
|
||||
continue;
|
||||
}
|
||||
@@ -254,7 +264,7 @@ fn add_noqa_inner(
|
||||
|
||||
let mut count: usize = 0;
|
||||
let mut output = String::new();
|
||||
for (lineno, line) in contents.lines().enumerate() {
|
||||
for (lineno, line) in lines.into_iter().enumerate() {
|
||||
match matches_by_line.get(&lineno) {
|
||||
None => {
|
||||
output.push_str(line);
|
||||
@@ -279,7 +289,7 @@ fn add_noqa_inner(
|
||||
output.push_str(line);
|
||||
output.push_str(line_ending);
|
||||
}
|
||||
Directive::Codes(_, start_byte, _, existing) => {
|
||||
Directive::Codes(_, start_byte, _, existing, _) => {
|
||||
// Reconstruct the line based on the preserved rule codes.
|
||||
// This enables us to tally the number of edits.
|
||||
let mut formatted = String::with_capacity(line.len());
|
||||
@@ -332,12 +342,13 @@ mod tests {
|
||||
use nohash_hasher::IntMap;
|
||||
use rustpython_parser::ast::Location;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::source_code::LineEnding;
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
use crate::noqa::{add_noqa_inner, NOQA_LINE_REGEX};
|
||||
use crate::registry::Diagnostic;
|
||||
use crate::rules::pycodestyle::rules::AmbiguousVariableName;
|
||||
use crate::rules::pyflakes;
|
||||
use crate::source_code::LineEnding;
|
||||
|
||||
#[test]
|
||||
fn regex() {
|
||||
|
||||
@@ -1,15 +1,12 @@
|
||||
//! Registry of [`Rule`] to [`DiagnosticKind`] mappings.
|
||||
//! Registry of all [`Rule`] implementations.
|
||||
|
||||
use ruff_macros::RuleNamespace;
|
||||
use rustpython_parser::ast::Location;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum_macros::{AsRefStr, EnumIter};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_macros::RuleNamespace;
|
||||
|
||||
use crate::codes::{self, RuleCodePrefix};
|
||||
use crate::fix::Fix;
|
||||
use crate::rules;
|
||||
use crate::violation::Violation;
|
||||
|
||||
ruff_macros::register_rules!(
|
||||
// pycodestyle errors
|
||||
@@ -53,6 +50,8 @@ ruff_macros::register_rules!(
|
||||
#[cfg(feature = "logical_lines")]
|
||||
rules::pycodestyle::rules::MultipleSpacesAfterKeyword,
|
||||
#[cfg(feature = "logical_lines")]
|
||||
rules::pycodestyle::rules::MissingWhitespace,
|
||||
#[cfg(feature = "logical_lines")]
|
||||
rules::pycodestyle::rules::MissingWhitespaceAfterKeyword,
|
||||
#[cfg(feature = "logical_lines")]
|
||||
rules::pycodestyle::rules::MultipleSpacesBeforeKeyword,
|
||||
@@ -147,6 +146,8 @@ ruff_macros::register_rules!(
|
||||
rules::pylint::rules::YieldInInit,
|
||||
rules::pylint::rules::InvalidAllObject,
|
||||
rules::pylint::rules::InvalidAllFormat,
|
||||
rules::pylint::rules::InvalidEnvvarDefault,
|
||||
rules::pylint::rules::InvalidEnvvarValue,
|
||||
rules::pylint::rules::BadStringFormatType,
|
||||
rules::pylint::rules::BidirectionalUnicode,
|
||||
rules::pylint::rules::BadStrStripCall,
|
||||
@@ -159,6 +160,7 @@ ruff_macros::register_rules!(
|
||||
rules::pylint::rules::PropertyWithParameters,
|
||||
rules::pylint::rules::ReturnInInit,
|
||||
rules::pylint::rules::ConsiderUsingFromImport,
|
||||
rules::pylint::rules::CompareToEmptyString,
|
||||
rules::pylint::rules::ComparisonOfConstant,
|
||||
rules::pylint::rules::ConsiderMergingIsinstance,
|
||||
rules::pylint::rules::ConsiderUsingSysExit,
|
||||
@@ -207,6 +209,7 @@ ruff_macros::register_rules!(
|
||||
rules::flake8_bugbear::rules::RaiseWithoutFromInsideExcept,
|
||||
rules::flake8_bugbear::rules::ZipWithoutExplicitStrict,
|
||||
rules::flake8_bugbear::rules::ExceptWithEmptyTuple,
|
||||
rules::flake8_bugbear::rules::ExceptWithNonExceptionClasses,
|
||||
rules::flake8_bugbear::rules::UnintentionalTypeAnnotation,
|
||||
// flake8-blind-except
|
||||
rules::flake8_blind_except::rules::BlindExcept,
|
||||
@@ -338,7 +341,7 @@ ruff_macros::register_rules!(
|
||||
rules::pyupgrade::rules::FString,
|
||||
rules::pyupgrade::rules::FunctoolsCache,
|
||||
rules::pyupgrade::rules::ExtraneousParentheses,
|
||||
rules::pyupgrade::rules::ImportReplacements,
|
||||
rules::pyupgrade::rules::DeprecatedImport,
|
||||
rules::pyupgrade::rules::OutdatedVersionBlock,
|
||||
rules::pyupgrade::rules::QuotedAnnotation,
|
||||
rules::pyupgrade::rules::IsinstanceWithTuple,
|
||||
@@ -607,6 +610,20 @@ ruff_macros::register_rules!(
|
||||
rules::flake8_django::rules::NonLeadingReceiverDecorator,
|
||||
);
|
||||
|
||||
impl Rule {
|
||||
pub fn from_code(code: &str) -> Result<Self, FromCodeError> {
|
||||
let (linter, code) = Linter::parse_code(code).ok_or(FromCodeError::Unknown)?;
|
||||
let prefix: RuleCodePrefix = RuleCodePrefix::parse(&linter, code)?;
|
||||
Ok(prefix.into_iter().next().unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(thiserror::Error, Debug)]
|
||||
pub enum FromCodeError {
|
||||
#[error("unknown rule code")]
|
||||
Unknown,
|
||||
}
|
||||
|
||||
#[derive(EnumIter, Debug, PartialEq, Eq, Clone, Hash, RuleNamespace)]
|
||||
pub enum Linter {
|
||||
/// [Pyflakes](https://pypi.org/project/pyflakes/)
|
||||
@@ -788,7 +805,7 @@ impl Linter {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(is_macro::Is)]
|
||||
#[derive(is_macro::Is, Copy, Clone)]
|
||||
pub enum LintSource {
|
||||
Ast,
|
||||
Io,
|
||||
@@ -803,9 +820,9 @@ pub enum LintSource {
|
||||
impl Rule {
|
||||
/// The source for the diagnostic (either the AST, the filesystem, or the
|
||||
/// physical lines).
|
||||
pub const fn lint_source(&self) -> &'static LintSource {
|
||||
pub const fn lint_source(&self) -> LintSource {
|
||||
match self {
|
||||
Rule::UnusedNOQA => &LintSource::Noqa,
|
||||
Rule::UnusedNOQA => LintSource::Noqa,
|
||||
Rule::BlanketNOQA
|
||||
| Rule::BlanketTypeIgnore
|
||||
| Rule::DocLineTooLong
|
||||
@@ -821,7 +838,7 @@ impl Rule {
|
||||
| Rule::ShebangWhitespace
|
||||
| Rule::TrailingWhitespace
|
||||
| Rule::IndentationContainsTabs
|
||||
| Rule::BlankLineContainsWhitespace => &LintSource::PhysicalLines,
|
||||
| Rule::BlankLineContainsWhitespace => LintSource::PhysicalLines,
|
||||
Rule::AmbiguousUnicodeCharacterComment
|
||||
| Rule::AmbiguousUnicodeCharacterDocstring
|
||||
| Rule::AmbiguousUnicodeCharacterString
|
||||
@@ -840,13 +857,14 @@ impl Rule {
|
||||
| Rule::UselessSemicolon
|
||||
| Rule::MultipleStatementsOnOneLineSemicolon
|
||||
| Rule::TrailingCommaProhibited
|
||||
| Rule::TypeCommentInStub => &LintSource::Tokens,
|
||||
Rule::IOError => &LintSource::Io,
|
||||
Rule::UnsortedImports | Rule::MissingRequiredImport => &LintSource::Imports,
|
||||
Rule::ImplicitNamespacePackage | Rule::InvalidModuleName => &LintSource::Filesystem,
|
||||
| Rule::TypeCommentInStub => LintSource::Tokens,
|
||||
Rule::IOError => LintSource::Io,
|
||||
Rule::UnsortedImports | Rule::MissingRequiredImport => LintSource::Imports,
|
||||
Rule::ImplicitNamespacePackage | Rule::InvalidModuleName => LintSource::Filesystem,
|
||||
#[cfg(feature = "logical_lines")]
|
||||
Rule::IndentationWithInvalidMultiple
|
||||
| Rule::IndentationWithInvalidMultipleComment
|
||||
| Rule::MissingWhitespace
|
||||
| Rule::MissingWhitespaceAfterKeyword
|
||||
| Rule::MissingWhitespaceAroundArithmeticOperator
|
||||
| Rule::MissingWhitespaceAroundBitwiseOrShiftOperator
|
||||
@@ -874,43 +892,12 @@ impl Rule {
|
||||
| Rule::WhitespaceAfterOpenBracket
|
||||
| Rule::WhitespaceBeforeCloseBracket
|
||||
| Rule::WhitespaceBeforeParameters
|
||||
| Rule::WhitespaceBeforePunctuation => &LintSource::LogicalLines,
|
||||
_ => &LintSource::Ast,
|
||||
| Rule::WhitespaceBeforePunctuation => LintSource::LogicalLines,
|
||||
_ => LintSource::Ast,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Diagnostic {
|
||||
pub kind: DiagnosticKind,
|
||||
pub location: Location,
|
||||
pub end_location: Location,
|
||||
pub fix: Option<Fix>,
|
||||
pub parent: Option<Location>,
|
||||
}
|
||||
|
||||
impl Diagnostic {
|
||||
pub fn new<K: Into<DiagnosticKind>>(kind: K, range: Range) -> Self {
|
||||
Self {
|
||||
kind: kind.into(),
|
||||
location: range.location,
|
||||
end_location: range.end_location,
|
||||
fix: None,
|
||||
parent: None,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn amend(&mut self, fix: Fix) -> &mut Self {
|
||||
self.fix = Some(fix);
|
||||
self
|
||||
}
|
||||
|
||||
pub fn parent(&mut self, parent: Location) -> &mut Self {
|
||||
self.parent = Some(parent);
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
/// Pairs of checks that shouldn't be enabled together.
|
||||
pub const INCOMPATIBLE_CODES: &[(Rule, Rule, &str); 2] = &[
|
||||
(
|
||||
|
||||
@@ -10,6 +10,7 @@ use ignore::{DirEntry, WalkBuilder, WalkState};
|
||||
use itertools::Itertools;
|
||||
use log::debug;
|
||||
use path_absolutize::path_dedot;
|
||||
use ruff_python_stdlib::path::is_python_file;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::fs;
|
||||
@@ -126,7 +127,8 @@ pub fn resolve_configuration(
|
||||
}
|
||||
|
||||
// Resolve the current path.
|
||||
let options = pyproject::load_options(&path)?;
|
||||
let options = pyproject::load_options(&path)
|
||||
.map_err(|err| anyhow!("Failed to parse `{}`: {}", path.display(), err))?;
|
||||
let project_root = relativity.resolve(&path);
|
||||
let configuration = Configuration::from_options(options, &project_root)?;
|
||||
|
||||
@@ -191,20 +193,9 @@ fn match_exclusion(file_path: &str, file_basename: &str, exclusion: &globset::Gl
|
||||
exclusion.is_match(file_path) || exclusion.is_match(file_basename)
|
||||
}
|
||||
|
||||
/// Return `true` if the [`Path`] appears to be that of a Python file.
|
||||
fn is_python_path(path: &Path) -> bool {
|
||||
path.extension()
|
||||
.map_or(false, |ext| ext == "py" || ext == "pyi")
|
||||
}
|
||||
|
||||
/// Return `true` if the [`Path`] appears to be that of a Python interface definition file (`.pyi`).
|
||||
pub fn is_interface_definition_path(path: &Path) -> bool {
|
||||
path.extension().map_or(false, |ext| ext == "pyi")
|
||||
}
|
||||
|
||||
/// Return `true` if the [`DirEntry`] appears to be that of a Python file.
|
||||
pub fn is_python_entry(entry: &DirEntry) -> bool {
|
||||
is_python_path(entry.path())
|
||||
is_python_file(entry.path())
|
||||
&& !entry
|
||||
.file_type()
|
||||
.map_or(false, |file_type| file_type.is_dir())
|
||||
@@ -430,28 +421,13 @@ mod tests {
|
||||
|
||||
use crate::fs;
|
||||
use crate::resolver::{
|
||||
is_file_excluded, is_python_path, match_exclusion, resolve_settings_with_processor,
|
||||
NoOpProcessor, PyprojectDiscovery, Relativity, Resolver,
|
||||
is_file_excluded, match_exclusion, resolve_settings_with_processor, NoOpProcessor,
|
||||
PyprojectDiscovery, Relativity, Resolver,
|
||||
};
|
||||
use crate::settings::pyproject::find_settings_toml;
|
||||
use crate::settings::types::FilePattern;
|
||||
use crate::test::test_resource_path;
|
||||
|
||||
#[test]
|
||||
fn inclusions() {
|
||||
let path = Path::new("foo/bar/baz.py").absolutize().unwrap();
|
||||
assert!(is_python_path(&path));
|
||||
|
||||
let path = Path::new("foo/bar/baz.pyi").absolutize().unwrap();
|
||||
assert!(is_python_path(&path));
|
||||
|
||||
let path = Path::new("foo/bar/baz.js").absolutize().unwrap();
|
||||
assert!(!is_python_path(&path));
|
||||
|
||||
let path = Path::new("foo/bar/baz").absolutize().unwrap();
|
||||
assert!(!is_python_path(&path));
|
||||
}
|
||||
|
||||
fn make_exclusion(file_pattern: FilePattern) -> GlobSet {
|
||||
let mut builder = globset::GlobSetBuilder::new();
|
||||
file_pattern.add_to(&mut builder).unwrap();
|
||||
|
||||
@@ -18,9 +18,7 @@ static REDIRECTS: Lazy<HashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||
// The following are here because we don't yet have the many-to-one mapping enabled.
|
||||
("SIM111", "SIM110"),
|
||||
// The following are deprecated.
|
||||
("C", "C4"),
|
||||
("C9", "C90"),
|
||||
("T", "T10"),
|
||||
("T1", "T10"),
|
||||
("T2", "T20"),
|
||||
// TODO(charlie): Remove by 2023-02-01.
|
||||
|
||||
@@ -15,9 +15,17 @@ use crate::rule_redirects::get_redirect;
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
pub enum RuleSelector {
|
||||
/// All rules
|
||||
/// Select all rules.
|
||||
All,
|
||||
/// Legacy category to select both the `mccabe` and `flake8-comprehensions` linters
|
||||
/// via a single selector.
|
||||
C,
|
||||
/// Legacy category to select both the `flake8-debugger` and `flake8-print` linters
|
||||
/// via a single selector.
|
||||
T,
|
||||
/// Select all rules for a given linter.
|
||||
Linter(Linter),
|
||||
/// Select all rules for a given linter with a given prefix.
|
||||
Prefix {
|
||||
prefix: RuleCodePrefix,
|
||||
redirected_from: Option<&'static str>,
|
||||
@@ -36,6 +44,10 @@ impl FromStr for RuleSelector {
|
||||
fn from_str(s: &str) -> Result<Self, Self::Err> {
|
||||
if s == "ALL" {
|
||||
Ok(Self::All)
|
||||
} else if s == "C" {
|
||||
Ok(Self::C)
|
||||
} else if s == "T" {
|
||||
Ok(Self::T)
|
||||
} else {
|
||||
let (s, redirected_from) = match get_redirect(s) {
|
||||
Some((from, target)) => (target, Some(from)),
|
||||
@@ -51,7 +63,7 @@ impl FromStr for RuleSelector {
|
||||
|
||||
Ok(Self::Prefix {
|
||||
prefix: RuleCodePrefix::parse(&linter, code)
|
||||
.map_err(|_| ParseError::Unknown(code.to_string()))?,
|
||||
.map_err(|_| ParseError::Unknown(s.to_string()))?,
|
||||
redirected_from,
|
||||
})
|
||||
}
|
||||
@@ -60,7 +72,7 @@ impl FromStr for RuleSelector {
|
||||
|
||||
#[derive(Debug, thiserror::Error)]
|
||||
pub enum ParseError {
|
||||
#[error("Unknown rule selector `{0}`")]
|
||||
#[error("Unknown rule selector: `{0}`")]
|
||||
// TODO(martin): tell the user how to discover rule codes via the CLI once such a command is
|
||||
// implemented (but that should of course be done only in ruff_cli and not here)
|
||||
Unknown(String),
|
||||
@@ -70,6 +82,8 @@ impl RuleSelector {
|
||||
pub fn prefix_and_code(&self) -> (&'static str, &'static str) {
|
||||
match self {
|
||||
RuleSelector::All => ("", "ALL"),
|
||||
RuleSelector::C => ("", "C"),
|
||||
RuleSelector::T => ("", "T"),
|
||||
RuleSelector::Prefix { prefix, .. } => {
|
||||
(prefix.linter().common_prefix(), prefix.short_code())
|
||||
}
|
||||
@@ -138,6 +152,16 @@ impl IntoIterator for &RuleSelector {
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
match self {
|
||||
RuleSelector::All => RuleSelectorIter::All(Rule::iter()),
|
||||
RuleSelector::C => RuleSelectorIter::Chain(
|
||||
Linter::Flake8Comprehensions
|
||||
.into_iter()
|
||||
.chain(Linter::McCabe.into_iter()),
|
||||
),
|
||||
RuleSelector::T => RuleSelectorIter::Chain(
|
||||
Linter::Flake8Debugger
|
||||
.into_iter()
|
||||
.chain(Linter::Flake8Print.into_iter()),
|
||||
),
|
||||
RuleSelector::Linter(linter) => RuleSelectorIter::Vec(linter.into_iter()),
|
||||
RuleSelector::Prefix { prefix, .. } => RuleSelectorIter::Vec(prefix.into_iter()),
|
||||
}
|
||||
@@ -146,6 +170,7 @@ impl IntoIterator for &RuleSelector {
|
||||
|
||||
pub enum RuleSelectorIter {
|
||||
All(RuleIter),
|
||||
Chain(std::iter::Chain<std::vec::IntoIter<Rule>, std::vec::IntoIter<Rule>>),
|
||||
Vec(std::vec::IntoIter<Rule>),
|
||||
}
|
||||
|
||||
@@ -155,13 +180,14 @@ impl Iterator for RuleSelectorIter {
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self {
|
||||
RuleSelectorIter::All(iter) => iter.next(),
|
||||
RuleSelectorIter::Chain(iter) => iter.next(),
|
||||
RuleSelectorIter::Vec(iter) => iter.next(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A const alternative to the `impl From<RuleCodePrefix> for RuleSelector`
|
||||
// to let us keep the fields of RuleSelector private.
|
||||
/// to let us keep the fields of [`RuleSelector`] private.
|
||||
// Note that Rust doesn't yet support `impl const From<RuleCodePrefix> for
|
||||
// RuleSelector` (see https://github.com/rust-lang/rust/issues/67792).
|
||||
// TODO(martin): Remove once RuleSelector is an enum with Linter & Rule variants
|
||||
@@ -177,13 +203,27 @@ impl JsonSchema for RuleSelector {
|
||||
"RuleSelector".to_string()
|
||||
}
|
||||
|
||||
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> schemars::schema::Schema {
|
||||
fn json_schema(_gen: &mut schemars::gen::SchemaGenerator) -> Schema {
|
||||
Schema::Object(SchemaObject {
|
||||
instance_type: Some(InstanceType::String.into()),
|
||||
enum_values: Some(
|
||||
std::iter::once("ALL".to_string())
|
||||
.chain(
|
||||
RuleCodePrefix::iter()
|
||||
.filter(|p| {
|
||||
// Once logical lines are active by default, please remove this.
|
||||
// This is here because generate-all output otherwise depends on
|
||||
// the feature sets which makes the test running with
|
||||
// `--all-features` fail
|
||||
!Rule::from_code(&format!(
|
||||
"{}{}",
|
||||
p.linter().common_prefix(),
|
||||
p.short_code()
|
||||
))
|
||||
.unwrap()
|
||||
.lint_source()
|
||||
.is_logical_lines()
|
||||
})
|
||||
.map(|p| {
|
||||
let prefix = p.linter().common_prefix();
|
||||
let code = p.short_code();
|
||||
@@ -207,6 +247,8 @@ impl RuleSelector {
|
||||
pub(crate) fn specificity(&self) -> Specificity {
|
||||
match self {
|
||||
RuleSelector::All => Specificity::All,
|
||||
RuleSelector::T => Specificity::LinterGroup,
|
||||
RuleSelector::C => Specificity::LinterGroup,
|
||||
RuleSelector::Linter(..) => Specificity::Linter,
|
||||
RuleSelector::Prefix { prefix, .. } => {
|
||||
let prefix: &'static str = prefix.short_code();
|
||||
@@ -226,6 +268,7 @@ impl RuleSelector {
|
||||
#[derive(EnumIter, PartialEq, Eq, PartialOrd, Ord)]
|
||||
pub(crate) enum Specificity {
|
||||
All,
|
||||
LinterGroup,
|
||||
Linter,
|
||||
Code1Char,
|
||||
Code2Chars,
|
||||
@@ -234,6 +277,7 @@ pub(crate) enum Specificity {
|
||||
Code5Chars,
|
||||
}
|
||||
|
||||
#[cfg(feature = "clap")]
|
||||
mod clap_completion {
|
||||
use clap::builder::{PossibleValue, TypedValueParser, ValueParserFactory};
|
||||
use strum::IntoEnumIterator;
|
||||
@@ -273,9 +317,7 @@ mod clap_completion {
|
||||
.map_err(|e| clap::Error::raw(clap::error::ErrorKind::InvalidValue, e))
|
||||
}
|
||||
|
||||
fn possible_values(
|
||||
&self,
|
||||
) -> Option<Box<dyn Iterator<Item = clap::builder::PossibleValue> + '_>> {
|
||||
fn possible_values(&self) -> Option<Box<dyn Iterator<Item = PossibleValue> + '_>> {
|
||||
Some(Box::new(
|
||||
std::iter::once(PossibleValue::new("ALL").help("all rules")).chain(
|
||||
Linter::iter()
|
||||
|
||||
@@ -1,28 +1,29 @@
|
||||
use ruff_macros::{define_violation, derive_message_formats};
|
||||
use rustpython_parser::ast::Location;
|
||||
|
||||
use super::detection::comment_contains_code;
|
||||
use crate::ast::types::Range;
|
||||
use crate::fix::Fix;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::settings::{flags, Settings};
|
||||
use crate::source_code::Locator;
|
||||
use crate::violation::AlwaysAutofixableViolation;
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::source_code::Locator;
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
use crate::registry::Rule;
|
||||
use crate::settings::{flags, Settings};
|
||||
|
||||
use super::detection::comment_contains_code;
|
||||
|
||||
/// ## What it does
|
||||
/// Checks for commented-out Python code.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Commented-out code is dead code, and is often included inadvertently.
|
||||
/// It should be removed.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// # print('foo')
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct CommentedOutCode;
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks for commented-out Python code.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Commented-out code is dead code, and is often included inadvertently.
|
||||
/// It should be removed.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// # print('foo')
|
||||
/// ```
|
||||
pub struct CommentedOutCode;
|
||||
);
|
||||
impl AlwaysAutofixableViolation for CommentedOutCode {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -55,7 +56,7 @@ pub fn commented_out_code(
|
||||
) -> Option<Diagnostic> {
|
||||
let location = Location::new(start.row(), 0);
|
||||
let end_location = Location::new(end.row() + 1, 0);
|
||||
let line = locator.slice(&Range::new(location, end_location));
|
||||
let line = locator.slice(Range::new(location, end_location));
|
||||
|
||||
// Verify that the comment is on its own line, and that it contains code.
|
||||
if is_standalone_comment(line) && comment_contains_code(line, &settings.task_tags[..]) {
|
||||
|
||||
@@ -3,7 +3,10 @@ source: crates/ruff/src/rules/eradicate/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
CommentedOutCode: ~
|
||||
name: CommentedOutCode
|
||||
body: Found commented-out code
|
||||
suggestion: Remove commented-out code
|
||||
fixable: true
|
||||
location:
|
||||
row: 1
|
||||
column: 0
|
||||
@@ -20,7 +23,10 @@ expression: diagnostics
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
CommentedOutCode: ~
|
||||
name: CommentedOutCode
|
||||
body: Found commented-out code
|
||||
suggestion: Remove commented-out code
|
||||
fixable: true
|
||||
location:
|
||||
row: 2
|
||||
column: 0
|
||||
@@ -37,7 +43,10 @@ expression: diagnostics
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
CommentedOutCode: ~
|
||||
name: CommentedOutCode
|
||||
body: Found commented-out code
|
||||
suggestion: Remove commented-out code
|
||||
fixable: true
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
@@ -54,7 +63,10 @@ expression: diagnostics
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
CommentedOutCode: ~
|
||||
name: CommentedOutCode
|
||||
body: Found commented-out code
|
||||
suggestion: Remove commented-out code
|
||||
fixable: true
|
||||
location:
|
||||
row: 5
|
||||
column: 0
|
||||
@@ -71,7 +83,10 @@ expression: diagnostics
|
||||
column: 0
|
||||
parent: ~
|
||||
- kind:
|
||||
CommentedOutCode: ~
|
||||
name: CommentedOutCode
|
||||
body: Found commented-out code
|
||||
suggestion: Remove commented-out code
|
||||
fixable: true
|
||||
location:
|
||||
row: 12
|
||||
column: 4
|
||||
|
||||
@@ -1,15 +1,16 @@
|
||||
use num_bigint::BigInt;
|
||||
use ruff_macros::{define_violation, derive_message_formats};
|
||||
use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind, Located};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::violation::Violation;
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::Rule;
|
||||
|
||||
#[violation]
|
||||
pub struct SysVersionSlice3Referenced;
|
||||
|
||||
define_violation!(
|
||||
pub struct SysVersionSlice3Referenced;
|
||||
);
|
||||
impl Violation for SysVersionSlice3Referenced {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -17,9 +18,9 @@ impl Violation for SysVersionSlice3Referenced {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SysVersion2Referenced;
|
||||
);
|
||||
#[violation]
|
||||
pub struct SysVersion2Referenced;
|
||||
|
||||
impl Violation for SysVersion2Referenced {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -27,9 +28,9 @@ impl Violation for SysVersion2Referenced {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SysVersionCmpStr3;
|
||||
);
|
||||
#[violation]
|
||||
pub struct SysVersionCmpStr3;
|
||||
|
||||
impl Violation for SysVersionCmpStr3 {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -37,9 +38,9 @@ impl Violation for SysVersionCmpStr3 {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SysVersionInfo0Eq3Referenced;
|
||||
);
|
||||
#[violation]
|
||||
pub struct SysVersionInfo0Eq3Referenced;
|
||||
|
||||
impl Violation for SysVersionInfo0Eq3Referenced {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -47,9 +48,9 @@ impl Violation for SysVersionInfo0Eq3Referenced {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SixPY3Referenced;
|
||||
);
|
||||
#[violation]
|
||||
pub struct SixPY3Referenced;
|
||||
|
||||
impl Violation for SixPY3Referenced {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -57,9 +58,9 @@ impl Violation for SixPY3Referenced {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SysVersionInfo1CmpInt;
|
||||
);
|
||||
#[violation]
|
||||
pub struct SysVersionInfo1CmpInt;
|
||||
|
||||
impl Violation for SysVersionInfo1CmpInt {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -70,9 +71,9 @@ impl Violation for SysVersionInfo1CmpInt {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SysVersionInfoMinorCmpInt;
|
||||
);
|
||||
#[violation]
|
||||
pub struct SysVersionInfoMinorCmpInt;
|
||||
|
||||
impl Violation for SysVersionInfoMinorCmpInt {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -83,9 +84,9 @@ impl Violation for SysVersionInfoMinorCmpInt {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SysVersion0Referenced;
|
||||
);
|
||||
#[violation]
|
||||
pub struct SysVersion0Referenced;
|
||||
|
||||
impl Violation for SysVersion0Referenced {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -93,9 +94,9 @@ impl Violation for SysVersion0Referenced {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SysVersionCmpStr10;
|
||||
);
|
||||
#[violation]
|
||||
pub struct SysVersionCmpStr10;
|
||||
|
||||
impl Violation for SysVersionCmpStr10 {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -103,9 +104,9 @@ impl Violation for SysVersionCmpStr10 {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
pub struct SysVersionSlice1Referenced;
|
||||
);
|
||||
#[violation]
|
||||
pub struct SysVersionSlice1Referenced;
|
||||
|
||||
impl Violation for SysVersionSlice1Referenced {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -115,6 +116,7 @@ impl Violation for SysVersionSlice1Referenced {
|
||||
|
||||
fn is_sys(checker: &Checker, expr: &Expr, target: &str) -> bool {
|
||||
checker
|
||||
.ctx
|
||||
.resolve_call_path(expr)
|
||||
.map_or(false, |call_path| call_path.as_slice() == ["sys", target])
|
||||
}
|
||||
@@ -142,7 +144,7 @@ pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
SysVersionSlice1Referenced,
|
||||
Range::from_located(value),
|
||||
Range::from(value),
|
||||
));
|
||||
} else if *i == BigInt::from(3)
|
||||
&& checker
|
||||
@@ -152,7 +154,7 @@ pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
SysVersionSlice3Referenced,
|
||||
Range::from_located(value),
|
||||
Range::from(value),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -165,17 +167,15 @@ pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
||||
if *i == BigInt::from(2)
|
||||
&& checker.settings.rules.enabled(&Rule::SysVersion2Referenced)
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
SysVersion2Referenced,
|
||||
Range::from_located(value),
|
||||
));
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(SysVersion2Referenced, Range::from(value)));
|
||||
} else if *i == BigInt::from(0)
|
||||
&& checker.settings.rules.enabled(&Rule::SysVersion0Referenced)
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
SysVersion0Referenced,
|
||||
Range::from_located(value),
|
||||
));
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(SysVersion0Referenced, Range::from(value)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -214,7 +214,7 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
SysVersionInfo0Eq3Referenced,
|
||||
Range::from_located(left),
|
||||
Range::from(left),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -232,10 +232,9 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
|
||||
) = (ops, comparators)
|
||||
{
|
||||
if checker.settings.rules.enabled(&Rule::SysVersionInfo1CmpInt) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
SysVersionInfo1CmpInt,
|
||||
Range::from_located(left),
|
||||
));
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(SysVersionInfo1CmpInt, Range::from(left)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -264,7 +263,7 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
SysVersionInfoMinorCmpInt,
|
||||
Range::from_located(left),
|
||||
Range::from(left),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -288,16 +287,14 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
|
||||
{
|
||||
if s.len() == 1 {
|
||||
if checker.settings.rules.enabled(&Rule::SysVersionCmpStr10) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
SysVersionCmpStr10,
|
||||
Range::from_located(left),
|
||||
));
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(SysVersionCmpStr10, Range::from(left)));
|
||||
}
|
||||
} else if checker.settings.rules.enabled(&Rule::SysVersionCmpStr3) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
SysVersionCmpStr3,
|
||||
Range::from_located(left),
|
||||
));
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(SysVersionCmpStr3, Range::from(left)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -306,11 +303,12 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
|
||||
/// YTT202
|
||||
pub fn name_or_attribute(checker: &mut Checker, expr: &Expr) {
|
||||
if checker
|
||||
.ctx
|
||||
.resolve_call_path(expr)
|
||||
.map_or(false, |call_path| call_path.as_slice() == ["six", "PY3"])
|
||||
{
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(SixPY3Referenced, Range::from_located(expr)));
|
||||
.push(Diagnostic::new(SixPY3Referenced, Range::from(expr)));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SysVersionSlice3Referenced: ~
|
||||
name: SysVersionSlice3Referenced
|
||||
body: "`sys.version[:3]` referenced (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 6
|
||||
column: 6
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionSlice3Referenced: ~
|
||||
name: SysVersionSlice3Referenced
|
||||
body: "`sys.version[:3]` referenced (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 7
|
||||
column: 6
|
||||
@@ -23,7 +29,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionSlice3Referenced: ~
|
||||
name: SysVersionSlice3Referenced
|
||||
body: "`sys.version[:3]` referenced (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 8
|
||||
column: 6
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SysVersion2Referenced: ~
|
||||
name: SysVersion2Referenced
|
||||
body: "`sys.version[2]` referenced (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 11
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersion2Referenced: ~
|
||||
name: SysVersion2Referenced
|
||||
body: "`sys.version[2]` referenced (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 5
|
||||
column: 11
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SysVersionCmpStr3: ~
|
||||
name: SysVersionCmpStr3
|
||||
body: "`sys.version` compared to string (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 0
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionCmpStr3: ~
|
||||
name: SysVersionCmpStr3
|
||||
body: "`sys.version` compared to string (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 5
|
||||
column: 0
|
||||
@@ -23,7 +29,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionCmpStr3: ~
|
||||
name: SysVersionCmpStr3
|
||||
body: "`sys.version` compared to string (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 6
|
||||
column: 0
|
||||
@@ -33,7 +42,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionCmpStr3: ~
|
||||
name: SysVersionCmpStr3
|
||||
body: "`sys.version` compared to string (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 7
|
||||
column: 0
|
||||
@@ -43,7 +55,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionCmpStr3: ~
|
||||
name: SysVersionCmpStr3
|
||||
body: "`sys.version` compared to string (python3.10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 8
|
||||
column: 0
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SysVersionInfo0Eq3Referenced: ~
|
||||
name: SysVersionInfo0Eq3Referenced
|
||||
body: "`sys.version_info[0] == 3` referenced (python4), use `>=`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 7
|
||||
column: 6
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionInfo0Eq3Referenced: ~
|
||||
name: SysVersionInfo0Eq3Referenced
|
||||
body: "`sys.version_info[0] == 3` referenced (python4), use `>=`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 8
|
||||
column: 6
|
||||
@@ -23,7 +29,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionInfo0Eq3Referenced: ~
|
||||
name: SysVersionInfo0Eq3Referenced
|
||||
body: "`sys.version_info[0] == 3` referenced (python4), use `>=`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 9
|
||||
column: 6
|
||||
@@ -33,7 +42,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionInfo0Eq3Referenced: ~
|
||||
name: SysVersionInfo0Eq3Referenced
|
||||
body: "`sys.version_info[0] == 3` referenced (python4), use `>=`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 10
|
||||
column: 6
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SixPY3Referenced: ~
|
||||
name: SixPY3Referenced
|
||||
body: "`six.PY3` referenced (python4), use `not six.PY2`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 3
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SixPY3Referenced: ~
|
||||
name: SixPY3Referenced
|
||||
body: "`six.PY3` referenced (python4), use `not six.PY2`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 6
|
||||
column: 3
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SysVersionInfo1CmpInt: ~
|
||||
name: SysVersionInfo1CmpInt
|
||||
body: "`sys.version_info[1]` compared to integer (python4), compare `sys.version_info` to tuple"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 0
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionInfo1CmpInt: ~
|
||||
name: SysVersionInfo1CmpInt
|
||||
body: "`sys.version_info[1]` compared to integer (python4), compare `sys.version_info` to tuple"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 5
|
||||
column: 0
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SysVersionInfoMinorCmpInt: ~
|
||||
name: SysVersionInfoMinorCmpInt
|
||||
body: "`sys.version_info.minor` compared to integer (python4), compare `sys.version_info` to tuple"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 0
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionInfoMinorCmpInt: ~
|
||||
name: SysVersionInfoMinorCmpInt
|
||||
body: "`sys.version_info.minor` compared to integer (python4), compare `sys.version_info` to tuple"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 5
|
||||
column: 0
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SysVersion0Referenced: ~
|
||||
name: SysVersion0Referenced
|
||||
body: "`sys.version[0]` referenced (python10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 11
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersion0Referenced: ~
|
||||
name: SysVersion0Referenced
|
||||
body: "`sys.version[0]` referenced (python10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 5
|
||||
column: 11
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SysVersionCmpStr10: ~
|
||||
name: SysVersionCmpStr10
|
||||
body: "`sys.version` compared to string (python10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 0
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionCmpStr10: ~
|
||||
name: SysVersionCmpStr10
|
||||
body: "`sys.version` compared to string (python10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 5
|
||||
column: 0
|
||||
@@ -23,7 +29,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionCmpStr10: ~
|
||||
name: SysVersionCmpStr10
|
||||
body: "`sys.version` compared to string (python10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 6
|
||||
column: 0
|
||||
@@ -33,7 +42,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionCmpStr10: ~
|
||||
name: SysVersionCmpStr10
|
||||
body: "`sys.version` compared to string (python10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 7
|
||||
column: 0
|
||||
@@ -43,7 +55,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionCmpStr10: ~
|
||||
name: SysVersionCmpStr10
|
||||
body: "`sys.version` compared to string (python10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 8
|
||||
column: 0
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_2020/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_2020/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
SysVersionSlice1Referenced: ~
|
||||
name: SysVersionSlice1Referenced
|
||||
body: "`sys.version[:1]` referenced (python10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 6
|
||||
@@ -13,7 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
SysVersionSlice1Referenced: ~
|
||||
name: SysVersionSlice1Referenced
|
||||
body: "`sys.version[:1]` referenced (python10), use `sys.version_info`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 5
|
||||
column: 6
|
||||
|
||||
@@ -2,14 +2,14 @@ use anyhow::{bail, Result};
|
||||
use rustpython_parser::ast::Stmt;
|
||||
use rustpython_parser::{lexer, Mode, Tok};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::fix::Fix;
|
||||
use crate::source_code::Locator;
|
||||
use ruff_diagnostics::Fix;
|
||||
use ruff_python_ast::source_code::Locator;
|
||||
use ruff_python_ast::types::Range;
|
||||
|
||||
/// ANN204
|
||||
pub fn add_return_none_annotation(locator: &Locator, stmt: &Stmt) -> Result<Fix> {
|
||||
let range = Range::from_located(stmt);
|
||||
let contents = locator.slice(&range);
|
||||
let range = Range::from(stmt);
|
||||
let contents = locator.slice(range);
|
||||
|
||||
// Find the colon (following the `def` keyword).
|
||||
let mut seen_lpar = false;
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use rustpython_parser::ast::{Arguments, Expr, Stmt, StmtKind};
|
||||
|
||||
use crate::ast::cast;
|
||||
use ruff_python_ast::cast;
|
||||
use ruff_python_ast::visibility;
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::docstrings::definition::{Definition, DefinitionKind};
|
||||
use crate::visibility;
|
||||
|
||||
pub(super) fn match_function_def(
|
||||
stmt: &Stmt,
|
||||
@@ -33,7 +34,7 @@ pub fn overloaded_name(checker: &Checker, definition: &Definition) -> Option<Str
|
||||
| DefinitionKind::NestedFunction(stmt)
|
||||
| DefinitionKind::Method(stmt) = definition.kind
|
||||
{
|
||||
if visibility::is_overload(checker, cast::decorator_list(stmt)) {
|
||||
if visibility::is_overload(&checker.ctx, cast::decorator_list(stmt)) {
|
||||
let (name, ..) = match_function_def(stmt);
|
||||
Some(name.to_string())
|
||||
} else {
|
||||
@@ -51,7 +52,7 @@ pub fn is_overload_impl(checker: &Checker, definition: &Definition, overloaded_n
|
||||
| DefinitionKind::NestedFunction(stmt)
|
||||
| DefinitionKind::Method(stmt) = definition.kind
|
||||
{
|
||||
if visibility::is_overload(checker, cast::decorator_list(stmt)) {
|
||||
if visibility::is_overload(&checker.ctx, cast::decorator_list(stmt)) {
|
||||
false
|
||||
} else {
|
||||
let (name, ..) = match_function_def(stmt);
|
||||
|
||||
@@ -1,44 +1,46 @@
|
||||
use log::error;
|
||||
use ruff_macros::{define_violation, derive_message_formats};
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
use ruff_python_ast::helpers::ReturnStatementVisitor;
|
||||
use ruff_python_ast::types::Range;
|
||||
use ruff_python_ast::visibility;
|
||||
use ruff_python_ast::visibility::Visibility;
|
||||
use ruff_python_ast::visitor::Visitor;
|
||||
use ruff_python_ast::{cast, helpers};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::docstrings::definition::{Definition, DefinitionKind};
|
||||
use crate::registry::{AsRule, Rule};
|
||||
|
||||
use super::fixes;
|
||||
use super::helpers::match_function_def;
|
||||
use crate::ast::helpers::ReturnStatementVisitor;
|
||||
use crate::ast::types::Range;
|
||||
use crate::ast::visitor::Visitor;
|
||||
use crate::ast::{cast, helpers};
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::docstrings::definition::{Definition, DefinitionKind};
|
||||
use crate::registry::{Diagnostic, Rule};
|
||||
use crate::violation::{AlwaysAutofixableViolation, Violation};
|
||||
use crate::visibility;
|
||||
use crate::visibility::Visibility;
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that function arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def foo(x):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def foo(x: int):
|
||||
/// ...
|
||||
/// ```
|
||||
pub struct MissingTypeFunctionArgument {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that function arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def foo(x):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def foo(x: int):
|
||||
/// ...
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingTypeFunctionArgument {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for MissingTypeFunctionArgument {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -47,30 +49,30 @@ impl Violation for MissingTypeFunctionArgument {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that function `*args` arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def foo(*args):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def foo(*args: int):
|
||||
/// ...
|
||||
/// ```
|
||||
pub struct MissingTypeArgs {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that function `*args` arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def foo(*args):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def foo(*args: int):
|
||||
/// ...
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingTypeArgs {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for MissingTypeArgs {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -79,30 +81,30 @@ impl Violation for MissingTypeArgs {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that function `**kwargs` arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def foo(**kwargs):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def foo(**kwargs: int):
|
||||
/// ...
|
||||
/// ```
|
||||
pub struct MissingTypeKwargs {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that function `**kwargs` arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def foo(**kwargs):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def foo(**kwargs: int):
|
||||
/// ...
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingTypeKwargs {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for MissingTypeKwargs {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -111,35 +113,35 @@ impl Violation for MissingTypeKwargs {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that instance method `self` arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// Note that many type checkers will infer the type of `self` automatically, so this
|
||||
/// annotation is not strictly necessary.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// def bar(self):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// def bar(self: "Foo"):
|
||||
/// ...
|
||||
/// ```
|
||||
pub struct MissingTypeSelf {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that instance method `self` arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// Note that many type checkers will infer the type of `self` automatically, so this
|
||||
/// annotation is not strictly necessary.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// def bar(self):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// def bar(self: "Foo"):
|
||||
/// ...
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingTypeSelf {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for MissingTypeSelf {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -148,37 +150,37 @@ impl Violation for MissingTypeSelf {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that class method `cls` arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// Note that many type checkers will infer the type of `cls` automatically, so this
|
||||
/// annotation is not strictly necessary.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @classmethod
|
||||
/// def bar(cls):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @classmethod
|
||||
/// def bar(cls: Type["Foo"]):
|
||||
/// ...
|
||||
/// ```
|
||||
pub struct MissingTypeCls {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that class method `cls` arguments have type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the types of function arguments. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any provided arguments match expectation.
|
||||
///
|
||||
/// Note that many type checkers will infer the type of `cls` automatically, so this
|
||||
/// annotation is not strictly necessary.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @classmethod
|
||||
/// def bar(cls):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @classmethod
|
||||
/// def bar(cls: Type["Foo"]):
|
||||
/// ...
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingTypeCls {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for MissingTypeCls {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -187,30 +189,30 @@ impl Violation for MissingTypeCls {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that public functions and methods have return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def add(a, b):
|
||||
/// return a + b
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def add(a: int, b: int) -> int:
|
||||
/// return a + b
|
||||
/// ```
|
||||
pub struct MissingReturnTypePublicFunction {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that public functions and methods have return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def add(a, b):
|
||||
/// return a + b
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def add(a: int, b: int) -> int:
|
||||
/// return a + b
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingReturnTypePublicFunction {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for MissingReturnTypePublicFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -219,30 +221,30 @@ impl Violation for MissingReturnTypePublicFunction {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that private functions and methods have return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def _add(a, b):
|
||||
/// return a + b
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def _add(a: int, b: int) -> int:
|
||||
/// return a + b
|
||||
/// ```
|
||||
pub struct MissingReturnTypePrivateFunction {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that private functions and methods have return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def _add(a, b):
|
||||
/// return a + b
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def _add(a: int, b: int) -> int:
|
||||
/// return a + b
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingReturnTypePrivateFunction {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for MissingReturnTypePrivateFunction {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -251,43 +253,43 @@ impl Violation for MissingReturnTypePrivateFunction {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that "special" methods, like `__init__`, `__new__`, and `__call__`, have
|
||||
/// return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// Note that type checkers often allow you to omit the return type annotation for
|
||||
/// `__init__` methods, as long as at least one argument has a type annotation. To
|
||||
/// opt-in to this behavior, use the `mypy-init-return` setting in your `pyproject.toml`
|
||||
/// or `ruff.toml` file:
|
||||
///
|
||||
/// ```toml
|
||||
/// [tool.ruff.flake8-annotations]
|
||||
/// mypy-init-return = true
|
||||
/// ```
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// def __init__(self, x: int):
|
||||
/// self.x = x
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// def __init__(self, x: int) -> None:
|
||||
/// self.x = x
|
||||
/// ```
|
||||
pub struct MissingReturnTypeSpecialMethod {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that "special" methods, like `__init__`, `__new__`, and `__call__`, have
|
||||
/// return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// Note that type checkers often allow you to omit the return type annotation for
|
||||
/// `__init__` methods, as long as at least one argument has a type annotation. To
|
||||
/// opt-in to this behavior, use the `mypy-init-return` setting in your `pyproject.toml`
|
||||
/// or `ruff.toml` file:
|
||||
///
|
||||
/// ```toml
|
||||
/// [tool.ruff.flake8-annotations]
|
||||
/// mypy-init-return = true
|
||||
/// ```
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// def __init__(self, x: int):
|
||||
/// self.x = x
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// def __init__(self, x: int) -> None:
|
||||
/// self.x = x
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingReturnTypeSpecialMethod {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl AlwaysAutofixableViolation for MissingReturnTypeSpecialMethod {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -300,34 +302,34 @@ impl AlwaysAutofixableViolation for MissingReturnTypeSpecialMethod {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that static methods have return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @staticmethod
|
||||
/// def bar():
|
||||
/// return 1
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @staticmethod
|
||||
/// def bar() -> int:
|
||||
/// return 1
|
||||
/// ```
|
||||
pub struct MissingReturnTypeStaticMethod {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that static methods have return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @staticmethod
|
||||
/// def bar():
|
||||
/// return 1
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @staticmethod
|
||||
/// def bar() -> int:
|
||||
/// return 1
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingReturnTypeStaticMethod {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for MissingReturnTypeStaticMethod {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -336,34 +338,34 @@ impl Violation for MissingReturnTypeStaticMethod {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that class methods have return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @classmethod
|
||||
/// def bar(cls):
|
||||
/// return 1
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @classmethod
|
||||
/// def bar(cls) -> int:
|
||||
/// return 1
|
||||
/// ```
|
||||
pub struct MissingReturnTypeClassMethod {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that class methods have return type annotations.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// Type annotations are a good way to document the return types of functions. They also
|
||||
/// help catch bugs, when used alongside a type checker, by ensuring that the types of
|
||||
/// any returned values, and the types expected by callers, match expectation.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @classmethod
|
||||
/// def bar(cls):
|
||||
/// return 1
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// class Foo:
|
||||
/// @classmethod
|
||||
/// def bar(cls) -> int:
|
||||
/// return 1
|
||||
/// ```
|
||||
#[violation]
|
||||
pub struct MissingReturnTypeClassMethod {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for MissingReturnTypeClassMethod {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -372,39 +374,39 @@ impl Violation for MissingReturnTypeClassMethod {
|
||||
}
|
||||
}
|
||||
|
||||
define_violation!(
|
||||
/// ## What it does
|
||||
/// Checks that an expression is annotated with a more specific type than
|
||||
/// `Any`.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// `Any` is a special type indicating an unconstrained type. When an
|
||||
/// expression is annotated with type `Any`, type checkers will allow all
|
||||
/// operations on it.
|
||||
///
|
||||
/// It's better to be explicit about the type of an expression, and to use
|
||||
/// `Any` as an "escape hatch" only when it is really needed.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def foo(x: Any):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def foo(x: int):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// ## References
|
||||
/// - [PEP 484](https://www.python.org/dev/peps/pep-0484/#the-any-type)
|
||||
/// - [`typing.Any`](https://docs.python.org/3/library/typing.html#typing.Any)
|
||||
/// - [Mypy: The Any type](https://mypy.readthedocs.io/en/stable/kinds_of_types.html#the-any-type)
|
||||
pub struct AnyType {
|
||||
pub name: String,
|
||||
}
|
||||
);
|
||||
/// ## What it does
|
||||
/// Checks that an expression is annotated with a more specific type than
|
||||
/// `Any`.
|
||||
///
|
||||
/// ## Why is this bad?
|
||||
/// `Any` is a special type indicating an unconstrained type. When an
|
||||
/// expression is annotated with type `Any`, type checkers will allow all
|
||||
/// operations on it.
|
||||
///
|
||||
/// It's better to be explicit about the type of an expression, and to use
|
||||
/// `Any` as an "escape hatch" only when it is really needed.
|
||||
///
|
||||
/// ## Example
|
||||
/// ```python
|
||||
/// def foo(x: Any):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// Use instead:
|
||||
/// ```python
|
||||
/// def foo(x: int):
|
||||
/// ...
|
||||
/// ```
|
||||
///
|
||||
/// ## References
|
||||
/// - [PEP 484](https://www.python.org/dev/peps/pep-0484/#the-any-type)
|
||||
/// - [`typing.Any`](https://docs.python.org/3/library/typing.html#typing.Any)
|
||||
/// - [Mypy: The Any type](https://mypy.readthedocs.io/en/stable/kinds_of_types.html#the-any-type)
|
||||
#[violation]
|
||||
pub struct AnyType {
|
||||
pub name: String,
|
||||
}
|
||||
|
||||
impl Violation for AnyType {
|
||||
#[derive_message_formats]
|
||||
fn message(&self) -> String {
|
||||
@@ -441,10 +443,10 @@ fn check_dynamically_typed<F>(
|
||||
) where
|
||||
F: FnOnce() -> String,
|
||||
{
|
||||
if checker.match_typing_expr(annotation, "Any") {
|
||||
if checker.ctx.match_typing_expr(annotation, "Any") {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
AnyType { name: func() },
|
||||
Range::from_located(annotation),
|
||||
Range::from(annotation),
|
||||
));
|
||||
};
|
||||
}
|
||||
@@ -482,7 +484,8 @@ pub fn definition(
|
||||
.skip(
|
||||
// If this is a non-static method, skip `cls` or `self`.
|
||||
usize::from(
|
||||
is_method && !visibility::is_staticmethod(checker, cast::decorator_list(stmt)),
|
||||
is_method
|
||||
&& !visibility::is_staticmethod(&checker.ctx, cast::decorator_list(stmt)),
|
||||
),
|
||||
)
|
||||
{
|
||||
@@ -510,7 +513,7 @@ pub fn definition(
|
||||
MissingTypeFunctionArgument {
|
||||
name: arg.node.arg.to_string(),
|
||||
},
|
||||
Range::from_located(arg),
|
||||
Range::from(arg),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -541,7 +544,7 @@ pub fn definition(
|
||||
MissingTypeArgs {
|
||||
name: arg.node.arg.to_string(),
|
||||
},
|
||||
Range::from_located(arg),
|
||||
Range::from(arg),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -572,7 +575,7 @@ pub fn definition(
|
||||
MissingTypeKwargs {
|
||||
name: arg.node.arg.to_string(),
|
||||
},
|
||||
Range::from_located(arg),
|
||||
Range::from(arg),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -580,16 +583,16 @@ pub fn definition(
|
||||
}
|
||||
|
||||
// ANN101, ANN102
|
||||
if is_method && !visibility::is_staticmethod(checker, cast::decorator_list(stmt)) {
|
||||
if is_method && !visibility::is_staticmethod(&checker.ctx, cast::decorator_list(stmt)) {
|
||||
if let Some(arg) = args.posonlyargs.first().or_else(|| args.args.first()) {
|
||||
if arg.node.annotation.is_none() {
|
||||
if visibility::is_classmethod(checker, cast::decorator_list(stmt)) {
|
||||
if visibility::is_classmethod(&checker.ctx, cast::decorator_list(stmt)) {
|
||||
if checker.settings.rules.enabled(&Rule::MissingTypeCls) {
|
||||
diagnostics.push(Diagnostic::new(
|
||||
MissingTypeCls {
|
||||
name: arg.node.arg.to_string(),
|
||||
},
|
||||
Range::from_located(arg),
|
||||
Range::from(arg),
|
||||
));
|
||||
}
|
||||
} else {
|
||||
@@ -598,7 +601,7 @@ pub fn definition(
|
||||
MissingTypeSelf {
|
||||
name: arg.node.arg.to_string(),
|
||||
},
|
||||
Range::from_located(arg),
|
||||
Range::from(arg),
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -619,7 +622,7 @@ pub fn definition(
|
||||
// (explicitly or implicitly).
|
||||
checker.settings.flake8_annotations.suppress_none_returning && is_none_returning(body)
|
||||
) {
|
||||
if is_method && visibility::is_classmethod(checker, cast::decorator_list(stmt)) {
|
||||
if is_method && visibility::is_classmethod(&checker.ctx, cast::decorator_list(stmt)) {
|
||||
if checker
|
||||
.settings
|
||||
.rules
|
||||
@@ -632,7 +635,8 @@ pub fn definition(
|
||||
helpers::identifier_range(stmt, checker.locator),
|
||||
));
|
||||
}
|
||||
} else if is_method && visibility::is_staticmethod(checker, cast::decorator_list(stmt))
|
||||
} else if is_method
|
||||
&& visibility::is_staticmethod(&checker.ctx, cast::decorator_list(stmt))
|
||||
{
|
||||
if checker
|
||||
.settings
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
//! Settings for the `flake-annotations` plugin.
|
||||
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use ruff_macros::CacheKey;
|
||||
use ruff_macros::ConfigurationOptions;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(
|
||||
Debug, PartialEq, Eq, Default, Serialize, Deserialize, ConfigurationOptions, JsonSchema,
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
---
|
||||
source: src/rules/flake8_annotations/mod.rs
|
||||
source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: bar
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `bar`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 29
|
||||
column: 8
|
||||
|
||||
@@ -3,8 +3,10 @@ source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
AnyType:
|
||||
name: a
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `a`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 10
|
||||
column: 11
|
||||
@@ -14,8 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: foo
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `foo`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 15
|
||||
column: 46
|
||||
@@ -25,8 +29,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: a
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `a`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 40
|
||||
column: 28
|
||||
@@ -36,8 +42,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: foo_method
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `foo_method`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 44
|
||||
column: 66
|
||||
|
||||
@@ -3,8 +3,10 @@ source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: foo
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `foo`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 4
|
||||
@@ -14,8 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeFunctionArgument:
|
||||
name: a
|
||||
name: MissingTypeFunctionArgument
|
||||
body: "Missing type annotation for function argument `a`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 8
|
||||
@@ -25,8 +29,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeFunctionArgument:
|
||||
name: b
|
||||
name: MissingTypeFunctionArgument
|
||||
body: "Missing type annotation for function argument `b`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 4
|
||||
column: 11
|
||||
@@ -36,8 +42,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: foo
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `foo`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 9
|
||||
column: 4
|
||||
@@ -47,8 +55,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeFunctionArgument:
|
||||
name: b
|
||||
name: MissingTypeFunctionArgument
|
||||
body: "Missing type annotation for function argument `b`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 9
|
||||
column: 16
|
||||
@@ -58,8 +68,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeFunctionArgument:
|
||||
name: b
|
||||
name: MissingTypeFunctionArgument
|
||||
body: "Missing type annotation for function argument `b`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 14
|
||||
column: 16
|
||||
@@ -69,8 +81,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: foo
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `foo`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 19
|
||||
column: 4
|
||||
@@ -80,8 +94,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: foo
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `foo`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 24
|
||||
column: 4
|
||||
@@ -91,8 +107,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: a
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `a`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 44
|
||||
column: 11
|
||||
@@ -102,8 +120,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: foo
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `foo`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 49
|
||||
column: 46
|
||||
@@ -113,8 +133,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: "*args"
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `*args`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 54
|
||||
column: 23
|
||||
@@ -124,8 +146,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: "**kwargs"
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `**kwargs`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 54
|
||||
column: 38
|
||||
@@ -135,8 +159,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: "*args"
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `*args`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 59
|
||||
column: 23
|
||||
@@ -146,8 +172,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: "**kwargs"
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `**kwargs`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 64
|
||||
column: 38
|
||||
@@ -157,8 +185,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeSelf:
|
||||
name: self
|
||||
name: MissingTypeSelf
|
||||
body: "Missing type annotation for `self` in method"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 74
|
||||
column: 12
|
||||
@@ -168,8 +198,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: a
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `a`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 78
|
||||
column: 28
|
||||
@@ -179,8 +211,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: foo
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `foo`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 82
|
||||
column: 66
|
||||
@@ -190,8 +224,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: "*params"
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `*params`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 86
|
||||
column: 42
|
||||
@@ -201,8 +237,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: "**options"
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `**options`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 86
|
||||
column: 58
|
||||
@@ -212,8 +250,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: "*params"
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `*params`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 90
|
||||
column: 42
|
||||
@@ -223,8 +263,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
AnyType:
|
||||
name: "**options"
|
||||
name: AnyType
|
||||
body: "Dynamically typed expressions (typing.Any) are disallowed in `**options`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 94
|
||||
column: 58
|
||||
@@ -234,8 +276,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeCls:
|
||||
name: cls
|
||||
name: MissingTypeCls
|
||||
body: "Missing type annotation for `cls` in classmethod"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 104
|
||||
column: 12
|
||||
@@ -245,8 +289,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeSelf:
|
||||
name: self
|
||||
name: MissingTypeSelf
|
||||
body: "Missing type annotation for `self` in method"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 108
|
||||
column: 12
|
||||
|
||||
@@ -3,8 +3,10 @@ source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: error_partially_typed_1
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `error_partially_typed_1`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 24
|
||||
column: 4
|
||||
@@ -14,8 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeFunctionArgument:
|
||||
name: b
|
||||
name: MissingTypeFunctionArgument
|
||||
body: "Missing type annotation for function argument `b`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 24
|
||||
column: 36
|
||||
@@ -25,8 +29,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeFunctionArgument:
|
||||
name: b
|
||||
name: MissingTypeFunctionArgument
|
||||
body: "Missing type annotation for function argument `b`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 28
|
||||
column: 36
|
||||
@@ -36,8 +42,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: error_partially_typed_3
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `error_partially_typed_3`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 32
|
||||
column: 4
|
||||
@@ -47,8 +55,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: error_typed_self
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `error_typed_self`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 43
|
||||
column: 8
|
||||
|
||||
@@ -3,8 +3,10 @@ source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
MissingReturnTypeSpecialMethod:
|
||||
name: __init__
|
||||
name: MissingReturnTypeSpecialMethod
|
||||
body: "Missing return type annotation for special method `__init__`"
|
||||
suggestion: "Add `None` return type"
|
||||
fixable: true
|
||||
location:
|
||||
row: 5
|
||||
column: 8
|
||||
@@ -21,8 +23,10 @@ expression: diagnostics
|
||||
column: 22
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingReturnTypeSpecialMethod:
|
||||
name: __init__
|
||||
name: MissingReturnTypeSpecialMethod
|
||||
body: "Missing return type annotation for special method `__init__`"
|
||||
suggestion: "Add `None` return type"
|
||||
fixable: true
|
||||
location:
|
||||
row: 11
|
||||
column: 8
|
||||
@@ -39,8 +43,10 @@ expression: diagnostics
|
||||
column: 27
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingReturnTypePrivateFunction:
|
||||
name: __init__
|
||||
name: MissingReturnTypePrivateFunction
|
||||
body: "Missing return type annotation for private function `__init__`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 40
|
||||
column: 4
|
||||
@@ -50,8 +56,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingReturnTypeSpecialMethod:
|
||||
name: __init__
|
||||
name: MissingReturnTypeSpecialMethod
|
||||
body: "Missing return type annotation for special method `__init__`"
|
||||
suggestion: "Add `None` return type"
|
||||
fixable: true
|
||||
location:
|
||||
row: 47
|
||||
column: 8
|
||||
|
||||
@@ -3,8 +3,10 @@ source: crates/ruff/src/rules/flake8_annotations/mod.rs
|
||||
expression: diagnostics
|
||||
---
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: foo
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `foo`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 45
|
||||
column: 4
|
||||
@@ -14,8 +16,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingReturnTypePublicFunction:
|
||||
name: foo
|
||||
name: MissingReturnTypePublicFunction
|
||||
body: "Missing return type annotation for public function `foo`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 50
|
||||
column: 4
|
||||
@@ -25,8 +29,10 @@ expression: diagnostics
|
||||
fix: ~
|
||||
parent: ~
|
||||
- kind:
|
||||
MissingTypeFunctionArgument:
|
||||
name: a
|
||||
name: MissingTypeFunctionArgument
|
||||
body: "Missing type annotation for function argument `a`"
|
||||
suggestion: ~
|
||||
fixable: false
|
||||
location:
|
||||
row: 59
|
||||
column: 8
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user