Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0b9188011b | ||
|
|
b657d912d9 | ||
|
|
1559671093 | ||
|
|
70a53bf12b | ||
|
|
cd1e07f37c | ||
|
|
7bd6db62d9 | ||
|
|
f8b49f308d | ||
|
|
b1f9c7b6bd | ||
|
|
0867d2ded9 | ||
|
|
3f597a3b30 | ||
|
|
6733aad216 | ||
|
|
89980ad651 | ||
|
|
38f896502a | ||
|
|
7cab541343 | ||
|
|
1a3d2ead41 | ||
|
|
f96c64b40d | ||
|
|
0791869451 | ||
|
|
965918744b | ||
|
|
6b4aedb366 | ||
|
|
8123e3e94e | ||
|
|
9f9a545c51 | ||
|
|
5bf8219db3 | ||
|
|
529513bf02 | ||
|
|
124782771f | ||
|
|
98cab5cdba | ||
|
|
40f38c94a5 | ||
|
|
7839204bf7 | ||
|
|
e63ea704f0 |
8
.github/workflows/flake8-to-ruff.yaml
vendored
8
.github/workflows/flake8-to-ruff.yaml
vendored
@@ -34,7 +34,6 @@ jobs:
|
||||
with:
|
||||
target: x86_64
|
||||
args: --release --out dist --sdist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel - x86_64
|
||||
run: |
|
||||
pip install dist/${{ env.CRATE_NAME }}-*.whl --force-reinstall
|
||||
@@ -61,7 +60,6 @@ jobs:
|
||||
uses: messense/maturin-action@v1
|
||||
with:
|
||||
args: --release --universal2 --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel - universal2
|
||||
run: |
|
||||
pip install dist/${{ env.CRATE_NAME }}-*universal2.whl --force-reinstall
|
||||
@@ -93,7 +91,6 @@ jobs:
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
args: --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -121,7 +118,6 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel
|
||||
if: matrix.target == 'x86_64'
|
||||
run: |
|
||||
@@ -148,7 +144,6 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --no-default-features --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
maturin-version: "v0.13.0"
|
||||
- uses: uraimo/run-on-arch-action@v2.0.5
|
||||
if: matrix.target != 'ppc64'
|
||||
name: Install built wheel
|
||||
@@ -187,7 +182,6 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: musllinux_1_2
|
||||
args: --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel
|
||||
if: matrix.target == 'x86_64-unknown-linux-musl'
|
||||
uses: addnab/docker-run-action@v3
|
||||
@@ -223,7 +217,6 @@ jobs:
|
||||
target: ${{ matrix.platform.target }}
|
||||
manylinux: musllinux_1_2
|
||||
args: --release --out dist -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
maturin-version: "v0.13.0"
|
||||
- uses: uraimo/run-on-arch-action@master
|
||||
name: Install built wheel
|
||||
with:
|
||||
@@ -261,7 +254,6 @@ jobs:
|
||||
- name: Build wheels
|
||||
uses: messense/maturin-action@v1
|
||||
with:
|
||||
maturin-version: "v0.13.0"
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --release --out dist -i pypy${{ matrix.python-version }} -m ./${{ env.CRATE_NAME }}/Cargo.toml
|
||||
|
||||
8
.github/workflows/ruff.yaml
vendored
8
.github/workflows/ruff.yaml
vendored
@@ -36,7 +36,6 @@ jobs:
|
||||
with:
|
||||
target: x86_64
|
||||
args: --release --out dist --sdist
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel - x86_64
|
||||
run: |
|
||||
pip install dist/${{ env.PACKAGE_NAME }}-*.whl --force-reinstall
|
||||
@@ -63,7 +62,6 @@ jobs:
|
||||
uses: messense/maturin-action@v1
|
||||
with:
|
||||
args: --release --universal2 --out dist
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel - universal2
|
||||
run: |
|
||||
pip install dist/${{ env.PACKAGE_NAME }}-*universal2.whl --force-reinstall
|
||||
@@ -95,7 +93,6 @@ jobs:
|
||||
with:
|
||||
target: ${{ matrix.target }}
|
||||
args: --release --out dist
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -123,7 +120,6 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --release --out dist
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel
|
||||
if: matrix.target == 'x86_64'
|
||||
run: |
|
||||
@@ -150,7 +146,6 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --no-default-features --release --out dist
|
||||
maturin-version: "v0.13.0"
|
||||
- uses: uraimo/run-on-arch-action@v2.0.5
|
||||
if: matrix.target != 'ppc64'
|
||||
name: Install built wheel
|
||||
@@ -189,7 +184,6 @@ jobs:
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: musllinux_1_2
|
||||
args: --release --out dist
|
||||
maturin-version: "v0.13.0"
|
||||
- name: Install built wheel
|
||||
if: matrix.target == 'x86_64-unknown-linux-musl'
|
||||
uses: addnab/docker-run-action@v3
|
||||
@@ -225,7 +219,6 @@ jobs:
|
||||
target: ${{ matrix.platform.target }}
|
||||
manylinux: musllinux_1_2
|
||||
args: --release --out dist
|
||||
maturin-version: "v0.13.0"
|
||||
- uses: uraimo/run-on-arch-action@master
|
||||
name: Install built wheel
|
||||
with:
|
||||
@@ -263,7 +256,6 @@ jobs:
|
||||
- name: Build wheels
|
||||
uses: messense/maturin-action@v1
|
||||
with:
|
||||
maturin-version: "v0.13.0"
|
||||
target: ${{ matrix.target }}
|
||||
manylinux: auto
|
||||
args: --release --out dist -i pypy${{ matrix.python-version }}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
repos:
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.129
|
||||
rev: v0.0.133
|
||||
hooks:
|
||||
- id: ruff
|
||||
|
||||
|
||||
652
Cargo.lock
generated
652
Cargo.lock
generated
@@ -94,133 +94,6 @@ dependencies = [
|
||||
"wait-timeout",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e14485364214912d3b19cc3435dde4df66065127f05fa0d75c712f36f12c2f28"
|
||||
dependencies = [
|
||||
"concurrent-queue",
|
||||
"event-listener",
|
||||
"futures-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-executor"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "871f9bb5e0a22eeb7e8cf16641feb87c9dc67032ccf8ff49e772eb9941d3a965"
|
||||
dependencies = [
|
||||
"async-task",
|
||||
"concurrent-queue",
|
||||
"fastrand",
|
||||
"futures-lite",
|
||||
"once_cell",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-global-executor"
|
||||
version = "2.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-executor",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"blocking",
|
||||
"futures-lite",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-io"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e8121296a9f05be7f34aa4196b1747243b3b62e048bb7906f644f3fbfc490cf7"
|
||||
dependencies = [
|
||||
"async-lock",
|
||||
"autocfg",
|
||||
"concurrent-queue",
|
||||
"futures-lite",
|
||||
"libc",
|
||||
"log",
|
||||
"parking",
|
||||
"polling",
|
||||
"slab",
|
||||
"socket2",
|
||||
"waker-fn",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-lock"
|
||||
version = "2.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c8101efe8695a6c17e02911402145357e718ac92d3ff88ae8419e84b1707b685"
|
||||
dependencies = [
|
||||
"event-listener",
|
||||
"futures-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-process"
|
||||
version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02111fd8655a613c25069ea89fc8d9bb89331fa77486eb3bc059ee757cfa481c"
|
||||
dependencies = [
|
||||
"async-io",
|
||||
"autocfg",
|
||||
"blocking",
|
||||
"cfg-if 1.0.0",
|
||||
"event-listener",
|
||||
"futures-lite",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"signal-hook",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-std"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-global-executor",
|
||||
"async-io",
|
||||
"async-lock",
|
||||
"async-process",
|
||||
"crossbeam-utils",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-lite",
|
||||
"gloo-timers",
|
||||
"kv-log-macro",
|
||||
"log",
|
||||
"memchr",
|
||||
"once_cell",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
"wasm-bindgen-futures",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-task"
|
||||
version = "4.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a40729d2133846d9ed0ea60a8b9541bccddab49cd30f0715a1da672fe9a2524"
|
||||
|
||||
[[package]]
|
||||
name = "atomic-waker"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "065374052e7df7ee4047b1160cca5e1467a12351a40b3da123c870ba0b8eda2a"
|
||||
|
||||
[[package]]
|
||||
name = "atty"
|
||||
version = "0.2.14"
|
||||
@@ -238,15 +111,6 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b25d992356d2eb0ed82172f5248873db5560c4721f564b13cb5193bda5e668e"
|
||||
dependencies = [
|
||||
"byteorder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
@@ -283,50 +147,6 @@ version = "1.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
|
||||
dependencies = [
|
||||
"block-padding",
|
||||
"byte-tools",
|
||||
"byteorder",
|
||||
"generic-array 0.12.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-buffer"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4"
|
||||
dependencies = [
|
||||
"generic-array 0.14.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "block-padding"
|
||||
version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fa79dedbb091f449f1f39e53edf88d5dbe95f895dae6135a8d7b881fb5af73f5"
|
||||
dependencies = [
|
||||
"byte-tools",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "blocking"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c6ccb65d468978a086b69884437ded69a90faab3bbe6e67f242173ea728acccc"
|
||||
dependencies = [
|
||||
"async-channel",
|
||||
"async-task",
|
||||
"atomic-waker",
|
||||
"fastrand",
|
||||
"futures-lite",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
version = "0.2.17"
|
||||
@@ -357,46 +177,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "572f695136211188308f16ad2ca5c851a712c464060ae6974944458eb83880ba"
|
||||
|
||||
[[package]]
|
||||
name = "byte-tools"
|
||||
version = "0.3.1"
|
||||
name = "cachedir"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
|
||||
|
||||
[[package]]
|
||||
name = "byteorder"
|
||||
version = "1.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "14c189c53d098945499cdfa7ecc63567cf3886b3332b312a5b4585d8d3a6a610"
|
||||
|
||||
[[package]]
|
||||
name = "cacache"
|
||||
version = "10.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5c13caedf5b624de6448b78e980320a27266557350198dc67cf64bc8561c27e8"
|
||||
checksum = "e236bf5873ea57ec2877445297f4da008916bfae51567131acfc54a073d694f3"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"digest 0.9.0",
|
||||
"either",
|
||||
"futures",
|
||||
"hex 0.4.3",
|
||||
"memmap2",
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sha-1 0.9.8",
|
||||
"sha2 0.9.9",
|
||||
"ssri",
|
||||
"tempfile",
|
||||
"thiserror",
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cache-padded"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c1db59621ec70f09c5e9b597b220c7a2b43611f4710dc03ceb8748637775692c"
|
||||
|
||||
[[package]]
|
||||
name = "cast"
|
||||
version = "0.3.0"
|
||||
@@ -582,15 +370,6 @@ version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2382f75942f4b3be3690fe4f86365e9c853c1587d6ee58212cebf6e2a9ccd101"
|
||||
|
||||
[[package]]
|
||||
name = "concurrent-queue"
|
||||
version = "1.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "af4780a44ab5696ea9e28294517f1fffb421a83a25af521333c838635509db9c"
|
||||
dependencies = [
|
||||
"cache-padded",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "configparser"
|
||||
version = "3.0.2"
|
||||
@@ -616,15 +395,6 @@ version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.3.2"
|
||||
@@ -719,16 +489,6 @@ version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[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.81"
|
||||
@@ -785,24 +545,6 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3d0c8c8752312f9713efd397ff63acb9f85585afbf179282e720e7704954dd5"
|
||||
dependencies = [
|
||||
"generic-array 0.12.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "digest"
|
||||
version = "0.9.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066"
|
||||
dependencies = [
|
||||
"generic-array 0.14.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "directories"
|
||||
version = "4.0.1"
|
||||
@@ -890,18 +632,6 @@ version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "event-listener"
|
||||
version = "2.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
|
||||
|
||||
[[package]]
|
||||
name = "fake-simd"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.8.0"
|
||||
@@ -940,15 +670,15 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.129-dev.0"
|
||||
version = "0.0.133-dev.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.0.22",
|
||||
"configparser",
|
||||
"fnv",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"ruff",
|
||||
"rustc-hash",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"toml",
|
||||
@@ -1014,129 +744,6 @@ version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "38390104763dc37a5145a53c29c63c1290b5d316d6086ec32c293f6736051bb0"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-executor",
|
||||
"futures-io",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-channel"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52ba265a92256105f45b719605a571ffe2d1f0fea3807304b522c1d778f79eed"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-core"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04909a7a7e4633ae6c4a9ab280aeb86da1236243a77b694a49eacd659a4bd3ac"
|
||||
|
||||
[[package]]
|
||||
name = "futures-executor"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7acc85df6714c176ab5edf386123fafe217be88c0840ec11f199441134a074e2"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-task",
|
||||
"futures-util",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-io"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00f5fb52a06bdcadeb54e8d3671f8888a39697dcb0b81b23b55174030427f4eb"
|
||||
|
||||
[[package]]
|
||||
name = "futures-lite"
|
||||
version = "1.12.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7694489acd39452c77daa48516b894c153f192c3578d5a839b62c58099fcbf48"
|
||||
dependencies = [
|
||||
"fastrand",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"memchr",
|
||||
"parking",
|
||||
"pin-project-lite",
|
||||
"waker-fn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-macro"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bdfb8ce053d86b91919aad980c220b1fb8401a9394410e1c289ed7e66b61835d"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "futures-sink"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "39c15cf1a4aa79df40f1bb462fb39676d0ad9e366c2a33b590d7c66f4f81fcf9"
|
||||
|
||||
[[package]]
|
||||
name = "futures-task"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2ffb393ac5d9a6eaa9d3fdf37ae2776656b706e200c8e16b1bdb227f5198e6ea"
|
||||
|
||||
[[package]]
|
||||
name = "futures-util"
|
||||
version = "0.3.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "197676987abd2f9cadff84926f410af1c183608d36641465df73ae8211dc65d6"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-io",
|
||||
"futures-macro",
|
||||
"futures-sink",
|
||||
"futures-task",
|
||||
"memchr",
|
||||
"pin-project-lite",
|
||||
"pin-utils",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.12.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ffdf9f34f1447443d37393cc6c2b8313aebddcd96906caf34e54c68d8e57d7bd"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9"
|
||||
dependencies = [
|
||||
"typenum",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
@@ -1167,18 +774,6 @@ version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
|
||||
|
||||
[[package]]
|
||||
name = "gloo-timers"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5fb7d06c1c8cc2a29bee7ec961009a0b2caa0793ee4900c2ffb348734ba1c8f9"
|
||||
dependencies = [
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "1.8.2"
|
||||
@@ -1209,18 +804,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "805026a5d0141ffc30abb3be3173848ad46a1b1664fe632428479619a3644d77"
|
||||
|
||||
[[package]]
|
||||
name = "hex"
|
||||
version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hexf-parse"
|
||||
version = "0.2.1"
|
||||
@@ -1363,15 +946,6 @@ dependencies = [
|
||||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kv-log-macro"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0de8b303297635ad57c9f5059fd9cee7a47f8e8daa09df0fcd07dd39fb22977f"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop"
|
||||
version = "0.19.8"
|
||||
@@ -1508,7 +1082,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"value-bag",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1532,15 +1105,6 @@ version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memmap2"
|
||||
version = "0.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "95af15f345b17af2efc8ead6080fb8bc376f8cec1b35277b935637595fe77498"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
@@ -1727,30 +1291,12 @@ version = "11.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2839e79665f131bdb5782e51f2c6c9599c133c6098982a54c794358bf432529c"
|
||||
|
||||
[[package]]
|
||||
name = "opaque-debug"
|
||||
version = "0.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9"
|
||||
|
||||
[[package]]
|
||||
name = "parking"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "427c3892f9e783d91cc128285287e70a59e206ca452770ece88a76f7a3eddd72"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
@@ -1923,18 +1469,6 @@ version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
|
||||
|
||||
[[package]]
|
||||
name = "pin-utils"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
|
||||
|
||||
[[package]]
|
||||
name = "plotters"
|
||||
version = "0.3.4"
|
||||
@@ -1963,20 +1497,6 @@ dependencies = [
|
||||
"plotters-backend",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab4609a838d88b73d8238967b60dd115cc08d38e2bbaf51ee1e4b695f89122e2"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"log",
|
||||
"wepoll-ffi",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ppv-lite86"
|
||||
version = "0.2.17"
|
||||
@@ -2248,7 +1768,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.129"
|
||||
version = "0.0.133"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.9.1",
|
||||
"anyhow",
|
||||
@@ -2256,7 +1776,7 @@ dependencies = [
|
||||
"atty",
|
||||
"bincode",
|
||||
"bitflags",
|
||||
"cacache",
|
||||
"cachedir",
|
||||
"chrono",
|
||||
"clap 4.0.22",
|
||||
"clearscreen",
|
||||
@@ -2266,7 +1786,6 @@ dependencies = [
|
||||
"dirs 4.0.0",
|
||||
"fern",
|
||||
"filetime",
|
||||
"fnv",
|
||||
"getrandom 0.2.8",
|
||||
"glob",
|
||||
"insta",
|
||||
@@ -2281,6 +1800,7 @@ dependencies = [
|
||||
"rayon",
|
||||
"regex",
|
||||
"ropey",
|
||||
"rustc-hash",
|
||||
"rustpython-ast",
|
||||
"rustpython-common",
|
||||
"rustpython-parser",
|
||||
@@ -2298,7 +1818,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_dev"
|
||||
version = "0.0.129"
|
||||
version = "0.0.133"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.0.22",
|
||||
@@ -2313,6 +1833,12 @@ dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.20.7"
|
||||
@@ -2328,7 +1854,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-ast"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb#27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"rustpython-common",
|
||||
@@ -2338,7 +1864,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-common"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb#27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
dependencies = [
|
||||
"ascii",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -2361,7 +1887,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-compiler-core"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb#27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitflags",
|
||||
@@ -2378,7 +1904,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-parser"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb#27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
@@ -2390,6 +1916,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"phf 0.10.1",
|
||||
"phf_codegen 0.10.0",
|
||||
"rustc-hash",
|
||||
"rustpython-ast",
|
||||
"rustpython-compiler-core",
|
||||
"thiserror",
|
||||
@@ -2479,75 +2006,6 @@ dependencies = [
|
||||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f7d94d0bede923b3cea61f3f1ff57ff8cdfd77b400fb8f9998949e0cf04163df"
|
||||
dependencies = [
|
||||
"block-buffer 0.7.3",
|
||||
"digest 0.8.1",
|
||||
"fake-simd",
|
||||
"opaque-debug 0.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha-1"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "99cd6713db3cf16b6c84e06321e049a9b9f699826e16096d23bbcc44d15d51a6"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.8.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a256f46ea78a0c0d9ff00077504903ac881a1dafdc20da66545699e7776b3e69"
|
||||
dependencies = [
|
||||
"block-buffer 0.7.3",
|
||||
"digest 0.8.1",
|
||||
"fake-simd",
|
||||
"opaque-debug 0.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sha2"
|
||||
version = "0.9.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800"
|
||||
dependencies = [
|
||||
"block-buffer 0.9.0",
|
||||
"cfg-if 1.0.0",
|
||||
"cpufeatures",
|
||||
"digest 0.9.0",
|
||||
"opaque-debug 0.3.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook"
|
||||
version = "0.3.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a253b5e89e2698464fc26b545c9edceb338e18a89effeeecfea192c3025be29d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "signal-hook-registry"
|
||||
version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.2.0"
|
||||
@@ -2581,37 +2039,12 @@ version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f67ad224767faa3c7d8b6d91985b78e70a1324408abcb1cfcc2be4c06bc06043"
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "02e2d2db9033d13a1567121ddd7a095ee144db4e1ca1b1bda3419bc0da294ebd"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "spin"
|
||||
version = "0.5.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
|
||||
[[package]]
|
||||
name = "ssri"
|
||||
version = "7.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a9cec0d388f39fbe79d7aa600e8d38053bf97b1bc8d350da7c0ba800d0f423f2"
|
||||
dependencies = [
|
||||
"base64 0.10.1",
|
||||
"digest 0.8.1",
|
||||
"hex 0.3.2",
|
||||
"serde",
|
||||
"sha-1 0.8.2",
|
||||
"sha2 0.8.2",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
version = "1.1.0"
|
||||
@@ -2856,12 +2289,6 @@ dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typenum"
|
||||
version = "1.15.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987"
|
||||
|
||||
[[package]]
|
||||
name = "unic-char-property"
|
||||
version = "0.9.0"
|
||||
@@ -3000,7 +2427,7 @@ version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b97acb4c28a254fd7a4aeec976c46a7fa404eac4d7c134b30c75144846d7cb8f"
|
||||
dependencies = [
|
||||
"base64 0.13.1",
|
||||
"base64",
|
||||
"chunked_transfer",
|
||||
"flate2",
|
||||
"log",
|
||||
@@ -3024,16 +2451,6 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "value-bag"
|
||||
version = "1.0.0-alpha.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2209b78d1249f7e6f3293657c9779fe31ced465df091bbd433a1cf88e916ec55"
|
||||
dependencies = [
|
||||
"ctor",
|
||||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.4"
|
||||
@@ -3055,12 +2472,6 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "waker-fn"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9d5b2c62b4012a3e1eca5a7e077d13b3bf498c4073e33ccd58626607748ceeca"
|
||||
|
||||
[[package]]
|
||||
name = "walkdir"
|
||||
version = "2.3.2"
|
||||
@@ -3109,18 +2520,6 @@ dependencies = [
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-futures"
|
||||
version = "0.4.33"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23639446165ca5a5de86ae1d8896b737ae80319560fbaa4c2887b7da6e7ebd7d"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen-macro"
|
||||
version = "0.2.83"
|
||||
@@ -3179,15 +2578,6 @@ dependencies = [
|
||||
"webpki",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wepoll-ffi"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d743fdedc5c64377b5fc2bc036b01c7fd642205a0d96356034ae3404d49eb7fb"
|
||||
dependencies = [
|
||||
"cc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "which"
|
||||
version = "4.3.0"
|
||||
|
||||
12
Cargo.toml
12
Cargo.toml
@@ -6,7 +6,7 @@ members = [
|
||||
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.0.129"
|
||||
version = "0.0.133"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
@@ -18,6 +18,7 @@ anyhow = { version = "1.0.66" }
|
||||
atty = { version = "0.2.14" }
|
||||
bincode = { version = "1.3.3" }
|
||||
bitflags = { version = "1.3.2" }
|
||||
cachedir = { version = "0.3.0" }
|
||||
chrono = { version = "0.4.21", default-features = false, features = ["clock"] }
|
||||
clap = { version = "4.0.1", features = ["derive"] }
|
||||
colored = { version = "2.0.0" }
|
||||
@@ -25,7 +26,6 @@ common-path = { version = "1.0.0" }
|
||||
dirs = { version = "4.0.0" }
|
||||
fern = { version = "0.6.1" }
|
||||
filetime = { version = "0.2.17" }
|
||||
fnv = { version = "1.0.7" }
|
||||
glob = { version = "0.3.0" }
|
||||
itertools = { version = "0.10.5" }
|
||||
libcst = { git = "https://github.com/charliermarsh/LibCST", rev = "a13ec97dd4eb925bde4d426c6e422582793b260c" }
|
||||
@@ -38,9 +38,10 @@ path-absolutize = { version = "3.0.14", features = ["once_cell_cache", "use_unix
|
||||
rayon = { version = "1.5.3" }
|
||||
regex = { version = "1.6.0" }
|
||||
ropey = { version = "1.5.0", features = ["cr_lines", "simd"], default-features = false }
|
||||
rustpython-ast = { features = ["unparse"], git = "https://github.com/RustPython/RustPython.git", rev = "27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb" }
|
||||
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb" }
|
||||
rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb" }
|
||||
rustc-hash = { version = "1.1.0" }
|
||||
rustpython-ast = { features = ["unparse"], git = "https://github.com/RustPython/RustPython.git", rev = "f885db8c61514f069979861f6b3bd83292086231" }
|
||||
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "f885db8c61514f069979861f6b3bd83292086231" }
|
||||
rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "f885db8c61514f069979861f6b3bd83292086231" }
|
||||
serde = { version = "1.0.147", features = ["derive"] }
|
||||
serde_json = { version = "1.0.87" }
|
||||
strum = { version = "0.24.1", features = ["strum_macros"] }
|
||||
@@ -52,7 +53,6 @@ update-informer = { version = "0.5.0", default-features = false, features = ["py
|
||||
walkdir = { version = "2.3.2" }
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||
cacache = { version = "10.0.1" } # uses async-std
|
||||
clearscreen = { version = "1.0.10" } # uses which
|
||||
|
||||
# https://docs.rs/getrandom/0.2.7/getrandom/#webassembly-support
|
||||
|
||||
18
README.md
18
README.md
@@ -155,6 +155,10 @@ dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
|
||||
|
||||
# Assume Python 3.10.
|
||||
target-version = "py310"
|
||||
|
||||
[tool.ruff.mccabe]
|
||||
# Unlike Flake8, default to a complexity level of 10.
|
||||
max-complexity = 10
|
||||
```
|
||||
|
||||
As an example, the following would configure Ruff to: (1) avoid checking for line-length
|
||||
@@ -465,7 +469,8 @@ For more, see [pyupgrade](https://pypi.org/project/pyupgrade/3.2.0/) on PyPI.
|
||||
| U010 | UnnecessaryFutureImport | Unnecessary `__future__` import `...` for target Python version | 🛠 |
|
||||
| U011 | UnnecessaryLRUCacheParams | Unnecessary parameters to `functools.lru_cache` | 🛠 |
|
||||
| U012 | UnnecessaryEncodeUTF8 | Unnecessary call to `encode` as UTF-8 | 🛠 |
|
||||
| U013 | ConvertTypedDictFunctionalToClass | Convert `TypedDict` functional syntax to class syntax | 🛠 |
|
||||
| U013 | ConvertTypedDictFunctionalToClass | Convert `...` from `TypedDict` functional to class syntax | 🛠 |
|
||||
| U014 | ConvertNamedTupleFunctionalToClass | Convert `...` from `NamedTuple` functional to class syntax | 🛠 |
|
||||
|
||||
### pep8-naming
|
||||
|
||||
@@ -549,10 +554,10 @@ For more, see [flake8-bugbear](https://pypi.org/project/flake8-bugbear/22.10.27/
|
||||
| B007 | UnusedLoopControlVariable | Loop control variable `i` not used within the loop body | 🛠 |
|
||||
| B008 | FunctionCallArgumentDefault | Do not perform function call in argument defaults | |
|
||||
| B009 | GetAttrWithConstant | Do not call `getattr` with a constant attribute value. It is not any safer than normal property access. | 🛠 |
|
||||
| B010 | SetAttrWithConstant | Do not call `setattr` with a constant attribute value. It is not any safer than normal property access. | |
|
||||
| B010 | SetAttrWithConstant | Do not call `setattr` with a constant attribute value. It is not any safer than normal property access. | 🛠 |
|
||||
| B011 | DoNotAssertFalse | Do not `assert False` (`python -O` removes these calls), raise `AssertionError()` | 🛠 |
|
||||
| B012 | JumpStatementInFinally | `return/continue/break` inside finally blocks cause exceptions to be silenced | |
|
||||
| B013 | RedundantTupleInExceptionHandler | A length-one tuple literal is redundant. Write `except ValueError` instead of `except (ValueError,)`. | |
|
||||
| B013 | RedundantTupleInExceptionHandler | A length-one tuple literal is redundant. Write `except ValueError` instead of `except (ValueError,)`. | 🛠 |
|
||||
| B014 | DuplicateHandlerException | Exception handler with duplicate exception: `ValueError` | 🛠 |
|
||||
| B015 | UselessComparison | Pointless comparison. This comparison does nothing but waste CPU instructions. Either prepend `assert` or remove it. | |
|
||||
| B016 | CannotRaiseLiteral | Cannot raise a literal. Did you intend to return it or raise an Exception? | |
|
||||
@@ -663,6 +668,7 @@ For more, see [mccabe](https://pypi.org/project/mccabe/0.7.0/) on PyPI.
|
||||
| RUF001 | AmbiguousUnicodeCharacterString | String contains ambiguous unicode character '𝐁' (did you mean 'B'?) | 🛠 |
|
||||
| RUF002 | AmbiguousUnicodeCharacterDocstring | Docstring contains ambiguous unicode character '𝐁' (did you mean 'B'?) | 🛠 |
|
||||
| RUF003 | AmbiguousUnicodeCharacterComment | Comment contains ambiguous unicode character '𝐁' (did you mean 'B'?) | |
|
||||
| RUF101 | ConvertExitToSysExit | `exit()` is only available in the interpreter, use `sys.exit()` instead | 🛠 |
|
||||
|
||||
### Meta rules
|
||||
|
||||
@@ -820,7 +826,7 @@ including:
|
||||
- [`flake8-boolean-trap`](https://pypi.org/project/flake8-boolean-trap/)
|
||||
- [`mccabe`](https://pypi.org/project/mccabe/)
|
||||
- [`isort`](https://pypi.org/project/isort/)
|
||||
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (14/33)
|
||||
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (15/33)
|
||||
- [`autoflake`](https://pypi.org/project/autoflake/) (1/7)
|
||||
|
||||
Beyond rule-set parity, Ruff suffers from the following limitations vis-à-vis Flake8:
|
||||
@@ -852,7 +858,7 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl
|
||||
- [`mccabe`](https://pypi.org/project/mccabe/)
|
||||
|
||||
Ruff can also replace [`isort`](https://pypi.org/project/isort/), [`yesqa`](https://github.com/asottile/yesqa),
|
||||
and a subset of the rules implemented in [`pyupgrade`](https://pypi.org/project/pyupgrade/) (14/33).
|
||||
and a subset of the rules implemented in [`pyupgrade`](https://pypi.org/project/pyupgrade/) (15/33).
|
||||
|
||||
If you're looking to use Ruff, but rely on an unsupported Flake8 plugin, free to file an Issue.
|
||||
|
||||
@@ -891,7 +897,7 @@ select = [
|
||||
"E",
|
||||
"W",
|
||||
# isort
|
||||
"I"
|
||||
"I001"
|
||||
]
|
||||
src = ["src", "tests"]
|
||||
|
||||
|
||||
12
flake8_to_ruff/Cargo.lock
generated
12
flake8_to_ruff/Cargo.lock
generated
@@ -771,7 +771,7 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "flake8_to_ruff"
|
||||
version = "0.0.129"
|
||||
version = "0.0.133"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@@ -1975,7 +1975,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.129"
|
||||
version = "0.0.133"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bincode",
|
||||
@@ -2028,7 +2028,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-ast"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb#27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"rustpython-common",
|
||||
@@ -2038,7 +2038,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-common"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb#27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
dependencies = [
|
||||
"ascii",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -2061,7 +2061,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-compiler-core"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb#27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitflags",
|
||||
@@ -2078,7 +2078,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-parser"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb#27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.129-dev.0"
|
||||
version = "0.0.133-dev.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
@@ -10,10 +10,10 @@ name = "flake8_to_ruff"
|
||||
anyhow = { version = "1.0.66" }
|
||||
clap = { version = "4.0.1", features = ["derive"] }
|
||||
configparser = { version = "3.0.2" }
|
||||
fnv = { version = "1.0.7" }
|
||||
once_cell = { version = "1.16.0" }
|
||||
regex = { version = "1.6.0" }
|
||||
ruff = { path = "..", default-features = false }
|
||||
rustc-hash = { version = "1.1.0" }
|
||||
serde = { version = "1.0.147", features = ["derive"] }
|
||||
serde_json = { version = "1.0.87" }
|
||||
toml = { version = "0.5.9" }
|
||||
|
||||
@@ -25,7 +25,7 @@ requires-python = ">=3.7"
|
||||
repository = "https://github.com/charliermarsh/ruff#subdirectory=crates/flake8_to_ruff"
|
||||
|
||||
[build-system]
|
||||
requires = ["maturin>=0.13,<0.14"]
|
||||
requires = ["maturin>=0.14,<0.15"]
|
||||
build-backend = "maturin"
|
||||
|
||||
[tool.maturin]
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
use fnv::FnvHashMap;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use ruff::checks_gen::CheckCodePrefix;
|
||||
use ruff::settings::types::PatternPrefixPair;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
static COMMA_SEPARATED_LIST_RE: Lazy<Regex> = Lazy::new(|| Regex::new(r"[,\s]").unwrap());
|
||||
|
||||
@@ -179,8 +179,8 @@ pub fn parse_files_to_codes_mapping(value: &str) -> Result<Vec<PatternPrefixPair
|
||||
/// Collect a list of `PatternPrefixPair` structs as a `BTreeMap`.
|
||||
pub fn collect_per_file_ignores(
|
||||
pairs: Vec<PatternPrefixPair>,
|
||||
) -> FnvHashMap<String, Vec<CheckCodePrefix>> {
|
||||
let mut per_file_ignores: FnvHashMap<String, Vec<CheckCodePrefix>> = FnvHashMap::default();
|
||||
) -> FxHashMap<String, Vec<CheckCodePrefix>> {
|
||||
let mut per_file_ignores: FxHashMap<String, Vec<CheckCodePrefix>> = FxHashMap::default();
|
||||
for pair in pairs {
|
||||
per_file_ignores
|
||||
.entry(pair.pattern)
|
||||
|
||||
@@ -25,12 +25,11 @@ requires-python = ">=3.7"
|
||||
repository = "https://github.com/charliermarsh/ruff"
|
||||
|
||||
[build-system]
|
||||
requires = ["maturin>=0.13,<0.14"]
|
||||
requires = ["maturin>=0.14,<0.15"]
|
||||
build-backend = "maturin"
|
||||
|
||||
[tool.maturin]
|
||||
bindings = "bin"
|
||||
sdist-include = ["Cargo.lock"]
|
||||
strip = true
|
||||
|
||||
[tool.isort]
|
||||
|
||||
1
resources/test/fixtures/B009_B010.py
vendored
1
resources/test/fixtures/B009_B010.py
vendored
@@ -34,3 +34,4 @@ setattr(foo, "bar", None)
|
||||
setattr(foo, "_123abc", None)
|
||||
setattr(foo, "abc123", None)
|
||||
setattr(foo, r"abc123", None)
|
||||
setattr(foo.bar, r"baz", None)
|
||||
|
||||
30
resources/test/fixtures/C901.py
vendored
30
resources/test/fixtures/C901.py
vendored
@@ -106,3 +106,33 @@ async def foobar(a, b, c):
|
||||
# Complexity = 1
|
||||
def annotated_assign():
|
||||
x: Any = None
|
||||
|
||||
|
||||
# Complexity = 9
|
||||
class Class:
|
||||
def handle(self, *args, **options):
|
||||
if args:
|
||||
return
|
||||
|
||||
class ServiceProvider:
|
||||
def a(self):
|
||||
pass
|
||||
|
||||
def b(self, data):
|
||||
if not args:
|
||||
pass
|
||||
|
||||
class Logger:
|
||||
def c(*args, **kwargs):
|
||||
pass
|
||||
|
||||
def error(self, message):
|
||||
pass
|
||||
|
||||
def info(self, message):
|
||||
pass
|
||||
|
||||
def exception(self):
|
||||
pass
|
||||
|
||||
return ServiceProvider(Logger())
|
||||
|
||||
8
resources/test/fixtures/N804.py
vendored
8
resources/test/fixtures/N804.py
vendored
@@ -30,6 +30,14 @@ class Class:
|
||||
def __init_subclass__(self, default_name, **kwargs):
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def class_method_with_positional_only_argument(cls, x, /, other):
|
||||
...
|
||||
|
||||
@classmethod
|
||||
def bad_class_method_with_positional_only_argument(self, x, /, other):
|
||||
...
|
||||
|
||||
|
||||
class MetaClass(ABCMeta):
|
||||
def bad_method(self):
|
||||
|
||||
21
resources/test/fixtures/N807.py
vendored
21
resources/test/fixtures/N807.py
vendored
@@ -10,6 +10,27 @@ def good__():
|
||||
pass
|
||||
|
||||
|
||||
def nested():
|
||||
def __bad__():
|
||||
pass
|
||||
|
||||
def __good():
|
||||
pass
|
||||
|
||||
def good__():
|
||||
pass
|
||||
|
||||
|
||||
class Class:
|
||||
def __good__(self):
|
||||
pass
|
||||
|
||||
|
||||
# https://peps.python.org/pep-0562/
|
||||
def __getattr__(name):
|
||||
pass
|
||||
|
||||
|
||||
# https://peps.python.org/pep-0562/
|
||||
def __dir__():
|
||||
pass
|
||||
|
||||
5
resources/test/fixtures/RUF101_0.py
vendored
Normal file
5
resources/test/fixtures/RUF101_0.py
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(2)
|
||||
10
resources/test/fixtures/RUF101_1.py
vendored
Normal file
10
resources/test/fixtures/RUF101_1.py
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
import sys
|
||||
|
||||
exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
|
||||
|
||||
sys.exit(2)
|
||||
7
resources/test/fixtures/RUF101_2.py
vendored
Normal file
7
resources/test/fixtures/RUF101_2.py
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
import sys as sys2
|
||||
|
||||
exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
7
resources/test/fixtures/RUF101_3.py
vendored
Normal file
7
resources/test/fixtures/RUF101_3.py
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
from sys import exit
|
||||
|
||||
exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
7
resources/test/fixtures/RUF101_4.py
vendored
Normal file
7
resources/test/fixtures/RUF101_4.py
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
from sys import exit as exit2
|
||||
|
||||
exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
7
resources/test/fixtures/RUF101_5.py
vendored
Normal file
7
resources/test/fixtures/RUF101_5.py
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
from sys import *
|
||||
|
||||
exit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
12
resources/test/fixtures/RUF101_6.py
vendored
Normal file
12
resources/test/fixtures/RUF101_6.py
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
exit(0)
|
||||
|
||||
|
||||
def exit(e):
|
||||
pass
|
||||
|
||||
|
||||
exit(1)
|
||||
|
||||
|
||||
def main():
|
||||
exit(2)
|
||||
4
resources/test/fixtures/U006.py
vendored
4
resources/test/fixtures/U006.py
vendored
@@ -24,3 +24,7 @@ from typing import List as IList
|
||||
|
||||
def f(x: IList[str]) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f(x: "List[str]") -> None:
|
||||
...
|
||||
|
||||
29
resources/test/fixtures/U007.py
vendored
29
resources/test/fixtures/U007.py
vendored
@@ -1,40 +1,43 @@
|
||||
import typing
|
||||
from typing import Optional
|
||||
from typing import Union
|
||||
|
||||
|
||||
def f(x: Optional[str]) -> None:
|
||||
...
|
||||
|
||||
|
||||
import typing
|
||||
|
||||
|
||||
def f(x: typing.Optional[str]) -> None:
|
||||
...
|
||||
|
||||
|
||||
from typing import Union
|
||||
|
||||
|
||||
def f(x: Union[str, int, Union[float, bytes]]) -> None:
|
||||
...
|
||||
|
||||
|
||||
import typing
|
||||
|
||||
|
||||
def f(x: typing.Union[str, int]) -> None:
|
||||
...
|
||||
|
||||
|
||||
from typing import Union
|
||||
def f(x: typing.Union[(str, int)]) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f(x: typing.Union[(str, int), float]) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f(x: "Union[str, int, Union[float, bytes]]") -> None:
|
||||
...
|
||||
|
||||
|
||||
import typing
|
||||
|
||||
|
||||
def f(x: "typing.Union[str, int]") -> None:
|
||||
...
|
||||
|
||||
|
||||
def f(x: Union["str", int]) -> None:
|
||||
...
|
||||
|
||||
|
||||
def f(x: Union[("str", "int"), float]) -> None:
|
||||
...
|
||||
|
||||
22
resources/test/fixtures/U014.py
vendored
Normal file
22
resources/test/fixtures/U014.py
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
from typing import NamedTuple
|
||||
import typing
|
||||
|
||||
# with complex annotations
|
||||
NT1 = NamedTuple("NT1", [("a", int), ("b", tuple[str, ...])])
|
||||
|
||||
# with default values as list
|
||||
NT2 = NamedTuple(
|
||||
"NT2",
|
||||
[("a", int), ("b", str), ("c", list[bool])],
|
||||
defaults=["foo", [True]],
|
||||
)
|
||||
|
||||
# with namespace
|
||||
NT3 = typing.NamedTuple("NT3", [("a", int), ("b", str)])
|
||||
|
||||
# with too many default values
|
||||
NT4 = NamedTuple(
|
||||
"NT4",
|
||||
[("a", int), ("b", str)],
|
||||
defaults=[1, "bar", "baz"],
|
||||
)
|
||||
4
resources/test/fixtures/isort/order_relative_imports_by_level.py
vendored
Normal file
4
resources/test/fixtures/isort/order_relative_imports_by_level.py
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
from .a import a
|
||||
from ..a import a
|
||||
from ..b import a
|
||||
from .b import a
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_dev"
|
||||
version = "0.0.129"
|
||||
version = "0.0.133"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
@@ -10,8 +10,8 @@ codegen = { version = "0.2.0" }
|
||||
itertools = { version = "0.10.5" }
|
||||
libcst = { git = "https://github.com/charliermarsh/LibCST", rev = "a13ec97dd4eb925bde4d426c6e422582793b260c" }
|
||||
ruff = { path = ".." }
|
||||
rustpython-ast = { features = ["unparse"], git = "https://github.com/RustPython/RustPython.git", rev = "27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb" }
|
||||
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb" }
|
||||
rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "27bf82a2251d7e6ac6cd75e6ad51be12a53d84bb" }
|
||||
rustpython-ast = { features = ["unparse"], git = "https://github.com/RustPython/RustPython.git", rev = "f885db8c61514f069979861f6b3bd83292086231" }
|
||||
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "f885db8c61514f069979861f6b3bd83292086231" }
|
||||
rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "f885db8c61514f069979861f6b3bd83292086231" }
|
||||
strum = { version = "0.24.1", features = ["strum_macros"] }
|
||||
strum_macros = { version = "0.24.3" }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind, Location, Stmt, StmtKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
@@ -45,7 +45,7 @@ pub fn collect_call_paths(expr: &Expr) -> Vec<&str> {
|
||||
/// Rewrite any import aliases on a call path.
|
||||
pub fn dealias_call_path<'a>(
|
||||
call_path: Vec<&'a str>,
|
||||
import_aliases: &FnvHashMap<&str, &'a str>,
|
||||
import_aliases: &FxHashMap<&str, &'a str>,
|
||||
) -> Vec<&'a str> {
|
||||
if let Some(head) = call_path.first() {
|
||||
if let Some(origin) = import_aliases.get(head) {
|
||||
@@ -79,8 +79,8 @@ pub fn match_module_member(
|
||||
expr: &Expr,
|
||||
module: &str,
|
||||
member: &str,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> bool {
|
||||
match_call_path(
|
||||
&dealias_call_path(collect_call_paths(expr), import_aliases),
|
||||
@@ -97,7 +97,7 @@ pub fn match_call_path(
|
||||
call_path: &[&str],
|
||||
module: &str,
|
||||
member: &str,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
) -> bool {
|
||||
// If we have no segments, we can't ever match.
|
||||
let num_segments = call_path.len();
|
||||
@@ -295,7 +295,7 @@ pub fn match_trailing_content(stmt: &Stmt, locator: &SourceCodeLocator) -> bool
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_parser::parser;
|
||||
|
||||
use crate::ast::helpers::match_module_member;
|
||||
@@ -307,8 +307,8 @@ mod tests {
|
||||
&expr,
|
||||
"",
|
||||
"list",
|
||||
&FnvHashMap::default(),
|
||||
&FnvHashMap::default(),
|
||||
&FxHashMap::default(),
|
||||
&FxHashMap::default(),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@@ -320,8 +320,8 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re",
|
||||
"Match",
|
||||
&FnvHashMap::default(),
|
||||
&FnvHashMap::default(),
|
||||
&FxHashMap::default(),
|
||||
&FxHashMap::default(),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@@ -333,16 +333,16 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re",
|
||||
"Match",
|
||||
&FnvHashMap::default(),
|
||||
&FnvHashMap::default(),
|
||||
&FxHashMap::default(),
|
||||
&FxHashMap::default(),
|
||||
));
|
||||
let expr = parser::parse_expression("re.Match", "<filename>")?;
|
||||
assert!(!match_module_member(
|
||||
&expr,
|
||||
"typing.re",
|
||||
"Match",
|
||||
&FnvHashMap::default(),
|
||||
&FnvHashMap::default(),
|
||||
&FxHashMap::default(),
|
||||
&FxHashMap::default(),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@@ -354,8 +354,8 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re",
|
||||
"Match",
|
||||
&FnvHashMap::from_iter([("typing.re", FnvHashSet::from_iter(["*"]))]),
|
||||
&FnvHashMap::default()
|
||||
&FxHashMap::from_iter([("typing.re", FxHashSet::from_iter(["*"]))]),
|
||||
&FxHashMap::default()
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@@ -367,8 +367,8 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re",
|
||||
"Match",
|
||||
&FnvHashMap::from_iter([("typing.re", FnvHashSet::from_iter(["Match"]))]),
|
||||
&FnvHashMap::default()
|
||||
&FxHashMap::from_iter([("typing.re", FxHashSet::from_iter(["Match"]))]),
|
||||
&FxHashMap::default()
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@@ -380,8 +380,8 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re",
|
||||
"Match",
|
||||
&FnvHashMap::from_iter([("typing", FnvHashSet::from_iter(["re"]))]),
|
||||
&FnvHashMap::default()
|
||||
&FxHashMap::from_iter([("typing", FxHashSet::from_iter(["re"]))]),
|
||||
&FxHashMap::default()
|
||||
));
|
||||
|
||||
let expr = parser::parse_expression("match.Match", "<filename>")?;
|
||||
@@ -389,8 +389,8 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re.match",
|
||||
"Match",
|
||||
&FnvHashMap::from_iter([("typing.re", FnvHashSet::from_iter(["match"]))]),
|
||||
&FnvHashMap::default()
|
||||
&FxHashMap::from_iter([("typing.re", FxHashSet::from_iter(["match"]))]),
|
||||
&FxHashMap::default()
|
||||
));
|
||||
|
||||
let expr = parser::parse_expression("re.match.Match", "<filename>")?;
|
||||
@@ -398,8 +398,8 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re.match",
|
||||
"Match",
|
||||
&FnvHashMap::from_iter([("typing", FnvHashSet::from_iter(["re"]))]),
|
||||
&FnvHashMap::default()
|
||||
&FxHashMap::from_iter([("typing", FxHashSet::from_iter(["re"]))]),
|
||||
&FxHashMap::default()
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@@ -411,8 +411,8 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re",
|
||||
"Match",
|
||||
&FnvHashMap::from_iter([("typing.re", FnvHashSet::from_iter(["Match"]))]),
|
||||
&FnvHashMap::from_iter([("IMatch", "Match")]),
|
||||
&FxHashMap::from_iter([("typing.re", FxHashSet::from_iter(["Match"]))]),
|
||||
&FxHashMap::from_iter([("IMatch", "Match")]),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@@ -424,8 +424,8 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re",
|
||||
"Match",
|
||||
&FnvHashMap::default(),
|
||||
&FnvHashMap::from_iter([("t", "typing.re")]),
|
||||
&FxHashMap::default(),
|
||||
&FxHashMap::from_iter([("t", "typing.re")]),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
@@ -437,8 +437,8 @@ mod tests {
|
||||
&expr,
|
||||
"typing.re",
|
||||
"Match",
|
||||
&FnvHashMap::default(),
|
||||
&FnvHashMap::from_iter([("t", "typing")]),
|
||||
&FxHashMap::default(),
|
||||
&FxHashMap::from_iter([("t", "typing")]),
|
||||
));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||
|
||||
use fnv::FnvHashMap;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::{Expr, Keyword};
|
||||
use rustpython_parser::ast::{Located, Location};
|
||||
|
||||
@@ -19,9 +19,7 @@ impl Range {
|
||||
pub fn from_located<T>(located: &Located<T>) -> Self {
|
||||
Range {
|
||||
location: located.location,
|
||||
end_location: located
|
||||
.end_location
|
||||
.expect("AST nodes should have end_location."),
|
||||
end_location: located.end_location.unwrap(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -54,7 +52,7 @@ pub struct Scope<'a> {
|
||||
pub id: usize,
|
||||
pub kind: ScopeKind<'a>,
|
||||
pub import_starred: bool,
|
||||
pub values: FnvHashMap<&'a str, Binding>,
|
||||
pub values: FxHashMap<&'a str, Binding>,
|
||||
}
|
||||
|
||||
impl<'a> Scope<'a> {
|
||||
@@ -63,7 +61,7 @@ impl<'a> Scope<'a> {
|
||||
id: id(),
|
||||
kind,
|
||||
import_starred: false,
|
||||
values: FnvHashMap::default(),
|
||||
values: FxHashMap::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
88
src/cache.rs
88
src/cache.rs
@@ -1,19 +1,11 @@
|
||||
// cacache uses asyncd-std which has no wasm support, so currently no caching
|
||||
// support on wasm
|
||||
#![cfg_attr(
|
||||
target_family = "wasm",
|
||||
allow(unused_imports, unused_variables, dead_code)
|
||||
)]
|
||||
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::fs;
|
||||
use std::fs::{create_dir_all, File, Metadata};
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::io::Write;
|
||||
use std::path::Path;
|
||||
|
||||
use anyhow::Result;
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
use cacache::Error::EntryNotFound;
|
||||
use filetime::FileTime;
|
||||
use log::error;
|
||||
use path_absolutize::Absolutize;
|
||||
@@ -82,28 +74,59 @@ fn cache_dir() -> &'static str {
|
||||
"./.ruff_cache"
|
||||
}
|
||||
|
||||
fn cache_key(path: &Path, settings: &Settings, autofix: &fixer::Mode) -> String {
|
||||
fn content_dir() -> &'static str {
|
||||
"content"
|
||||
}
|
||||
|
||||
fn cache_key(path: &Path, settings: &Settings, autofix: &fixer::Mode) -> u64 {
|
||||
let mut hasher = DefaultHasher::new();
|
||||
CARGO_PKG_VERSION.hash(&mut hasher);
|
||||
path.absolutize().unwrap().hash(&mut hasher);
|
||||
settings.hash(&mut hasher);
|
||||
autofix.hash(&mut hasher);
|
||||
format!(
|
||||
"{}@{}@{}",
|
||||
path.absolutize().unwrap().to_string_lossy(),
|
||||
CARGO_PKG_VERSION,
|
||||
hasher.finish()
|
||||
hasher.finish()
|
||||
}
|
||||
|
||||
/// Initialize the cache directory.
|
||||
pub fn init() -> Result<()> {
|
||||
let path = Path::new(cache_dir());
|
||||
|
||||
// Create the cache directories.
|
||||
create_dir_all(path.join(content_dir()))?;
|
||||
|
||||
// Add the CACHEDIR.TAG.
|
||||
if !cachedir::is_tagged(path)? {
|
||||
cachedir::add_tag(path)?;
|
||||
}
|
||||
|
||||
// Add the .gitignore.
|
||||
let gitignore_path = path.join(".gitignore");
|
||||
if !gitignore_path.exists() {
|
||||
let mut file = File::create(gitignore_path)?;
|
||||
file.write_all(b"*")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn write_sync(key: &u64, value: &[u8]) -> Result<(), std::io::Error> {
|
||||
fs::write(
|
||||
Path::new(cache_dir())
|
||||
.join(content_dir())
|
||||
.join(format!("{key:x}")),
|
||||
value,
|
||||
)
|
||||
}
|
||||
|
||||
pub fn init() -> Result<()> {
|
||||
let gitignore_path = Path::new(cache_dir()).join(".gitignore");
|
||||
if gitignore_path.exists() {
|
||||
return Ok(());
|
||||
}
|
||||
create_dir_all(cache_dir())?;
|
||||
let mut file = File::create(gitignore_path)?;
|
||||
file.write_all(b"*").map_err(|e| e.into())
|
||||
fn read_sync(key: &u64) -> Result<Vec<u8>, std::io::Error> {
|
||||
fs::read(
|
||||
Path::new(cache_dir())
|
||||
.join(content_dir())
|
||||
.join(format!("{key:x}")),
|
||||
)
|
||||
}
|
||||
|
||||
/// Get a value from the cache.
|
||||
pub fn get(
|
||||
path: &Path,
|
||||
metadata: &Metadata,
|
||||
@@ -115,9 +138,8 @@ pub fn get(
|
||||
return None;
|
||||
};
|
||||
|
||||
#[cfg(not(target_family = "wasm"))] // cacache needs async-std which doesn't support wasm
|
||||
match cacache::read_sync(cache_dir(), cache_key(path, settings, autofix)) {
|
||||
Ok(encoded) => match bincode::deserialize::<CheckResult>(&encoded[..]) {
|
||||
if let Ok(encoded) = read_sync(&cache_key(path, settings, autofix)) {
|
||||
match bincode::deserialize::<CheckResult>(&encoded[..]) {
|
||||
Ok(CheckResult {
|
||||
metadata: CacheMetadata { mtime },
|
||||
messages,
|
||||
@@ -127,13 +149,12 @@ pub fn get(
|
||||
}
|
||||
}
|
||||
Err(e) => error!("Failed to deserialize encoded cache entry: {e:?}"),
|
||||
},
|
||||
Err(EntryNotFound(..)) => {}
|
||||
Err(e) => error!("Failed to read from cache: {e:?}"),
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Set a value in the cache.
|
||||
pub fn set(
|
||||
path: &Path,
|
||||
metadata: &Metadata,
|
||||
@@ -146,18 +167,15 @@ pub fn set(
|
||||
return;
|
||||
};
|
||||
|
||||
#[cfg(not(target_family = "wasm"))] // modification date not supported on wasm
|
||||
let check_result = CheckResultRef {
|
||||
metadata: &CacheMetadata {
|
||||
mtime: FileTime::from_last_modification_time(metadata).unix_seconds(),
|
||||
},
|
||||
messages,
|
||||
};
|
||||
#[cfg(not(target_family = "wasm"))] // cacache needs async-std which doesn't support wasm
|
||||
if let Err(e) = cacache::write_sync(
|
||||
cache_dir(),
|
||||
cache_key(path, settings, autofix),
|
||||
bincode::serialize(&check_result).unwrap(),
|
||||
if let Err(e) = write_sync(
|
||||
&cache_key(path, settings, autofix),
|
||||
&bincode::serialize(&check_result).unwrap(),
|
||||
) {
|
||||
error!("Failed to write to cache: {e:?}")
|
||||
}
|
||||
|
||||
@@ -4,9 +4,9 @@ use std::collections::BTreeMap;
|
||||
use std::ops::Deref;
|
||||
use std::path::Path;
|
||||
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use itertools::Itertools;
|
||||
use log::error;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_parser::ast::{
|
||||
Arg, Arguments, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind,
|
||||
KeywordData, Operator, Stmt, StmtKind, Suite,
|
||||
@@ -37,7 +37,7 @@ use crate::visibility::{module_visibility, transition_scope, Modifier, Visibilit
|
||||
use crate::{
|
||||
docstrings, flake8_2020, flake8_annotations, flake8_bandit, flake8_blind_except,
|
||||
flake8_boolean_trap, flake8_bugbear, flake8_builtins, flake8_comprehensions, flake8_print,
|
||||
flake8_tidy_imports, mccabe, pep8_naming, pycodestyle, pydocstyle, pyflakes, pyupgrade,
|
||||
flake8_tidy_imports, mccabe, pep8_naming, pycodestyle, pydocstyle, pyflakes, pyupgrade, rules,
|
||||
};
|
||||
|
||||
const GLOBAL_SCOPE_INDEX: usize = 0;
|
||||
@@ -54,10 +54,10 @@ pub struct Checker<'a> {
|
||||
definitions: Vec<(Definition<'a>, Visibility)>,
|
||||
// Edit tracking.
|
||||
// TODO(charlie): Instead of exposing deletions, wrap in a public API.
|
||||
pub(crate) deletions: FnvHashSet<usize>,
|
||||
pub(crate) deletions: FxHashSet<usize>,
|
||||
// Import tracking.
|
||||
pub(crate) from_imports: FnvHashMap<&'a str, FnvHashSet<&'a str>>,
|
||||
pub(crate) import_aliases: FnvHashMap<&'a str, &'a str>,
|
||||
pub(crate) from_imports: FxHashMap<&'a str, FxHashSet<&'a str>>,
|
||||
pub(crate) import_aliases: FxHashMap<&'a str, &'a str>,
|
||||
// Retain all scopes and parent nodes, along with a stack of indexes to track which are active
|
||||
// at various points in time.
|
||||
pub(crate) parents: Vec<&'a Stmt>,
|
||||
@@ -74,6 +74,7 @@ pub struct Checker<'a> {
|
||||
visible_scope: VisibleScope,
|
||||
in_f_string: Option<Range>,
|
||||
in_annotation: bool,
|
||||
in_deferred_string_annotation: bool,
|
||||
in_literal: bool,
|
||||
in_subscript: bool,
|
||||
seen_import_boundary: bool,
|
||||
@@ -116,6 +117,7 @@ impl<'a> Checker<'a> {
|
||||
},
|
||||
in_f_string: Default::default(),
|
||||
in_annotation: Default::default(),
|
||||
in_deferred_string_annotation: Default::default(),
|
||||
in_literal: Default::default(),
|
||||
in_subscript: Default::default(),
|
||||
seen_import_boundary: Default::default(),
|
||||
@@ -471,7 +473,7 @@ where
|
||||
}
|
||||
StmtKind::Return { .. } => {
|
||||
if self.settings.enabled.contains(&CheckCode::F706) {
|
||||
if let Some(index) = self.scope_stack.last().cloned() {
|
||||
if let Some(&index) = self.scope_stack.last() {
|
||||
if matches!(
|
||||
self.scopes[index].kind,
|
||||
ScopeKind::Class(_) | ScopeKind::Module
|
||||
@@ -687,7 +689,7 @@ where
|
||||
if let Some(module) = module {
|
||||
self.from_imports
|
||||
.entry(module)
|
||||
.or_insert_with(FnvHashSet::default)
|
||||
.or_insert_with(FxHashSet::default)
|
||||
.extend(
|
||||
names
|
||||
.iter()
|
||||
@@ -1002,6 +1004,11 @@ where
|
||||
self, stmt, targets, value,
|
||||
);
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::U014) {
|
||||
pyupgrade::plugins::convert_named_tuple_functional_to_class(
|
||||
self, stmt, targets, value,
|
||||
);
|
||||
}
|
||||
}
|
||||
StmtKind::AnnAssign { target, value, .. } => {
|
||||
if self.settings.enabled.contains(&CheckCode::E731) {
|
||||
@@ -1145,7 +1152,8 @@ where
|
||||
match &expr.node {
|
||||
ExprKind::Subscript { value, slice, .. } => {
|
||||
// Ex) typing.List[...]
|
||||
if self.settings.enabled.contains(&CheckCode::U007)
|
||||
if !self.in_deferred_string_annotation
|
||||
&& self.settings.enabled.contains(&CheckCode::U007)
|
||||
&& self.settings.target_version >= PythonVersion::Py310
|
||||
{
|
||||
pyupgrade::plugins::use_pep604_annotation(self, expr, value, slice);
|
||||
@@ -1183,7 +1191,8 @@ where
|
||||
match ctx {
|
||||
ExprContext::Load => {
|
||||
// Ex) List[...]
|
||||
if self.settings.enabled.contains(&CheckCode::U006)
|
||||
if !self.in_deferred_string_annotation
|
||||
&& self.settings.enabled.contains(&CheckCode::U006)
|
||||
&& self.settings.target_version >= PythonVersion::Py39
|
||||
&& typing::is_pep585_builtin(
|
||||
expr,
|
||||
@@ -1522,6 +1531,11 @@ where
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ruff
|
||||
if self.settings.enabled.contains(&CheckCode::RUF101) {
|
||||
rules::plugins::convert_exit_to_sys_exit(self, func);
|
||||
}
|
||||
}
|
||||
ExprKind::Dict { keys, .. } => {
|
||||
let check_repeated_literals = self.settings.enabled.contains(&CheckCode::F601);
|
||||
@@ -2164,6 +2178,10 @@ impl<'a> Checker<'a> {
|
||||
&self.scopes[*(self.scope_stack.last().expect("No current scope found."))]
|
||||
}
|
||||
|
||||
pub fn current_scopes(&self) -> impl Iterator<Item = &Scope> {
|
||||
self.scope_stack.iter().rev().map(|s| &self.scopes[*s])
|
||||
}
|
||||
|
||||
pub fn current_parent(&self) -> &'a Stmt {
|
||||
self.parents[*(self.parent_stack.last().expect("No parent found."))]
|
||||
}
|
||||
@@ -2183,7 +2201,7 @@ impl<'a> Checker<'a> {
|
||||
'b: 'a,
|
||||
{
|
||||
if self.settings.enabled.contains(&CheckCode::F402) {
|
||||
let scope = &self.scopes[*(self.scope_stack.last().expect("No current scope found."))];
|
||||
let scope = self.current_scope();
|
||||
if let Some(existing) = scope.values.get(&name) {
|
||||
if matches!(binding.kind, BindingKind::LoopVar)
|
||||
&& matches!(
|
||||
@@ -2208,7 +2226,7 @@ impl<'a> Checker<'a> {
|
||||
|
||||
// TODO(charlie): Don't treat annotations as assignments if there is an existing
|
||||
// value.
|
||||
let scope = &self.scopes[*(self.scope_stack.last().expect("No current scope found."))];
|
||||
let scope = self.current_scope();
|
||||
let binding = match scope.values.get(&name) {
|
||||
None => binding,
|
||||
Some(existing) => Binding {
|
||||
@@ -2224,8 +2242,7 @@ impl<'a> Checker<'a> {
|
||||
|
||||
fn handle_node_load(&mut self, expr: &Expr) {
|
||||
if let ExprKind::Name { id, .. } = &expr.node {
|
||||
let scope_id =
|
||||
self.scopes[*(self.scope_stack.last().expect("No current scope found."))].id;
|
||||
let scope_id = self.current_scope().id;
|
||||
|
||||
let mut first_iter = true;
|
||||
let mut in_generator = false;
|
||||
@@ -2380,7 +2397,7 @@ impl<'a> Checker<'a> {
|
||||
return;
|
||||
}
|
||||
|
||||
let current = &self.scopes[*(self.scope_stack.last().expect("No current scope found."))];
|
||||
let current = self.current_scope();
|
||||
if id == "__all__"
|
||||
&& matches!(current.kind, ScopeKind::Module)
|
||||
&& matches!(
|
||||
@@ -2489,9 +2506,11 @@ impl<'a> Checker<'a> {
|
||||
}
|
||||
}
|
||||
for (expr, (scopes, parents)) in allocator.iter().zip(stacks) {
|
||||
self.in_deferred_string_annotation = true;
|
||||
self.scope_stack = scopes;
|
||||
self.parent_stack = parents;
|
||||
self.visit_expr(expr);
|
||||
self.in_deferred_string_annotation = false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -170,6 +170,7 @@ pub enum CheckCode {
|
||||
U011,
|
||||
U012,
|
||||
U013,
|
||||
U014,
|
||||
// pydocstyle
|
||||
D100,
|
||||
D101,
|
||||
@@ -248,6 +249,7 @@ pub enum CheckCode {
|
||||
RUF001,
|
||||
RUF002,
|
||||
RUF003,
|
||||
RUF101,
|
||||
// Meta
|
||||
M001,
|
||||
}
|
||||
@@ -500,7 +502,8 @@ pub enum CheckKind {
|
||||
UnnecessaryFutureImport(Vec<String>),
|
||||
UnnecessaryLRUCacheParams,
|
||||
UnnecessaryEncodeUTF8,
|
||||
ConvertTypedDictFunctionalToClass,
|
||||
ConvertTypedDictFunctionalToClass(String),
|
||||
ConvertNamedTupleFunctionalToClass(String),
|
||||
// pydocstyle
|
||||
BlankLineAfterLastSection(String),
|
||||
BlankLineAfterSection(String),
|
||||
@@ -581,6 +584,7 @@ pub enum CheckKind {
|
||||
AmbiguousUnicodeCharacterString(char, char),
|
||||
AmbiguousUnicodeCharacterDocstring(char, char),
|
||||
AmbiguousUnicodeCharacterComment(char, char),
|
||||
ConvertExitToSysExit,
|
||||
// Meta
|
||||
UnusedNOQA(Option<Vec<String>>),
|
||||
}
|
||||
@@ -773,7 +777,8 @@ impl CheckCode {
|
||||
CheckCode::U010 => CheckKind::UnnecessaryFutureImport(vec!["...".to_string()]),
|
||||
CheckCode::U011 => CheckKind::UnnecessaryLRUCacheParams,
|
||||
CheckCode::U012 => CheckKind::UnnecessaryEncodeUTF8,
|
||||
CheckCode::U013 => CheckKind::ConvertTypedDictFunctionalToClass,
|
||||
CheckCode::U013 => CheckKind::ConvertTypedDictFunctionalToClass("...".to_string()),
|
||||
CheckCode::U014 => CheckKind::ConvertNamedTupleFunctionalToClass("...".to_string()),
|
||||
// pydocstyle
|
||||
CheckCode::D100 => CheckKind::PublicModule,
|
||||
CheckCode::D101 => CheckKind::PublicClass,
|
||||
@@ -869,6 +874,7 @@ impl CheckCode {
|
||||
CheckCode::RUF001 => CheckKind::AmbiguousUnicodeCharacterString('𝐁', 'B'),
|
||||
CheckCode::RUF002 => CheckKind::AmbiguousUnicodeCharacterDocstring('𝐁', 'B'),
|
||||
CheckCode::RUF003 => CheckKind::AmbiguousUnicodeCharacterComment('𝐁', 'B'),
|
||||
CheckCode::RUF101 => CheckKind::ConvertExitToSysExit,
|
||||
// Meta
|
||||
CheckCode::M001 => CheckKind::UnusedNOQA(None),
|
||||
}
|
||||
@@ -1005,6 +1011,7 @@ impl CheckCode {
|
||||
CheckCode::U011 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U012 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U013 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U014 => CheckCategory::Pyupgrade,
|
||||
CheckCode::D100 => CheckCategory::Pydocstyle,
|
||||
CheckCode::D101 => CheckCategory::Pydocstyle,
|
||||
CheckCode::D102 => CheckCategory::Pydocstyle,
|
||||
@@ -1078,6 +1085,7 @@ impl CheckCode {
|
||||
CheckCode::RUF001 => CheckCategory::Ruff,
|
||||
CheckCode::RUF002 => CheckCategory::Ruff,
|
||||
CheckCode::RUF003 => CheckCategory::Ruff,
|
||||
CheckCode::RUF101 => CheckCategory::Ruff,
|
||||
CheckCode::M001 => CheckCategory::Meta,
|
||||
}
|
||||
}
|
||||
@@ -1227,7 +1235,8 @@ impl CheckKind {
|
||||
CheckKind::UnnecessaryFutureImport(_) => &CheckCode::U010,
|
||||
CheckKind::UnnecessaryLRUCacheParams => &CheckCode::U011,
|
||||
CheckKind::UnnecessaryEncodeUTF8 => &CheckCode::U012,
|
||||
CheckKind::ConvertTypedDictFunctionalToClass => &CheckCode::U013,
|
||||
CheckKind::ConvertTypedDictFunctionalToClass(_) => &CheckCode::U013,
|
||||
CheckKind::ConvertNamedTupleFunctionalToClass(_) => &CheckCode::U014,
|
||||
// pydocstyle
|
||||
CheckKind::BlankLineAfterLastSection(_) => &CheckCode::D413,
|
||||
CheckKind::BlankLineAfterSection(_) => &CheckCode::D410,
|
||||
@@ -1308,6 +1317,7 @@ impl CheckKind {
|
||||
CheckKind::AmbiguousUnicodeCharacterString(..) => &CheckCode::RUF001,
|
||||
CheckKind::AmbiguousUnicodeCharacterDocstring(..) => &CheckCode::RUF002,
|
||||
CheckKind::AmbiguousUnicodeCharacterComment(..) => &CheckCode::RUF003,
|
||||
CheckKind::ConvertExitToSysExit => &CheckCode::RUF101,
|
||||
// Meta
|
||||
CheckKind::UnusedNOQA(_) => &CheckCode::M001,
|
||||
}
|
||||
@@ -1776,8 +1786,11 @@ impl CheckKind {
|
||||
"Unnecessary parameters to `functools.lru_cache`".to_string()
|
||||
}
|
||||
CheckKind::UnnecessaryEncodeUTF8 => "Unnecessary call to `encode` as UTF-8".to_string(),
|
||||
CheckKind::ConvertTypedDictFunctionalToClass => {
|
||||
"Convert `TypedDict` functional syntax to class syntax".to_string()
|
||||
CheckKind::ConvertTypedDictFunctionalToClass(name) => {
|
||||
format!("Convert `{name}` from `TypedDict` functional to class syntax")
|
||||
}
|
||||
CheckKind::ConvertNamedTupleFunctionalToClass(name) => {
|
||||
format!("Convert `{name}` from `NamedTuple` functional to class syntax")
|
||||
}
|
||||
// pydocstyle
|
||||
CheckKind::FitsOnOneLine => "One-line docstring should fit on one line".to_string(),
|
||||
@@ -1994,6 +2007,9 @@ impl CheckKind {
|
||||
'{representant}'?)"
|
||||
)
|
||||
}
|
||||
CheckKind::ConvertExitToSysExit => "`exit()` is only available in the interpreter, \
|
||||
use `sys.exit()` instead"
|
||||
.to_string(),
|
||||
// Meta
|
||||
CheckKind::UnusedNOQA(codes) => match codes {
|
||||
None => "Unused `noqa` directive".to_string(),
|
||||
@@ -2045,7 +2061,9 @@ impl CheckKind {
|
||||
| CheckKind::BlankLineAfterSummary
|
||||
| CheckKind::BlankLineBeforeSection(..)
|
||||
| CheckKind::CapitalizeSectionName(..)
|
||||
| CheckKind::ConvertTypedDictFunctionalToClass
|
||||
| CheckKind::ConvertExitToSysExit
|
||||
| CheckKind::ConvertNamedTupleFunctionalToClass(..)
|
||||
| CheckKind::ConvertTypedDictFunctionalToClass(..)
|
||||
| CheckKind::DashedUnderlineAfterSection(..)
|
||||
| CheckKind::DeprecatedUnittestAlias(..)
|
||||
| CheckKind::DoNotAssertFalse
|
||||
@@ -2071,11 +2089,13 @@ impl CheckKind {
|
||||
| CheckKind::PPrintFound
|
||||
| CheckKind::PrintFound
|
||||
| CheckKind::RaiseNotImplemented
|
||||
| CheckKind::RedundantTupleInExceptionHandler(..)
|
||||
| CheckKind::SectionNameEndsInColon(..)
|
||||
| CheckKind::SectionNotOverIndented(..)
|
||||
| CheckKind::SectionUnderlineAfterName(..)
|
||||
| CheckKind::SectionUnderlineMatchesSectionLength(..)
|
||||
| CheckKind::SectionUnderlineNotOverIndented(..)
|
||||
| CheckKind::SetAttrWithConstant
|
||||
| CheckKind::SuperCallWithParameters
|
||||
| CheckKind::TrueFalseComparison(..)
|
||||
| CheckKind::TypeOfPrimitive(..)
|
||||
|
||||
@@ -267,6 +267,9 @@ pub enum CheckCodePrefix {
|
||||
RUF001,
|
||||
RUF002,
|
||||
RUF003,
|
||||
RUF1,
|
||||
RUF10,
|
||||
RUF101,
|
||||
S,
|
||||
S1,
|
||||
S10,
|
||||
@@ -297,6 +300,7 @@ pub enum CheckCodePrefix {
|
||||
U011,
|
||||
U012,
|
||||
U013,
|
||||
U014,
|
||||
W,
|
||||
W2,
|
||||
W29,
|
||||
@@ -1057,12 +1061,20 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::Q001 => vec![CheckCode::Q001],
|
||||
CheckCodePrefix::Q002 => vec![CheckCode::Q002],
|
||||
CheckCodePrefix::Q003 => vec![CheckCode::Q003],
|
||||
CheckCodePrefix::RUF => vec![CheckCode::RUF001, CheckCode::RUF002, CheckCode::RUF003],
|
||||
CheckCodePrefix::RUF => vec![
|
||||
CheckCode::RUF001,
|
||||
CheckCode::RUF002,
|
||||
CheckCode::RUF003,
|
||||
CheckCode::RUF101,
|
||||
],
|
||||
CheckCodePrefix::RUF0 => vec![CheckCode::RUF001, CheckCode::RUF002, CheckCode::RUF003],
|
||||
CheckCodePrefix::RUF00 => vec![CheckCode::RUF001, CheckCode::RUF002, CheckCode::RUF003],
|
||||
CheckCodePrefix::RUF001 => vec![CheckCode::RUF001],
|
||||
CheckCodePrefix::RUF002 => vec![CheckCode::RUF002],
|
||||
CheckCodePrefix::RUF003 => vec![CheckCode::RUF003],
|
||||
CheckCodePrefix::RUF1 => vec![CheckCode::RUF101],
|
||||
CheckCodePrefix::RUF10 => vec![CheckCode::RUF101],
|
||||
CheckCodePrefix::RUF101 => vec![CheckCode::RUF101],
|
||||
CheckCodePrefix::S => vec![
|
||||
CheckCode::S101,
|
||||
CheckCode::S102,
|
||||
@@ -1111,6 +1123,7 @@ impl CheckCodePrefix {
|
||||
CheckCode::U011,
|
||||
CheckCode::U012,
|
||||
CheckCode::U013,
|
||||
CheckCode::U014,
|
||||
],
|
||||
CheckCodePrefix::U0 => vec![
|
||||
CheckCode::U001,
|
||||
@@ -1125,6 +1138,7 @@ impl CheckCodePrefix {
|
||||
CheckCode::U011,
|
||||
CheckCode::U012,
|
||||
CheckCode::U013,
|
||||
CheckCode::U014,
|
||||
],
|
||||
CheckCodePrefix::U00 => vec![
|
||||
CheckCode::U001,
|
||||
@@ -1149,11 +1163,13 @@ impl CheckCodePrefix {
|
||||
CheckCode::U011,
|
||||
CheckCode::U012,
|
||||
CheckCode::U013,
|
||||
CheckCode::U014,
|
||||
],
|
||||
CheckCodePrefix::U010 => vec![CheckCode::U010],
|
||||
CheckCodePrefix::U011 => vec![CheckCode::U011],
|
||||
CheckCodePrefix::U012 => vec![CheckCode::U012],
|
||||
CheckCodePrefix::U013 => vec![CheckCode::U013],
|
||||
CheckCodePrefix::U014 => vec![CheckCode::U014],
|
||||
CheckCodePrefix::W => vec![CheckCode::W292, CheckCode::W605],
|
||||
CheckCodePrefix::W2 => vec![CheckCode::W292],
|
||||
CheckCodePrefix::W29 => vec![CheckCode::W292],
|
||||
@@ -1466,6 +1482,9 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::RUF001 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::RUF002 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::RUF003 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::RUF1 => PrefixSpecificity::Hundreds,
|
||||
CheckCodePrefix::RUF10 => PrefixSpecificity::Tens,
|
||||
CheckCodePrefix::RUF101 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::S => PrefixSpecificity::Category,
|
||||
CheckCodePrefix::S1 => PrefixSpecificity::Hundreds,
|
||||
CheckCodePrefix::S10 => PrefixSpecificity::Tens,
|
||||
@@ -1496,6 +1515,7 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::U011 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::U012 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::U013 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::U014 => PrefixSpecificity::Explicit,
|
||||
CheckCodePrefix::W => PrefixSpecificity::Category,
|
||||
CheckCodePrefix::W2 => PrefixSpecificity::Hundreds,
|
||||
CheckCodePrefix::W29 => PrefixSpecificity::Tens,
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::{command, Parser};
|
||||
use fnv::FnvHashMap;
|
||||
use regex::Regex;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::checks_gen::CheckCodePrefix;
|
||||
use crate::logging::LogLevel;
|
||||
@@ -146,8 +147,8 @@ pub fn extract_log_level(cli: &Cli) -> LogLevel {
|
||||
pub fn collect_per_file_ignores(
|
||||
pairs: Vec<PatternPrefixPair>,
|
||||
project_root: Option<&PathBuf>,
|
||||
) -> Vec<PerFileIgnore> {
|
||||
let mut per_file_ignores: FnvHashMap<String, Vec<CheckCodePrefix>> = FnvHashMap::default();
|
||||
) -> Result<Vec<PerFileIgnore>> {
|
||||
let mut per_file_ignores: FxHashMap<String, Vec<CheckCodePrefix>> = FxHashMap::default();
|
||||
for pair in pairs {
|
||||
per_file_ignores
|
||||
.entry(pair.pattern)
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
//! Abstractions for Google-style docstrings.
|
||||
|
||||
use fnv::FnvHashSet;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
pub(crate) static GOOGLE_SECTION_NAMES: Lazy<FnvHashSet<&'static str>> = Lazy::new(|| {
|
||||
FnvHashSet::from_iter([
|
||||
pub(crate) static GOOGLE_SECTION_NAMES: Lazy<FxHashSet<&'static str>> = Lazy::new(|| {
|
||||
FxHashSet::from_iter([
|
||||
"Args",
|
||||
"Arguments",
|
||||
"Attention",
|
||||
@@ -36,36 +36,35 @@ pub(crate) static GOOGLE_SECTION_NAMES: Lazy<FnvHashSet<&'static str>> = Lazy::n
|
||||
])
|
||||
});
|
||||
|
||||
pub(crate) static LOWERCASE_GOOGLE_SECTION_NAMES: Lazy<FnvHashSet<&'static str>> =
|
||||
Lazy::new(|| {
|
||||
FnvHashSet::from_iter([
|
||||
"args",
|
||||
"arguments",
|
||||
"attention",
|
||||
"attributes",
|
||||
"caution",
|
||||
"danger",
|
||||
"error",
|
||||
"example",
|
||||
"examples",
|
||||
"hint",
|
||||
"important",
|
||||
"keyword args",
|
||||
"keyword arguments",
|
||||
"methods",
|
||||
"note",
|
||||
"notes",
|
||||
"return",
|
||||
"returns",
|
||||
"raises",
|
||||
"references",
|
||||
"see also",
|
||||
"tip",
|
||||
"todo",
|
||||
"warning",
|
||||
"warnings",
|
||||
"warns",
|
||||
"yield",
|
||||
"yields",
|
||||
])
|
||||
});
|
||||
pub(crate) static LOWERCASE_GOOGLE_SECTION_NAMES: Lazy<FxHashSet<&'static str>> = Lazy::new(|| {
|
||||
FxHashSet::from_iter([
|
||||
"args",
|
||||
"arguments",
|
||||
"attention",
|
||||
"attributes",
|
||||
"caution",
|
||||
"danger",
|
||||
"error",
|
||||
"example",
|
||||
"examples",
|
||||
"hint",
|
||||
"important",
|
||||
"keyword args",
|
||||
"keyword arguments",
|
||||
"methods",
|
||||
"note",
|
||||
"notes",
|
||||
"return",
|
||||
"returns",
|
||||
"raises",
|
||||
"references",
|
||||
"see also",
|
||||
"tip",
|
||||
"todo",
|
||||
"warning",
|
||||
"warnings",
|
||||
"warns",
|
||||
"yield",
|
||||
"yields",
|
||||
])
|
||||
});
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
//! Abstractions for NumPy-style docstrings.
|
||||
|
||||
use fnv::FnvHashSet;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
pub(crate) static LOWERCASE_NUMPY_SECTION_NAMES: Lazy<FnvHashSet<&'static str>> = Lazy::new(|| {
|
||||
FnvHashSet::from_iter([
|
||||
pub(crate) static LOWERCASE_NUMPY_SECTION_NAMES: Lazy<FxHashSet<&'static str>> = Lazy::new(|| {
|
||||
FxHashSet::from_iter([
|
||||
"short summary",
|
||||
"extended summary",
|
||||
"parameters",
|
||||
@@ -21,8 +21,8 @@ pub(crate) static LOWERCASE_NUMPY_SECTION_NAMES: Lazy<FnvHashSet<&'static str>>
|
||||
])
|
||||
});
|
||||
|
||||
pub(crate) static NUMPY_SECTION_NAMES: Lazy<FnvHashSet<&'static str>> = Lazy::new(|| {
|
||||
FnvHashSet::from_iter([
|
||||
pub(crate) static NUMPY_SECTION_NAMES: Lazy<FxHashSet<&'static str>> = Lazy::new(|| {
|
||||
FxHashSet::from_iter([
|
||||
"Short Summary",
|
||||
"Extended Summary",
|
||||
"Parameters",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use fnv::FnvHashSet;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::docstrings::google::{GOOGLE_SECTION_NAMES, LOWERCASE_GOOGLE_SECTION_NAMES};
|
||||
use crate::docstrings::numpy::{LOWERCASE_NUMPY_SECTION_NAMES, NUMPY_SECTION_NAMES};
|
||||
@@ -10,14 +10,14 @@ pub(crate) enum SectionStyle {
|
||||
}
|
||||
|
||||
impl SectionStyle {
|
||||
pub(crate) fn section_names(&self) -> &Lazy<FnvHashSet<&'static str>> {
|
||||
pub(crate) fn section_names(&self) -> &Lazy<FxHashSet<&'static str>> {
|
||||
match self {
|
||||
SectionStyle::NumPy => &NUMPY_SECTION_NAMES,
|
||||
SectionStyle::Google => &GOOGLE_SECTION_NAMES,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn lowercase_section_names(&self) -> &Lazy<FnvHashSet<&'static str>> {
|
||||
pub(crate) fn lowercase_section_names(&self) -> &Lazy<FxHashSet<&'static str>> {
|
||||
match self {
|
||||
SectionStyle::NumPy => &LOWERCASE_NUMPY_SECTION_NAMES,
|
||||
SectionStyle::Google => &LOWERCASE_GOOGLE_SECTION_NAMES,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::{Constant, Expr, ExprKind, Keyword, Stmt, StmtKind};
|
||||
|
||||
use crate::ast::helpers::match_module_member;
|
||||
@@ -9,8 +9,8 @@ use crate::checks::{Check, CheckCode, CheckKind};
|
||||
fn is_abc_class(
|
||||
bases: &[Expr],
|
||||
keywords: &[Keyword],
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> bool {
|
||||
keywords.iter().any(|keyword| {
|
||||
keyword
|
||||
@@ -46,16 +46,16 @@ fn is_empty_body(body: &[Stmt]) -> bool {
|
||||
|
||||
fn is_abstractmethod(
|
||||
expr: &Expr,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> bool {
|
||||
match_module_member(expr, "abc", "abstractmethod", from_imports, import_aliases)
|
||||
}
|
||||
|
||||
fn is_overload(
|
||||
expr: &Expr,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> bool {
|
||||
match_module_member(expr, "typing", "overload", from_imports, import_aliases)
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::{Arguments, Constant, Expr, ExprKind};
|
||||
|
||||
use crate::ast::helpers::{
|
||||
@@ -24,8 +24,8 @@ const IMMUTABLE_FUNCS: [(&str, &str); 7] = [
|
||||
fn is_immutable_func(
|
||||
expr: &Expr,
|
||||
extend_immutable_calls: &[(&str, &str)],
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> bool {
|
||||
let call_path = dealias_call_path(collect_call_paths(expr), import_aliases);
|
||||
IMMUTABLE_FUNCS
|
||||
@@ -37,8 +37,8 @@ fn is_immutable_func(
|
||||
struct ArgumentDefaultVisitor<'a> {
|
||||
checks: Vec<(CheckKind, Range)>,
|
||||
extend_immutable_calls: &'a [(&'a str, &'a str)],
|
||||
from_imports: &'a FnvHashMap<&'a str, FnvHashSet<&'a str>>,
|
||||
import_aliases: &'a FnvHashMap<&'a str, &'a str>,
|
||||
from_imports: &'a FxHashMap<&'a str, FxHashSet<&'a str>>,
|
||||
import_aliases: &'a FxHashMap<&'a str, &'a str>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Visitor<'b> for ArgumentDefaultVisitor<'b>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use fnv::FnvHashMap;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::{Expr, ExprKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
@@ -9,7 +9,7 @@ use crate::checks::{Check, CheckKind};
|
||||
|
||||
#[derive(Default)]
|
||||
struct NameFinder<'a> {
|
||||
names: FnvHashMap<&'a str, &'a Expr>,
|
||||
names: FxHashMap<&'a str, &'a Expr>,
|
||||
}
|
||||
|
||||
impl<'a, 'b> Visitor<'b> for NameFinder<'a>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::{Arguments, Constant, Expr, ExprKind, Operator};
|
||||
|
||||
use crate::ast::helpers::{collect_call_paths, dealias_call_path, match_call_path};
|
||||
@@ -59,8 +59,8 @@ const IMMUTABLE_GENERIC_TYPES: &[(&str, &str)] = &[
|
||||
|
||||
pub fn is_mutable_func(
|
||||
expr: &Expr,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> bool {
|
||||
let call_path = dealias_call_path(collect_call_paths(expr), import_aliases);
|
||||
MUTABLE_FUNCS
|
||||
@@ -70,8 +70,8 @@ pub fn is_mutable_func(
|
||||
|
||||
fn is_mutable_expr(
|
||||
expr: &Expr,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> bool {
|
||||
match &expr.node {
|
||||
ExprKind::List { .. }
|
||||
@@ -87,8 +87,8 @@ fn is_mutable_expr(
|
||||
|
||||
fn is_immutable_annotation(
|
||||
expr: &Expr,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> bool {
|
||||
match &expr.node {
|
||||
ExprKind::Name { .. } | ExprKind::Attribute { .. } => {
|
||||
|
||||
@@ -1,8 +1,55 @@
|
||||
use rustpython_ast::{Excepthandler, ExcepthandlerKind, ExprKind};
|
||||
use anyhow::Result;
|
||||
use log::error;
|
||||
use rustpython_ast::{Excepthandler, ExcepthandlerKind, ExprKind, Located};
|
||||
use rustpython_parser::lexer;
|
||||
use rustpython_parser::lexer::Tok;
|
||||
|
||||
use crate::ast::helpers;
|
||||
use crate::ast::types::Range;
|
||||
use crate::autofix::Fix;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
use crate::code_gen::SourceGenerator;
|
||||
use crate::SourceCodeLocator;
|
||||
|
||||
/// Given a statement like `except (ValueError,)`, find the range of the
|
||||
/// parenthesized expression.
|
||||
fn match_tuple_range<T>(located: &Located<T>, locator: &SourceCodeLocator) -> Result<Range> {
|
||||
// Extract contents from the source code.
|
||||
let range = Range::from_located(located);
|
||||
let contents = locator.slice_source_code_range(&range);
|
||||
|
||||
// Find the left (opening) and right (closing) parentheses.
|
||||
let mut location = None;
|
||||
let mut end_location = None;
|
||||
let mut count: usize = 0;
|
||||
for (start, tok, end) in lexer::make_tokenizer(&contents).flatten() {
|
||||
if matches!(tok, Tok::Lpar) {
|
||||
if count == 0 {
|
||||
location = Some(helpers::to_absolute(&start, &range.location));
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
|
||||
if matches!(tok, Tok::Rpar) {
|
||||
count -= 1;
|
||||
if count == 0 {
|
||||
end_location = Some(helpers::to_absolute(&end, &range.location));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if let (Some(location), Some(end_location)) = (location, end_location) {
|
||||
Ok(Range {
|
||||
location,
|
||||
end_location,
|
||||
})
|
||||
} else {
|
||||
Err(anyhow::anyhow!(
|
||||
"Unable to find left and right parentheses."
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// B013
|
||||
pub fn redundant_tuple_in_exception_handler(checker: &mut Checker, handlers: &[Excepthandler]) {
|
||||
@@ -10,11 +57,29 @@ pub fn redundant_tuple_in_exception_handler(checker: &mut Checker, handlers: &[E
|
||||
let ExcepthandlerKind::ExceptHandler { type_, .. } = &handler.node;
|
||||
if let Some(type_) = type_ {
|
||||
if let ExprKind::Tuple { elts, .. } = &type_.node {
|
||||
if elts.len() == 1 {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::RedundantTupleInExceptionHandler(elts[0].to_string()),
|
||||
if let [elt] = &elts[..] {
|
||||
let mut check = Check::new(
|
||||
CheckKind::RedundantTupleInExceptionHandler(elt.to_string()),
|
||||
Range::from_located(type_),
|
||||
));
|
||||
);
|
||||
if checker.patch(check.kind.code()) {
|
||||
let mut generator = SourceGenerator::new();
|
||||
if let Ok(()) = generator.unparse_expr(elt, 0) {
|
||||
if let Ok(content) = generator.generate() {
|
||||
match match_tuple_range(handler, checker.locator) {
|
||||
Ok(range) => {
|
||||
check.amend(Fix::replacement(
|
||||
content,
|
||||
range.location,
|
||||
range.end_location,
|
||||
));
|
||||
}
|
||||
Err(e) => error!("Failed to locate parentheses: {}", e),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
checker.add_check(check)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,61 @@
|
||||
use rustpython_ast::{Constant, Expr, ExprKind};
|
||||
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::autofix::Fix;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
use crate::code_gen::SourceGenerator;
|
||||
use crate::python::identifiers::IDENTIFIER_REGEX;
|
||||
use crate::python::keyword::KWLIST;
|
||||
|
||||
fn assignment(obj: &Expr, name: &str, value: &Expr) -> Option<String> {
|
||||
let stmt = Stmt::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
StmtKind::Assign {
|
||||
targets: vec![Expr::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
ExprKind::Attribute {
|
||||
value: Box::new(obj.clone()),
|
||||
attr: name.to_string(),
|
||||
ctx: ExprContext::Store,
|
||||
},
|
||||
)],
|
||||
value: Box::new(value.clone()),
|
||||
type_comment: None,
|
||||
},
|
||||
);
|
||||
let mut generator = SourceGenerator::new();
|
||||
match generator.unparse_stmt(&stmt) {
|
||||
Ok(()) => generator.generate().ok(),
|
||||
Err(_) => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// B010
|
||||
pub fn setattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if id == "setattr" {
|
||||
if let [_, arg, _] = args {
|
||||
if let [obj, name, value] = args {
|
||||
if let ExprKind::Constant {
|
||||
value: Constant::Str(value),
|
||||
value: Constant::Str(name),
|
||||
..
|
||||
} = &arg.node
|
||||
} = &name.node
|
||||
{
|
||||
if IDENTIFIER_REGEX.is_match(value) && !KWLIST.contains(&value.as_str()) {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::SetAttrWithConstant,
|
||||
Range::from_located(expr),
|
||||
));
|
||||
if IDENTIFIER_REGEX.is_match(name) && !KWLIST.contains(&name.as_str()) {
|
||||
let mut check =
|
||||
Check::new(CheckKind::SetAttrWithConstant, Range::from_located(expr));
|
||||
if checker.patch(check.kind.code()) {
|
||||
if let Some(content) = assignment(obj, name, value) {
|
||||
check.amend(Fix::replacement(
|
||||
content,
|
||||
expr.location,
|
||||
expr.end_location.unwrap(),
|
||||
));
|
||||
}
|
||||
}
|
||||
checker.add_check(check);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use fnv::FnvHashMap;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::{Expr, ExprKind, Stmt};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
@@ -11,7 +11,7 @@ use crate::checks::{Check, CheckKind};
|
||||
/// Identify all `ExprKind::Name` nodes in an AST.
|
||||
struct NameFinder<'a> {
|
||||
/// A map from identifier to defining expression.
|
||||
names: FnvHashMap<&'a str, &'a Expr>,
|
||||
names: FxHashMap<&'a str, &'a Expr>,
|
||||
}
|
||||
|
||||
impl NameFinder<'_> {
|
||||
|
||||
@@ -5,7 +5,6 @@ use crate::checks::{Check, CheckKind};
|
||||
|
||||
/// Check whether a function call is a `print` or `pprint` invocation
|
||||
pub fn print_call(
|
||||
expr: &Expr,
|
||||
func: &Expr,
|
||||
check_print: bool,
|
||||
check_pprint: bool,
|
||||
@@ -13,7 +12,7 @@ pub fn print_call(
|
||||
) -> Option<Check> {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if check_print && id == "print" {
|
||||
return Some(Check::new(CheckKind::PrintFound, Range::from_located(expr)));
|
||||
return Some(Check::new(CheckKind::PrintFound, location));
|
||||
} else if check_pprint && id == "pprint" {
|
||||
return Some(Check::new(CheckKind::PPrintFound, location));
|
||||
}
|
||||
|
||||
@@ -10,7 +10,6 @@ use crate::flake8_print::checks;
|
||||
/// T201, T203
|
||||
pub fn print_call(checker: &mut Checker, expr: &Expr, func: &Expr) {
|
||||
if let Some(mut check) = checks::print_call(
|
||||
expr,
|
||||
func,
|
||||
checker.settings.enabled.contains(&CheckCode::T201),
|
||||
checker.settings.enabled.contains(&CheckCode::T203),
|
||||
|
||||
18
src/fs.rs
18
src/fs.rs
@@ -5,9 +5,9 @@ use std::ops::Deref;
|
||||
use std::path::{Path, PathBuf};
|
||||
|
||||
use anyhow::{anyhow, Result};
|
||||
use fnv::FnvHashSet;
|
||||
use log::debug;
|
||||
use path_absolutize::{path_dedot, Absolutize};
|
||||
use rustc_hash::FxHashSet;
|
||||
use walkdir::{DirEntry, WalkDir};
|
||||
|
||||
use crate::checks::CheckCode;
|
||||
@@ -121,7 +121,7 @@ pub fn iter_python_files<'a>(
|
||||
pub(crate) fn ignores_from_path<'a>(
|
||||
path: &Path,
|
||||
pattern_code_pairs: &'a [PerFileIgnore],
|
||||
) -> Result<FnvHashSet<&'a CheckCode>> {
|
||||
) -> Result<FxHashSet<&'a CheckCode>> {
|
||||
let (file_path, file_basename) = extract_path_names(path)?;
|
||||
Ok(pattern_code_pairs
|
||||
.iter()
|
||||
@@ -203,7 +203,7 @@ mod tests {
|
||||
let exclude = vec![FilePattern::from_user(
|
||||
"foo",
|
||||
Some(&project_root.to_path_buf()),
|
||||
)];
|
||||
)?];
|
||||
let (file_path, file_basename) = extract_path_names(&path)?;
|
||||
assert!(is_excluded(file_path, file_basename, exclude.iter()));
|
||||
|
||||
@@ -211,7 +211,7 @@ mod tests {
|
||||
let exclude = vec![FilePattern::from_user(
|
||||
"bar",
|
||||
Some(&project_root.to_path_buf()),
|
||||
)];
|
||||
)?];
|
||||
let (file_path, file_basename) = extract_path_names(&path)?;
|
||||
assert!(is_excluded(file_path, file_basename, exclude.iter()));
|
||||
|
||||
@@ -221,7 +221,7 @@ mod tests {
|
||||
let exclude = vec![FilePattern::from_user(
|
||||
"baz.py",
|
||||
Some(&project_root.to_path_buf()),
|
||||
)];
|
||||
)?];
|
||||
let (file_path, file_basename) = extract_path_names(&path)?;
|
||||
assert!(is_excluded(file_path, file_basename, exclude.iter()));
|
||||
|
||||
@@ -229,7 +229,7 @@ mod tests {
|
||||
let exclude = vec![FilePattern::from_user(
|
||||
"foo/bar",
|
||||
Some(&project_root.to_path_buf()),
|
||||
)];
|
||||
)?];
|
||||
let (file_path, file_basename) = extract_path_names(&path)?;
|
||||
assert!(is_excluded(file_path, file_basename, exclude.iter()));
|
||||
|
||||
@@ -239,7 +239,7 @@ mod tests {
|
||||
let exclude = vec![FilePattern::from_user(
|
||||
"foo/bar/baz.py",
|
||||
Some(&project_root.to_path_buf()),
|
||||
)];
|
||||
)?];
|
||||
let (file_path, file_basename) = extract_path_names(&path)?;
|
||||
assert!(is_excluded(file_path, file_basename, exclude.iter()));
|
||||
|
||||
@@ -249,7 +249,7 @@ mod tests {
|
||||
let exclude = vec![FilePattern::from_user(
|
||||
"foo/bar/*.py",
|
||||
Some(&project_root.to_path_buf()),
|
||||
)];
|
||||
)?];
|
||||
let (file_path, file_basename) = extract_path_names(&path)?;
|
||||
assert!(is_excluded(file_path, file_basename, exclude.iter()));
|
||||
|
||||
@@ -259,7 +259,7 @@ mod tests {
|
||||
let exclude = vec![FilePattern::from_user(
|
||||
"baz",
|
||||
Some(&project_root.to_path_buf()),
|
||||
)];
|
||||
)?];
|
||||
let (file_path, file_basename) = extract_path_names(&path)?;
|
||||
assert!(!is_excluded(file_path, file_basename, exclude.iter()));
|
||||
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
use std::cmp::Reverse;
|
||||
use std::collections::{BTreeMap, BTreeSet};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use fnv::FnvHashMap;
|
||||
use itertools::Itertools;
|
||||
use ropey::RopeBuilder;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::{Stmt, StmtKind};
|
||||
|
||||
use crate::isort::categorize::{categorize, ImportType};
|
||||
@@ -355,7 +356,7 @@ fn sort_imports(block: ImportBlock) -> OrderedImportBlock {
|
||||
atop: comments.atop,
|
||||
inline: Default::default(),
|
||||
},
|
||||
FnvHashMap::from_iter([(
|
||||
FxHashMap::from_iter([(
|
||||
alias,
|
||||
CommentSet {
|
||||
atop: Default::default(),
|
||||
@@ -381,6 +382,7 @@ fn sort_imports(block: ImportBlock) -> OrderedImportBlock {
|
||||
// Sort each `StmtKind::ImportFrom` by module key, breaking ties based on
|
||||
// members.
|
||||
(
|
||||
Reverse(import_from.level),
|
||||
import_from
|
||||
.module
|
||||
.as_ref()
|
||||
@@ -477,6 +479,7 @@ mod tests {
|
||||
#[test_case(Path::new("leading_prefix.py"))]
|
||||
#[test_case(Path::new("no_reorder_within_section.py"))]
|
||||
#[test_case(Path::new("order_by_type.py"))]
|
||||
#[test_case(Path::new("order_relative_imports_by_level.py"))]
|
||||
#[test_case(Path::new("preserve_comment_order.py"))]
|
||||
#[test_case(Path::new("preserve_indentation.py"))]
|
||||
#[test_case(Path::new("reorder_within_section.py"))]
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
---
|
||||
source: src/isort/mod.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: UnsortedImports
|
||||
location:
|
||||
row: 1
|
||||
column: 0
|
||||
end_location:
|
||||
row: 5
|
||||
column: 0
|
||||
fix:
|
||||
patch:
|
||||
content: "from ..a import a\nfrom ..b import a\nfrom .a import a\nfrom .b import a\n"
|
||||
location:
|
||||
row: 1
|
||||
column: 0
|
||||
end_location:
|
||||
row: 5
|
||||
column: 0
|
||||
applied: false
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use fnv::FnvHashMap;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::ast;
|
||||
|
||||
@@ -51,14 +51,14 @@ impl Importable for ImportFromData<'_> {
|
||||
pub struct ImportBlock<'a> {
|
||||
// Set of (name, asname), used to track regular imports.
|
||||
// Ex) `import module`
|
||||
pub import: FnvHashMap<AliasData<'a>, CommentSet<'a>>,
|
||||
pub import: FxHashMap<AliasData<'a>, CommentSet<'a>>,
|
||||
// Map from (module, level) to `AliasData`, used to track 'from' imports.
|
||||
// Ex) `from module import member`
|
||||
pub import_from:
|
||||
FnvHashMap<ImportFromData<'a>, (CommentSet<'a>, FnvHashMap<AliasData<'a>, CommentSet<'a>>)>,
|
||||
FxHashMap<ImportFromData<'a>, (CommentSet<'a>, FxHashMap<AliasData<'a>, CommentSet<'a>>)>,
|
||||
// Set of (module, level, name, asname), used to track re-exported 'from' imports.
|
||||
// Ex) `from module import member as member`
|
||||
pub import_from_as: FnvHashMap<(ImportFromData<'a>, AliasData<'a>), CommentSet<'a>>,
|
||||
pub import_from_as: FxHashMap<(ImportFromData<'a>, AliasData<'a>), CommentSet<'a>>,
|
||||
}
|
||||
|
||||
type AliasDataWithComments<'a> = (AliasData<'a>, CommentSet<'a>);
|
||||
|
||||
@@ -188,7 +188,6 @@ pub fn lint_stdin(
|
||||
.collect())
|
||||
}
|
||||
|
||||
#[cfg_attr(target_family = "wasm", allow(unused_variables))]
|
||||
pub fn lint_path(
|
||||
path: &Path,
|
||||
settings: &Settings,
|
||||
@@ -198,7 +197,6 @@ pub fn lint_path(
|
||||
let metadata = path.metadata()?;
|
||||
|
||||
// Check the cache.
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
if let Some(messages) = cache::get(path, &metadata, settings, autofix, mode) {
|
||||
debug!("Cache hit for: {}", path.to_string_lossy());
|
||||
return Ok(messages);
|
||||
@@ -251,7 +249,7 @@ pub fn lint_path(
|
||||
Message::from_check(check, filename, source)
|
||||
})
|
||||
.collect();
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
|
||||
cache::set(path, &metadata, settings, autofix, &messages, mode);
|
||||
|
||||
Ok(messages)
|
||||
@@ -519,6 +517,7 @@ mod tests {
|
||||
#[test_case(CheckCode::U011, Path::new("U011_1.py"); "U011_1")]
|
||||
#[test_case(CheckCode::U012, Path::new("U012.py"); "U012")]
|
||||
#[test_case(CheckCode::U013, Path::new("U013.py"); "U013")]
|
||||
#[test_case(CheckCode::U014, Path::new("U014.py"); "U014")]
|
||||
#[test_case(CheckCode::W292, Path::new("W292_0.py"); "W292_0")]
|
||||
#[test_case(CheckCode::W292, Path::new("W292_1.py"); "W292_1")]
|
||||
#[test_case(CheckCode::W292, Path::new("W292_2.py"); "W292_2")]
|
||||
@@ -527,6 +526,13 @@ mod tests {
|
||||
#[test_case(CheckCode::RUF001, Path::new("RUF001.py"); "RUF001")]
|
||||
#[test_case(CheckCode::RUF002, Path::new("RUF002.py"); "RUF002")]
|
||||
#[test_case(CheckCode::RUF003, Path::new("RUF003.py"); "RUF003")]
|
||||
#[test_case(CheckCode::RUF101, Path::new("RUF101_0.py"); "RUF101_0")]
|
||||
#[test_case(CheckCode::RUF101, Path::new("RUF101_1.py"); "RUF101_1")]
|
||||
#[test_case(CheckCode::RUF101, Path::new("RUF101_2.py"); "RUF101_2")]
|
||||
#[test_case(CheckCode::RUF101, Path::new("RUF101_3.py"); "RUF101_3")]
|
||||
#[test_case(CheckCode::RUF101, Path::new("RUF101_4.py"); "RUF101_4")]
|
||||
#[test_case(CheckCode::RUF101, Path::new("RUF101_5.py"); "RUF101_5")]
|
||||
#[test_case(CheckCode::RUF101, Path::new("RUF101_6.py"); "RUF101_6")]
|
||||
#[test_case(CheckCode::YTT101, Path::new("YTT101.py"); "YTT101")]
|
||||
#[test_case(CheckCode::YTT102, Path::new("YTT102.py"); "YTT102")]
|
||||
#[test_case(CheckCode::YTT103, Path::new("YTT103.py"); "YTT103")]
|
||||
|
||||
29
src/main.rs
29
src/main.rs
@@ -4,7 +4,6 @@ use std::process::ExitCode;
|
||||
use std::sync::mpsc::channel;
|
||||
use std::time::Instant;
|
||||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
use ::ruff::cache;
|
||||
use ::ruff::checks::{CheckCode, CheckKind};
|
||||
use ::ruff::cli::{collect_per_file_ignores, extract_log_level, Cli};
|
||||
@@ -220,12 +219,12 @@ fn inner_main() -> Result<ExitCode> {
|
||||
.exclude
|
||||
.iter()
|
||||
.map(|path| FilePattern::from_user(path, project_root.as_ref()))
|
||||
.collect();
|
||||
.collect::<Result<_>>()?;
|
||||
let extend_exclude: Vec<FilePattern> = cli
|
||||
.extend_exclude
|
||||
.iter()
|
||||
.map(|path| FilePattern::from_user(path, project_root.as_ref()))
|
||||
.collect();
|
||||
.collect::<Result<_>>()?;
|
||||
|
||||
let mut configuration =
|
||||
Configuration::from_pyproject(pyproject.as_ref(), project_root.as_ref())?;
|
||||
@@ -237,7 +236,7 @@ fn inner_main() -> Result<ExitCode> {
|
||||
}
|
||||
if !cli.per_file_ignores.is_empty() {
|
||||
configuration.per_file_ignores =
|
||||
collect_per_file_ignores(cli.per_file_ignores, project_root.as_ref());
|
||||
collect_per_file_ignores(cli.per_file_ignores, project_root.as_ref())?;
|
||||
}
|
||||
if !cli.select.is_empty() {
|
||||
configuration.select = cli.select;
|
||||
@@ -286,7 +285,7 @@ fn inner_main() -> Result<ExitCode> {
|
||||
}
|
||||
|
||||
// Extract settings for internal use.
|
||||
let autofix = configuration.fix;
|
||||
let fix_enabled: bool = configuration.fix;
|
||||
let settings = Settings::from_configuration(configuration);
|
||||
|
||||
if cli.show_files {
|
||||
@@ -294,12 +293,16 @@ fn inner_main() -> Result<ExitCode> {
|
||||
return Ok(ExitCode::SUCCESS);
|
||||
}
|
||||
|
||||
#[cfg(not(target_family = "wasm"))]
|
||||
cache::init()?;
|
||||
// Initialize the cache.
|
||||
let mut cache_enabled: bool = !cli.no_cache;
|
||||
if cache_enabled && cache::init().is_err() {
|
||||
eprintln!("Unable to initialize cache; disabling...");
|
||||
cache_enabled = false;
|
||||
}
|
||||
|
||||
let printer = Printer::new(&cli.format, &log_level);
|
||||
if cli.watch {
|
||||
if autofix {
|
||||
if fix_enabled {
|
||||
eprintln!("Warning: --fix is not enabled in watch mode.");
|
||||
}
|
||||
|
||||
@@ -319,7 +322,7 @@ fn inner_main() -> Result<ExitCode> {
|
||||
printer.clear_screen()?;
|
||||
printer.write_to_user("Starting linter in watch mode...\n");
|
||||
|
||||
let messages = run_once(&cli.files, &settings, !cli.no_cache, false)?;
|
||||
let messages = run_once(&cli.files, &settings, cache_enabled, false)?;
|
||||
printer.write_continuously(&messages)?;
|
||||
|
||||
// Configure the file watcher.
|
||||
@@ -337,7 +340,7 @@ fn inner_main() -> Result<ExitCode> {
|
||||
printer.clear_screen()?;
|
||||
printer.write_to_user("File change detected...\n");
|
||||
|
||||
let messages = run_once(&cli.files, &settings, !cli.no_cache, false)?;
|
||||
let messages = run_once(&cli.files, &settings, cache_enabled, false)?;
|
||||
printer.write_continuously(&messages)?;
|
||||
}
|
||||
}
|
||||
@@ -362,15 +365,15 @@ fn inner_main() -> Result<ExitCode> {
|
||||
let messages = if is_stdin {
|
||||
let filename = cli.stdin_filename.unwrap_or_else(|| "-".to_string());
|
||||
let path = Path::new(&filename);
|
||||
run_once_stdin(&settings, path, autofix)?
|
||||
run_once_stdin(&settings, path, fix_enabled)?
|
||||
} else {
|
||||
run_once(&cli.files, &settings, !cli.no_cache, autofix)?
|
||||
run_once(&cli.files, &settings, cache_enabled, fix_enabled)?
|
||||
};
|
||||
|
||||
// Always try to print violations (the printer itself may suppress output),
|
||||
// unless we're writing fixes via stdin (in which case, the transformed
|
||||
// source code goes to stdout).
|
||||
if !(is_stdin && autofix) {
|
||||
if !(is_stdin && fix_enabled) {
|
||||
printer.write_once(&messages)?;
|
||||
}
|
||||
|
||||
|
||||
@@ -46,7 +46,6 @@ fn get_complexity_number(stmts: &[Stmt]) -> usize {
|
||||
complexity += get_complexity_number(body);
|
||||
}
|
||||
StmtKind::ClassDef { body, .. } => {
|
||||
complexity += 1;
|
||||
complexity += get_complexity_number(body);
|
||||
}
|
||||
_ => {}
|
||||
@@ -71,3 +70,235 @@ pub fn function_is_too_complex(
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
use rustpython_parser::parser;
|
||||
|
||||
use crate::mccabe::checks::get_complexity_number;
|
||||
|
||||
#[test]
|
||||
fn trivial() -> Result<()> {
|
||||
let source = r#"
|
||||
def trivial():
|
||||
pass
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn expr_as_statement() -> Result<()> {
|
||||
let source = r#"
|
||||
def expr_as_statement():
|
||||
0xF00D
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn sequential() -> Result<()> {
|
||||
let source = r#"
|
||||
def sequential(n):
|
||||
k = n + 4
|
||||
s = k + n
|
||||
return s
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn if_elif_else_dead_path() -> Result<()> {
|
||||
let source = r#"
|
||||
def if_elif_else_dead_path(n):
|
||||
if n > 3:
|
||||
return "bigger than three"
|
||||
elif n > 4:
|
||||
return "is never executed"
|
||||
else:
|
||||
return "smaller than or equal to three"
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 3);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_ifs() -> Result<()> {
|
||||
let source = r#"
|
||||
def nested_ifs():
|
||||
if n > 3:
|
||||
if n > 4:
|
||||
return "bigger than four"
|
||||
else:
|
||||
return "bigger than three"
|
||||
else:
|
||||
return "smaller than or equal to three"
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 3);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn for_loop() -> Result<()> {
|
||||
let source = r#"
|
||||
def for_loop():
|
||||
for i in range(10):
|
||||
print(i)
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 2);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn for_else() -> Result<()> {
|
||||
let source = r#"
|
||||
def for_else(mylist):
|
||||
for i in mylist:
|
||||
print(i)
|
||||
else:
|
||||
print(None)
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 2);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn recursive() -> Result<()> {
|
||||
let source = r#"
|
||||
def recursive(n):
|
||||
if n > 4:
|
||||
return f(n - 1)
|
||||
else:
|
||||
return n
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 2);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_functions() -> Result<()> {
|
||||
let source = r#"
|
||||
def nested_functions():
|
||||
def a():
|
||||
def b():
|
||||
pass
|
||||
|
||||
b()
|
||||
|
||||
a()
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 3);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn try_else() -> Result<()> {
|
||||
let source = r#"
|
||||
def try_else():
|
||||
try:
|
||||
print(1)
|
||||
except TypeA:
|
||||
print(2)
|
||||
except TypeB:
|
||||
print(3)
|
||||
else:
|
||||
print(4)
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 4);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested_try_finally() -> Result<()> {
|
||||
let source = r#"
|
||||
def nested_try_finally():
|
||||
try:
|
||||
try:
|
||||
print(1)
|
||||
finally:
|
||||
print(2)
|
||||
finally:
|
||||
print(3)
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 3);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn foobar() -> Result<()> {
|
||||
let source = r#"
|
||||
async def foobar(a, b, c):
|
||||
await whatever(a, b, c)
|
||||
if await b:
|
||||
pass
|
||||
async with c:
|
||||
pass
|
||||
async for x in a:
|
||||
pass
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 3);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn annotated_assign() -> Result<()> {
|
||||
let source = r#"
|
||||
def annotated_assign():
|
||||
x: Any = None
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 1);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn class() -> Result<()> {
|
||||
let source = r#"
|
||||
class Class:
|
||||
def handle(self, *args, **options):
|
||||
if args:
|
||||
return
|
||||
|
||||
class ServiceProvider:
|
||||
def a(self):
|
||||
pass
|
||||
|
||||
def b(self, data):
|
||||
if not args:
|
||||
pass
|
||||
|
||||
class Logger:
|
||||
def c(*args, **kwargs):
|
||||
pass
|
||||
|
||||
def error(self, message):
|
||||
pass
|
||||
|
||||
def info(self, message):
|
||||
pass
|
||||
|
||||
def exception(self):
|
||||
pass
|
||||
|
||||
return ServiceProvider(Logger())
|
||||
"#;
|
||||
let stmts = parser::parse_program(source, "<filename>")?;
|
||||
assert_eq!(get_complexity_number(&stmts), 9);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,7 +164,84 @@ expression: checks
|
||||
row: 107
|
||||
column: 0
|
||||
end_location:
|
||||
row: 109
|
||||
row: 112
|
||||
column: 0
|
||||
fix: ~
|
||||
- kind:
|
||||
FunctionIsTooComplex:
|
||||
- handle
|
||||
- 9
|
||||
location:
|
||||
row: 113
|
||||
column: 4
|
||||
end_location:
|
||||
row: 139
|
||||
column: 0
|
||||
fix: ~
|
||||
- kind:
|
||||
FunctionIsTooComplex:
|
||||
- a
|
||||
- 1
|
||||
location:
|
||||
row: 118
|
||||
column: 12
|
||||
end_location:
|
||||
row: 121
|
||||
column: 12
|
||||
fix: ~
|
||||
- kind:
|
||||
FunctionIsTooComplex:
|
||||
- b
|
||||
- 2
|
||||
location:
|
||||
row: 121
|
||||
column: 12
|
||||
end_location:
|
||||
row: 125
|
||||
column: 8
|
||||
fix: ~
|
||||
- kind:
|
||||
FunctionIsTooComplex:
|
||||
- c
|
||||
- 1
|
||||
location:
|
||||
row: 126
|
||||
column: 12
|
||||
end_location:
|
||||
row: 129
|
||||
column: 12
|
||||
fix: ~
|
||||
- kind:
|
||||
FunctionIsTooComplex:
|
||||
- error
|
||||
- 1
|
||||
location:
|
||||
row: 129
|
||||
column: 12
|
||||
end_location:
|
||||
row: 132
|
||||
column: 12
|
||||
fix: ~
|
||||
- kind:
|
||||
FunctionIsTooComplex:
|
||||
- info
|
||||
- 1
|
||||
location:
|
||||
row: 132
|
||||
column: 12
|
||||
end_location:
|
||||
row: 135
|
||||
column: 12
|
||||
fix: ~
|
||||
- kind:
|
||||
FunctionIsTooComplex:
|
||||
- exception
|
||||
- 1
|
||||
location:
|
||||
row: 135
|
||||
column: 12
|
||||
end_location:
|
||||
row: 138
|
||||
column: 8
|
||||
fix: ~
|
||||
|
||||
|
||||
@@ -13,4 +13,15 @@ expression: checks
|
||||
row: 85
|
||||
column: 0
|
||||
fix: ~
|
||||
- kind:
|
||||
FunctionIsTooComplex:
|
||||
- handle
|
||||
- 9
|
||||
location:
|
||||
row: 113
|
||||
column: 4
|
||||
end_location:
|
||||
row: 139
|
||||
column: 0
|
||||
fix: ~
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ impl fmt::Display for Message {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let label = format!(
|
||||
"{}{}{}{}{}{} {} {}",
|
||||
relativize_path(Path::new(&self.filename)).white().bold(),
|
||||
relativize_path(Path::new(&self.filename)).bold(),
|
||||
":".cyan(),
|
||||
self.location.row(),
|
||||
":".cyan(),
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::{Arguments, Expr, ExprKind, Stmt};
|
||||
|
||||
use crate::ast::types::{Range, Scope, ScopeKind};
|
||||
@@ -59,8 +59,8 @@ pub fn invalid_first_argument_name_for_class_method(
|
||||
name: &str,
|
||||
decorator_list: &[Expr],
|
||||
args: &Arguments,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
settings: &Settings,
|
||||
) -> Option<Check> {
|
||||
if matches!(
|
||||
@@ -74,7 +74,14 @@ pub fn invalid_first_argument_name_for_class_method(
|
||||
),
|
||||
FunctionType::ClassMethod
|
||||
) {
|
||||
if let Some(arg) = args.args.first() {
|
||||
if let Some(arg) = args.posonlyargs.first() {
|
||||
if arg.node.arg != "cls" {
|
||||
return Some(Check::new(
|
||||
CheckKind::InvalidFirstArgumentNameForClassMethod,
|
||||
Range::from_located(arg),
|
||||
));
|
||||
}
|
||||
} else if let Some(arg) = args.args.first() {
|
||||
if arg.node.arg != "cls" {
|
||||
return Some(Check::new(
|
||||
CheckKind::InvalidFirstArgumentNameForClassMethod,
|
||||
@@ -92,8 +99,8 @@ pub fn invalid_first_argument_name_for_method(
|
||||
name: &str,
|
||||
decorator_list: &[Expr],
|
||||
args: &Arguments,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
settings: &Settings,
|
||||
) -> Option<Check> {
|
||||
if matches!(
|
||||
@@ -125,6 +132,11 @@ pub fn dunder_function_name(scope: &Scope, stmt: &Stmt, name: &str) -> Option<Ch
|
||||
return None;
|
||||
}
|
||||
if name.starts_with("__") && name.ends_with("__") {
|
||||
// Allowed under PEP 562 (https://peps.python.org/pep-0562/).
|
||||
if matches!(scope.kind, ScopeKind::Module) && (name == "__getattr__" || name == "__dir__") {
|
||||
return None;
|
||||
}
|
||||
|
||||
return Some(Check::new(
|
||||
CheckKind::DunderFunctionName,
|
||||
Range::from_located(stmt),
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use itertools::Itertools;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::{Expr, Stmt, StmtKind};
|
||||
|
||||
use crate::ast::helpers::{
|
||||
@@ -24,8 +24,8 @@ pub fn function_type(
|
||||
scope: &Scope,
|
||||
name: &str,
|
||||
decorator_list: &[Expr],
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
settings: &Settings,
|
||||
) -> FunctionType {
|
||||
if let ScopeKind::Class(scope) = &scope.kind {
|
||||
@@ -87,7 +87,7 @@ pub fn is_acronym(name: &str, asname: &str) -> bool {
|
||||
|
||||
pub fn is_namedtuple_assignment(
|
||||
stmt: &Stmt,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
) -> bool {
|
||||
if let StmtKind::Assign { value, .. } = &stmt.node {
|
||||
match_call_path(
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use anyhow::Result;
|
||||
use fnv::FnvHashMap;
|
||||
use itertools::izip;
|
||||
use log::error;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::{Arguments, Location, StmtKind};
|
||||
use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind, Stmt, Unaryop};
|
||||
|
||||
@@ -46,7 +46,7 @@ pub fn literal_comparisons(
|
||||
// through the list of operators, we apply "dummy" fixes for each error,
|
||||
// then replace the entire expression at the end with one "real" fix, to
|
||||
// avoid conflicts.
|
||||
let mut bad_ops: FnvHashMap<usize, Cmpop> = FnvHashMap::default();
|
||||
let mut bad_ops: FxHashMap<usize, Cmpop> = FxHashMap::default();
|
||||
let mut checks: Vec<Check> = vec![];
|
||||
|
||||
let op = ops.first().unwrap();
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use std::collections::BTreeSet;
|
||||
|
||||
use fnv::FnvHashSet;
|
||||
use itertools::Itertools;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustpython_ast::{Arg, Constant, ExprKind, Location, StmtKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
@@ -1292,11 +1292,7 @@ fn common_section(
|
||||
blanks_and_section_underline(checker, definition, context);
|
||||
}
|
||||
|
||||
fn missing_args(
|
||||
checker: &mut Checker,
|
||||
definition: &Definition,
|
||||
docstrings_args: &FnvHashSet<&str>,
|
||||
) {
|
||||
fn missing_args(checker: &mut Checker, definition: &Definition, docstrings_args: &FxHashSet<&str>) {
|
||||
if let DefinitionKind::Function(parent)
|
||||
| DefinitionKind::NestedFunction(parent)
|
||||
| DefinitionKind::Method(parent) = definition.kind
|
||||
@@ -1389,7 +1385,7 @@ fn args_section(checker: &mut Checker, definition: &Definition, context: &Sectio
|
||||
checker,
|
||||
definition,
|
||||
// Collect the list of arguments documented in the docstring.
|
||||
&FnvHashSet::from_iter(args_sections.iter().filter_map(|section| {
|
||||
&FxHashSet::from_iter(args_sections.iter().filter_map(|section| {
|
||||
match GOOGLE_ARGS_REGEX.captures(section.as_str()) {
|
||||
Some(caps) => caps.get(1).map(|arg_name| arg_name.as_str()),
|
||||
None => None,
|
||||
@@ -1400,7 +1396,7 @@ fn args_section(checker: &mut Checker, definition: &Definition, context: &Sectio
|
||||
|
||||
fn parameters_section(checker: &mut Checker, definition: &Definition, context: &SectionContext) {
|
||||
// Collect the list of arguments documented in the docstring.
|
||||
let mut docstring_args: FnvHashSet<&str> = FnvHashSet::default();
|
||||
let mut docstring_args: FxHashSet<&str> = FxHashSet::default();
|
||||
let section_level_indent = whitespace::leading_space(context.line);
|
||||
for i in 1..context.following_lines.len() {
|
||||
let current_line = context.following_lines[i - 1];
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use fnv::FnvHashSet;
|
||||
use regex::Regex;
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustpython_parser::ast::{
|
||||
Arg, Arguments, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprKind, Stmt, StmtKind,
|
||||
};
|
||||
@@ -115,7 +115,7 @@ pub fn duplicate_arguments(arguments: &Arguments) -> Vec<Check> {
|
||||
}
|
||||
|
||||
// Search for duplicates.
|
||||
let mut idents: FnvHashSet<&str> = FnvHashSet::default();
|
||||
let mut idents: FxHashSet<&str> = FxHashSet::default();
|
||||
for arg in all_arguments {
|
||||
let ident = &arg.node.arg;
|
||||
if idents.contains(ident.as_str()) {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use fnv::FnvHashSet;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
// See: https://pycqa.github.io/isort/docs/configuration/options.html#known-standard-library
|
||||
pub static KNOWN_STANDARD_LIBRARY: Lazy<FnvHashSet<&'static str>> = Lazy::new(|| {
|
||||
FnvHashSet::from_iter([
|
||||
pub static KNOWN_STANDARD_LIBRARY: Lazy<FxHashSet<&'static str>> = Lazy::new(|| {
|
||||
FxHashSet::from_iter([
|
||||
"_ast",
|
||||
"_dummy_thread",
|
||||
"_thread",
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::Expr;
|
||||
|
||||
use crate::ast::helpers::{collect_call_paths, dealias_call_path, match_call_path};
|
||||
|
||||
// See: https://pypi.org/project/typing-extensions/
|
||||
static TYPING_EXTENSIONS: Lazy<FnvHashSet<&'static str>> = Lazy::new(|| {
|
||||
FnvHashSet::from_iter([
|
||||
static TYPING_EXTENSIONS: Lazy<FxHashSet<&'static str>> = Lazy::new(|| {
|
||||
FxHashSet::from_iter([
|
||||
"Annotated",
|
||||
"Any",
|
||||
"AsyncContextManager",
|
||||
@@ -211,8 +211,8 @@ pub enum SubscriptKind {
|
||||
|
||||
pub fn match_annotated_subscript(
|
||||
expr: &Expr,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> Option<SubscriptKind> {
|
||||
let call_path = dealias_call_path(collect_call_paths(expr), import_aliases);
|
||||
if !call_path.is_empty() {
|
||||
@@ -234,8 +234,8 @@ pub fn match_annotated_subscript(
|
||||
/// PEP 585 built-in.
|
||||
pub fn is_pep585_builtin(
|
||||
expr: &Expr,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> bool {
|
||||
let call_path = dealias_call_path(collect_call_paths(expr), import_aliases);
|
||||
if !call_path.is_empty() {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::{Constant, KeywordData};
|
||||
use rustpython_parser::ast::{ArgData, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
@@ -143,8 +143,8 @@ pub fn type_of_primitive(func: &Expr, args: &[Expr], location: Range) -> Option<
|
||||
pub fn unnecessary_lru_cache_params(
|
||||
decorator_list: &[Expr],
|
||||
target_version: PythonVersion,
|
||||
from_imports: &FnvHashMap<&str, FnvHashSet<&str>>,
|
||||
import_aliases: &FnvHashMap<&str, &str>,
|
||||
from_imports: &FxHashMap<&str, FxHashSet<&str>>,
|
||||
import_aliases: &FxHashMap<&str, &str>,
|
||||
) -> Option<Check> {
|
||||
for expr in decorator_list.iter() {
|
||||
if let ExprKind::Call {
|
||||
@@ -162,12 +162,13 @@ pub fn unnecessary_lru_cache_params(
|
||||
import_aliases,
|
||||
)
|
||||
{
|
||||
let range = Range {
|
||||
location: func.end_location.unwrap(),
|
||||
end_location: expr.end_location.unwrap(),
|
||||
};
|
||||
// Ex) `functools.lru_cache()`
|
||||
if keywords.is_empty() {
|
||||
return Some(Check::new(
|
||||
CheckKind::UnnecessaryLRUCacheParams,
|
||||
Range::from_located(expr),
|
||||
));
|
||||
return Some(Check::new(CheckKind::UnnecessaryLRUCacheParams, range));
|
||||
}
|
||||
// Ex) `functools.lru_cache(maxsize=None)`
|
||||
if target_version >= PythonVersion::Py39 && keywords.len() == 1 {
|
||||
@@ -181,10 +182,7 @@ pub fn unnecessary_lru_cache_params(
|
||||
}
|
||||
)
|
||||
{
|
||||
return Some(Check::new(
|
||||
CheckKind::UnnecessaryLRUCacheParams,
|
||||
Range::from_located(expr),
|
||||
));
|
||||
return Some(Check::new(CheckKind::UnnecessaryLRUCacheParams, range));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -191,34 +191,3 @@ pub fn remove_unnecessary_future_import(
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
/// U011
|
||||
pub fn remove_unnecessary_lru_cache_params(
|
||||
locator: &SourceCodeLocator,
|
||||
decor_at: &Location,
|
||||
) -> Option<Fix> {
|
||||
let contents = locator.slice_source_code_at(decor_at);
|
||||
let mut fix_start = None;
|
||||
let mut fix_end = None;
|
||||
let mut count: usize = 0;
|
||||
for (start, tok, end) in lexer::make_tokenizer(&contents).flatten() {
|
||||
if matches!(tok, Tok::Lpar) {
|
||||
if count == 0 {
|
||||
fix_start = Some(helpers::to_absolute(&start, decor_at));
|
||||
}
|
||||
count += 1;
|
||||
}
|
||||
|
||||
if matches!(tok, Tok::Rpar) {
|
||||
count -= 1;
|
||||
if count == 0 {
|
||||
fix_end = Some(helpers::to_absolute(&end, decor_at));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
match (fix_start, fix_end) {
|
||||
(Some(start), Some(end)) => Some(Fix::deletion(start, end)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
208
src/pyupgrade/plugins/convert_named_tuple_functional_to_class.rs
Normal file
208
src/pyupgrade/plugins/convert_named_tuple_functional_to_class.rs
Normal file
@@ -0,0 +1,208 @@
|
||||
use anyhow::{bail, Result};
|
||||
use log::error;
|
||||
use rustpython_ast::{Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind};
|
||||
|
||||
use crate::ast::helpers::match_module_member;
|
||||
use crate::ast::types::Range;
|
||||
use crate::autofix::Fix;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
use crate::code_gen::SourceGenerator;
|
||||
use crate::python::identifiers::IDENTIFIER_REGEX;
|
||||
use crate::python::keyword::KWLIST;
|
||||
|
||||
/// Return the typename, args, keywords and mother class
|
||||
fn match_named_tuple_assign<'a>(
|
||||
checker: &Checker,
|
||||
targets: &'a [Expr],
|
||||
value: &'a Expr,
|
||||
) -> Option<(&'a str, &'a [Expr], &'a [Keyword], &'a ExprKind)> {
|
||||
if let Some(target) = targets.get(0) {
|
||||
if let ExprKind::Name { id: typename, .. } = &target.node {
|
||||
if let ExprKind::Call {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
} = &value.node
|
||||
{
|
||||
if match_module_member(
|
||||
func,
|
||||
"typing",
|
||||
"NamedTuple",
|
||||
&checker.from_imports,
|
||||
&checker.import_aliases,
|
||||
) {
|
||||
return Some((typename, args, keywords, &func.node));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
None
|
||||
}
|
||||
|
||||
/// Generate a `StmtKind::AnnAssign` representing the provided property
|
||||
/// definition.
|
||||
fn create_property_assignment_stmt(
|
||||
property: &str,
|
||||
annotation: &ExprKind,
|
||||
value: Option<&ExprKind>,
|
||||
) -> Stmt {
|
||||
Stmt::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
StmtKind::AnnAssign {
|
||||
target: Box::new(Expr::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
ExprKind::Name {
|
||||
id: property.to_string(),
|
||||
ctx: ExprContext::Load,
|
||||
},
|
||||
)),
|
||||
annotation: Box::new(Expr::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
annotation.clone(),
|
||||
)),
|
||||
value: value
|
||||
.map(|v| Box::new(Expr::new(Default::default(), Default::default(), v.clone()))),
|
||||
simple: 1,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Match the `defaults` keyword in a `NamedTuple(...)` call.
|
||||
fn match_defaults(keywords: &[Keyword]) -> Result<&[Expr]> {
|
||||
match keywords.iter().find(|keyword| {
|
||||
if let Some(arg) = &keyword.node.arg {
|
||||
arg.as_str() == "defaults"
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}) {
|
||||
Some(defaults) => match &defaults.node.value.node {
|
||||
ExprKind::List { elts, .. } => Ok(elts),
|
||||
ExprKind::Tuple { elts, .. } => Ok(elts),
|
||||
_ => bail!("Expected defaults to be `ExprKind::List` | `ExprKind::Tuple`"),
|
||||
},
|
||||
None => Ok(&[]),
|
||||
}
|
||||
}
|
||||
|
||||
/// Create a list of property assignments from the `NamedTuple` arguments.
|
||||
fn create_properties_from_args(args: &[Expr], defaults: &[Expr]) -> Result<Vec<Stmt>> {
|
||||
if let Some(fields) = args.get(1) {
|
||||
if let ExprKind::List { elts, .. } = &fields.node {
|
||||
let padded_defaults = if elts.len() >= defaults.len() {
|
||||
std::iter::repeat(None)
|
||||
.take(elts.len() - defaults.len())
|
||||
.chain(defaults.iter().map(Some))
|
||||
} else {
|
||||
bail!("Defaults must be `None` or an iterable of at least the number of fields")
|
||||
};
|
||||
elts.iter()
|
||||
.zip(padded_defaults)
|
||||
.map(|(field, default)| {
|
||||
if let ExprKind::Tuple { elts, .. } = &field.node {
|
||||
if let [field_name, annotation] = elts.as_slice() {
|
||||
if let ExprKind::Constant {
|
||||
value: Constant::Str(property),
|
||||
..
|
||||
} = &field_name.node
|
||||
{
|
||||
if IDENTIFIER_REGEX.is_match(property)
|
||||
&& !KWLIST.contains(&property.as_str())
|
||||
{
|
||||
Ok(create_property_assignment_stmt(
|
||||
property,
|
||||
&annotation.node,
|
||||
default.map(|d| &d.node),
|
||||
))
|
||||
} else {
|
||||
bail!("Invalid property name: {}", property)
|
||||
}
|
||||
} else {
|
||||
bail!("Expected `field_name` to be `Constant::Str`")
|
||||
}
|
||||
} else {
|
||||
bail!("Expected `elts` to have exactly two elements")
|
||||
}
|
||||
} else {
|
||||
bail!("Expected `field` to be `ExprKind::Tuple`")
|
||||
}
|
||||
})
|
||||
.collect()
|
||||
} else {
|
||||
bail!("Expected argument to be `ExprKind::List`")
|
||||
}
|
||||
} else {
|
||||
Ok(vec![])
|
||||
}
|
||||
}
|
||||
|
||||
/// Generate a `StmtKind:ClassDef` statement based on the provided body and
|
||||
/// keywords.
|
||||
fn create_class_def_stmt(typename: &str, body: Vec<Stmt>, base_class: &ExprKind) -> Stmt {
|
||||
Stmt::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
StmtKind::ClassDef {
|
||||
name: typename.to_string(),
|
||||
bases: vec![Expr::new(
|
||||
Default::default(),
|
||||
Default::default(),
|
||||
base_class.clone(),
|
||||
)],
|
||||
keywords: vec![],
|
||||
body,
|
||||
decorator_list: vec![],
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
fn convert_to_class(
|
||||
stmt: &Stmt,
|
||||
typename: &str,
|
||||
body: Vec<Stmt>,
|
||||
base_class: &ExprKind,
|
||||
) -> Result<Fix> {
|
||||
let mut generator = SourceGenerator::new();
|
||||
generator.unparse_stmt(&create_class_def_stmt(typename, body, base_class))?;
|
||||
let content = generator.generate()?;
|
||||
Ok(Fix::replacement(
|
||||
content,
|
||||
stmt.location,
|
||||
stmt.end_location.unwrap(),
|
||||
))
|
||||
}
|
||||
|
||||
/// U014
|
||||
pub fn convert_named_tuple_functional_to_class(
|
||||
checker: &mut Checker,
|
||||
stmt: &Stmt,
|
||||
targets: &[Expr],
|
||||
value: &Expr,
|
||||
) {
|
||||
if let Some((typename, args, keywords, base_class)) =
|
||||
match_named_tuple_assign(checker, targets, value)
|
||||
{
|
||||
match match_defaults(keywords) {
|
||||
Ok(defaults) => {
|
||||
if let Ok(properties) = create_properties_from_args(args, defaults) {
|
||||
let mut check = Check::new(
|
||||
CheckKind::ConvertNamedTupleFunctionalToClass(typename.to_string()),
|
||||
Range::from_located(stmt),
|
||||
);
|
||||
if checker.patch(check.kind.code()) {
|
||||
match convert_to_class(stmt, typename, properties, base_class) {
|
||||
Ok(fix) => check.amend(fix),
|
||||
Err(err) => error!("Failed to convert `NamedTuple`: {}", err),
|
||||
}
|
||||
}
|
||||
checker.add_check(check);
|
||||
}
|
||||
}
|
||||
Err(err) => error!("Failed to parse defaults: {}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -230,7 +230,7 @@ pub fn convert_typed_dict_functional_to_class(
|
||||
Err(err) => error!("Failed to parse TypedDict: {}", err),
|
||||
Ok((body, total_keyword)) => {
|
||||
let mut check = Check::new(
|
||||
CheckKind::ConvertTypedDictFunctionalToClass,
|
||||
CheckKind::ConvertTypedDictFunctionalToClass(class_name.to_string()),
|
||||
Range::from_located(stmt),
|
||||
);
|
||||
if checker.patch(check.kind.code()) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use fnv::FnvHashMap;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::{Expr, ExprKind};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
@@ -7,8 +7,8 @@ use crate::autofix::Fix;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
|
||||
static DEPRECATED_ALIASES: Lazy<FnvHashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||
FnvHashMap::from_iter([
|
||||
static DEPRECATED_ALIASES: Lazy<FxHashMap<&'static str, &'static str>> = Lazy::new(|| {
|
||||
FxHashMap::from_iter([
|
||||
("failUnlessEqual", "assertEqual"),
|
||||
("assertEquals", "assertEqual"),
|
||||
("failIfEqual", "assertNotEqual"),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
pub use convert_named_tuple_functional_to_class::convert_named_tuple_functional_to_class;
|
||||
pub use convert_typed_dict_functional_to_class::convert_typed_dict_functional_to_class;
|
||||
pub use deprecated_unittest_alias::deprecated_unittest_alias;
|
||||
pub use super_call_with_parameters::super_call_with_parameters;
|
||||
@@ -10,6 +11,7 @@ pub use use_pep604_annotation::use_pep604_annotation;
|
||||
pub use useless_metaclass_type::useless_metaclass_type;
|
||||
pub use useless_object_inheritance::useless_object_inheritance;
|
||||
|
||||
mod convert_named_tuple_functional_to_class;
|
||||
mod convert_typed_dict_functional_to_class;
|
||||
mod deprecated_unittest_alias;
|
||||
mod super_call_with_parameters;
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
use rustpython_parser::ast::Expr;
|
||||
|
||||
use crate::autofix::Fix;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::pyupgrade::{checks, fixes};
|
||||
use crate::pyupgrade::checks;
|
||||
|
||||
/// U011
|
||||
pub fn unnecessary_lru_cache_params(checker: &mut Checker, decorator_list: &[Expr]) {
|
||||
@@ -12,11 +13,7 @@ pub fn unnecessary_lru_cache_params(checker: &mut Checker, decorator_list: &[Exp
|
||||
&checker.import_aliases,
|
||||
) {
|
||||
if checker.patch(check.kind.code()) {
|
||||
if let Some(fix) =
|
||||
fixes::remove_unnecessary_lru_cache_params(checker.locator, &check.location)
|
||||
{
|
||||
check.amend(fix);
|
||||
}
|
||||
check.amend(Fix::deletion(check.location, check.end_location));
|
||||
}
|
||||
checker.add_check(check);
|
||||
}
|
||||
|
||||
@@ -42,8 +42,25 @@ fn union(elts: &[Expr]) -> Expr {
|
||||
}
|
||||
}
|
||||
|
||||
/// Returns `true` if any argument in the slice is a string.
|
||||
fn any_arg_is_str(slice: &Expr) -> bool {
|
||||
match &slice.node {
|
||||
ExprKind::Constant {
|
||||
value: Constant::Str(_),
|
||||
..
|
||||
} => true,
|
||||
ExprKind::Tuple { elts, .. } => elts.iter().any(any_arg_is_str),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// U007
|
||||
pub fn use_pep604_annotation(checker: &mut Checker, expr: &Expr, value: &Expr, slice: &Expr) {
|
||||
// Avoid rewriting forward annotations.
|
||||
if any_arg_is_str(slice) {
|
||||
return;
|
||||
}
|
||||
|
||||
let call_path = dealias_call_path(collect_call_paths(value), &checker.import_aliases);
|
||||
if checker.match_typing_call_path(&call_path, "Optional") {
|
||||
let mut check = Check::new(CheckKind::UsePEP604Annotation, Range::from_located(expr));
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use fnv::FnvHashMap;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_ast::Location;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
@@ -9,8 +9,8 @@ use crate::source_code_locator::SourceCodeLocator;
|
||||
use crate::{Check, Settings};
|
||||
|
||||
/// See: https://github.com/microsoft/vscode/blob/095ddabc52b82498ee7f718a34f9dd11d59099a8/src/vs/base/common/strings.ts#L1094
|
||||
static CONFUSABLES: Lazy<FnvHashMap<u32, u32>> = Lazy::new(|| {
|
||||
FnvHashMap::from_iter([
|
||||
static CONFUSABLES: Lazy<FxHashMap<u32, u32>> = Lazy::new(|| {
|
||||
FxHashMap::from_iter([
|
||||
(8232, 32),
|
||||
(8233, 32),
|
||||
(5760, 32),
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
//! Module for Ruff-specific rules.
|
||||
|
||||
pub mod checks;
|
||||
pub mod plugins;
|
||||
|
||||
92
src/rules/plugins/convert_exit_to_sys_exit.rs
Normal file
92
src/rules/plugins/convert_exit_to_sys_exit.rs
Normal file
@@ -0,0 +1,92 @@
|
||||
use rustpython_ast::{Expr, ExprKind};
|
||||
|
||||
use crate::ast::types::{BindingKind, Range};
|
||||
use crate::autofix::Fix;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
|
||||
/// Return `true` if the `module` was imported using a star import (e.g., `from
|
||||
/// sys import *`).
|
||||
fn is_module_star_imported(checker: &Checker, module: &str) -> bool {
|
||||
checker.current_scopes().any(|scope| {
|
||||
scope.values.values().any(|binding| {
|
||||
if let BindingKind::StarImportation(_, name) = &binding.kind {
|
||||
name.as_ref().map(|name| name == module).unwrap_or_default()
|
||||
} else {
|
||||
false
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// Return `true` if `exit` is (still) bound as a built-in in the current scope.
|
||||
fn has_builtin_exit_in_scope(checker: &Checker) -> bool {
|
||||
!is_module_star_imported(checker, "sys")
|
||||
&& checker
|
||||
.current_scopes()
|
||||
.find_map(|scope| scope.values.get("exit"))
|
||||
.map(|binding| matches!(binding.kind, BindingKind::Builtin))
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Return the appropriate `sys.exit` reference based on the current set of
|
||||
/// imports, or `None` is `sys.exit` hasn't been imported.
|
||||
fn get_member_import_name_alias(checker: &Checker, module: &str, member: &str) -> Option<String> {
|
||||
checker.current_scopes().find_map(|scope| {
|
||||
scope
|
||||
.values
|
||||
.values()
|
||||
.find_map(|binding| match &binding.kind {
|
||||
// e.g. module=sys object=exit
|
||||
// `import sys` -> `sys.exit`
|
||||
// `import sys as sys2` -> `sys2.exit`
|
||||
BindingKind::Importation(name, full_name, _) if full_name == module => {
|
||||
Some(format!("{}.{}", name, member))
|
||||
}
|
||||
// e.g. module=os.path object=join
|
||||
// `from os.path import join` -> `join`
|
||||
// `from os.path import join as join2` -> `join2`
|
||||
BindingKind::FromImportation(name, full_name, _)
|
||||
if full_name == &format!("{}.{}", module, member) =>
|
||||
{
|
||||
Some(name.to_string())
|
||||
}
|
||||
// e.g. module=os.path object=join
|
||||
// `from os.path import *` -> `join`
|
||||
BindingKind::StarImportation(_, name)
|
||||
if name.as_ref().map(|name| name == module).unwrap_or_default() =>
|
||||
{
|
||||
Some(member.to_string())
|
||||
}
|
||||
// e.g. module=os.path object=join
|
||||
// `import os.path ` -> `os.path.join`
|
||||
BindingKind::SubmoduleImportation(_, full_name, _) if full_name == module => {
|
||||
Some(format!("{}.{}", full_name, member))
|
||||
}
|
||||
// Non-imports.
|
||||
_ => None,
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
/// RUF101
|
||||
pub fn convert_exit_to_sys_exit(checker: &mut Checker, func: &Expr) {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if id == "exit" {
|
||||
if has_builtin_exit_in_scope(checker) {
|
||||
let mut check =
|
||||
Check::new(CheckKind::ConvertExitToSysExit, Range::from_located(func));
|
||||
if checker.patch(check.kind.code()) {
|
||||
if let Some(content) = get_member_import_name_alias(checker, "sys", "exit") {
|
||||
check.amend(Fix::replacement(
|
||||
content,
|
||||
func.location,
|
||||
func.end_location.unwrap(),
|
||||
))
|
||||
}
|
||||
}
|
||||
checker.add_check(check);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
3
src/rules/plugins/mod.rs
Normal file
3
src/rules/plugins/mod.rs
Normal file
@@ -0,0 +1,3 @@
|
||||
pub use convert_exit_to_sys_exit::convert_exit_to_sys_exit;
|
||||
|
||||
mod convert_exit_to_sys_exit;
|
||||
@@ -111,13 +111,14 @@ impl Configuration {
|
||||
.map(|path| FilePattern::from_user(path, project_root))
|
||||
.collect()
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| DEFAULT_EXCLUDE.clone()),
|
||||
extend_exclude: options
|
||||
.extend_exclude
|
||||
.unwrap_or_default()
|
||||
.iter()
|
||||
.map(|path| FilePattern::from_user(path, project_root))
|
||||
.collect(),
|
||||
.collect::<Result<_>>()?,
|
||||
extend_ignore: options.extend_ignore.unwrap_or_default(),
|
||||
select: options
|
||||
.select
|
||||
@@ -138,6 +139,7 @@ impl Configuration {
|
||||
CheckCodePrefix::M,
|
||||
CheckCodePrefix::N,
|
||||
CheckCodePrefix::Q,
|
||||
CheckCodePrefix::RUF,
|
||||
CheckCodePrefix::S,
|
||||
CheckCodePrefix::T,
|
||||
CheckCodePrefix::U,
|
||||
@@ -158,6 +160,7 @@ impl Configuration {
|
||||
})
|
||||
.collect()
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or_default(),
|
||||
show_source: options.show_source.unwrap_or_default(),
|
||||
// Plugins
|
||||
|
||||
@@ -5,9 +5,9 @@
|
||||
use std::hash::{Hash, Hasher};
|
||||
use std::path::PathBuf;
|
||||
|
||||
use fnv::FnvHashSet;
|
||||
use path_absolutize::path_dedot;
|
||||
use regex::Regex;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::checks::CheckCode;
|
||||
use crate::checks_gen::{CheckCodePrefix, PrefixSpecificity};
|
||||
@@ -27,10 +27,10 @@ pub mod user;
|
||||
#[derive(Debug)]
|
||||
pub struct Settings {
|
||||
pub dummy_variable_rgx: Regex,
|
||||
pub enabled: FnvHashSet<CheckCode>,
|
||||
pub enabled: FxHashSet<CheckCode>,
|
||||
pub exclude: Vec<FilePattern>,
|
||||
pub extend_exclude: Vec<FilePattern>,
|
||||
pub fixable: FnvHashSet<CheckCode>,
|
||||
pub fixable: FxHashSet<CheckCode>,
|
||||
pub line_length: usize,
|
||||
pub per_file_ignores: Vec<PerFileIgnore>,
|
||||
pub show_source: bool,
|
||||
@@ -83,8 +83,8 @@ impl Settings {
|
||||
pub fn for_rule(check_code: CheckCode) -> Self {
|
||||
Self {
|
||||
dummy_variable_rgx: Regex::new("^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$").unwrap(),
|
||||
enabled: FnvHashSet::from_iter([check_code.clone()]),
|
||||
fixable: FnvHashSet::from_iter([check_code]),
|
||||
enabled: FxHashSet::from_iter([check_code.clone()]),
|
||||
fixable: FxHashSet::from_iter([check_code]),
|
||||
exclude: Default::default(),
|
||||
extend_exclude: Default::default(),
|
||||
line_length: 88,
|
||||
@@ -105,8 +105,8 @@ impl Settings {
|
||||
pub fn for_rules(check_codes: Vec<CheckCode>) -> Self {
|
||||
Self {
|
||||
dummy_variable_rgx: Regex::new("^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$").unwrap(),
|
||||
enabled: FnvHashSet::from_iter(check_codes.clone()),
|
||||
fixable: FnvHashSet::from_iter(check_codes),
|
||||
enabled: FxHashSet::from_iter(check_codes.clone()),
|
||||
fixable: FxHashSet::from_iter(check_codes),
|
||||
exclude: Default::default(),
|
||||
extend_exclude: Default::default(),
|
||||
line_length: 88,
|
||||
@@ -154,8 +154,8 @@ impl Hash for Settings {
|
||||
|
||||
/// Given a set of selected and ignored prefixes, resolve the set of enabled
|
||||
/// error codes.
|
||||
fn resolve_codes(select: &[CheckCodePrefix], ignore: &[CheckCodePrefix]) -> FnvHashSet<CheckCode> {
|
||||
let mut codes: FnvHashSet<CheckCode> = FnvHashSet::default();
|
||||
fn resolve_codes(select: &[CheckCodePrefix], ignore: &[CheckCodePrefix]) -> FxHashSet<CheckCode> {
|
||||
let mut codes: FxHashSet<CheckCode> = FxHashSet::default();
|
||||
for specificity in [
|
||||
PrefixSpecificity::Category,
|
||||
PrefixSpecificity::Hundreds,
|
||||
@@ -180,7 +180,7 @@ fn resolve_codes(select: &[CheckCodePrefix], ignore: &[CheckCodePrefix]) -> FnvH
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use fnv::FnvHashSet;
|
||||
use rustc_hash::FxHashSet;
|
||||
|
||||
use crate::checks::CheckCode;
|
||||
use crate::checks_gen::CheckCodePrefix;
|
||||
@@ -189,19 +189,19 @@ mod tests {
|
||||
#[test]
|
||||
fn resolver() {
|
||||
let actual = resolve_codes(&[CheckCodePrefix::W], &[]);
|
||||
let expected = FnvHashSet::from_iter([CheckCode::W292, CheckCode::W605]);
|
||||
let expected = FxHashSet::from_iter([CheckCode::W292, CheckCode::W605]);
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
let actual = resolve_codes(&[CheckCodePrefix::W6], &[]);
|
||||
let expected = FnvHashSet::from_iter([CheckCode::W605]);
|
||||
let expected = FxHashSet::from_iter([CheckCode::W605]);
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
let actual = resolve_codes(&[CheckCodePrefix::W], &[CheckCodePrefix::W292]);
|
||||
let expected = FnvHashSet::from_iter([CheckCode::W605]);
|
||||
let expected = FxHashSet::from_iter([CheckCode::W605]);
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
let actual = resolve_codes(&[CheckCodePrefix::W605], &[CheckCodePrefix::W605]);
|
||||
let expected = FnvHashSet::from_iter([]);
|
||||
let expected = FxHashSet::from_iter([]);
|
||||
assert_eq!(actual, expected);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
//! Options that the user can provide via pyproject.toml.
|
||||
|
||||
use fnv::FnvHashMap;
|
||||
use rustc_hash::FxHashMap;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::checks_gen::CheckCodePrefix;
|
||||
@@ -36,5 +36,5 @@ pub struct Options {
|
||||
pub mccabe: Option<mccabe::settings::Options>,
|
||||
pub pep8_naming: Option<pep8_naming::settings::Options>,
|
||||
// Tables are required to go last.
|
||||
pub per_file_ignores: Option<FnvHashMap<String, Vec<CheckCodePrefix>>>,
|
||||
pub per_file_ignores: Option<FxHashMap<String, Vec<CheckCodePrefix>>>,
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ mod tests {
|
||||
use std::str::FromStr;
|
||||
|
||||
use anyhow::Result;
|
||||
use fnv::FnvHashMap;
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::checks_gen::CheckCodePrefix;
|
||||
use crate::flake8_quotes::settings::Quote;
|
||||
@@ -374,7 +374,7 @@ other-attribute = 1
|
||||
extend_ignore: None,
|
||||
fixable: None,
|
||||
unfixable: None,
|
||||
per_file_ignores: Some(FnvHashMap::from_iter([(
|
||||
per_file_ignores: Some(FxHashMap::from_iter([(
|
||||
"__init__.py".to_string(),
|
||||
vec![CheckCodePrefix::F401]
|
||||
),])),
|
||||
|
||||
@@ -51,21 +51,21 @@ pub enum FilePattern {
|
||||
}
|
||||
|
||||
impl FilePattern {
|
||||
pub fn from_user(pattern: &str, project_root: Option<&PathBuf>) -> Self {
|
||||
pub fn from_user(pattern: &str, project_root: Option<&PathBuf>) -> Result<Self> {
|
||||
let path = Path::new(pattern);
|
||||
let absolute_path = match project_root {
|
||||
Some(project_root) => fs::normalize_path_to(path, project_root),
|
||||
None => fs::normalize_path(path),
|
||||
};
|
||||
|
||||
let absolute = Pattern::new(&absolute_path.to_string_lossy()).expect("Invalid pattern.");
|
||||
let absolute = Pattern::new(&absolute_path.to_string_lossy())?;
|
||||
let basename = if !pattern.contains(std::path::MAIN_SEPARATOR) {
|
||||
Some(Pattern::new(pattern).expect("Invalid pattern."))
|
||||
Some(Pattern::new(pattern)?)
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
FilePattern::Complex(absolute, basename)
|
||||
Ok(FilePattern::Complex(absolute, basename))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -80,10 +80,10 @@ impl PerFileIgnore {
|
||||
pattern: &str,
|
||||
prefixes: &[CheckCodePrefix],
|
||||
project_root: Option<&PathBuf>,
|
||||
) -> Self {
|
||||
let pattern = FilePattern::from_user(pattern, project_root);
|
||||
) -> Result<Self> {
|
||||
let pattern = FilePattern::from_user(pattern, project_root)?;
|
||||
let codes = BTreeSet::from_iter(prefixes.iter().flat_map(|prefix| prefix.codes()));
|
||||
Self { pattern, codes }
|
||||
Ok(Self { pattern, codes })
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,7 +9,16 @@ expression: checks
|
||||
end_location:
|
||||
row: 33
|
||||
column: 25
|
||||
fix: ~
|
||||
fix:
|
||||
patch:
|
||||
content: foo.bar = None
|
||||
location:
|
||||
row: 33
|
||||
column: 0
|
||||
end_location:
|
||||
row: 33
|
||||
column: 25
|
||||
applied: false
|
||||
- kind: SetAttrWithConstant
|
||||
location:
|
||||
row: 34
|
||||
@@ -17,7 +26,16 @@ expression: checks
|
||||
end_location:
|
||||
row: 34
|
||||
column: 29
|
||||
fix: ~
|
||||
fix:
|
||||
patch:
|
||||
content: foo._123abc = None
|
||||
location:
|
||||
row: 34
|
||||
column: 0
|
||||
end_location:
|
||||
row: 34
|
||||
column: 29
|
||||
applied: false
|
||||
- kind: SetAttrWithConstant
|
||||
location:
|
||||
row: 35
|
||||
@@ -25,7 +43,16 @@ expression: checks
|
||||
end_location:
|
||||
row: 35
|
||||
column: 28
|
||||
fix: ~
|
||||
fix:
|
||||
patch:
|
||||
content: foo.abc123 = None
|
||||
location:
|
||||
row: 35
|
||||
column: 0
|
||||
end_location:
|
||||
row: 35
|
||||
column: 28
|
||||
applied: false
|
||||
- kind: SetAttrWithConstant
|
||||
location:
|
||||
row: 36
|
||||
@@ -33,5 +60,31 @@ expression: checks
|
||||
end_location:
|
||||
row: 36
|
||||
column: 29
|
||||
fix: ~
|
||||
fix:
|
||||
patch:
|
||||
content: foo.abc123 = None
|
||||
location:
|
||||
row: 36
|
||||
column: 0
|
||||
end_location:
|
||||
row: 36
|
||||
column: 29
|
||||
applied: false
|
||||
- kind: SetAttrWithConstant
|
||||
location:
|
||||
row: 37
|
||||
column: 0
|
||||
end_location:
|
||||
row: 37
|
||||
column: 30
|
||||
fix:
|
||||
patch:
|
||||
content: foo.bar.baz = None
|
||||
location:
|
||||
row: 37
|
||||
column: 0
|
||||
end_location:
|
||||
row: 37
|
||||
column: 30
|
||||
applied: false
|
||||
|
||||
|
||||
@@ -10,5 +10,14 @@ expression: checks
|
||||
end_location:
|
||||
row: 3
|
||||
column: 19
|
||||
fix: ~
|
||||
fix:
|
||||
patch:
|
||||
content: ValueError
|
||||
location:
|
||||
row: 3
|
||||
column: 7
|
||||
end_location:
|
||||
row: 3
|
||||
column: 20
|
||||
applied: false
|
||||
|
||||
|
||||
@@ -12,10 +12,18 @@ expression: checks
|
||||
fix: ~
|
||||
- kind: InvalidFirstArgumentNameForClassMethod
|
||||
location:
|
||||
row: 35
|
||||
row: 38
|
||||
column: 55
|
||||
end_location:
|
||||
row: 38
|
||||
column: 59
|
||||
fix: ~
|
||||
- kind: InvalidFirstArgumentNameForClassMethod
|
||||
location:
|
||||
row: 43
|
||||
column: 19
|
||||
end_location:
|
||||
row: 35
|
||||
row: 43
|
||||
column: 23
|
||||
fix: ~
|
||||
|
||||
|
||||
@@ -10,4 +10,12 @@ expression: checks
|
||||
row: 5
|
||||
column: 0
|
||||
fix: ~
|
||||
- kind: DunderFunctionName
|
||||
location:
|
||||
row: 14
|
||||
column: 4
|
||||
end_location:
|
||||
row: 17
|
||||
column: 4
|
||||
fix: ~
|
||||
|
||||
|
||||
21
src/snapshots/ruff__linter__tests__RUF101_RUF101_0.py.snap
Normal file
21
src/snapshots/ruff__linter__tests__RUF101_RUF101_0.py.snap
Normal file
@@ -0,0 +1,21 @@
|
||||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: ConvertExitToSysExit
|
||||
location:
|
||||
row: 1
|
||||
column: 0
|
||||
end_location:
|
||||
row: 1
|
||||
column: 4
|
||||
fix: ~
|
||||
- kind: ConvertExitToSysExit
|
||||
location:
|
||||
row: 5
|
||||
column: 4
|
||||
end_location:
|
||||
row: 5
|
||||
column: 8
|
||||
fix: ~
|
||||
|
||||
39
src/snapshots/ruff__linter__tests__RUF101_RUF101_1.py.snap
Normal file
39
src/snapshots/ruff__linter__tests__RUF101_RUF101_1.py.snap
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: ConvertExitToSysExit
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 3
|
||||
column: 4
|
||||
fix:
|
||||
patch:
|
||||
content: sys.exit
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 3
|
||||
column: 4
|
||||
applied: false
|
||||
- kind: ConvertExitToSysExit
|
||||
location:
|
||||
row: 7
|
||||
column: 4
|
||||
end_location:
|
||||
row: 7
|
||||
column: 8
|
||||
fix:
|
||||
patch:
|
||||
content: sys.exit
|
||||
location:
|
||||
row: 7
|
||||
column: 4
|
||||
end_location:
|
||||
row: 7
|
||||
column: 8
|
||||
applied: false
|
||||
|
||||
39
src/snapshots/ruff__linter__tests__RUF101_RUF101_2.py.snap
Normal file
39
src/snapshots/ruff__linter__tests__RUF101_RUF101_2.py.snap
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: ConvertExitToSysExit
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 3
|
||||
column: 4
|
||||
fix:
|
||||
patch:
|
||||
content: sys2.exit
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 3
|
||||
column: 4
|
||||
applied: false
|
||||
- kind: ConvertExitToSysExit
|
||||
location:
|
||||
row: 7
|
||||
column: 4
|
||||
end_location:
|
||||
row: 7
|
||||
column: 8
|
||||
fix:
|
||||
patch:
|
||||
content: sys2.exit
|
||||
location:
|
||||
row: 7
|
||||
column: 4
|
||||
end_location:
|
||||
row: 7
|
||||
column: 8
|
||||
applied: false
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
[]
|
||||
|
||||
39
src/snapshots/ruff__linter__tests__RUF101_RUF101_4.py.snap
Normal file
39
src/snapshots/ruff__linter__tests__RUF101_RUF101_4.py.snap
Normal file
@@ -0,0 +1,39 @@
|
||||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: ConvertExitToSysExit
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 3
|
||||
column: 4
|
||||
fix:
|
||||
patch:
|
||||
content: exit2
|
||||
location:
|
||||
row: 3
|
||||
column: 0
|
||||
end_location:
|
||||
row: 3
|
||||
column: 4
|
||||
applied: false
|
||||
- kind: ConvertExitToSysExit
|
||||
location:
|
||||
row: 7
|
||||
column: 4
|
||||
end_location:
|
||||
row: 7
|
||||
column: 8
|
||||
fix:
|
||||
patch:
|
||||
content: exit2
|
||||
location:
|
||||
row: 7
|
||||
column: 4
|
||||
end_location:
|
||||
row: 7
|
||||
column: 8
|
||||
applied: false
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
[]
|
||||
|
||||
13
src/snapshots/ruff__linter__tests__RUF101_RUF101_6.py.snap
Normal file
13
src/snapshots/ruff__linter__tests__RUF101_RUF101_6.py.snap
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: ConvertExitToSysExit
|
||||
location:
|
||||
row: 1
|
||||
column: 0
|
||||
end_location:
|
||||
row: 1
|
||||
column: 4
|
||||
fix: ~
|
||||
|
||||
@@ -4,138 +4,121 @@ expression: checks
|
||||
---
|
||||
- kind: UsePEP604Annotation
|
||||
location:
|
||||
row: 4
|
||||
row: 6
|
||||
column: 9
|
||||
end_location:
|
||||
row: 4
|
||||
row: 6
|
||||
column: 22
|
||||
fix:
|
||||
patch:
|
||||
content: str | None
|
||||
location:
|
||||
row: 4
|
||||
row: 6
|
||||
column: 9
|
||||
end_location:
|
||||
row: 4
|
||||
row: 6
|
||||
column: 22
|
||||
applied: false
|
||||
- kind: UsePEP604Annotation
|
||||
location:
|
||||
row: 11
|
||||
row: 10
|
||||
column: 9
|
||||
end_location:
|
||||
row: 11
|
||||
row: 10
|
||||
column: 29
|
||||
fix:
|
||||
patch:
|
||||
content: str | None
|
||||
location:
|
||||
row: 11
|
||||
row: 10
|
||||
column: 9
|
||||
end_location:
|
||||
row: 11
|
||||
row: 10
|
||||
column: 29
|
||||
applied: false
|
||||
- kind: UsePEP604Annotation
|
||||
location:
|
||||
row: 18
|
||||
row: 14
|
||||
column: 9
|
||||
end_location:
|
||||
row: 18
|
||||
row: 14
|
||||
column: 45
|
||||
fix:
|
||||
patch:
|
||||
content: "str | int | Union[float, bytes]"
|
||||
location:
|
||||
row: 18
|
||||
row: 14
|
||||
column: 9
|
||||
end_location:
|
||||
row: 18
|
||||
row: 14
|
||||
column: 45
|
||||
applied: false
|
||||
- kind: UsePEP604Annotation
|
||||
location:
|
||||
row: 18
|
||||
row: 14
|
||||
column: 25
|
||||
end_location:
|
||||
row: 18
|
||||
row: 14
|
||||
column: 44
|
||||
fix:
|
||||
patch:
|
||||
content: float | bytes
|
||||
location:
|
||||
row: 18
|
||||
row: 14
|
||||
column: 25
|
||||
end_location:
|
||||
row: 18
|
||||
row: 14
|
||||
column: 44
|
||||
applied: false
|
||||
- kind: UsePEP604Annotation
|
||||
location:
|
||||
row: 25
|
||||
row: 18
|
||||
column: 9
|
||||
end_location:
|
||||
row: 25
|
||||
row: 18
|
||||
column: 31
|
||||
fix:
|
||||
patch:
|
||||
content: str | int
|
||||
location:
|
||||
row: 25
|
||||
row: 18
|
||||
column: 9
|
||||
end_location:
|
||||
row: 25
|
||||
row: 18
|
||||
column: 31
|
||||
applied: false
|
||||
- kind: UsePEP604Annotation
|
||||
location:
|
||||
row: 32
|
||||
row: 22
|
||||
column: 9
|
||||
end_location:
|
||||
row: 32
|
||||
column: 47
|
||||
fix:
|
||||
patch:
|
||||
content: "str | int | Union[float, bytes]"
|
||||
location:
|
||||
row: 32
|
||||
column: 9
|
||||
end_location:
|
||||
row: 32
|
||||
column: 47
|
||||
applied: false
|
||||
- kind: UsePEP604Annotation
|
||||
location:
|
||||
row: 32
|
||||
column: 9
|
||||
end_location:
|
||||
row: 32
|
||||
column: 47
|
||||
fix:
|
||||
patch:
|
||||
content: float | bytes
|
||||
location:
|
||||
row: 32
|
||||
column: 9
|
||||
end_location:
|
||||
row: 32
|
||||
column: 47
|
||||
applied: false
|
||||
- kind: UsePEP604Annotation
|
||||
location:
|
||||
row: 39
|
||||
column: 9
|
||||
end_location:
|
||||
row: 39
|
||||
row: 22
|
||||
column: 33
|
||||
fix:
|
||||
patch:
|
||||
content: str | int
|
||||
location:
|
||||
row: 39
|
||||
row: 22
|
||||
column: 9
|
||||
end_location:
|
||||
row: 39
|
||||
row: 22
|
||||
column: 33
|
||||
applied: false
|
||||
- kind: UsePEP604Annotation
|
||||
location:
|
||||
row: 26
|
||||
column: 9
|
||||
end_location:
|
||||
row: 26
|
||||
column: 40
|
||||
fix:
|
||||
patch:
|
||||
content: "(str, int) | float"
|
||||
location:
|
||||
row: 26
|
||||
column: 9
|
||||
end_location:
|
||||
row: 26
|
||||
column: 40
|
||||
applied: false
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 5
|
||||
column: 1
|
||||
column: 10
|
||||
end_location:
|
||||
row: 5
|
||||
column: 12
|
||||
@@ -22,7 +22,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 11
|
||||
column: 1
|
||||
column: 20
|
||||
end_location:
|
||||
row: 11
|
||||
column: 22
|
||||
@@ -39,7 +39,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 16
|
||||
column: 1
|
||||
column: 10
|
||||
end_location:
|
||||
row: 16
|
||||
column: 24
|
||||
@@ -56,7 +56,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 21
|
||||
column: 1
|
||||
column: 20
|
||||
end_location:
|
||||
row: 21
|
||||
column: 34
|
||||
@@ -73,7 +73,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 27
|
||||
column: 1
|
||||
column: 10
|
||||
end_location:
|
||||
row: 28
|
||||
column: 1
|
||||
@@ -90,7 +90,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 33
|
||||
column: 1
|
||||
column: 10
|
||||
end_location:
|
||||
row: 35
|
||||
column: 1
|
||||
@@ -107,7 +107,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 40
|
||||
column: 1
|
||||
column: 20
|
||||
end_location:
|
||||
row: 42
|
||||
column: 19
|
||||
@@ -124,7 +124,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 47
|
||||
column: 1
|
||||
column: 20
|
||||
end_location:
|
||||
row: 51
|
||||
column: 1
|
||||
@@ -141,7 +141,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 56
|
||||
column: 1
|
||||
column: 20
|
||||
end_location:
|
||||
row: 62
|
||||
column: 1
|
||||
@@ -158,7 +158,7 @@ expression: checks
|
||||
- kind: UnnecessaryLRUCacheParams
|
||||
location:
|
||||
row: 67
|
||||
column: 1
|
||||
column: 20
|
||||
end_location:
|
||||
row: 72
|
||||
column: 1
|
||||
|
||||
@@ -2,7 +2,8 @@
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType1
|
||||
location:
|
||||
row: 5
|
||||
column: 0
|
||||
@@ -19,7 +20,8 @@ expression: checks
|
||||
row: 5
|
||||
column: 52
|
||||
applied: false
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType2
|
||||
location:
|
||||
row: 8
|
||||
column: 0
|
||||
@@ -36,7 +38,8 @@ expression: checks
|
||||
row: 8
|
||||
column: 50
|
||||
applied: false
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType3
|
||||
location:
|
||||
row: 11
|
||||
column: 0
|
||||
@@ -53,7 +56,8 @@ expression: checks
|
||||
row: 11
|
||||
column: 44
|
||||
applied: false
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType4
|
||||
location:
|
||||
row: 14
|
||||
column: 0
|
||||
@@ -70,7 +74,8 @@ expression: checks
|
||||
row: 14
|
||||
column: 30
|
||||
applied: false
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType5
|
||||
location:
|
||||
row: 17
|
||||
column: 0
|
||||
@@ -87,7 +92,8 @@ expression: checks
|
||||
row: 17
|
||||
column: 46
|
||||
applied: false
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType6
|
||||
location:
|
||||
row: 18
|
||||
column: 0
|
||||
@@ -104,7 +110,8 @@ expression: checks
|
||||
row: 18
|
||||
column: 41
|
||||
applied: false
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType7
|
||||
location:
|
||||
row: 21
|
||||
column: 0
|
||||
@@ -121,7 +128,8 @@ expression: checks
|
||||
row: 21
|
||||
column: 56
|
||||
applied: false
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType8
|
||||
location:
|
||||
row: 24
|
||||
column: 0
|
||||
@@ -138,7 +146,8 @@ expression: checks
|
||||
row: 24
|
||||
column: 65
|
||||
applied: false
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType10
|
||||
location:
|
||||
row: 30
|
||||
column: 0
|
||||
@@ -155,7 +164,8 @@ expression: checks
|
||||
row: 30
|
||||
column: 59
|
||||
applied: false
|
||||
- kind: ConvertTypedDictFunctionalToClass
|
||||
- kind:
|
||||
ConvertTypedDictFunctionalToClass: MyType11
|
||||
location:
|
||||
row: 33
|
||||
column: 0
|
||||
|
||||
59
src/snapshots/ruff__linter__tests__U014_U014.py.snap
Normal file
59
src/snapshots/ruff__linter__tests__U014_U014.py.snap
Normal file
@@ -0,0 +1,59 @@
|
||||
---
|
||||
source: src/linter.rs
|
||||
expression: checks
|
||||
---
|
||||
- kind:
|
||||
ConvertNamedTupleFunctionalToClass: NT1
|
||||
location:
|
||||
row: 5
|
||||
column: 0
|
||||
end_location:
|
||||
row: 5
|
||||
column: 61
|
||||
fix:
|
||||
patch:
|
||||
content: "class NT1(NamedTuple):\n a: int\n b: tuple[str, ...]"
|
||||
location:
|
||||
row: 5
|
||||
column: 0
|
||||
end_location:
|
||||
row: 5
|
||||
column: 61
|
||||
applied: false
|
||||
- kind:
|
||||
ConvertNamedTupleFunctionalToClass: NT2
|
||||
location:
|
||||
row: 8
|
||||
column: 0
|
||||
end_location:
|
||||
row: 12
|
||||
column: 1
|
||||
fix:
|
||||
patch:
|
||||
content: "class NT2(NamedTuple):\n a: int\n b: str = 'foo'\n c: list[bool] = [True]"
|
||||
location:
|
||||
row: 8
|
||||
column: 0
|
||||
end_location:
|
||||
row: 12
|
||||
column: 1
|
||||
applied: false
|
||||
- kind:
|
||||
ConvertNamedTupleFunctionalToClass: NT3
|
||||
location:
|
||||
row: 15
|
||||
column: 0
|
||||
end_location:
|
||||
row: 15
|
||||
column: 56
|
||||
fix:
|
||||
patch:
|
||||
content: "class NT3(typing.NamedTuple):\n a: int\n b: str"
|
||||
location:
|
||||
row: 15
|
||||
column: 0
|
||||
end_location:
|
||||
row: 15
|
||||
column: 56
|
||||
applied: false
|
||||
|
||||
Reference in New Issue
Block a user