Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4b41ae3f53 | ||
|
|
f944e1e1cf | ||
|
|
4fbc1082de | ||
|
|
cf2e887e38 | ||
|
|
ee994e8c07 | ||
|
|
c69c4fd655 | ||
|
|
e01e45ca35 | ||
|
|
4be74785fe | ||
|
|
40b7c64f7d | ||
|
|
a76c5d1226 | ||
|
|
5aeddeb825 | ||
|
|
5f8294aea4 | ||
|
|
e07d3f6313 | ||
|
|
1d1662cb9c | ||
|
|
55ce7bd0df | ||
|
|
e695f6eb25 | ||
|
|
fb2c457a9b | ||
|
|
523cf62eda | ||
|
|
7024ad7cc7 | ||
|
|
871ac511ae | ||
|
|
0685af8a4f | ||
|
|
5e9a8fcf53 | ||
|
|
76439235af | ||
|
|
0c9c6a1c1c | ||
|
|
46a99243cd | ||
|
|
d06dc4c72d | ||
|
|
8f6b2fb32b | ||
|
|
1d61db5b62 | ||
|
|
e15c0c68cb | ||
|
|
abb2adc4d8 | ||
|
|
e070166409 | ||
|
|
0ae6890094 | ||
|
|
21cace0973 | ||
|
|
4994b72ba2 | ||
|
|
dbb1a6e44b | ||
|
|
4b0c3e3bc9 | ||
|
|
ddae3586d5 | ||
|
|
97684b7215 | ||
|
|
20e6ff112a | ||
|
|
6cb84d29f0 | ||
|
|
d069054792 | ||
|
|
c659cb86d9 | ||
|
|
8a3f29497b | ||
|
|
58e7baedd0 | ||
|
|
00eff2b09a | ||
|
|
b6b509811d | ||
|
|
87bdda3cfa | ||
|
|
291727a27d | ||
|
|
e66b786229 | ||
|
|
e05e1cdf76 | ||
|
|
f92cc7a159 | ||
|
|
ebd2181946 | ||
|
|
3efa1a03f2 | ||
|
|
115e85b47d | ||
|
|
31a3314ebd | ||
|
|
bf33025ea9 | ||
|
|
1a33ee3fc4 | ||
|
|
4722885910 | ||
|
|
117fcb6936 | ||
|
|
1a24d78f67 | ||
|
|
4a4082cf0e | ||
|
|
18b9fbd71e |
@@ -1,6 +1,6 @@
|
||||
repos:
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.150
|
||||
rev: v0.0.161
|
||||
hooks:
|
||||
- id: ruff
|
||||
|
||||
|
||||
400
Cargo.lock
generated
400
Cargo.lock
generated
@@ -21,9 +21,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "0.7.19"
|
||||
version = "0.7.20"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b4f55bd91a0978cbfd91c457a164bab8b4001c833b7f323132c0a4e1922dd44e"
|
||||
checksum = "cc936419f96fa211c1b9166887b38e5e40b19958e5b895be7c1f93adec7071ac"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -82,9 +82,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "2.0.6"
|
||||
version = "2.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba45b8163c49ab5f972e59a8a5a03b6d2972619d486e19ec9fe744f7c2753d3c"
|
||||
checksum = "fa3d466004a8b4cb1bc34044240a2fd29d17607e2e3bd613eb44fd48e8100da3"
|
||||
dependencies = [
|
||||
"bstr 1.0.1",
|
||||
"doc-comment",
|
||||
@@ -100,9 +100,9 @@ version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -193,9 +193,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.0.75"
|
||||
version = "1.0.77"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "41ca34107f97baef6cfb231b32f36115781856b8f8208e8c580e0bcaea374842"
|
||||
checksum = "e9f73505338f7d905b19d18738976aae232eb46b8efc15554ffc56deb5d9ebe4"
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
@@ -230,7 +230,7 @@ dependencies = [
|
||||
"num-traits",
|
||||
"time",
|
||||
"wasm-bindgen",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -280,14 +280,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.0.22"
|
||||
version = "4.0.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91b9970d7505127a162fdaa9b96428d28a479ba78c9ec7550a63a5d9863db682"
|
||||
checksum = "4d63b9e9c07271b9957ad22c173bae2a4d9a81127680962039296abcd2f8251d"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"bitflags",
|
||||
"clap_derive",
|
||||
"clap_lex 0.3.0",
|
||||
"is-terminal",
|
||||
"once_cell",
|
||||
"strsim",
|
||||
"termcolor",
|
||||
@@ -299,7 +299,7 @@ version = "4.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b7b3c9eae0de7bf8e3f904a5e40612b21fb2e2e566456d177809a48b892d24da"
|
||||
dependencies = [
|
||||
"clap 4.0.22",
|
||||
"clap 4.0.29",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -308,7 +308,7 @@ version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4160b4a4f72ef58bd766bad27c09e6ef1cc9d82a22f6a0f55d152985a4a48e31"
|
||||
dependencies = [
|
||||
"clap 4.0.22",
|
||||
"clap 4.0.29",
|
||||
"clap_complete",
|
||||
"clap_complete_fig",
|
||||
]
|
||||
@@ -319,7 +319,7 @@ version = "4.0.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46b30e010e669cd021e5004f3be26cff6b7c08d2a8a0d65b48d43a8cc0efd6c3"
|
||||
dependencies = [
|
||||
"clap 4.0.22",
|
||||
"clap 4.0.29",
|
||||
"clap_complete",
|
||||
]
|
||||
|
||||
@@ -364,7 +364,7 @@ dependencies = [
|
||||
"terminfo",
|
||||
"thiserror",
|
||||
"which",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -394,7 +394,7 @@ checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
|
||||
dependencies = [
|
||||
"atty",
|
||||
"lazy_static",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -419,7 +419,7 @@ dependencies = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"terminal_size",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -496,9 +496,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-epoch"
|
||||
version = "0.9.11"
|
||||
version = "0.9.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f916dfc5d356b0ed9dae65f1db9fc9770aa2851d2662b988ccf4fe3516e86348"
|
||||
checksum = "01a9af1f4c2ef74bb8aa1f7e19706bc72d03598c8a570bb5de72243c7a9d9d5a"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -509,9 +509,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "crossbeam-utils"
|
||||
version = "0.8.12"
|
||||
version = "0.8.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "edbafec5fa1f196ca66527c1b12c2ec4745ca14b50f1ad8f9f6f720b55d11fac"
|
||||
checksum = "4fb766fa798726286dbbb842f174001dab8abc7b627a1dd86e0b7222a95d929f"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
@@ -524,9 +524,9 @@ checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||
|
||||
[[package]]
|
||||
name = "cxx"
|
||||
version = "1.0.81"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "97abf9f0eca9e52b7f81b945524e76710e6cb2366aead23b7d4fbf72e281f888"
|
||||
checksum = "bdf07d07d6531bfcdbe9b8b739b104610c6508dcc4d63b410585faf338241daf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cxxbridge-flags",
|
||||
@@ -536,9 +536,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxx-build"
|
||||
version = "1.0.81"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7cc32cc5fea1d894b77d269ddb9f192110069a8a9c1f1d441195fba90553dea3"
|
||||
checksum = "d2eb5b96ecdc99f72657332953d4d9c50135af1bac34277801cc3937906ebd39"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"codespan-reporting",
|
||||
@@ -551,15 +551,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-flags"
|
||||
version = "1.0.81"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8ca220e4794c934dc6b1207c3b42856ad4c302f2df1712e9f8d2eec5afaacf1f"
|
||||
checksum = "ac040a39517fd1674e0f32177648334b0f4074625b5588a64519804ba0553b12"
|
||||
|
||||
[[package]]
|
||||
name = "cxxbridge-macro"
|
||||
version = "1.0.81"
|
||||
version = "1.0.83"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b846f081361125bfc8dc9d3940c84e1fd83ba54bbca7b17cd29483c828be0704"
|
||||
checksum = "1362b0ddcfc4eb0a1f57b68bd77dd99f0e826958a96abd0ae9bd092e114ffed6"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -624,7 +624,7 @@ checksum = "1b1d1d91c932ef41c0f2663aa8b0ca0342d444d842c06914aa0a7e352d0bada6"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -635,7 +635,7 @@ checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -665,6 +665,27 @@ version = "0.3.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
|
||||
|
||||
[[package]]
|
||||
name = "errno"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f639046355ee4f37944e44f60642c6f3a7efa3cf6b78c78a0d989a8ce6c396a1"
|
||||
dependencies = [
|
||||
"errno-dragonfly",
|
||||
"libc",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "errno-dragonfly"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "aa68f1b12764fab894d2755d2518754e71b4fd80ecfb822714a1206c2aab39bf"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastrand"
|
||||
version = "1.8.0"
|
||||
@@ -703,10 +724,10 @@ checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.150-dev.0"
|
||||
version = "0.0.161-dev.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.0.22",
|
||||
"clap 4.0.29",
|
||||
"configparser",
|
||||
"once_cell",
|
||||
"regex",
|
||||
@@ -719,9 +740,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "flate2"
|
||||
version = "1.0.24"
|
||||
version = "1.0.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f82b0f4c27ad9f8bfd1f3208d882da2b09c301bc1c828fd3a00d0216d2fbbff6"
|
||||
checksum = "a8a2db397cb1c8772f31494cb8917e48cd1e64f0fa7efac59fbd741a0a8ce841"
|
||||
dependencies = [
|
||||
"crc32fast",
|
||||
"miniz_oxide",
|
||||
@@ -742,41 +763,15 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ab7d1bd1bd33cc98b0889831b72da23c0aa4df9cec7e0702f46ecea04b35db6"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fsevent-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fsevent-sys"
|
||||
version = "2.0.1"
|
||||
version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f41b048a94555da0f42f1d632e2e19510084fb8e303b0daa2816e733fb3644a0"
|
||||
checksum = "76ee7a02da4d231650c7cea31349b889be2f45ddb3ef3032d2ec8185f6313fd2"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"fuchsia-zircon-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-zircon-sys"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.1.16"
|
||||
@@ -844,6 +839,15 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hermit-abi"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hexf-parse"
|
||||
version = "0.2.1"
|
||||
@@ -861,7 +865,7 @@ dependencies = [
|
||||
"iana-time-zone-haiku",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -896,9 +900,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "inotify"
|
||||
version = "0.7.1"
|
||||
version = "0.9.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4816c66d2c8ae673df83366c18341538f234a26d65a9ecea5c348b453ac1d02f"
|
||||
checksum = "f8069d3ec154eb856955c1c0fbffefbf5f3c40a104ec912d4797314c1801abff"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"inotify-sys",
|
||||
@@ -916,9 +920,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "insta"
|
||||
version = "1.21.0"
|
||||
version = "1.22.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "581d4e3314cae4536e5d22ffd23189d4a374696c5ef733eadafae0ed273fd303"
|
||||
checksum = "197f4e300af8b23664d4077bf5c40e0afa9ba66a567bb5a51d3def3c7b287d1c"
|
||||
dependencies = [
|
||||
"console",
|
||||
"lazy_static",
|
||||
@@ -938,12 +942,25 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iovec"
|
||||
version = "0.1.4"
|
||||
name = "io-lifetimes"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b2b3ea6ff95e175473f8ffe6a7eb7c00d054240321b84c57051175fe3c1e075e"
|
||||
checksum = "46112a93252b123d31a119a8d1a1ac19deac4fac6e0e8b0df58f0d4e5870e63c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "927609f78c2913a6f6ac3c27a4fe87f43e2a35367c0c4b0f8265e8f49a104330"
|
||||
dependencies = [
|
||||
"hermit-abi 0.2.6",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -977,13 +994,23 @@ dependencies = [
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kernel32-sys"
|
||||
version = "0.2.2"
|
||||
name = "kqueue"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
|
||||
checksum = "2c8fc60ba15bf51257aa9807a48a61013db043fcf3a78cb0d916e8e396dcad98"
|
||||
dependencies = [
|
||||
"winapi 0.2.8",
|
||||
"winapi-build",
|
||||
"kqueue-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "kqueue-sys"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8367585489f01bc55dd27404dcf56b95e6da061a256a666ab23be9ba96a2e587"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1024,12 +1051,6 @@ version = "1.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
|
||||
|
||||
[[package]]
|
||||
name = "lazycell"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
|
||||
|
||||
[[package]]
|
||||
name = "lexical-parse-float"
|
||||
version = "0.8.5"
|
||||
@@ -1062,9 +1083,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.137"
|
||||
version = "0.2.138"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc7fcc620a3bff7cdd7a365be3376c97191aeaccc2a603e600951e452615bf89"
|
||||
checksum = "db6d7e329c562c5dfab7a46a2afabc8b987ab9a4834c9d1ca04dc54c1546cef8"
|
||||
|
||||
[[package]]
|
||||
name = "libcst"
|
||||
@@ -1105,6 +1126,12 @@ version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||
|
||||
[[package]]
|
||||
name = "linux-raw-sys"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f9f08d8963a6c613f4b1a78f4f4a4dbfadf8e6545b2d72861731e4858b8b47f"
|
||||
|
||||
[[package]]
|
||||
name = "lock_api"
|
||||
version = "0.4.9"
|
||||
@@ -1147,74 +1174,32 @@ checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d"
|
||||
|
||||
[[package]]
|
||||
name = "memoffset"
|
||||
version = "0.6.5"
|
||||
version = "0.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5aa361d4faea93603064a027415f07bd8e1d5c88c9fbf68bf56a285428fd79ce"
|
||||
checksum = "5de893c32cde5f383baa4c04c5d6dbdd735cfd4a794b0debdb2bb1b421da5ff4"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miniz_oxide"
|
||||
version = "0.5.4"
|
||||
version = "0.6.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "96590ba8f175222643a85693f33d26e9c8a015f599c216509b1a6894af675d34"
|
||||
checksum = "b275950c28b37e794e8c55d88aeb5e139d0ce23fdbbeda68f8d7174abdf9e8fa"
|
||||
dependencies = [
|
||||
"adler",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "0.6.23"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4afd66f5b91bf2a3bc13fad0e21caedac168ca4c707504e75585648ae80e4cc4"
|
||||
checksum = "e5d732bc30207a6423068df043e3d02e0735b155ad7ce1a6f76fe2baa5b158de"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"fuchsia-zircon",
|
||||
"fuchsia-zircon-sys",
|
||||
"iovec",
|
||||
"kernel32-sys",
|
||||
"libc",
|
||||
"log",
|
||||
"miow",
|
||||
"net2",
|
||||
"slab",
|
||||
"winapi 0.2.8",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio-extras"
|
||||
version = "2.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52403fe290012ce777c4626790c8951324a2b9e3316b3143779c72b029742f19"
|
||||
dependencies = [
|
||||
"lazycell",
|
||||
"log",
|
||||
"mio",
|
||||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "miow"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ebd808424166322d4a38da87083bfddd3ac4c131334ed55856112eb06d46944d"
|
||||
dependencies = [
|
||||
"kernel32-sys",
|
||||
"net2",
|
||||
"winapi 0.2.8",
|
||||
"ws2_32-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "net2"
|
||||
version = "0.2.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74d0df99cfcd2530b2e694f6e17e7f37b8e26bb23983ac530c0c97408837c631"
|
||||
dependencies = [
|
||||
"cfg-if 0.1.10",
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1231,9 +1216,9 @@ checksum = "d906846a98739ed9d73d66e62c2641eef8321f1734b7a1156ab045a0248fb2b3"
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.24.2"
|
||||
version = "0.24.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "195cdbc1741b8134346d515b3a56a1c94b0912758009cfd53f99ea0f57b065fc"
|
||||
checksum = "fa52e972a9a719cecb6864fb88568781eb706bac2cd1d4f04a648542dbf78069"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -1258,20 +1243,20 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "notify"
|
||||
version = "4.0.17"
|
||||
version = "5.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ae03c8c853dba7bfd23e571ff0cff7bc9dceb40a4cd684cd1681824183f45257"
|
||||
checksum = "ed2c66da08abae1c024c01d635253e402341b4060a12e99b31c7594063bf490a"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"crossbeam-channel",
|
||||
"filetime",
|
||||
"fsevent",
|
||||
"fsevent-sys",
|
||||
"inotify",
|
||||
"kqueue",
|
||||
"libc",
|
||||
"mio",
|
||||
"mio-extras",
|
||||
"walkdir",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1321,7 +1306,7 @@ version = "1.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6058e64324c71e02bc2b150e4f3bc8286db6c83092132ffa3f6b1eab0f9def5"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"hermit-abi 0.1.19",
|
||||
"libc",
|
||||
]
|
||||
|
||||
@@ -1339,9 +1324,9 @@ checksum = "0ab1bc2a289d34bd04a330323ac98a1b4bc82c9d9fcb1e66b63caa84da26b575"
|
||||
|
||||
[[package]]
|
||||
name = "os_str_bytes"
|
||||
version = "6.3.1"
|
||||
version = "6.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3baf96e39c5359d2eb0dd6ccb42c62b91d9678aa68160d261b9e0ccbf9e9dea9"
|
||||
checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
@@ -1355,9 +1340,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.4"
|
||||
version = "0.9.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dc9e0dc2adc1c69d09143aff38d3d30c5c3f0df0dad82e6d25547af174ebec0"
|
||||
checksum = "7ff9f3fef3968a3ec5945535ed654cb38ff72d7495a25619e2247fb15a2ed9ba"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
@@ -1557,9 +1542,9 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "2.1.2"
|
||||
version = "2.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ab68289ded120dcbf9d571afcf70163233229052aec9b08ab09532f698d0e1e6"
|
||||
checksum = "f54fc5dc63ed3bbf19494623db4f3af16842c0d975818e469022d09e53f0aa05"
|
||||
dependencies = [
|
||||
"difflib",
|
||||
"itertools",
|
||||
@@ -1568,15 +1553,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "predicates-core"
|
||||
version = "1.0.4"
|
||||
version = "1.0.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a6e7125585d872860e9955ca571650b27a4979c5823084168c5ed5bbfb016b56"
|
||||
checksum = "72f883590242d3c6fc5bf50299011695fa6590c2c70eac95ee1bdb9a733ad1a2"
|
||||
|
||||
[[package]]
|
||||
name = "predicates-tree"
|
||||
version = "1.0.6"
|
||||
version = "1.0.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad3f7fa8d61e139cbc7c3edfebf3b6678883a53f5ffac65d1259329a93ee43a5"
|
||||
checksum = "54ff541861505aabf6ea722d2131ee980b8276e10a1297b94e896dd8b621850d"
|
||||
dependencies = [
|
||||
"predicates-core",
|
||||
"termtree",
|
||||
@@ -1736,11 +1721,10 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon"
|
||||
version = "1.5.3"
|
||||
version = "1.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd99e5772ead8baa5215278c9b15bf92087709e9c1b2d1f97cdb5a183c933a7d"
|
||||
checksum = "1e060280438193c554f654141c9ea9417886713b7acd75974c85b18a69a88e0b"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
"crossbeam-deque",
|
||||
"either",
|
||||
"rayon-core",
|
||||
@@ -1748,9 +1732,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rayon-core"
|
||||
version = "1.9.3"
|
||||
version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "258bcdb5ac6dad48491bb2992db6b7cf74878b0384908af124823d118c99683f"
|
||||
checksum = "cac410af5d00ab6884528b4ab69d1e8e146e8d471201800fa1b4524126de6ad3"
|
||||
dependencies = [
|
||||
"crossbeam-channel",
|
||||
"crossbeam-deque",
|
||||
@@ -1807,7 +1791,7 @@ version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1822,7 +1806,7 @@ dependencies = [
|
||||
"spin",
|
||||
"untrusted",
|
||||
"web-sys",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1837,7 +1821,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.150"
|
||||
version = "0.0.161"
|
||||
dependencies = [
|
||||
"annotate-snippets 0.9.1",
|
||||
"anyhow",
|
||||
@@ -1847,7 +1831,7 @@ dependencies = [
|
||||
"bitflags",
|
||||
"cachedir",
|
||||
"chrono",
|
||||
"clap 4.0.22",
|
||||
"clap 4.0.29",
|
||||
"clap_complete_command",
|
||||
"clearscreen",
|
||||
"colored",
|
||||
@@ -1889,13 +1873,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_dev"
|
||||
version = "0.0.150"
|
||||
version = "0.0.161"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.0.22",
|
||||
"clap 4.0.29",
|
||||
"codegen",
|
||||
"itertools",
|
||||
"libcst",
|
||||
"once_cell",
|
||||
"ruff",
|
||||
"rustpython-ast",
|
||||
"rustpython-common",
|
||||
@@ -1910,6 +1895,20 @@ version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
|
||||
|
||||
[[package]]
|
||||
name = "rustix"
|
||||
version = "0.36.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb93e85278e08bb5788653183213d3a60fc242b10cb9be96586f5a73dcb67c23"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"errno",
|
||||
"io-lifetimes",
|
||||
"libc",
|
||||
"linux-raw-sys",
|
||||
"windows-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls"
|
||||
version = "0.20.7"
|
||||
@@ -1925,7 +1924,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-ast"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=28f9f65ccc625f00835d84bbb5fba274dce5aa89#28f9f65ccc625f00835d84bbb5fba274dce5aa89"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"rustpython-common",
|
||||
@@ -1935,7 +1934,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-common"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=28f9f65ccc625f00835d84bbb5fba274dce5aa89#28f9f65ccc625f00835d84bbb5fba274dce5aa89"
|
||||
dependencies = [
|
||||
"ascii",
|
||||
"cfg-if 1.0.0",
|
||||
@@ -1958,7 +1957,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-compiler-core"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=28f9f65ccc625f00835d84bbb5fba274dce5aa89#28f9f65ccc625f00835d84bbb5fba274dce5aa89"
|
||||
dependencies = [
|
||||
"bincode",
|
||||
"bitflags",
|
||||
@@ -1975,7 +1974,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "rustpython-parser"
|
||||
version = "0.1.2"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=28f9f65ccc625f00835d84bbb5fba274dce5aa89#28f9f65ccc625f00835d84bbb5fba274dce5aa89"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
@@ -2048,18 +2047,18 @@ checksum = "e25dfac463d778e353db5be2449d1cce89bd6fd23c9f1ea21310ce6e5a1b29c4"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.147"
|
||||
version = "1.0.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965"
|
||||
checksum = "e53f64bb4ba0191d6d0676e1b141ca55047d83b74f5607e6d8eb88126c52c2dc"
|
||||
dependencies = [
|
||||
"serde_derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde_derive"
|
||||
version = "1.0.147"
|
||||
version = "1.0.148"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852"
|
||||
checksum = "a55492425aa53521babf6137309e7d34c20bbfbbfcfe2c7f3a047fd1f6b92c0c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2068,9 +2067,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_json"
|
||||
version = "1.0.87"
|
||||
version = "1.0.89"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45"
|
||||
checksum = "020ff22c755c2ed3f8cf162dbb41a7268d934702f3ed3631656ea597e08fc3db"
|
||||
dependencies = [
|
||||
"itoa",
|
||||
"ryu",
|
||||
@@ -2079,9 +2078,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "similar"
|
||||
version = "2.2.0"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62ac7f900db32bf3fd12e0117dd3dc4da74bc52ebaac97f39668446d89694803"
|
||||
checksum = "420acb44afdae038210c99e69aae24109f32f15500aa708e81d46c9f29d55fcf"
|
||||
|
||||
[[package]]
|
||||
name = "siphasher"
|
||||
@@ -2089,15 +2088,6 @@ version = "0.3.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7bd3e3206899af3f8b12af284fafc038cc1dc2b41d1b89dd17297221c5d225de"
|
||||
|
||||
[[package]]
|
||||
name = "slab"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef"
|
||||
dependencies = [
|
||||
"autocfg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.10.0"
|
||||
@@ -2171,9 +2161,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "1.0.103"
|
||||
version = "1.0.105"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a864042229133ada95abf3b54fdc62ef5ccabe9515b64717bcb9a1919e59445d"
|
||||
checksum = "60b9b43d45702de4c839cb9b51d9f529c5dd26a4aff255b42b1ebc03e88ee908"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -2191,7 +2181,7 @@ dependencies = [
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2202,7 +2192,7 @@ checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
|
||||
dependencies = [
|
||||
"dirs-next",
|
||||
"rustversion",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2221,7 +2211,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2304,7 +2294,7 @@ checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2567,7 +2557,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "808cf2735cd4b6866113f648b791c6adc5714537bc222d9347bb203386ffda56"
|
||||
dependencies = [
|
||||
"same-file",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
"winapi-util",
|
||||
]
|
||||
|
||||
@@ -2689,12 +2679,6 @@ version = "0.5.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
@@ -2705,12 +2689,6 @@ dependencies = [
|
||||
"winapi-x86_64-pc-windows-gnu",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi-build"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
|
||||
|
||||
[[package]]
|
||||
name = "winapi-i686-pc-windows-gnu"
|
||||
version = "0.4.0"
|
||||
@@ -2723,7 +2701,7 @@ version = "0.1.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2789,16 +2767,6 @@ version = "0.42.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f40009d85759725a34da6d89a94e63d7bdc50a862acf0dbc7c8e488f1edcb6f5"
|
||||
|
||||
[[package]]
|
||||
name = "ws2_32-sys"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
|
||||
dependencies = [
|
||||
"winapi 0.2.8",
|
||||
"winapi-build",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "yaml-rust"
|
||||
version = "0.4.5"
|
||||
@@ -2814,5 +2782,5 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
10
Cargo.toml
10
Cargo.toml
@@ -6,7 +6,7 @@ members = [
|
||||
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.0.150"
|
||||
version = "0.0.161"
|
||||
edition = "2021"
|
||||
rust-version = "1.65.0"
|
||||
|
||||
@@ -33,7 +33,7 @@ itertools = { version = "0.10.5" }
|
||||
libcst = { git = "https://github.com/charliermarsh/LibCST", rev = "f2f0b7a487a8725d161fe8b3ed73a6758b21e177" }
|
||||
log = { version = "0.4.17" }
|
||||
nohash-hasher = { version = "0.2.0" }
|
||||
notify = { version = "4.0.17" }
|
||||
notify = { version = "5.0.0" }
|
||||
num-bigint = { version = "0.4.3" }
|
||||
once_cell = { version = "1.16.0" }
|
||||
path-absolutize = { version = "3.0.14", features = ["once_cell_cache", "use_unix_paths_on_wasm"] }
|
||||
@@ -42,9 +42,9 @@ rayon = { version = "1.5.3" }
|
||||
regex = { version = "1.6.0" }
|
||||
ropey = { version = "1.5.0", features = ["cr_lines", "simd"], default-features = false }
|
||||
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" }
|
||||
rustpython-ast = { features = ["unparse"], git = "https://github.com/RustPython/RustPython.git", rev = "28f9f65ccc625f00835d84bbb5fba274dce5aa89" }
|
||||
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "28f9f65ccc625f00835d84bbb5fba274dce5aa89" }
|
||||
rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "28f9f65ccc625f00835d84bbb5fba274dce5aa89" }
|
||||
serde = { version = "1.0.147", features = ["derive"] }
|
||||
serde_json = { version = "1.0.87" }
|
||||
strum = { version = "0.24.1", features = ["strum_macros"] }
|
||||
|
||||
48
LICENSE
48
LICENSE
@@ -363,6 +363,31 @@ are:
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
- flake8-return, licensed as follows:
|
||||
"""
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2019 Afonasev Evgeniy
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
- isort, licensed as follows:
|
||||
"""
|
||||
The MIT License (MIT)
|
||||
@@ -471,6 +496,29 @@ are:
|
||||
SOFTWARE.
|
||||
"""
|
||||
|
||||
- pygrep-hooks, licensed as follows:
|
||||
"""
|
||||
Copyright (c) 2018 Anthony Sottile
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
"""
|
||||
|
||||
- pyupgrade, licensed as follows:
|
||||
"""
|
||||
Copyright (c) 2017 Anthony Sottile
|
||||
|
||||
394
README.md
394
README.md
@@ -71,26 +71,28 @@ of [Conda](https://docs.conda.io/en/latest/):
|
||||
1. [Supported Rules](#supported-rules)
|
||||
1. [Pyflakes (F)](#pyflakes)
|
||||
1. [pycodestyle (E, W)](#pycodestyle)
|
||||
1. [mccabe (C90)](#mccabe)
|
||||
1. [isort (I)](#isort)
|
||||
1. [pydocstyle (D)](#pydocstyle)
|
||||
1. [pyupgrade (U)](#pyupgrade)
|
||||
1. [pyupgrade (UP)](#pyupgrade)
|
||||
1. [pep8-naming (N)](#pep8-naming)
|
||||
1. [eradicate (ERA)](#eradicate)
|
||||
1. [flake8-2020 (YTT)](#flake8-2020)
|
||||
1. [flake8-annotations (ANN)](#flake8-annotations)
|
||||
1. [flake8-bandit (S)](#flake8-bandit)
|
||||
1. [flake8-comprehensions (C)](#flake8-comprehensions)
|
||||
1. [flake8-blind-except (BLE)](#flake8-blind-except)
|
||||
1. [flake8-boolean-trap (FBT)](#flake8-boolean-trap)
|
||||
1. [flake8-bugbear (B)](#flake8-bugbear)
|
||||
1. [flake8-builtins (A)](#flake8-builtins)
|
||||
1. [flake8-debugger (T)](#flake8-debugger)
|
||||
1. [flake8-tidy-imports (I25)](#flake8-tidy-imports)
|
||||
1. [flake8-print (T)](#flake8-print)
|
||||
1. [flake8-comprehensions (C4)](#flake8-comprehensions)
|
||||
1. [flake8-debugger (T10)](#flake8-debugger)
|
||||
1. [flake8-print (T20)](#flake8-print)
|
||||
1. [flake8-quotes (Q)](#flake8-quotes)
|
||||
1. [flake8-annotations (ANN)](#flake8-annotations)
|
||||
1. [flake8-2020 (YTT)](#flake8-2020)
|
||||
1. [flake8-blind-except (BLE)](#flake8-blind-except)
|
||||
1. [mccabe (C90)](#mccabe)
|
||||
1. [flake8-return (RET)](#flake8-return)
|
||||
1. [flake8-tidy-imports (I25)](#flake8-tidy-imports)
|
||||
1. [eradicate (ERA)](#eradicate)
|
||||
1. [pygrep-hooks (PGH)](#pygrep-hooks)
|
||||
1. [Pylint (PL)](#pylint)
|
||||
1. [Ruff-specific rules (RUF)](#ruff-specific-rules)
|
||||
1. [Meta rules (M)](#meta-rules)
|
||||
1. [Editor Integrations](#editor-integrations)
|
||||
1. [FAQ](#faq)
|
||||
1. [Development](#development)
|
||||
@@ -143,7 +145,7 @@ Ruff also works with [pre-commit](https://pre-commit.com):
|
||||
```yaml
|
||||
repos:
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.150
|
||||
rev: v0.0.161
|
||||
hooks:
|
||||
- id: ruff
|
||||
```
|
||||
@@ -314,10 +316,10 @@ Options:
|
||||
|
||||
### Ignoring errors
|
||||
|
||||
To omit a lint check entirely, add it to the "ignore" list via `--ignore` or `--extend-ignore`,
|
||||
either on the command-line or in your `project.toml` file.
|
||||
To omit a lint check entirely, add it to the "ignore" list via [`ignore`](#ignore) or
|
||||
[`extend-ignore`](#extend-ignore), either on the command-line or in your `project.toml` file.
|
||||
|
||||
To ignore an error in-line, Ruff uses a `noqa` system similar to [Flake8](https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html).
|
||||
To ignore an error inline, Ruff uses a `noqa` system similar to [Flake8](https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html).
|
||||
To ignore an individual error, add `# noqa: {code}` to the end of the line, like so:
|
||||
|
||||
```python
|
||||
@@ -332,7 +334,7 @@ x = 1 # noqa
|
||||
```
|
||||
|
||||
Note that, for multi-line strings, the `noqa` directive should come at the end of the string, and
|
||||
will apply to the entire body, like so:
|
||||
will apply to the entire string, like so:
|
||||
|
||||
```python
|
||||
"""Lorem ipsum dolor sit amet.
|
||||
@@ -341,15 +343,34 @@ Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor i
|
||||
""" # noqa: E501
|
||||
```
|
||||
|
||||
To ignore all errors across an entire file, Ruff supports Flake8's `# flake8: noqa` directive (or,
|
||||
equivalently, `# ruff: noqa`). Adding either of those directives to any part of a file will disable
|
||||
error reporting for the entire file.
|
||||
|
||||
For targeted exclusions across entire files (e.g., "Ignore all F841 violations in
|
||||
`/path/to/file.py`"), see the [`per-file-ignores`](#per-file-ignores) configuration setting.
|
||||
|
||||
### "Action Comments"
|
||||
|
||||
Ruff respects `isort`'s ["Action Comments"](https://pycqa.github.io/isort/docs/configuration/action_comments.html)
|
||||
(`# isort: skip_file`, `# isort: on`, `# isort: off`, `# isort: skip`, and `isort: split`), which
|
||||
enable selectively enabling and disabling import sorting for blocks of code and other inline
|
||||
configuration.
|
||||
|
||||
See the [`isort` documentation](https://pycqa.github.io/isort/docs/configuration/action_comments.html)
|
||||
for more.
|
||||
|
||||
### Automating `noqa` Directives
|
||||
|
||||
Ruff supports several workflows to aid in `noqa` management.
|
||||
|
||||
First, Ruff provides a special error code, `M001`, to enforce that your `noqa` directives are
|
||||
First, Ruff provides a special error code, `RUF100`, to enforce that your `noqa` directives are
|
||||
"valid", in that the errors they _say_ they ignore are actually being triggered on that line (and
|
||||
thus suppressed). You can run `ruff /path/to/file.py --extend-select M001` to flag unused `noqa`
|
||||
thus suppressed). You can run `ruff /path/to/file.py --extend-select RUF100` to flag unused `noqa`
|
||||
directives.
|
||||
|
||||
Second, Ruff can _automatically remove_ unused `noqa` directives via its autofix functionality.
|
||||
You can run `ruff /path/to/file.py --extend-select M001 --fix` to automatically remove unused
|
||||
You can run `ruff /path/to/file.py --extend-select RUF100 --fix` to automatically remove unused
|
||||
`noqa` directives.
|
||||
|
||||
Third, Ruff can _automatically add_ `noqa` directives to all failing lines. This is useful when
|
||||
@@ -439,6 +460,14 @@ For more, see [pycodestyle](https://pypi.org/project/pycodestyle/2.9.1/) on PyPI
|
||||
| W292 | NoNewLineAtEndOfFile | No newline at end of file | |
|
||||
| W605 | InvalidEscapeSequence | Invalid escape sequence: '\c' | |
|
||||
|
||||
### mccabe
|
||||
|
||||
For more, see [mccabe](https://pypi.org/project/mccabe/0.7.0/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| C901 | FunctionIsTooComplex | `...` is too complex (10) | |
|
||||
|
||||
### isort
|
||||
|
||||
For more, see [isort](https://pypi.org/project/isort/5.10.1/) on PyPI.
|
||||
@@ -504,20 +533,20 @@ For more, see [pyupgrade](https://pypi.org/project/pyupgrade/3.2.0/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| U001 | UselessMetaclassType | `__metaclass__ = type` is implied | 🛠 |
|
||||
| U003 | TypeOfPrimitive | Use `str` instead of `type(...)` | 🛠 |
|
||||
| U004 | UselessObjectInheritance | Class `...` inherits from object | 🛠 |
|
||||
| U005 | DeprecatedUnittestAlias | `assertEquals` is deprecated, use `assertEqual` instead | 🛠 |
|
||||
| U006 | UsePEP585Annotation | Use `list` instead of `List` for type annotations | 🛠 |
|
||||
| U007 | UsePEP604Annotation | Use `X \| Y` for type annotations | 🛠 |
|
||||
| U008 | SuperCallWithParameters | Use `super()` instead of `super(__class__, self)` | 🛠 |
|
||||
| U009 | PEP3120UnnecessaryCodingComment | UTF-8 encoding declaration is unnecessary | 🛠 |
|
||||
| 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 `...` from `TypedDict` functional to class syntax | 🛠 |
|
||||
| U014 | ConvertNamedTupleFunctionalToClass | Convert `...` from `NamedTuple` functional to class syntax | 🛠 |
|
||||
| U015 | RedundantOpenModes | Unnecessary open mode parameters | 🛠 |
|
||||
| UP001 | UselessMetaclassType | `__metaclass__ = type` is implied | 🛠 |
|
||||
| UP003 | TypeOfPrimitive | Use `str` instead of `type(...)` | 🛠 |
|
||||
| UP004 | UselessObjectInheritance | Class `...` inherits from object | 🛠 |
|
||||
| UP005 | DeprecatedUnittestAlias | `assertEquals` is deprecated, use `assertEqual` instead | 🛠 |
|
||||
| UP006 | UsePEP585Annotation | Use `list` instead of `List` for type annotations | 🛠 |
|
||||
| UP007 | UsePEP604Annotation | Use `X \| Y` for type annotations | 🛠 |
|
||||
| UP008 | SuperCallWithParameters | Use `super()` instead of `super(__class__, self)` | 🛠 |
|
||||
| UP009 | PEP3120UnnecessaryCodingComment | UTF-8 encoding declaration is unnecessary | 🛠 |
|
||||
| UP010 | UnnecessaryFutureImport | Unnecessary `__future__` import `...` for target Python version | 🛠 |
|
||||
| UP011 | UnnecessaryLRUCacheParams | Unnecessary parameters to `functools.lru_cache` | 🛠 |
|
||||
| UP012 | UnnecessaryEncodeUTF8 | Unnecessary call to `encode` as UTF-8 | 🛠 |
|
||||
| UP013 | ConvertTypedDictFunctionalToClass | Convert `...` from `TypedDict` functional to class syntax | 🛠 |
|
||||
| UP014 | ConvertNamedTupleFunctionalToClass | Convert `...` from `NamedTuple` functional to class syntax | 🛠 |
|
||||
| UP015 | RedundantOpenModes | Unnecessary open mode parameters | 🛠 |
|
||||
|
||||
### pep8-naming
|
||||
|
||||
@@ -541,13 +570,40 @@ For more, see [pep8-naming](https://pypi.org/project/pep8-naming/0.13.2/) on PyP
|
||||
| N817 | CamelcaseImportedAsAcronym | Camelcase `...` imported as acronym `...` | |
|
||||
| N818 | ErrorSuffixOnExceptionName | Exception name `...` should be named with an Error suffix | |
|
||||
|
||||
### eradicate
|
||||
### flake8-2020
|
||||
|
||||
For more, see [eradicate](https://pypi.org/project/eradicate/2.1.0/) on PyPI.
|
||||
For more, see [flake8-2020](https://pypi.org/project/flake8-2020/1.7.0/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| ERA001 | CommentedOutCode | Found commented-out code | 🛠 |
|
||||
| YTT101 | SysVersionSlice3Referenced | `sys.version[:3]` referenced (python3.10), use `sys.version_info` | |
|
||||
| YTT102 | SysVersion2Referenced | `sys.version[2]` referenced (python3.10), use `sys.version_info` | |
|
||||
| YTT103 | SysVersionCmpStr3 | `sys.version` compared to string (python3.10), use `sys.version_info` | |
|
||||
| YTT201 | SysVersionInfo0Eq3Referenced | `sys.version_info[0] == 3` referenced (python4), use `>=` | |
|
||||
| YTT202 | SixPY3Referenced | `six.PY3` referenced (python4), use `not six.PY2` | |
|
||||
| YTT203 | SysVersionInfo1CmpInt | `sys.version_info[1]` compared to integer (python4), compare `sys.version_info` to tuple | |
|
||||
| YTT204 | SysVersionInfoMinorCmpInt | `sys.version_info.minor` compared to integer (python4), compare `sys.version_info` to tuple | |
|
||||
| YTT301 | SysVersion0Referenced | `sys.version[0]` referenced (python10), use `sys.version_info` | |
|
||||
| YTT302 | SysVersionCmpStr10 | `sys.version` compared to string (python10), use `sys.version_info` | |
|
||||
| YTT303 | SysVersionSlice1Referenced | `sys.version[:1]` referenced (python10), use `sys.version_info` | |
|
||||
|
||||
### flake8-annotations
|
||||
|
||||
For more, see [flake8-annotations](https://pypi.org/project/flake8-annotations/2.9.1/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| ANN001 | MissingTypeFunctionArgument | Missing type annotation for function argument `...` | |
|
||||
| ANN002 | MissingTypeArgs | Missing type annotation for `*...` | |
|
||||
| ANN003 | MissingTypeKwargs | Missing type annotation for `**...` | |
|
||||
| ANN101 | MissingTypeSelf | Missing type annotation for `...` in method | |
|
||||
| ANN102 | MissingTypeCls | Missing type annotation for `...` in classmethod | |
|
||||
| ANN201 | MissingReturnTypePublicFunction | Missing return type annotation for public function `...` | |
|
||||
| ANN202 | MissingReturnTypePrivateFunction | Missing return type annotation for private function `...` | |
|
||||
| ANN204 | MissingReturnTypeMagicMethod | Missing return type annotation for magic method `...` | |
|
||||
| ANN205 | MissingReturnTypeStaticMethod | Missing return type annotation for staticmethod `...` | |
|
||||
| ANN206 | MissingReturnTypeClassMethod | Missing return type annotation for classmethod `...` | |
|
||||
| ANN401 | DynamicallyTypedExpression | Dynamically typed expressions (typing.Any) are disallowed in `...` | |
|
||||
|
||||
### flake8-bandit
|
||||
|
||||
@@ -562,36 +618,13 @@ For more, see [flake8-bandit](https://pypi.org/project/flake8-bandit/4.1.1/) on
|
||||
| S106 | HardcodedPasswordFuncArg | Possible hardcoded password: `"..."` | |
|
||||
| S107 | HardcodedPasswordDefault | Possible hardcoded password: `"..."` | |
|
||||
|
||||
### flake8-comprehensions
|
||||
### flake8-blind-except
|
||||
|
||||
For more, see [flake8-comprehensions](https://pypi.org/project/flake8-comprehensions/3.10.1/) on PyPI.
|
||||
For more, see [flake8-blind-except](https://pypi.org/project/flake8-blind-except/0.2.1/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| C400 | UnnecessaryGeneratorList | Unnecessary generator (rewrite as a `list` comprehension) | 🛠 |
|
||||
| C401 | UnnecessaryGeneratorSet | Unnecessary generator (rewrite as a `set` comprehension) | 🛠 |
|
||||
| C402 | UnnecessaryGeneratorDict | Unnecessary generator (rewrite as a `dict` comprehension) | 🛠 |
|
||||
| C403 | UnnecessaryListComprehensionSet | Unnecessary `list` comprehension (rewrite as a `set` comprehension) | 🛠 |
|
||||
| C404 | UnnecessaryListComprehensionDict | Unnecessary `list` comprehension (rewrite as a `dict` comprehension) | 🛠 |
|
||||
| C405 | UnnecessaryLiteralSet | Unnecessary `(list\|tuple)` literal (rewrite as a `set` literal) | 🛠 |
|
||||
| C406 | UnnecessaryLiteralDict | Unnecessary `(list\|tuple)` literal (rewrite as a `dict` literal) | 🛠 |
|
||||
| C408 | UnnecessaryCollectionCall | Unnecessary `(dict\|list\|tuple)` call (rewrite as a literal) | 🛠 |
|
||||
| C409 | UnnecessaryLiteralWithinTupleCall | Unnecessary `(list\|tuple)` literal passed to `tuple()` (remove the outer call to `tuple()`) | 🛠 |
|
||||
| C410 | UnnecessaryLiteralWithinListCall | Unnecessary `(list\|tuple)` literal passed to `list()` (rewrite as a `list` literal) | 🛠 |
|
||||
| C411 | UnnecessaryListCall | Unnecessary `list` call (remove the outer call to `list()`) | 🛠 |
|
||||
| C413 | UnnecessaryCallAroundSorted | Unnecessary `(list\|reversed)` call around `sorted()` | |
|
||||
| C414 | UnnecessaryDoubleCastOrProcess | Unnecessary `(list\|reversed\|set\|sorted\|tuple)` call within `(list\|set\|sorted\|tuple)()` | |
|
||||
| C415 | UnnecessarySubscriptReversal | Unnecessary subscript reversal of iterable within `(reversed\|set\|sorted)()` | |
|
||||
| C416 | UnnecessaryComprehension | Unnecessary `(list\|set)` comprehension (rewrite using `(list\|set)()`) | 🛠 |
|
||||
| C417 | UnnecessaryMap | Unnecessary `map` usage (rewrite using a `(list\|set\|dict)` comprehension) | |
|
||||
|
||||
### flake8-debugger
|
||||
|
||||
For more, see [flake8-debugger](https://pypi.org/project/flake8-debugger/4.1.2/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| T100 | Debugger | Import for `...` found | |
|
||||
| BLE001 | BlindExcept | Blind except Exception: statement | |
|
||||
|
||||
### flake8-boolean-trap
|
||||
|
||||
@@ -647,13 +680,36 @@ For more, see [flake8-builtins](https://pypi.org/project/flake8-builtins/2.0.1/)
|
||||
| A002 | BuiltinArgumentShadowing | Argument `...` is shadowing a python builtin | |
|
||||
| A003 | BuiltinAttributeShadowing | Class attribute `...` is shadowing a python builtin | |
|
||||
|
||||
### flake8-tidy-imports
|
||||
### flake8-comprehensions
|
||||
|
||||
For more, see [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/4.8.0/) on PyPI.
|
||||
For more, see [flake8-comprehensions](https://pypi.org/project/flake8-comprehensions/3.10.1/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| I252 | BannedRelativeImport | Relative imports are banned | |
|
||||
| C400 | UnnecessaryGeneratorList | Unnecessary generator (rewrite as a `list` comprehension) | 🛠 |
|
||||
| C401 | UnnecessaryGeneratorSet | Unnecessary generator (rewrite as a `set` comprehension) | 🛠 |
|
||||
| C402 | UnnecessaryGeneratorDict | Unnecessary generator (rewrite as a `dict` comprehension) | 🛠 |
|
||||
| C403 | UnnecessaryListComprehensionSet | Unnecessary `list` comprehension (rewrite as a `set` comprehension) | 🛠 |
|
||||
| C404 | UnnecessaryListComprehensionDict | Unnecessary `list` comprehension (rewrite as a `dict` comprehension) | 🛠 |
|
||||
| C405 | UnnecessaryLiteralSet | Unnecessary `(list\|tuple)` literal (rewrite as a `set` literal) | 🛠 |
|
||||
| C406 | UnnecessaryLiteralDict | Unnecessary `(list\|tuple)` literal (rewrite as a `dict` literal) | 🛠 |
|
||||
| C408 | UnnecessaryCollectionCall | Unnecessary `(dict\|list\|tuple)` call (rewrite as a literal) | 🛠 |
|
||||
| C409 | UnnecessaryLiteralWithinTupleCall | Unnecessary `(list\|tuple)` literal passed to `tuple()` (remove the outer call to `tuple()`) | 🛠 |
|
||||
| C410 | UnnecessaryLiteralWithinListCall | Unnecessary `(list\|tuple)` literal passed to `list()` (rewrite as a `list` literal) | 🛠 |
|
||||
| C411 | UnnecessaryListCall | Unnecessary `list` call (remove the outer call to `list()`) | 🛠 |
|
||||
| C413 | UnnecessaryCallAroundSorted | Unnecessary `(list\|reversed)` call around `sorted()` | |
|
||||
| C414 | UnnecessaryDoubleCastOrProcess | Unnecessary `(list\|reversed\|set\|sorted\|tuple)` call within `(list\|set\|sorted\|tuple)()` | |
|
||||
| C415 | UnnecessarySubscriptReversal | Unnecessary subscript reversal of iterable within `(reversed\|set\|sorted)()` | |
|
||||
| C416 | UnnecessaryComprehension | Unnecessary `(list\|set)` comprehension (rewrite using `(list\|set)()`) | 🛠 |
|
||||
| C417 | UnnecessaryMap | Unnecessary `map` usage (rewrite using a `(list\|set\|dict)` comprehension) | |
|
||||
|
||||
### flake8-debugger
|
||||
|
||||
For more, see [flake8-debugger](https://pypi.org/project/flake8-debugger/4.1.2/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| T100 | Debugger | Import for `...` found | |
|
||||
|
||||
### flake8-print
|
||||
|
||||
@@ -675,56 +731,44 @@ For more, see [flake8-quotes](https://pypi.org/project/flake8-quotes/3.3.1/) on
|
||||
| Q002 | BadQuotesDocstring | Single quote docstring found but double quotes preferred | |
|
||||
| Q003 | AvoidQuoteEscape | Change outer quotes to avoid escaping inner quotes | |
|
||||
|
||||
### flake8-annotations
|
||||
### flake8-return
|
||||
|
||||
For more, see [flake8-annotations](https://pypi.org/project/flake8-annotations/2.9.1/) on PyPI.
|
||||
For more, see [flake8-return](https://pypi.org/project/flake8-return/1.2.0/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| ANN001 | MissingTypeFunctionArgument | Missing type annotation for function argument `...` | |
|
||||
| ANN002 | MissingTypeArgs | Missing type annotation for `*...` | |
|
||||
| ANN003 | MissingTypeKwargs | Missing type annotation for `**...` | |
|
||||
| ANN101 | MissingTypeSelf | Missing type annotation for `...` in method | |
|
||||
| ANN102 | MissingTypeCls | Missing type annotation for `...` in classmethod | |
|
||||
| ANN201 | MissingReturnTypePublicFunction | Missing return type annotation for public function `...` | |
|
||||
| ANN202 | MissingReturnTypePrivateFunction | Missing return type annotation for private function `...` | |
|
||||
| ANN204 | MissingReturnTypeMagicMethod | Missing return type annotation for magic method `...` | |
|
||||
| ANN205 | MissingReturnTypeStaticMethod | Missing return type annotation for staticmethod `...` | |
|
||||
| ANN206 | MissingReturnTypeClassMethod | Missing return type annotation for classmethod `...` | |
|
||||
| ANN401 | DynamicallyTypedExpression | Dynamically typed expressions (typing.Any) are disallowed in `...` | |
|
||||
| RET501 | UnnecessaryReturnNone | Do not explicitly `return None` in function if it is the only possible return value | 🛠 |
|
||||
| RET502 | ImplicitReturnValue | Do not implicitly `return None` in function able to return non-`None` value | 🛠 |
|
||||
| RET503 | ImplicitReturn | Missing explicit `return` at the end of function able to return non-`None` value | 🛠 |
|
||||
| RET504 | UnnecessaryAssign | Unnecessary variable assignment before `return` statement | |
|
||||
| RET505 | SuperfluousElseReturn | Unnecessary `else` after `return` statement | |
|
||||
| RET506 | SuperfluousElseRaise | Unnecessary `else` after `raise` statement | |
|
||||
| RET507 | SuperfluousElseContinue | Unnecessary `else` after `continue` statement | |
|
||||
| RET508 | SuperfluousElseBreak | Unnecessary `else` after `break` statement | |
|
||||
|
||||
### flake8-2020
|
||||
### flake8-tidy-imports
|
||||
|
||||
For more, see [flake8-2020](https://pypi.org/project/flake8-2020/1.7.0/) on PyPI.
|
||||
For more, see [flake8-tidy-imports](https://pypi.org/project/flake8-tidy-imports/4.8.0/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| YTT101 | SysVersionSlice3Referenced | `sys.version[:3]` referenced (python3.10), use `sys.version_info` | |
|
||||
| YTT102 | SysVersion2Referenced | `sys.version[2]` referenced (python3.10), use `sys.version_info` | |
|
||||
| YTT103 | SysVersionCmpStr3 | `sys.version` compared to string (python3.10), use `sys.version_info` | |
|
||||
| YTT201 | SysVersionInfo0Eq3Referenced | `sys.version_info[0] == 3` referenced (python4), use `>=` | |
|
||||
| YTT202 | SixPY3Referenced | `six.PY3` referenced (python4), use `not six.PY2` | |
|
||||
| YTT203 | SysVersionInfo1CmpInt | `sys.version_info[1]` compared to integer (python4), compare `sys.version_info` to tuple | |
|
||||
| YTT204 | SysVersionInfoMinorCmpInt | `sys.version_info.minor` compared to integer (python4), compare `sys.version_info` to tuple | |
|
||||
| YTT301 | SysVersion0Referenced | `sys.version[0]` referenced (python10), use `sys.version_info` | |
|
||||
| YTT302 | SysVersionCmpStr10 | `sys.version` compared to string (python10), use `sys.version_info` | |
|
||||
| YTT303 | SysVersionSlice1Referenced | `sys.version[:1]` referenced (python10), use `sys.version_info` | |
|
||||
| I252 | BannedRelativeImport | Relative imports are banned | |
|
||||
|
||||
### flake8-blind-except
|
||||
### eradicate
|
||||
|
||||
For more, see [flake8-blind-except](https://pypi.org/project/flake8-blind-except/0.2.1/) on PyPI.
|
||||
For more, see [eradicate](https://pypi.org/project/eradicate/2.1.0/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| BLE001 | BlindExcept | Blind except Exception: statement | |
|
||||
| ERA001 | CommentedOutCode | Found commented-out code | 🛠 |
|
||||
|
||||
### mccabe
|
||||
### pygrep-hooks
|
||||
|
||||
For more, see [mccabe](https://pypi.org/project/mccabe/0.7.0/) on PyPI.
|
||||
For more, see [pygrep-hooks](https://github.com/pre-commit/pygrep-hooks) on GitHub.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| C901 | FunctionIsTooComplex | `...` is too complex (10) | |
|
||||
| PGH001 | NoEval | No builtin `eval()` allowed | |
|
||||
|
||||
### Pylint
|
||||
|
||||
@@ -732,7 +776,15 @@ For more, see [Pylint](https://pypi.org/project/pylint/2.15.7/) on PyPI.
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| PLC0414 | UselessImportAlias | Import alias does not rename original package | 🛠 |
|
||||
| PLC2201 | MisplacedComparisonConstant | Comparison should be ... | 🛠 |
|
||||
| PLC3002 | UnnecessaryDirectLambdaCall | Lambda expression called directly. Execute the expression inline instead. | |
|
||||
| PLE1142 | AwaitOutsideAsync | `await` should be used within an async function | |
|
||||
| PLR0206 | PropertyWithParameters | Cannot have defined parameters for properties | |
|
||||
| PLR0402 | ConsiderUsingFromImport | Consider using `from ... import ...` | |
|
||||
| PLR1701 | ConsiderMergingIsinstance | Consider merging these isinstance calls: `isinstance(..., (...))` | |
|
||||
| PLR1722 | ConsiderUsingSysExit | Consider using `sys.exit()` | 🛠 |
|
||||
| PLW0120 | UselessElseOnLoop | Else clause on loop without a break statement, remove the else and de-indent all the code inside it | |
|
||||
|
||||
### Ruff-specific rules
|
||||
|
||||
@@ -741,13 +793,7 @@ For more, see [Pylint](https://pypi.org/project/pylint/2.15.7/) 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
|
||||
|
||||
| Code | Name | Message | Fix |
|
||||
| ---- | ---- | ------- | --- |
|
||||
| M001 | UnusedNOQA | Unused `noqa` directive | 🛠 |
|
||||
| RUF100 | UnusedNOQA | Unused `noqa` directive | 🛠 |
|
||||
|
||||
<!-- End auto-generated sections. -->
|
||||
|
||||
@@ -896,12 +942,14 @@ natively, including:
|
||||
- [`flake8-eradicate`](https://pypi.org/project/flake8-eradicate/)
|
||||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
||||
- [`flake8-return`](https://pypi.org/project/flake8-return/)
|
||||
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
||||
- [`flake8-tidy-imports`](https://pypi.org/project/flake8-tidy-imports/) (1/3)
|
||||
- [`mccabe`](https://pypi.org/project/mccabe/)
|
||||
- [`yesqa`](https://github.com/asottile/yesqa)
|
||||
- [`eradicate`](https://pypi.org/project/eradicate/)
|
||||
- [`pyupgrade`](https://pypi.org/project/pyupgrade/) (16/33)
|
||||
- [`pygrep-hooks`](https://github.com/pre-commit/pygrep-hooks) (1/10)
|
||||
- [`autoflake`](https://pypi.org/project/autoflake/) (1/7)
|
||||
|
||||
Beyond the rule set, Ruff suffers from the following limitations vis-à-vis Flake8:
|
||||
@@ -942,12 +990,15 @@ Today, Ruff can be used to replace Flake8 when used with any of the following pl
|
||||
- [`flake8-eradicate`](https://pypi.org/project/flake8-eradicate/)
|
||||
- [`flake8-print`](https://pypi.org/project/flake8-print/)
|
||||
- [`flake8-quotes`](https://pypi.org/project/flake8-quotes/)
|
||||
- [`flake8-return`](https://pypi.org/project/flake8-return/)
|
||||
- [`flake8-super`](https://pypi.org/project/flake8-super/)
|
||||
- [`flake8-tidy-imports`](https://pypi.org/project/flake8-tidy-imports/) (1/3)
|
||||
- [`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/) (16/33).
|
||||
Ruff can also replace [`isort`](https://pypi.org/project/isort/),
|
||||
[`yesqa`](https://github.com/asottile/yesqa), [`eradicate`](https://pypi.org/project/eradicate/),
|
||||
[`pygrep-hooks`](https://github.com/pre-commit/pygrep-hooks) (1/10), and a subset of the rules
|
||||
implemented in [`pyupgrade`](https://pypi.org/project/pyupgrade/) (16/33).
|
||||
|
||||
If you're looking to use Ruff, but rely on an unsupported Flake8 plugin, free to file an Issue.
|
||||
|
||||
@@ -1229,25 +1280,6 @@ Summary
|
||||
|
||||
### Options
|
||||
|
||||
#### [`dummy_variable_rgx`](#dummy_variable_rgx)
|
||||
|
||||
A regular expression used to identify "dummy" variables, or those which should be ignored when evaluating
|
||||
(e.g.) unused-variable checks.
|
||||
|
||||
**Default value**: `"^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"` (matches `_`, `__`, and `_var`, but not `_var_`)
|
||||
|
||||
**Type**: `Regex`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
# Only ignore variables named "_".
|
||||
dummy_variable_rgx = "^_$"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### [`exclude`](#exclude)
|
||||
|
||||
A list of file patterns to exclude from linting.
|
||||
@@ -1261,7 +1293,7 @@ Exclusions are based on globs, and can be either:
|
||||
(to exclude any Python files in `directory`). Note that these paths are relative to the
|
||||
project root (e.g., the directory containing your `pyproject.toml`).
|
||||
|
||||
Note that you'll typically want to use [`extend_exclude`](#extend_exclude) to modify the excluded
|
||||
Note that you'll typically want to use [`extend-exclude`](#extend-exclude) to modify the excluded
|
||||
paths.
|
||||
|
||||
**Default value**: `[".bzr", ".direnv", ".eggs", ".git", ".hg", ".mypy_cache", ".nox", ".pants.d", ".ruff_cache", ".svn", ".tox", ".venv", "__pypackages__", "_build", "buck-out", "build", "dist", "node_modules", "venv"]`
|
||||
@@ -1273,7 +1305,7 @@ paths.
|
||||
```toml
|
||||
[tool.ruff]
|
||||
exclude = [".venv"]
|
||||
````
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1291,7 +1323,7 @@ A list of file patterns to omit from linting, in addition to those specified by
|
||||
[tool.ruff]
|
||||
# In addition to the standard set of exclusions, omit all tests, plus a specific file.
|
||||
extend-exclude = ["tests", "src/bad.py"]
|
||||
````
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
@@ -1468,6 +1500,64 @@ line-length = 120
|
||||
|
||||
---
|
||||
|
||||
#### [`dummy-variable-rgx`](#dummy-variable-rgx)
|
||||
|
||||
A regular expression used to identify "dummy" variables, or those which should be ignored when evaluating
|
||||
(e.g.) unused-variable checks.
|
||||
|
||||
**Default value**: `"^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"` (matches `_`, `__`, and `_var`, but not `_var_`)
|
||||
|
||||
**Type**: `Regex`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
# Only ignore variables named "_".
|
||||
dummy-variable-rgx = "^_$"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### [`allowed-confusables`](#allowed-confusables)
|
||||
|
||||
A list of allowed "confusable" Unicode characters to ignore when enforcing `RUF001`, `RUF002`,
|
||||
and `RUF003`.
|
||||
|
||||
**Default value**: `[]`
|
||||
|
||||
**Type**: `Vec<char>`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
# Allow minus-sign (U+2212), greek-small-letter-rho (U+03C1), and greek-small-letter-alpha (U+03B1),
|
||||
# which could be confused for "-", "p", and "*", respectively.
|
||||
allowed-confusables = ["−", "ρ", "∗"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### [`ignore-init-module-imports`](#ignore-init-module-imports)
|
||||
|
||||
Avoid automatically removing unused imports in `__init__.py` files. Such imports will still be
|
||||
flagged, but with a dedicated message suggesting that the import is either added to the module's
|
||||
`__all__` symbol, or re-exported with a redundant alias (e.g., `import os as os`).
|
||||
|
||||
**Default value**: `false`
|
||||
|
||||
**Type**: `bool`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
```toml
|
||||
[tool.ruff]
|
||||
ignore-init-module-imports = true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### [`format`](#format)
|
||||
|
||||
The style in which violation messages should be formatted: `"text"` (default), `"grouped"`
|
||||
@@ -1747,7 +1837,7 @@ ban-relative-imports = "all"
|
||||
|
||||
### `isort`
|
||||
|
||||
#### [`known-first-party`](known-first-party)
|
||||
#### [`known-first-party`](#known-first-party)
|
||||
|
||||
A list of modules to consider first-party, regardless of whether they can be identified as such
|
||||
via introspection of the local filesystem.
|
||||
@@ -1765,7 +1855,7 @@ known-first-party = ["src"]
|
||||
|
||||
---
|
||||
|
||||
#### [`known-third-party`](known-third-party)
|
||||
#### [`known-third-party`](#known-third-party)
|
||||
|
||||
A list of modules to consider third-party, regardless of whether they can be identified as such
|
||||
via introspection of the local filesystem.
|
||||
@@ -1783,7 +1873,7 @@ known-third-party = ["fastapi"]
|
||||
|
||||
---
|
||||
|
||||
#### [`extra-standard-library`](extra-standard-library)
|
||||
#### [`extra-standard-library`](#extra-standard-library)
|
||||
|
||||
A list of modules to consider standard-library, in addition to those known to Ruff in advance.
|
||||
|
||||
@@ -1798,6 +1888,50 @@ A list of modules to consider standard-library, in addition to those known to Ru
|
||||
extra-standard-library = ["path"]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### [`combine-as-imports`](#combine-as-imports)
|
||||
|
||||
Combines as imports on the same line. See isort's [`combine-as-imports`](https://pycqa.github.io/isort/docs/configuration/options.html#combine-as-imports)
|
||||
option.
|
||||
|
||||
**Default value**: `false`
|
||||
|
||||
**Type**: `bool`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
```toml
|
||||
[tool.ruff.isort]
|
||||
combine-as-imports = true
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
#### [`force-wrap-aliases`](#force-wrap-aliases)
|
||||
|
||||
Force `import from` statements with multiple members and at least one alias (e.g., `import A as B`)
|
||||
to wrap such that every line contains exactly one member. For example, this formatting would be
|
||||
retained, rather than condensing to a single line:
|
||||
|
||||
```py
|
||||
from .utils import (
|
||||
test_directory as test_directory,
|
||||
test_id as test_id
|
||||
)
|
||||
```
|
||||
|
||||
**Default value**: `false`
|
||||
|
||||
**Type**: `bool`
|
||||
|
||||
**Example usage**:
|
||||
|
||||
```toml
|
||||
[tool.ruff.isort]
|
||||
force-wrap-aliases = true
|
||||
```
|
||||
|
||||
### `mccabe`
|
||||
|
||||
#### [`max-complexity`](#max-complexity)
|
||||
|
||||
11
create_plugin.sh
Executable file
11
create_plugin.sh
Executable file
@@ -0,0 +1,11 @@
|
||||
set -euxo pipefail
|
||||
|
||||
NAME=$1
|
||||
|
||||
mkdir -p src/$1
|
||||
mkdir -p resources/test/fixtures/$1
|
||||
touch src/$1/mod.rs
|
||||
|
||||
sed -i "" "s/mod flake8_print;/mod flake8_print; mod flake8_return;/g" src/lib.rs
|
||||
sed -i "" "s|// flake8-print|// flake8-return\n// flake8-print|g" src/checks.rs
|
||||
|
||||
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.150"
|
||||
version = "0.0.161"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@@ -1975,7 +1975,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.150"
|
||||
version = "0.0.161"
|
||||
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=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=28f9f65ccc625f00835d84bbb5fba274dce5aa89#28f9f65ccc625f00835d84bbb5fba274dce5aa89"
|
||||
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=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=28f9f65ccc625f00835d84bbb5fba274dce5aa89#28f9f65ccc625f00835d84bbb5fba274dce5aa89"
|
||||
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=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=28f9f65ccc625f00835d84bbb5fba274dce5aa89#28f9f65ccc625f00835d84bbb5fba274dce5aa89"
|
||||
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=f885db8c61514f069979861f6b3bd83292086231#f885db8c61514f069979861f6b3bd83292086231"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=28f9f65ccc625f00835d84bbb5fba274dce5aa89#28f9f65ccc625f00835d84bbb5fba274dce5aa89"
|
||||
dependencies = [
|
||||
"ahash",
|
||||
"anyhow",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.150-dev.0"
|
||||
version = "0.0.161-dev.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
|
||||
@@ -243,6 +243,7 @@ mod tests {
|
||||
fn it_converts_empty() -> Result<()> {
|
||||
let actual = convert(&HashMap::from([]), None)?;
|
||||
let expected = Pyproject::new(Options {
|
||||
allowed_confusables: None,
|
||||
dummy_variable_rgx: None,
|
||||
exclude: None,
|
||||
extend_exclude: None,
|
||||
@@ -253,6 +254,7 @@ mod tests {
|
||||
fixable: None,
|
||||
format: None,
|
||||
ignore: Some(vec![]),
|
||||
ignore_init_module_imports: None,
|
||||
line_length: None,
|
||||
per_file_ignores: None,
|
||||
select: Some(vec![
|
||||
@@ -285,6 +287,7 @@ mod tests {
|
||||
Some(vec![]),
|
||||
)?;
|
||||
let expected = Pyproject::new(Options {
|
||||
allowed_confusables: None,
|
||||
dummy_variable_rgx: None,
|
||||
exclude: None,
|
||||
extend_exclude: None,
|
||||
@@ -295,6 +298,7 @@ mod tests {
|
||||
fixable: None,
|
||||
format: None,
|
||||
ignore: Some(vec![]),
|
||||
ignore_init_module_imports: None,
|
||||
line_length: Some(100),
|
||||
per_file_ignores: None,
|
||||
select: Some(vec![
|
||||
@@ -327,6 +331,7 @@ mod tests {
|
||||
Some(vec![]),
|
||||
)?;
|
||||
let expected = Pyproject::new(Options {
|
||||
allowed_confusables: None,
|
||||
dummy_variable_rgx: None,
|
||||
exclude: None,
|
||||
extend_exclude: None,
|
||||
@@ -337,6 +342,7 @@ mod tests {
|
||||
fixable: None,
|
||||
format: None,
|
||||
ignore: Some(vec![]),
|
||||
ignore_init_module_imports: None,
|
||||
line_length: Some(100),
|
||||
per_file_ignores: None,
|
||||
select: Some(vec![
|
||||
@@ -369,6 +375,7 @@ mod tests {
|
||||
Some(vec![]),
|
||||
)?;
|
||||
let expected = Pyproject::new(Options {
|
||||
allowed_confusables: None,
|
||||
dummy_variable_rgx: None,
|
||||
exclude: None,
|
||||
extend_exclude: None,
|
||||
@@ -379,6 +386,7 @@ mod tests {
|
||||
fixable: None,
|
||||
format: None,
|
||||
ignore: Some(vec![]),
|
||||
ignore_init_module_imports: None,
|
||||
line_length: None,
|
||||
per_file_ignores: None,
|
||||
select: Some(vec![
|
||||
@@ -411,6 +419,7 @@ mod tests {
|
||||
Some(vec![]),
|
||||
)?;
|
||||
let expected = Pyproject::new(Options {
|
||||
allowed_confusables: None,
|
||||
dummy_variable_rgx: None,
|
||||
exclude: None,
|
||||
extend_exclude: None,
|
||||
@@ -421,6 +430,7 @@ mod tests {
|
||||
fixable: None,
|
||||
format: None,
|
||||
ignore: Some(vec![]),
|
||||
ignore_init_module_imports: None,
|
||||
line_length: None,
|
||||
per_file_ignores: None,
|
||||
select: Some(vec![
|
||||
@@ -461,6 +471,7 @@ mod tests {
|
||||
Some(vec![Plugin::Flake8Docstrings]),
|
||||
)?;
|
||||
let expected = Pyproject::new(Options {
|
||||
allowed_confusables: None,
|
||||
dummy_variable_rgx: None,
|
||||
exclude: None,
|
||||
extend_exclude: None,
|
||||
@@ -471,6 +482,7 @@ mod tests {
|
||||
fixable: None,
|
||||
format: None,
|
||||
ignore: Some(vec![]),
|
||||
ignore_init_module_imports: None,
|
||||
line_length: None,
|
||||
per_file_ignores: None,
|
||||
select: Some(vec![
|
||||
@@ -538,6 +550,7 @@ mod tests {
|
||||
None,
|
||||
)?;
|
||||
let expected = Pyproject::new(Options {
|
||||
allowed_confusables: None,
|
||||
dummy_variable_rgx: None,
|
||||
exclude: None,
|
||||
extend_exclude: None,
|
||||
@@ -548,6 +561,7 @@ mod tests {
|
||||
fixable: None,
|
||||
format: None,
|
||||
ignore: Some(vec![]),
|
||||
ignore_init_module_imports: None,
|
||||
line_length: None,
|
||||
per_file_ignores: None,
|
||||
select: Some(vec![
|
||||
|
||||
@@ -17,6 +17,7 @@ pub enum Plugin {
|
||||
Flake8Eradicate,
|
||||
Flake8Print,
|
||||
Flake8Quotes,
|
||||
Flake8Return,
|
||||
Flake8TidyImports,
|
||||
McCabe,
|
||||
PEP8Naming,
|
||||
@@ -39,6 +40,7 @@ impl FromStr for Plugin {
|
||||
"flake8-eradicate" => Ok(Plugin::Flake8BlindExcept),
|
||||
"flake8-print" => Ok(Plugin::Flake8Print),
|
||||
"flake8-quotes" => Ok(Plugin::Flake8Quotes),
|
||||
"flake8-return" => Ok(Plugin::Flake8Return),
|
||||
"flake8-tidy-imports" => Ok(Plugin::Flake8TidyImports),
|
||||
"mccabe" => Ok(Plugin::McCabe),
|
||||
"pep8-naming" => Ok(Plugin::PEP8Naming),
|
||||
@@ -62,6 +64,7 @@ impl Plugin {
|
||||
Plugin::Flake8Eradicate => CheckCodePrefix::ERA,
|
||||
Plugin::Flake8Print => CheckCodePrefix::T2,
|
||||
Plugin::Flake8Quotes => CheckCodePrefix::Q,
|
||||
Plugin::Flake8Return => CheckCodePrefix::RET,
|
||||
Plugin::Flake8TidyImports => CheckCodePrefix::I25,
|
||||
Plugin::McCabe => CheckCodePrefix::C9,
|
||||
Plugin::PEP8Naming => CheckCodePrefix::N,
|
||||
@@ -97,6 +100,7 @@ impl Plugin {
|
||||
Plugin::Flake8Eradicate => vec![CheckCodePrefix::ERA],
|
||||
Plugin::Flake8Print => vec![CheckCodePrefix::T2],
|
||||
Plugin::Flake8Quotes => vec![CheckCodePrefix::Q],
|
||||
Plugin::Flake8Return => vec![CheckCodePrefix::RET],
|
||||
Plugin::Flake8TidyImports => vec![CheckCodePrefix::I25],
|
||||
Plugin::McCabe => vec![CheckCodePrefix::C9],
|
||||
Plugin::PEP8Naming => vec![CheckCodePrefix::N],
|
||||
@@ -389,6 +393,7 @@ pub fn infer_plugins_from_codes(codes: &BTreeSet<CheckCodePrefix>) -> Vec<Plugin
|
||||
Plugin::Flake8Eradicate,
|
||||
Plugin::Flake8Print,
|
||||
Plugin::Flake8Quotes,
|
||||
Plugin::Flake8Return,
|
||||
Plugin::Flake8TidyImports,
|
||||
Plugin::PEP8Naming,
|
||||
Plugin::Pyupgrade,
|
||||
|
||||
@@ -31,3 +31,7 @@ build-backend = "maturin"
|
||||
[tool.maturin]
|
||||
bindings = "bin"
|
||||
strip = true
|
||||
|
||||
[tool.ruff.isort]
|
||||
force-wrap-aliases = true
|
||||
combine-as-imports = true
|
||||
|
||||
1
resources/test/fixtures/flake8_print/T100.py
vendored
1
resources/test/fixtures/flake8_print/T100.py
vendored
@@ -2,6 +2,7 @@ breakpoint()
|
||||
|
||||
|
||||
import pdb
|
||||
import builtins
|
||||
from builtins import breakpoint
|
||||
from pdb import set_trace as st
|
||||
from celery.contrib.rdb import set_trace
|
||||
|
||||
4
resources/test/fixtures/flake8_return/RET501.py
vendored
Normal file
4
resources/test/fixtures/flake8_return/RET501.py
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
def x(y):
|
||||
if not y:
|
||||
return
|
||||
return None # error
|
||||
65
resources/test/fixtures/flake8_return/RET502.py
vendored
Normal file
65
resources/test/fixtures/flake8_return/RET502.py
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
def x(y):
|
||||
if not y:
|
||||
return # error
|
||||
return 1
|
||||
|
||||
|
||||
# without return value
|
||||
def x(y):
|
||||
if not y:
|
||||
return
|
||||
return
|
||||
|
||||
|
||||
def x(y):
|
||||
if y:
|
||||
return
|
||||
print()
|
||||
|
||||
|
||||
# with return value
|
||||
def x(y):
|
||||
if not y:
|
||||
return 1
|
||||
return 2
|
||||
|
||||
|
||||
def x(y):
|
||||
for i in range(10):
|
||||
if i > 100:
|
||||
return i
|
||||
else:
|
||||
return 1
|
||||
|
||||
|
||||
def x(y):
|
||||
try:
|
||||
return 1
|
||||
except:
|
||||
return 2
|
||||
|
||||
|
||||
def x(y):
|
||||
try:
|
||||
return 1
|
||||
finally:
|
||||
return 2
|
||||
|
||||
|
||||
# inner function
|
||||
def x(y):
|
||||
if not y:
|
||||
return 1
|
||||
|
||||
def inner():
|
||||
return
|
||||
|
||||
return 2
|
||||
|
||||
|
||||
def x(y):
|
||||
if not y:
|
||||
return
|
||||
|
||||
def inner():
|
||||
return 1
|
||||
116
resources/test/fixtures/flake8_return/RET503.py
vendored
Normal file
116
resources/test/fixtures/flake8_return/RET503.py
vendored
Normal file
@@ -0,0 +1,116 @@
|
||||
###
|
||||
# Errors
|
||||
###
|
||||
|
||||
# if/elif/else
|
||||
def x(y):
|
||||
if not y:
|
||||
return 1
|
||||
# error
|
||||
|
||||
|
||||
def x(y):
|
||||
if not y:
|
||||
print() # error
|
||||
else:
|
||||
return 2
|
||||
|
||||
|
||||
def x(y):
|
||||
if not y:
|
||||
return 1
|
||||
|
||||
print() # error
|
||||
|
||||
|
||||
# for
|
||||
def x(y):
|
||||
for i in range(10):
|
||||
if i > 10:
|
||||
return i
|
||||
# error
|
||||
|
||||
|
||||
def x(y):
|
||||
for i in range(10):
|
||||
if i > 10:
|
||||
return i
|
||||
else:
|
||||
print() # error
|
||||
|
||||
|
||||
###
|
||||
# Non-errors
|
||||
###
|
||||
|
||||
# raise as last return
|
||||
def x(y):
|
||||
if not y:
|
||||
return 1
|
||||
raise Exception
|
||||
|
||||
|
||||
# last line in while loop
|
||||
def x(y):
|
||||
while True:
|
||||
if y > 0:
|
||||
return 1
|
||||
y += 1
|
||||
|
||||
|
||||
# exclude empty functions
|
||||
def x(y):
|
||||
return None
|
||||
|
||||
|
||||
# return inner with statement
|
||||
def x(y):
|
||||
with y:
|
||||
return 1
|
||||
|
||||
|
||||
async def function():
|
||||
async with thing as foo:
|
||||
return foo.bar
|
||||
|
||||
|
||||
# assert as last return
|
||||
def x(y):
|
||||
if not y:
|
||||
return 1
|
||||
assert False, "Sanity check"
|
||||
|
||||
|
||||
# return value within loop
|
||||
def bar1(x, y, z):
|
||||
for i in x:
|
||||
if i > y:
|
||||
break
|
||||
return z
|
||||
|
||||
|
||||
def bar3(x, y, z):
|
||||
for i in x:
|
||||
if i > y:
|
||||
if z:
|
||||
break
|
||||
else:
|
||||
return z
|
||||
return None
|
||||
|
||||
|
||||
def bar1(x, y, z):
|
||||
for i in x:
|
||||
if i < y:
|
||||
continue
|
||||
return z
|
||||
|
||||
|
||||
def bar3(x, y, z):
|
||||
for i in x:
|
||||
if i < y:
|
||||
if z:
|
||||
continue
|
||||
else:
|
||||
return z
|
||||
return None
|
||||
232
resources/test/fixtures/flake8_return/RET504.py
vendored
Normal file
232
resources/test/fixtures/flake8_return/RET504.py
vendored
Normal file
@@ -0,0 +1,232 @@
|
||||
###
|
||||
# Errors
|
||||
###
|
||||
def x():
|
||||
a = 1
|
||||
return a # error
|
||||
|
||||
|
||||
def x():
|
||||
b, a = 1, 2
|
||||
print(b)
|
||||
return a # error
|
||||
|
||||
|
||||
def x():
|
||||
a = 1
|
||||
print()
|
||||
return a # error
|
||||
|
||||
|
||||
def x():
|
||||
a = 1
|
||||
print(a)
|
||||
a = 2
|
||||
return a # error
|
||||
|
||||
|
||||
def x():
|
||||
a = 1
|
||||
if True:
|
||||
return a # error
|
||||
a = 2
|
||||
print(a)
|
||||
return a
|
||||
|
||||
|
||||
# Can be refactored false positives
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issuecomment-1122571066
|
||||
def get_bar_if_exists(obj):
|
||||
result = ""
|
||||
if hasattr(obj, "bar"):
|
||||
result = str(obj.bar)
|
||||
return result
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issue-641117366
|
||||
def x():
|
||||
formatted = _USER_AGENT_FORMATTER.format(format_string, **values)
|
||||
# clean up after any blank components
|
||||
formatted = formatted.replace("()", "").replace(" ", " ").strip()
|
||||
return formatted
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issue-641117366
|
||||
def user_agent_username(username=None):
|
||||
|
||||
if not username:
|
||||
return ""
|
||||
|
||||
username = username.replace(" ", "_") # Avoid spaces or %20.
|
||||
try:
|
||||
username.encode("ascii") # just test, but not actually use it
|
||||
except UnicodeEncodeError:
|
||||
username = quote(username.encode("utf-8"))
|
||||
else:
|
||||
# % is legal in the default $wgLegalTitleChars
|
||||
# This is so that ops know the real pywikibot will not
|
||||
# allow a useragent in the username to allow through a hand-coded
|
||||
# percent-encoded value.
|
||||
if "%" in username:
|
||||
username = quote(username)
|
||||
return username
|
||||
|
||||
|
||||
###
|
||||
# Non-errors
|
||||
###
|
||||
def x(y):
|
||||
a = 1
|
||||
print(a)
|
||||
return a
|
||||
|
||||
|
||||
def x():
|
||||
a = 1
|
||||
if y:
|
||||
return a
|
||||
a = a + 2
|
||||
print(a)
|
||||
return a
|
||||
|
||||
|
||||
def x():
|
||||
a = {}
|
||||
a["b"] = 2
|
||||
return a
|
||||
|
||||
|
||||
def x():
|
||||
a = []
|
||||
a.append(2)
|
||||
return a
|
||||
|
||||
|
||||
def x():
|
||||
a = lambda x: x
|
||||
a()
|
||||
return a
|
||||
|
||||
|
||||
# ignore unpacking
|
||||
def x():
|
||||
b, a = [1, 2]
|
||||
return a
|
||||
|
||||
|
||||
def x():
|
||||
val = ""
|
||||
for i in range(5):
|
||||
val = val + str(i)
|
||||
return val
|
||||
|
||||
|
||||
def x():
|
||||
val = ""
|
||||
i = 5
|
||||
while i:
|
||||
val = val + str(i)
|
||||
i = i - x
|
||||
return val
|
||||
|
||||
|
||||
# Test cases for using value for assignment then returning it
|
||||
# See:https://github.com/afonasev/flake8-return/issues/47
|
||||
def resolve_from_url(self, url: str) -> dict:
|
||||
local_match = self.local_scope_re.match(url)
|
||||
if local_match:
|
||||
schema = get_schema(name=local_match.group(1))
|
||||
self.store[url] = schema
|
||||
return schema
|
||||
raise NotImplementedError(...)
|
||||
|
||||
|
||||
my_dict = {}
|
||||
|
||||
|
||||
def my_func():
|
||||
foo = calculate_foo()
|
||||
my_dict["foo_result"] = foo
|
||||
return foo
|
||||
|
||||
|
||||
# Refactored incorrect false positives
|
||||
# See test cases above marked: "Can be refactored false positives"
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issuecomment-1122571066
|
||||
def get_bar_if_exists(obj):
|
||||
if hasattr(obj, "bar"):
|
||||
return str(obj.bar)
|
||||
return ""
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issue-641117366
|
||||
def x():
|
||||
formatted = _USER_AGENT_FORMATTER.format(format_string, **values)
|
||||
# clean up after any blank components
|
||||
return formatted.replace("()", "").replace(" ", " ").strip()
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/47#issue-641117366
|
||||
def user_agent_username(username=None):
|
||||
|
||||
if not username:
|
||||
return ""
|
||||
|
||||
username = username.replace(" ", "_") # Avoid spaces or %20.
|
||||
try:
|
||||
username.encode("ascii") # just test,
|
||||
# but not actually use it
|
||||
except UnicodeEncodeError:
|
||||
username = quote(username.encode("utf-8"))
|
||||
else:
|
||||
# % is legal in the default $wgLegalTitleChars
|
||||
# This is so that ops know the real pywikibot will not
|
||||
# allow a useragent in the username to allow through a
|
||||
# hand-coded percent-encoded value.
|
||||
if "%" in username:
|
||||
username = quote(username)
|
||||
return username
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/116#issue-1367575481
|
||||
def no_exception_loop():
|
||||
success = False
|
||||
for _ in range(10):
|
||||
try:
|
||||
success = True
|
||||
except Exception:
|
||||
print("exception")
|
||||
return success
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/116#issue-1367575481
|
||||
def no_exception():
|
||||
success = False
|
||||
try:
|
||||
success = True
|
||||
except Exception:
|
||||
print("exception")
|
||||
return success
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/116#issue-1367575481
|
||||
def exception():
|
||||
success = True
|
||||
try:
|
||||
print("raising")
|
||||
raise Exception
|
||||
except Exception:
|
||||
success = False
|
||||
return success
|
||||
|
||||
|
||||
# https://github.com/afonasev/flake8-return/issues/66
|
||||
def close(self):
|
||||
any_failed = False
|
||||
for task in self.tasks:
|
||||
try:
|
||||
task()
|
||||
except BaseException:
|
||||
any_failed = True
|
||||
report(traceback.format_exc())
|
||||
return any_failed
|
||||
141
resources/test/fixtures/flake8_return/RET505.py
vendored
Normal file
141
resources/test/fixtures/flake8_return/RET505.py
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
###
|
||||
# Error
|
||||
###
|
||||
def foo2(x, y, w, z):
|
||||
if x: # [no-else-return]
|
||||
a = 1
|
||||
return y
|
||||
elif z:
|
||||
b = 2
|
||||
return w
|
||||
else:
|
||||
c = 3
|
||||
return z
|
||||
|
||||
|
||||
def foo5(x, y, z):
|
||||
if x: # [no-else-return]
|
||||
if y:
|
||||
a = 4
|
||||
else:
|
||||
b = 2
|
||||
return
|
||||
elif z:
|
||||
c = 2
|
||||
else:
|
||||
c = 3
|
||||
return
|
||||
|
||||
|
||||
def foo2(x, y, w, z):
|
||||
if x:
|
||||
a = 1
|
||||
elif z:
|
||||
b = 2
|
||||
else:
|
||||
c = 3
|
||||
|
||||
if x: # [no-else-return]
|
||||
a = 1
|
||||
return y
|
||||
elif z:
|
||||
b = 2
|
||||
return w
|
||||
else:
|
||||
c = 3
|
||||
return z
|
||||
|
||||
|
||||
def foo1(x, y, z):
|
||||
if x: # [no-else-return]
|
||||
a = 1
|
||||
return y
|
||||
else:
|
||||
b = 2
|
||||
return z
|
||||
|
||||
|
||||
def foo3(x, y, z):
|
||||
if x:
|
||||
a = 1
|
||||
if y: # [no-else-return]
|
||||
b = 2
|
||||
return y
|
||||
else:
|
||||
c = 3
|
||||
return x
|
||||
else:
|
||||
d = 4
|
||||
return z
|
||||
|
||||
|
||||
def foo4(x, y):
|
||||
if x: # [no-else-return]
|
||||
if y:
|
||||
a = 4
|
||||
else:
|
||||
b = 2
|
||||
return
|
||||
else:
|
||||
c = 3
|
||||
return
|
||||
|
||||
|
||||
def foo6(x, y):
|
||||
if x:
|
||||
if y: # [no-else-return]
|
||||
a = 4
|
||||
return
|
||||
else:
|
||||
b = 2
|
||||
else:
|
||||
c = 3
|
||||
return
|
||||
|
||||
|
||||
def bar4(x):
|
||||
if x: # [no-else-return]
|
||||
return True
|
||||
else:
|
||||
try:
|
||||
return False
|
||||
except ValueError:
|
||||
return None
|
||||
|
||||
|
||||
###
|
||||
# Non-error
|
||||
###
|
||||
def bar1(x, y, z):
|
||||
if x:
|
||||
return y
|
||||
return z
|
||||
|
||||
|
||||
def bar2(w, x, y, z):
|
||||
if x:
|
||||
return y
|
||||
if z:
|
||||
a = 1
|
||||
else:
|
||||
return w
|
||||
return None
|
||||
|
||||
|
||||
def bar3(x, y, z):
|
||||
if x:
|
||||
if z:
|
||||
return y
|
||||
else:
|
||||
return z
|
||||
return None
|
||||
|
||||
|
||||
x = 0
|
||||
|
||||
if x == 1:
|
||||
y = "a"
|
||||
elif x == 2:
|
||||
y = "b"
|
||||
else:
|
||||
y = "c"
|
||||
112
resources/test/fixtures/flake8_return/RET506.py
vendored
Normal file
112
resources/test/fixtures/flake8_return/RET506.py
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
###
|
||||
# Errors
|
||||
###
|
||||
def foo2(x, y, w, z):
|
||||
if x: # [no-else-raise]
|
||||
a = 1
|
||||
raise Exception(y)
|
||||
elif z:
|
||||
b = 2
|
||||
raise Exception(w)
|
||||
else:
|
||||
c = 3
|
||||
raise Exception(z)
|
||||
|
||||
|
||||
def foo5(x, y, z):
|
||||
if x: # [no-else-raise]
|
||||
if y:
|
||||
a = 4
|
||||
else:
|
||||
b = 2
|
||||
raise Exception(x)
|
||||
elif z:
|
||||
raise Exception(y)
|
||||
else:
|
||||
c = 3
|
||||
raise Exception(z)
|
||||
|
||||
|
||||
def foo1(x, y, z):
|
||||
if x: # [no-else-raise]
|
||||
a = 1
|
||||
raise Exception(y)
|
||||
else:
|
||||
b = 2
|
||||
raise Exception(z)
|
||||
|
||||
|
||||
def foo3(x, y, z):
|
||||
if x:
|
||||
a = 1
|
||||
if y: # [no-else-raise]
|
||||
b = 2
|
||||
raise Exception(y)
|
||||
else:
|
||||
c = 3
|
||||
raise Exception(x)
|
||||
else:
|
||||
d = 4
|
||||
raise Exception(z)
|
||||
|
||||
|
||||
def foo4(x, y):
|
||||
if x: # [no-else-raise]
|
||||
if y:
|
||||
a = 4
|
||||
else:
|
||||
b = 2
|
||||
raise Exception(x)
|
||||
else:
|
||||
c = 3
|
||||
raise Exception(y)
|
||||
|
||||
|
||||
def foo6(x, y):
|
||||
if x:
|
||||
if y: # [no-else-raise]
|
||||
a = 4
|
||||
raise Exception(x)
|
||||
else:
|
||||
b = 2
|
||||
else:
|
||||
c = 3
|
||||
raise Exception(y)
|
||||
|
||||
|
||||
def bar4(x):
|
||||
if x: # [no-else-raise]
|
||||
raise Exception(True)
|
||||
else:
|
||||
try:
|
||||
raise Exception(False)
|
||||
except ValueError:
|
||||
raise Exception(None)
|
||||
|
||||
|
||||
###
|
||||
# Non-errors
|
||||
###
|
||||
def bar1(x, y, z):
|
||||
if x:
|
||||
raise Exception(y)
|
||||
raise Exception(z)
|
||||
|
||||
|
||||
def bar2(w, x, y, z):
|
||||
if x:
|
||||
raise Exception(y)
|
||||
if z:
|
||||
a = 1
|
||||
else:
|
||||
raise Exception(w)
|
||||
raise Exception(None)
|
||||
|
||||
|
||||
def bar3(x, y, z):
|
||||
if x:
|
||||
if z:
|
||||
raise Exception(y)
|
||||
else:
|
||||
raise Exception(z)
|
||||
raise Exception(None)
|
||||
106
resources/test/fixtures/flake8_return/RET507.py
vendored
Normal file
106
resources/test/fixtures/flake8_return/RET507.py
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
###
|
||||
# Errors
|
||||
###
|
||||
def foo2(x, y, w, z):
|
||||
for i in x:
|
||||
if i < y: # [no-else-continue]
|
||||
continue
|
||||
elif i < w:
|
||||
continue
|
||||
else:
|
||||
a = z
|
||||
|
||||
|
||||
def foo5(x, y, z):
|
||||
for i in x:
|
||||
if i < y: # [no-else-continue]
|
||||
if y:
|
||||
a = 4
|
||||
else:
|
||||
b = 2
|
||||
continue
|
||||
elif z:
|
||||
c = 2
|
||||
else:
|
||||
c = 3
|
||||
continue
|
||||
|
||||
|
||||
###
|
||||
# Non-errors
|
||||
###
|
||||
def foo1(x, y, z):
|
||||
for i in x:
|
||||
if i < y: # [no-else-continue]
|
||||
continue
|
||||
else:
|
||||
a = z
|
||||
|
||||
|
||||
def foo3(x, y, z):
|
||||
for i in x:
|
||||
if i < y:
|
||||
a = 1
|
||||
if z: # [no-else-continue]
|
||||
b = 2
|
||||
continue
|
||||
else:
|
||||
c = 3
|
||||
continue
|
||||
else:
|
||||
d = 4
|
||||
continue
|
||||
|
||||
|
||||
def foo4(x, y):
|
||||
for i in x:
|
||||
if i < x: # [no-else-continue]
|
||||
if y:
|
||||
a = 4
|
||||
else:
|
||||
b = 2
|
||||
continue
|
||||
else:
|
||||
c = 3
|
||||
continue
|
||||
|
||||
|
||||
def foo6(x, y):
|
||||
for i in x:
|
||||
if i < x:
|
||||
if y: # [no-else-continue]
|
||||
a = 4
|
||||
continue
|
||||
else:
|
||||
b = 2
|
||||
else:
|
||||
c = 3
|
||||
continue
|
||||
|
||||
|
||||
def bar4(x):
|
||||
for i in range(10):
|
||||
if x: # [no-else-continue]
|
||||
continue
|
||||
else:
|
||||
try:
|
||||
return
|
||||
except ValueError:
|
||||
continue
|
||||
|
||||
|
||||
def bar1(x, y, z):
|
||||
for i in x:
|
||||
if i < y:
|
||||
continue
|
||||
return z
|
||||
|
||||
|
||||
def bar3(x, y, z):
|
||||
for i in x:
|
||||
if i < y:
|
||||
if z:
|
||||
continue
|
||||
else:
|
||||
return z
|
||||
return None
|
||||
138
resources/test/fixtures/flake8_return/RET508.py
vendored
Normal file
138
resources/test/fixtures/flake8_return/RET508.py
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
###
|
||||
# Errors
|
||||
###
|
||||
def foo2(x, y, w, z):
|
||||
for i in x:
|
||||
if i > y: # [no-else-break]
|
||||
break
|
||||
elif i > w:
|
||||
break
|
||||
else:
|
||||
a = z
|
||||
|
||||
|
||||
def foo5(x, y, z):
|
||||
for i in x:
|
||||
if i > y: # [no-else-break]
|
||||
if y:
|
||||
a = 4
|
||||
else:
|
||||
b = 2
|
||||
break
|
||||
elif z:
|
||||
c = 2
|
||||
else:
|
||||
c = 3
|
||||
break
|
||||
|
||||
|
||||
def foo1(x, y, z):
|
||||
for i in x:
|
||||
if i > y: # [no-else-break]
|
||||
break
|
||||
else:
|
||||
a = z
|
||||
|
||||
|
||||
def foo3(x, y, z):
|
||||
for i in x:
|
||||
if i > y:
|
||||
a = 1
|
||||
if z: # [no-else-break]
|
||||
b = 2
|
||||
break
|
||||
else:
|
||||
c = 3
|
||||
break
|
||||
else:
|
||||
d = 4
|
||||
break
|
||||
|
||||
|
||||
def foo4(x, y):
|
||||
for i in x:
|
||||
if i > x: # [no-else-break]
|
||||
if y:
|
||||
a = 4
|
||||
else:
|
||||
b = 2
|
||||
break
|
||||
else:
|
||||
c = 3
|
||||
break
|
||||
|
||||
|
||||
def foo6(x, y):
|
||||
for i in x:
|
||||
if i > x:
|
||||
if y: # [no-else-break]
|
||||
a = 4
|
||||
break
|
||||
else:
|
||||
b = 2
|
||||
else:
|
||||
c = 3
|
||||
break
|
||||
|
||||
|
||||
def bar4(x):
|
||||
for i in range(10):
|
||||
if x: # [no-else-break]
|
||||
break
|
||||
else:
|
||||
try:
|
||||
return
|
||||
except ValueError:
|
||||
break
|
||||
|
||||
|
||||
###
|
||||
# Non-errors
|
||||
###
|
||||
def bar1(x, y, z):
|
||||
for i in x:
|
||||
if i > y:
|
||||
break
|
||||
return z
|
||||
|
||||
|
||||
def bar2(w, x, y, z):
|
||||
for i in w:
|
||||
if i > x:
|
||||
break
|
||||
if z < i:
|
||||
a = y
|
||||
else:
|
||||
break
|
||||
return
|
||||
|
||||
|
||||
def bar3(x, y, z):
|
||||
for i in x:
|
||||
if i > y:
|
||||
if z:
|
||||
break
|
||||
else:
|
||||
return z
|
||||
return None
|
||||
|
||||
|
||||
def nested1(x, y, z):
|
||||
for i in x:
|
||||
if i > x:
|
||||
for j in y:
|
||||
if j < z:
|
||||
break
|
||||
else:
|
||||
a = z
|
||||
|
||||
|
||||
def nested2(x, y, z):
|
||||
for i in x:
|
||||
if i > x:
|
||||
for j in y:
|
||||
if j > z:
|
||||
break
|
||||
break
|
||||
else:
|
||||
a = z
|
||||
4
resources/test/fixtures/isort/combine_as_imports.py
vendored
Normal file
4
resources/test/fixtures/isort/combine_as_imports.py
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
from module import Class as C
|
||||
from module import CONSTANT
|
||||
from module import function
|
||||
from module import function as f
|
||||
3
resources/test/fixtures/isort/force_wrap_aliases.py
vendored
Normal file
3
resources/test/fixtures/isort/force_wrap_aliases.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
from .a import a1 as a1, a2 as a2
|
||||
from .b import b1 as b1
|
||||
from .c import c1
|
||||
16
resources/test/fixtures/isort/insert_empty_lines.py
vendored
Normal file
16
resources/test/fixtures/isort/insert_empty_lines.py
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
import a
|
||||
import b
|
||||
x = 1
|
||||
import os
|
||||
import sys
|
||||
def f():
|
||||
pass
|
||||
if True:
|
||||
x = 1
|
||||
import collections
|
||||
import typing
|
||||
class X: pass
|
||||
y = 1
|
||||
import os
|
||||
import sys
|
||||
"""Docstring"""
|
||||
6
resources/test/fixtures/isort/preserve_import_star.py
vendored
Normal file
6
resources/test/fixtures/isort/preserve_import_star.py
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
from some_other_module import some_class
|
||||
from some_other_module import *
|
||||
# Above
|
||||
from some_module import some_class # Aside
|
||||
# Above
|
||||
from some_module import * # Aside
|
||||
10
resources/test/fixtures/isort/skip_file.py
vendored
Normal file
10
resources/test/fixtures/isort/skip_file.py
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
# isort: skip_file
|
||||
import e
|
||||
import f
|
||||
|
||||
# isort: split
|
||||
|
||||
import a
|
||||
import b
|
||||
import c
|
||||
import d
|
||||
9
resources/test/fixtures/isort/split.py
vendored
Normal file
9
resources/test/fixtures/isort/split.py
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
import e
|
||||
import f
|
||||
|
||||
# isort: split
|
||||
|
||||
import a
|
||||
import b
|
||||
import c
|
||||
import d
|
||||
13
resources/test/fixtures/pyflakes/F632.py
vendored
13
resources/test/fixtures/pyflakes/F632.py
vendored
@@ -4,5 +4,18 @@ if x is "abc":
|
||||
if 123 is not y:
|
||||
pass
|
||||
|
||||
if 123 is \
|
||||
not y:
|
||||
pass
|
||||
|
||||
if "123" is x < 3:
|
||||
pass
|
||||
|
||||
if "123" != x is 3:
|
||||
pass
|
||||
|
||||
if ("123" != x) is 3:
|
||||
pass
|
||||
|
||||
if "123" != (x is 3):
|
||||
pass
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Optional
|
||||
from typing import Callable, List, Tuple, Optional, Sequence
|
||||
|
||||
from models import (
|
||||
Fruit,
|
||||
@@ -37,4 +37,12 @@ def f(x: int) -> List[int]:
|
||||
return y
|
||||
|
||||
|
||||
x: Optional[int] = None
|
||||
x: Tuple[int, ...] = (1, 2)
|
||||
|
||||
|
||||
def f(param: "Optional[Callable]" = None) -> "None":
|
||||
pass
|
||||
|
||||
|
||||
def f(param: Optional["Sequence"] = None) -> "None":
|
||||
pass
|
||||
|
||||
9
resources/test/fixtures/pygrep-hooks/PGH001_0.py
vendored
Normal file
9
resources/test/fixtures/pygrep-hooks/PGH001_0.py
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
from ast import literal_eval
|
||||
|
||||
eval("3 + 4")
|
||||
|
||||
literal_eval({1: 2})
|
||||
|
||||
|
||||
def fn() -> None:
|
||||
eval("3 + 4")
|
||||
11
resources/test/fixtures/pygrep-hooks/PGH001_1.py
vendored
Normal file
11
resources/test/fixtures/pygrep-hooks/PGH001_1.py
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
def eval(content: str) -> None:
|
||||
pass
|
||||
|
||||
|
||||
eval("3 + 4")
|
||||
|
||||
literal_eval({1: 2})
|
||||
|
||||
|
||||
def fn() -> None:
|
||||
eval("3 + 4")
|
||||
38
resources/test/fixtures/pylint/consider_merging_isinstance.py
vendored
Normal file
38
resources/test/fixtures/pylint/consider_merging_isinstance.py
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
"""Checks use of consider-merging-isinstance"""
|
||||
# pylint:disable=line-too-long, simplifiable-condition
|
||||
|
||||
|
||||
def isinstances():
|
||||
"Examples of isinstances"
|
||||
var = range(10)
|
||||
|
||||
# merged
|
||||
if isinstance(var[1], (int, float)):
|
||||
pass
|
||||
result = isinstance(var[2], (int, float))
|
||||
|
||||
# not merged
|
||||
if isinstance(var[3], int) or isinstance(var[3], float) or isinstance(var[3], list) and True: # [consider-merging-isinstance]
|
||||
pass
|
||||
result = isinstance(var[4], int) or isinstance(var[4], float) or isinstance(var[5], list) and False # [consider-merging-isinstance]
|
||||
|
||||
result = isinstance(var[5], int) or True or isinstance(var[5], float) # [consider-merging-isinstance]
|
||||
|
||||
infered_isinstance = isinstance
|
||||
result = infered_isinstance(var[6], int) or infered_isinstance(var[6], float) or infered_isinstance(var[6], list) and False # [consider-merging-isinstance]
|
||||
result = isinstance(var[10], str) or isinstance(var[10], int) and var[8] * 14 or isinstance(var[10], float) and var[5] * 14.4 or isinstance(var[10], list) # [consider-merging-isinstance]
|
||||
result = isinstance(var[11], int) or isinstance(var[11], int) or isinstance(var[11], float) # [consider-merging-isinstance]
|
||||
|
||||
result = isinstance(var[20])
|
||||
result = isinstance()
|
||||
|
||||
# Combination merged and not merged
|
||||
result = isinstance(var[12], (int, float)) or isinstance(var[12], list) # [consider-merging-isinstance]
|
||||
|
||||
# not merged but valid
|
||||
result = isinstance(var[5], int) and var[5] * 14 or isinstance(var[5], float) and var[5] * 14.4
|
||||
result = isinstance(var[7], int) or not isinstance(var[7], float)
|
||||
result = isinstance(var[6], int) or isinstance(var[7], float)
|
||||
result = isinstance(var[6], int) or isinstance(var[7], int)
|
||||
result = isinstance(var[6], (float, int)) or False
|
||||
return result
|
||||
@@ -1,5 +1,7 @@
|
||||
exit(0)
|
||||
quit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(2)
|
||||
quit(2)
|
||||
@@ -1,10 +1,12 @@
|
||||
import sys
|
||||
|
||||
exit(0)
|
||||
quit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
quit(1)
|
||||
|
||||
|
||||
sys.exit(2)
|
||||
@@ -1,7 +1,9 @@
|
||||
import sys as sys2
|
||||
|
||||
exit(0)
|
||||
quit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
quit(1)
|
||||
@@ -1,7 +1,9 @@
|
||||
from sys import exit
|
||||
|
||||
exit(0)
|
||||
quit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
quit(1)
|
||||
@@ -1,7 +1,9 @@
|
||||
from sys import exit as exit2
|
||||
|
||||
exit(0)
|
||||
quit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
quit(1)
|
||||
@@ -1,7 +1,9 @@
|
||||
from sys import *
|
||||
|
||||
exit(0)
|
||||
quit(0)
|
||||
|
||||
|
||||
def main():
|
||||
exit(1)
|
||||
quit(1)
|
||||
@@ -1,12 +1,19 @@
|
||||
exit(0)
|
||||
quit(0)
|
||||
|
||||
|
||||
def exit(e):
|
||||
pass
|
||||
|
||||
|
||||
def quit(e):
|
||||
pass
|
||||
|
||||
|
||||
exit(1)
|
||||
quit(1)
|
||||
|
||||
|
||||
def main():
|
||||
exit(2)
|
||||
quit(2)
|
||||
27
resources/test/fixtures/pylint/import_aliasing.py
vendored
Normal file
27
resources/test/fixtures/pylint/import_aliasing.py
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# pylint: disable=unused-import, missing-docstring, invalid-name, reimported, import-error, wrong-import-order, no-name-in-module, shadowed-import
|
||||
# Functional tests for import aliasing
|
||||
# 1. useless-import-alias
|
||||
# 2. consider-using-from-import
|
||||
|
||||
import collections as collections # [useless-import-alias]
|
||||
from collections import OrderedDict as OrderedDict # [useless-import-alias]
|
||||
from collections import OrderedDict as o_dict
|
||||
import os.path as path # [consider-using-from-import]
|
||||
import os.path as p
|
||||
import foo.bar.foobar as foobar # [consider-using-from-import]
|
||||
import os
|
||||
import os as OS
|
||||
from sys import version
|
||||
from . import bar as bar # [useless-import-alias]
|
||||
from . import bar as Bar
|
||||
from . import bar
|
||||
from ..foo import bar as bar # [useless-import-alias]
|
||||
from ..foo.bar import foobar as foobar # [useless-import-alias]
|
||||
from ..foo.bar import foobar as anotherfoobar
|
||||
from . import foo as foo, foo2 as bar2 # [useless-import-alias]
|
||||
from . import foo as bar, foo2 as foo2 # [useless-import-alias]
|
||||
from . import foo as bar, foo2 as bar2
|
||||
from foo.bar import foobar as foobar # [useless-import-alias]
|
||||
from foo.bar import foobar as foo
|
||||
from .foo.bar import f as foobar
|
||||
from ............a import b # [relative-beyond-top-level]
|
||||
50
resources/test/fixtures/pylint/misplaced_comparison_constant.py
vendored
Normal file
50
resources/test/fixtures/pylint/misplaced_comparison_constant.py
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
"""Check that the constants are on the right side of the comparisons"""
|
||||
|
||||
# pylint: disable=singleton-comparison, missing-docstring, too-few-public-methods
|
||||
# pylint: disable=comparison-of-constants
|
||||
|
||||
class MyClass:
|
||||
def __init__(self):
|
||||
self.attr = 1
|
||||
|
||||
def dummy_return(self):
|
||||
return self.attr
|
||||
|
||||
def dummy_return():
|
||||
return 2
|
||||
|
||||
def bad_comparisons():
|
||||
"""this is not ok"""
|
||||
instance = MyClass()
|
||||
for i in range(10):
|
||||
if 5 <= i: # [misplaced-comparison-constant]
|
||||
pass
|
||||
if 1 == i: # [misplaced-comparison-constant]
|
||||
pass
|
||||
if 3 < dummy_return(): # [misplaced-comparison-constant]
|
||||
pass
|
||||
if 4 != instance.dummy_return(): # [misplaced-comparison-constant]
|
||||
pass
|
||||
if 1 == instance.attr: # [misplaced-comparison-constant]
|
||||
pass
|
||||
if "aaa" == instance.attr: # [misplaced-comparison-constant]
|
||||
pass
|
||||
|
||||
def good_comparison():
|
||||
"""this is ok"""
|
||||
for i in range(10):
|
||||
if i == 5:
|
||||
pass
|
||||
|
||||
def double_comparison():
|
||||
"""Check that we return early for non-binary comparison"""
|
||||
for i in range(10):
|
||||
if i == 1 == 2:
|
||||
pass
|
||||
if 2 <= i <= 8:
|
||||
print("Between 2 and 8 inclusive")
|
||||
|
||||
def const_comparison():
|
||||
"""Check that we return early for comparison of two constants"""
|
||||
if 1 == 2:
|
||||
pass
|
||||
30
resources/test/fixtures/pylint/property_with_parameters.py
vendored
Normal file
30
resources/test/fixtures/pylint/property_with_parameters.py
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
# pylint: disable=missing-docstring, too-few-public-methods
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
||||
|
||||
class Cls:
|
||||
@property
|
||||
def attribute(self, param, param1): # [property-with-parameters]
|
||||
return param + param1
|
||||
|
||||
@property
|
||||
def attribute_keyword_only(self, *, param, param1): # [property-with-parameters]
|
||||
return param + param1
|
||||
|
||||
@property
|
||||
def attribute_positional_only(self, param, param1, /): # [property-with-parameters]
|
||||
return param + param1
|
||||
|
||||
|
||||
class MyClassBase(metaclass=ABCMeta):
|
||||
"""MyClassBase."""
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def example(self):
|
||||
"""Getter."""
|
||||
|
||||
@example.setter
|
||||
@abstractmethod
|
||||
def example(self, value):
|
||||
"""Setter."""
|
||||
5
resources/test/fixtures/pylint/unnecessary_direct_lambda_call.py
vendored
Normal file
5
resources/test/fixtures/pylint/unnecessary_direct_lambda_call.py
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
"""Test unnecessary direct calls to lambda expressions."""
|
||||
# pylint: disable=undefined-variable, line-too-long
|
||||
|
||||
y = (lambda x: x**2 + 2*x + 1)(a) # [unnecessary-direct-lambda-call]
|
||||
y = max((lambda x: x**2)(a), (lambda x: x+1)(a)) # [unnecessary-direct-lambda-call,unnecessary-direct-lambda-call]
|
||||
103
resources/test/fixtures/pylint/useless_else_on_loop.py
vendored
Normal file
103
resources/test/fixtures/pylint/useless_else_on_loop.py
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
"""Check for else branches on loops with break and return only."""
|
||||
|
||||
|
||||
def test_return_for():
|
||||
"""else + return is not acceptable."""
|
||||
for i in range(10):
|
||||
if i % 2:
|
||||
return i
|
||||
else: # [useless-else-on-loop]
|
||||
print("math is broken")
|
||||
return None
|
||||
|
||||
|
||||
def test_return_while():
|
||||
"""else + return is not acceptable."""
|
||||
while True:
|
||||
return 1
|
||||
else: # [useless-else-on-loop]
|
||||
print("math is broken")
|
||||
return None
|
||||
|
||||
|
||||
while True:
|
||||
|
||||
def short_fun():
|
||||
"""A function with a loop."""
|
||||
for _ in range(10):
|
||||
break
|
||||
|
||||
else: # [useless-else-on-loop]
|
||||
print("or else!")
|
||||
|
||||
|
||||
while True:
|
||||
while False:
|
||||
break
|
||||
else: # [useless-else-on-loop]
|
||||
print("or else!")
|
||||
|
||||
for j in range(10):
|
||||
pass
|
||||
else: # [useless-else-on-loop]
|
||||
print("fat chance")
|
||||
for j in range(10):
|
||||
break
|
||||
|
||||
|
||||
def test_return_for2():
|
||||
"""no false positive for break in else
|
||||
|
||||
https://bitbucket.org/logilab/pylint/issue/117/useless-else-on-loop-false-positives
|
||||
"""
|
||||
for i in range(10):
|
||||
for _ in range(i):
|
||||
if i % 2:
|
||||
break
|
||||
else:
|
||||
break
|
||||
else:
|
||||
print("great math")
|
||||
|
||||
|
||||
def test_break_in_orelse_deep():
|
||||
"""no false positive for break in else deeply nested"""
|
||||
for _ in range(10):
|
||||
if 1 < 2: # pylint: disable=comparison-of-constants
|
||||
for _ in range(3):
|
||||
if 3 < 2: # pylint: disable=comparison-of-constants
|
||||
break
|
||||
else:
|
||||
break
|
||||
else:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def test_break_in_orelse_deep2():
|
||||
"""should rise a useless-else-on-loop message, as the break statement is only
|
||||
for the inner for loop
|
||||
"""
|
||||
for _ in range(10):
|
||||
if 1 < 2: # pylint: disable=comparison-of-constants
|
||||
for _ in range(3):
|
||||
if 3 < 2: # pylint: disable=comparison-of-constants
|
||||
break
|
||||
else:
|
||||
print("all right")
|
||||
else: # [useless-else-on-loop]
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def test_break_in_orelse_deep3():
|
||||
"""no false positive for break deeply nested in else"""
|
||||
for _ in range(10):
|
||||
for _ in range(3):
|
||||
pass
|
||||
else:
|
||||
if 1 < 2: # pylint: disable=comparison-of-constants
|
||||
break
|
||||
else:
|
||||
return True
|
||||
return False
|
||||
10
resources/test/fixtures/pyproject.toml
vendored
10
resources/test/fixtures/pyproject.toml
vendored
@@ -1,4 +1,5 @@
|
||||
[tool.ruff]
|
||||
allowed-confusables = ["−", "ρ", "∗"]
|
||||
line-length = 88
|
||||
extend-exclude = [
|
||||
"excluded_file.py",
|
||||
@@ -35,13 +36,8 @@ ignore-names = [
|
||||
"longMessage",
|
||||
"maxDiff",
|
||||
]
|
||||
classmethod-decorators = [
|
||||
"classmethod",
|
||||
"pydantic.validator",
|
||||
]
|
||||
staticmethod-decorators = [
|
||||
"staticmethod",
|
||||
]
|
||||
classmethod-decorators = ["classmethod", "pydantic.validator"]
|
||||
staticmethod-decorators = ["staticmethod"]
|
||||
|
||||
[tool.ruff.flake8-tidy-imports]
|
||||
ban-relative-imports = "parents"
|
||||
|
||||
3
resources/test/fixtures/pyupgrade/U009_4.py
vendored
3
resources/test/fixtures/pyupgrade/U009_4.py
vendored
@@ -1,3 +0,0 @@
|
||||
# coding=utf8 # noqa: U009
|
||||
|
||||
print("Hello world")
|
||||
3
resources/test/fixtures/pyupgrade/UP009_4.py
vendored
Normal file
3
resources/test/fixtures/pyupgrade/UP009_4.py
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
# coding=utf8 # noqa: UP009
|
||||
|
||||
print("Hello world")
|
||||
@@ -1,7 +1,7 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from typing import List, Optional
|
||||
from typing import List, Optional, TypeAlias, Union
|
||||
|
||||
from models import (
|
||||
Fruit,
|
||||
@@ -38,3 +38,5 @@ def f(x: int) -> List[int]:
|
||||
|
||||
|
||||
x: Optional[int] = None
|
||||
|
||||
MyList: TypeAlias = Union[List[int], List[str]]
|
||||
|
||||
7
resources/test/fixtures/ruff/RUF002.py
vendored
7
resources/test/fixtures/ruff/RUF002.py
vendored
@@ -1,7 +0,0 @@
|
||||
x = "𝐁ad string"
|
||||
|
||||
|
||||
def f():
|
||||
"""Here's a docstring with an unusual parenthesis: )"""
|
||||
# And here's a comment with an unusual punctuation mark: ᜵
|
||||
...
|
||||
7
resources/test/fixtures/ruff/RUF003.py
vendored
7
resources/test/fixtures/ruff/RUF003.py
vendored
@@ -1,7 +0,0 @@
|
||||
x = "𝐁ad string"
|
||||
|
||||
|
||||
def f():
|
||||
"""Here's a docstring with an unusual parenthesis: )"""
|
||||
# And here's a comment with an unusual punctuation mark: ᜵
|
||||
...
|
||||
@@ -1,7 +1,14 @@
|
||||
x = "𝐁ad string"
|
||||
y = "−"
|
||||
|
||||
|
||||
def f():
|
||||
"""Here's a docstring with an unusual parenthesis: )"""
|
||||
# And here's a comment with an unusual punctuation mark: ᜵
|
||||
...
|
||||
|
||||
|
||||
def g():
|
||||
"""Here's a docstring with a greek rho: ρ"""
|
||||
# And here's a comment with a greek alpha: ∗
|
||||
...
|
||||
7
resources/test/fixtures/ruff/flake8_noqa.py
vendored
Normal file
7
resources/test/fixtures/ruff/flake8_noqa.py
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# flake8: noqa
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def f():
|
||||
x = 1
|
||||
9
resources/test/fixtures/ruff/redirects.py
vendored
Normal file
9
resources/test/fixtures/ruff/redirects.py
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def f(x: Optional[str]) -> None: # noqa: U007
|
||||
...
|
||||
|
||||
|
||||
def f(x: Optional[str]) -> None: # noqa: UP007
|
||||
...
|
||||
7
resources/test/fixtures/ruff/ruff_noqa.py
vendored
Normal file
7
resources/test/fixtures/ruff/ruff_noqa.py
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
# ruff: noqa
|
||||
|
||||
import os
|
||||
|
||||
|
||||
def f():
|
||||
x = 1
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "ruff_dev"
|
||||
version = "0.0.150"
|
||||
version = "0.0.161"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
@@ -9,9 +9,10 @@ clap = { version = "4.0.1", features = ["derive"] }
|
||||
codegen = { version = "0.2.0" }
|
||||
itertools = { version = "0.10.5" }
|
||||
libcst = { git = "https://github.com/charliermarsh/LibCST", rev = "f2f0b7a487a8725d161fe8b3ed73a6758b21e177" }
|
||||
once_cell = { version = "1.16.0" }
|
||||
ruff = { path = ".." }
|
||||
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" }
|
||||
rustpython-ast = { features = ["unparse"], git = "https://github.com/RustPython/RustPython.git", rev = "28f9f65ccc625f00835d84bbb5fba274dce5aa89" }
|
||||
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "28f9f65ccc625f00835d84bbb5fba274dce5aa89" }
|
||||
rustpython-parser = { features = ["lalrpop"], git = "https://github.com/RustPython/RustPython.git", rev = "28f9f65ccc625f00835d84bbb5fba274dce5aa89" }
|
||||
strum = { version = "0.24.1", features = ["strum_macros"] }
|
||||
strum_macros = { version = "0.24.3" }
|
||||
|
||||
@@ -8,7 +8,7 @@ use anyhow::Result;
|
||||
use clap::Parser;
|
||||
use codegen::{Scope, Type, Variant};
|
||||
use itertools::Itertools;
|
||||
use ruff::checks::CheckCode;
|
||||
use ruff::checks::{CheckCode, REDIRECTS};
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
const FILE: &str = "src/checks_gen.rs";
|
||||
@@ -26,18 +26,49 @@ pub fn main(cli: &Cli) -> Result<()> {
|
||||
// Build up a map from prefix to matching CheckCodes.
|
||||
let mut prefix_to_codes: BTreeMap<String, BTreeSet<CheckCode>> = BTreeMap::default();
|
||||
for check_code in CheckCode::iter() {
|
||||
let as_ref: String = check_code.as_ref().to_string();
|
||||
let prefix_len = as_ref
|
||||
let code_str: String = check_code.as_ref().to_string();
|
||||
let code_prefix_len = code_str
|
||||
.chars()
|
||||
.take_while(|char| char.is_alphabetic())
|
||||
.count();
|
||||
for i in prefix_len..=as_ref.len() {
|
||||
let prefix = as_ref[..i].to_string();
|
||||
let code_suffix_len = code_str.len() - code_prefix_len;
|
||||
for i in 0..=code_suffix_len {
|
||||
let prefix = code_str[..code_prefix_len + i].to_string();
|
||||
let entry = prefix_to_codes.entry(prefix).or_default();
|
||||
entry.insert(check_code.clone());
|
||||
}
|
||||
}
|
||||
|
||||
// Add any aliases (e.g., "U001" to "UP001").
|
||||
for (alias, check_code) in REDIRECTS.iter() {
|
||||
// Compute the length of the prefix and suffix for both codes.
|
||||
let code_str: String = check_code.as_ref().to_string();
|
||||
let code_prefix_len = code_str
|
||||
.chars()
|
||||
.take_while(|char| char.is_alphabetic())
|
||||
.count();
|
||||
let code_suffix_len = code_str.len() - code_prefix_len;
|
||||
let alias_prefix_len = alias
|
||||
.chars()
|
||||
.take_while(|char| char.is_alphabetic())
|
||||
.count();
|
||||
let alias_suffix_len = alias.len() - alias_prefix_len;
|
||||
assert_eq!(code_suffix_len, alias_suffix_len);
|
||||
for i in 0..=code_suffix_len {
|
||||
let source = code_str[..code_prefix_len + i].to_string();
|
||||
let destination = alias[..alias_prefix_len + i].to_string();
|
||||
if source != destination {
|
||||
prefix_to_codes.insert(
|
||||
destination,
|
||||
prefix_to_codes
|
||||
.get(&source)
|
||||
.unwrap_or_else(|| panic!("Unknown CheckCode: {source:?}"))
|
||||
.clone(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let mut scope = Scope::new();
|
||||
|
||||
// Create the `CheckCodePrefix` definition.
|
||||
@@ -81,13 +112,27 @@ pub fn main(cli: &Cli) -> Result<()> {
|
||||
.line("#[allow(clippy::match_same_arms)]")
|
||||
.line("match self {");
|
||||
for (prefix, codes) in &prefix_to_codes {
|
||||
gen = gen.line(format!(
|
||||
"CheckCodePrefix::{prefix} => vec![{}],",
|
||||
codes
|
||||
.iter()
|
||||
.map(|code| format!("CheckCode::{}", code.as_ref()))
|
||||
.join(", ")
|
||||
));
|
||||
if let Some(target) = REDIRECTS.get(&prefix.as_str()) {
|
||||
gen = gen.line(format!(
|
||||
"CheckCodePrefix::{prefix} => {{ eprintln!(\"{{}}{{}} {{}}\", \
|
||||
\"warning\".yellow().bold(), \":\".bold(), \"`{}` has been renamed to \
|
||||
`{}`\".bold()); \n vec![{}] }}",
|
||||
prefix,
|
||||
target.as_ref(),
|
||||
codes
|
||||
.iter()
|
||||
.map(|code| format!("CheckCode::{}", code.as_ref()))
|
||||
.join(", ")
|
||||
));
|
||||
} else {
|
||||
gen = gen.line(format!(
|
||||
"CheckCodePrefix::{prefix} => vec![{}],",
|
||||
codes
|
||||
.iter()
|
||||
.map(|code| format!("CheckCode::{}", code.as_ref()))
|
||||
.join(", ")
|
||||
));
|
||||
}
|
||||
}
|
||||
gen.line("}");
|
||||
|
||||
@@ -123,6 +168,8 @@ pub fn main(cli: &Cli) -> Result<()> {
|
||||
.push_str("//! File automatically generated by `examples/generate_check_code_prefix.rs`.");
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
output.push_str("use colored::Colorize;");
|
||||
output.push('\n');
|
||||
output.push_str("use serde::{{Serialize, Deserialize}};");
|
||||
output.push('\n');
|
||||
output.push_str("use strum_macros::EnumString;");
|
||||
|
||||
@@ -28,11 +28,12 @@ pub fn main(cli: &Cli) -> Result<()> {
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
|
||||
if let Some(url) = check_category.url() {
|
||||
if let Some((url, platform)) = check_category.url() {
|
||||
output.push_str(&format!(
|
||||
"For more, see [{}]({}) on PyPI.",
|
||||
"For more, see [{}]({}) on {}.",
|
||||
check_category.title(),
|
||||
url
|
||||
url,
|
||||
platform
|
||||
));
|
||||
output.push('\n');
|
||||
output.push('\n');
|
||||
|
||||
@@ -61,15 +61,6 @@ pub fn dealias_call_path<'a>(
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `true` if the `Expr` is a name or attribute reference to `${target}`.
|
||||
pub fn match_name_or_attr(expr: &Expr, target: &str) -> bool {
|
||||
match &expr.node {
|
||||
ExprKind::Attribute { attr, .. } => target == attr,
|
||||
ExprKind::Name { id, .. } => target == id,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return `true` if the `Expr` is a reference to `${module}.${target}`.
|
||||
///
|
||||
/// Useful for, e.g., ensuring that a `Union` reference represents
|
||||
@@ -310,6 +301,16 @@ pub fn match_trailing_content(stmt: &Stmt, locator: &SourceCodeLocator) -> bool
|
||||
false
|
||||
}
|
||||
|
||||
/// Return the number of trailing empty lines following a statement.
|
||||
pub fn count_trailing_lines(stmt: &Stmt, locator: &SourceCodeLocator) -> usize {
|
||||
let suffix =
|
||||
locator.slice_source_code_at(&Location::new(stmt.end_location.unwrap().row() + 1, 0));
|
||||
suffix
|
||||
.lines()
|
||||
.take_while(|line| line.trim().is_empty())
|
||||
.count()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use anyhow::Result;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
use rustpython_ast::{Cmpop, Located};
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::lexer;
|
||||
use rustpython_parser::lexer::Tok;
|
||||
|
||||
use crate::ast::types::{BindingKind, Scope};
|
||||
|
||||
@@ -93,20 +96,164 @@ pub fn in_nested_block<'a>(parents: &mut impl Iterator<Item = &'a Stmt>) -> bool
|
||||
|
||||
/// Check if a node represents an unpacking assignment.
|
||||
pub fn is_unpacking_assignment(stmt: &Stmt) -> bool {
|
||||
if let StmtKind::Assign { targets, value, .. } = &stmt.node {
|
||||
if !targets.iter().any(|child| {
|
||||
matches!(
|
||||
child.node,
|
||||
ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. }
|
||||
)
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
match &value.node {
|
||||
ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. } => return false,
|
||||
_ => {}
|
||||
}
|
||||
return true;
|
||||
let StmtKind::Assign { targets, value, .. } = &stmt.node else {
|
||||
return false;
|
||||
};
|
||||
if !targets.iter().any(|child| {
|
||||
matches!(
|
||||
child.node,
|
||||
ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. }
|
||||
)
|
||||
}) {
|
||||
return false;
|
||||
}
|
||||
!matches!(
|
||||
&value.node,
|
||||
ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. }
|
||||
)
|
||||
}
|
||||
|
||||
pub type LocatedCmpop<U = ()> = Located<Cmpop, U>;
|
||||
|
||||
/// Extract all `Cmpop` operators from a source code snippet, with appropriate
|
||||
/// ranges.
|
||||
///
|
||||
/// `RustPython` doesn't include line and column information on `Cmpop` nodes.
|
||||
/// `CPython` doesn't either. This method iterates over the token stream and
|
||||
/// re-identifies `Cmpop` nodes, annotating them with valid ranges.
|
||||
pub fn locate_cmpops(contents: &str) -> Vec<LocatedCmpop> {
|
||||
let mut tok_iter = lexer::make_tokenizer(contents)
|
||||
.flatten()
|
||||
.into_iter()
|
||||
.peekable();
|
||||
let mut ops: Vec<LocatedCmpop> = vec![];
|
||||
let mut count: usize = 0;
|
||||
loop {
|
||||
let Some((start, tok, end)) = tok_iter.next() else {
|
||||
break;
|
||||
};
|
||||
if matches!(tok, Tok::Lpar) {
|
||||
count += 1;
|
||||
continue;
|
||||
} else if matches!(tok, Tok::Rpar) {
|
||||
count -= 1;
|
||||
continue;
|
||||
}
|
||||
if count == 0 {
|
||||
match tok {
|
||||
Tok::Not => {
|
||||
if let Some((_, _, end)) =
|
||||
tok_iter.next_if(|(_, tok, _)| matches!(tok, Tok::In))
|
||||
{
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::NotIn));
|
||||
}
|
||||
}
|
||||
Tok::In => {
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::In));
|
||||
}
|
||||
Tok::Is => {
|
||||
if let Some((_, _, end)) =
|
||||
tok_iter.next_if(|(_, tok, _)| matches!(tok, Tok::Not))
|
||||
{
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::IsNot));
|
||||
} else {
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::Is));
|
||||
}
|
||||
}
|
||||
Tok::NotEqual => {
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::NotEq));
|
||||
}
|
||||
Tok::EqEqual => {
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::Eq));
|
||||
}
|
||||
Tok::GreaterEqual => {
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::GtE));
|
||||
}
|
||||
Tok::Greater => {
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::Gt));
|
||||
}
|
||||
Tok::LessEqual => {
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::LtE));
|
||||
}
|
||||
Tok::Less => {
|
||||
ops.push(LocatedCmpop::new(start, end, Cmpop::Lt));
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
ops
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use rustpython_ast::{Cmpop, Location};
|
||||
|
||||
use crate::ast::operations::{locate_cmpops, LocatedCmpop};
|
||||
|
||||
#[test]
|
||||
fn locates_cmpops() {
|
||||
assert_eq!(
|
||||
locate_cmpops("x == 1"),
|
||||
vec![LocatedCmpop::new(
|
||||
Location::new(1, 2),
|
||||
Location::new(1, 4),
|
||||
Cmpop::Eq
|
||||
)]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
locate_cmpops("x != 1"),
|
||||
vec![LocatedCmpop::new(
|
||||
Location::new(1, 2),
|
||||
Location::new(1, 4),
|
||||
Cmpop::NotEq
|
||||
)]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
locate_cmpops("x is 1"),
|
||||
vec![LocatedCmpop::new(
|
||||
Location::new(1, 2),
|
||||
Location::new(1, 4),
|
||||
Cmpop::Is
|
||||
)]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
locate_cmpops("x is not 1"),
|
||||
vec![LocatedCmpop::new(
|
||||
Location::new(1, 2),
|
||||
Location::new(1, 8),
|
||||
Cmpop::IsNot
|
||||
)]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
locate_cmpops("x in 1"),
|
||||
vec![LocatedCmpop::new(
|
||||
Location::new(1, 2),
|
||||
Location::new(1, 4),
|
||||
Cmpop::In
|
||||
)]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
locate_cmpops("x not in 1"),
|
||||
vec![LocatedCmpop::new(
|
||||
Location::new(1, 2),
|
||||
Location::new(1, 8),
|
||||
Cmpop::NotIn
|
||||
)]
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
locate_cmpops("x != (1 is not 2)"),
|
||||
vec![LocatedCmpop::new(
|
||||
Location::new(1, 2),
|
||||
Location::new(1, 4),
|
||||
Cmpop::NotEq
|
||||
)]
|
||||
);
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
@@ -4,8 +4,6 @@ use rustpython_parser::ast::{
|
||||
PatternKind, Stmt, StmtKind, Unaryop, Withitem,
|
||||
};
|
||||
|
||||
use crate::ast::helpers::match_name_or_attr;
|
||||
|
||||
pub trait Visitor<'a> {
|
||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||
walk_stmt(self, stmt);
|
||||
@@ -150,11 +148,7 @@ pub fn walk_stmt<'a, V: Visitor<'a> + ?Sized>(visitor: &mut V, stmt: &'a Stmt) {
|
||||
} => {
|
||||
visitor.visit_annotation(annotation);
|
||||
if let Some(expr) = value {
|
||||
if match_name_or_attr(annotation, "TypeAlias") {
|
||||
visitor.visit_annotation(expr);
|
||||
} else {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
visitor.visit_expr(target);
|
||||
}
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
use std::str::Lines;
|
||||
|
||||
use rustpython_ast::{Located, Location};
|
||||
|
||||
use crate::ast::types::Range;
|
||||
@@ -37,3 +39,38 @@ pub fn clean(indentation: &str) -> String {
|
||||
.map(|char| if char.is_whitespace() { char } else { ' ' })
|
||||
.collect()
|
||||
}
|
||||
|
||||
/// Like `str#lines`, but includes a trailing newline as an empty line.
|
||||
pub struct LinesWithTrailingNewline<'a> {
|
||||
trailing: Option<&'a str>,
|
||||
underlying: Lines<'a>,
|
||||
}
|
||||
|
||||
impl<'a> LinesWithTrailingNewline<'a> {
|
||||
pub fn from(input: &'a str) -> LinesWithTrailingNewline<'a> {
|
||||
LinesWithTrailingNewline {
|
||||
underlying: input.lines(),
|
||||
trailing: if input.ends_with('\n') {
|
||||
Some("")
|
||||
} else {
|
||||
None
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Iterator for LinesWithTrailingNewline<'a> {
|
||||
type Item = &'a str;
|
||||
|
||||
#[inline]
|
||||
fn next(&mut self) -> Option<&'a str> {
|
||||
let mut next = self.underlying.next();
|
||||
if next.is_none() {
|
||||
if self.trailing.is_some() {
|
||||
next = self.trailing;
|
||||
self.trailing = None;
|
||||
}
|
||||
}
|
||||
next
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,7 +92,7 @@ fn apply_fixes<'a>(
|
||||
}
|
||||
|
||||
// Add the remaining content.
|
||||
let slice = locator.slice_source_code_at(last_pos);
|
||||
let slice = locator.slice_source_code_at(&last_pos);
|
||||
output.append(&slice);
|
||||
|
||||
(Cow::from(output.finish()), num_fixed)
|
||||
|
||||
317
src/check_ast.rs
317
src/check_ast.rs
@@ -36,12 +36,14 @@ 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_debugger,
|
||||
flake8_print, flake8_tidy_imports, mccabe, pep8_naming, pycodestyle, pydocstyle, pyflakes,
|
||||
pylint, pyupgrade, rules,
|
||||
flake8_print, flake8_return, flake8_tidy_imports, mccabe, pep8_naming, pycodestyle, pydocstyle,
|
||||
pyflakes, pygrep_hooks, pylint, pyupgrade,
|
||||
};
|
||||
|
||||
const GLOBAL_SCOPE_INDEX: usize = 0;
|
||||
|
||||
type DeferralContext = (Vec<usize>, Vec<usize>);
|
||||
|
||||
#[allow(clippy::struct_excessive_bools)]
|
||||
pub struct Checker<'a> {
|
||||
// Input data.
|
||||
@@ -66,17 +68,18 @@ pub struct Checker<'a> {
|
||||
scopes: Vec<Scope<'a>>,
|
||||
scope_stack: Vec<usize>,
|
||||
dead_scopes: Vec<usize>,
|
||||
deferred_string_annotations: Vec<(Range, &'a str, Vec<usize>, Vec<usize>)>,
|
||||
deferred_annotations: Vec<(&'a Expr, Vec<usize>, Vec<usize>)>,
|
||||
deferred_functions: Vec<(&'a Stmt, Vec<usize>, Vec<usize>, VisibleScope)>,
|
||||
deferred_lambdas: Vec<(&'a Expr, Vec<usize>, Vec<usize>)>,
|
||||
deferred_string_type_definitions: Vec<(Range, &'a str, bool, DeferralContext)>,
|
||||
deferred_type_definitions: Vec<(&'a Expr, bool, DeferralContext)>,
|
||||
deferred_functions: Vec<(&'a Stmt, DeferralContext, VisibleScope)>,
|
||||
deferred_lambdas: Vec<(&'a Expr, DeferralContext)>,
|
||||
deferred_assignments: Vec<usize>,
|
||||
// Internal, derivative state.
|
||||
visible_scope: VisibleScope,
|
||||
in_f_string: Option<Range>,
|
||||
in_annotation: bool,
|
||||
in_deferred_string_annotation: bool,
|
||||
in_deferred_annotation: bool,
|
||||
in_type_definition: bool,
|
||||
in_deferred_string_type_definition: bool,
|
||||
in_deferred_type_definition: bool,
|
||||
in_literal: bool,
|
||||
in_subscript: bool,
|
||||
in_withitem: bool,
|
||||
@@ -110,8 +113,8 @@ impl<'a> Checker<'a> {
|
||||
scopes: vec![],
|
||||
scope_stack: vec![],
|
||||
dead_scopes: vec![],
|
||||
deferred_string_annotations: vec![],
|
||||
deferred_annotations: vec![],
|
||||
deferred_string_type_definitions: vec![],
|
||||
deferred_type_definitions: vec![],
|
||||
deferred_functions: vec![],
|
||||
deferred_lambdas: vec![],
|
||||
deferred_assignments: vec![],
|
||||
@@ -122,8 +125,9 @@ impl<'a> Checker<'a> {
|
||||
},
|
||||
in_f_string: None,
|
||||
in_annotation: false,
|
||||
in_deferred_string_annotation: false,
|
||||
in_deferred_annotation: false,
|
||||
in_type_definition: false,
|
||||
in_deferred_string_type_definition: false,
|
||||
in_deferred_type_definition: false,
|
||||
in_literal: false,
|
||||
in_subscript: false,
|
||||
in_withitem: false,
|
||||
@@ -408,7 +412,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::U011)
|
||||
if self.settings.enabled.contains(&CheckCode::UP011)
|
||||
&& self.settings.target_version >= PythonVersion::Py38
|
||||
{
|
||||
pyupgrade::plugins::unnecessary_lru_cache_params(self, decorator_list);
|
||||
@@ -417,9 +421,23 @@ where
|
||||
if self.settings.enabled.contains(&CheckCode::B018) {
|
||||
flake8_bugbear::plugins::useless_expression(self, body);
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::B019) {
|
||||
flake8_bugbear::plugins::cached_instance_method(self, decorator_list);
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::RET501)
|
||||
|| self.settings.enabled.contains(&CheckCode::RET502)
|
||||
|| self.settings.enabled.contains(&CheckCode::RET503)
|
||||
|| self.settings.enabled.contains(&CheckCode::RET504)
|
||||
|| self.settings.enabled.contains(&CheckCode::RET505)
|
||||
|| self.settings.enabled.contains(&CheckCode::RET506)
|
||||
|| self.settings.enabled.contains(&CheckCode::RET507)
|
||||
|| self.settings.enabled.contains(&CheckCode::RET508)
|
||||
{
|
||||
flake8_return::plugins::function(self, body);
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::C901) {
|
||||
if let Some(check) = mccabe::checks::function_is_too_complex(
|
||||
stmt,
|
||||
@@ -437,6 +455,10 @@ where
|
||||
);
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::PLR0206) {
|
||||
pylint::plugins::property_with_parameters(self, stmt, decorator_list, args);
|
||||
}
|
||||
|
||||
self.check_builtin_shadowing(name, Range::from_located(stmt), true);
|
||||
|
||||
// Visit the decorators and arguments, but avoid the body, which will be
|
||||
@@ -509,7 +531,7 @@ where
|
||||
decorator_list,
|
||||
body,
|
||||
} => {
|
||||
if self.settings.enabled.contains(&CheckCode::U004) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP004) {
|
||||
pyupgrade::plugins::useless_object_inheritance(
|
||||
self, stmt, name, bases, keywords,
|
||||
);
|
||||
@@ -646,6 +668,14 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// pylint
|
||||
if self.settings.enabled.contains(&CheckCode::PLC0414) {
|
||||
pylint::plugins::useless_import_alias(self, alias);
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::PLR0402) {
|
||||
pylint::plugins::consider_using_from_import(self, alias);
|
||||
}
|
||||
|
||||
if let Some(asname) = &alias.node.asname {
|
||||
for alias in names {
|
||||
if let Some(asname) = &alias.node.asname {
|
||||
@@ -733,7 +763,7 @@ where
|
||||
}
|
||||
|
||||
if let Some("__future__") = module.as_deref() {
|
||||
if self.settings.enabled.contains(&CheckCode::U010) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP010) {
|
||||
pyupgrade::plugins::unnecessary_future_import(self, stmt, names);
|
||||
}
|
||||
}
|
||||
@@ -938,6 +968,11 @@ where
|
||||
self.add_check(check);
|
||||
}
|
||||
}
|
||||
|
||||
// pylint
|
||||
if self.settings.enabled.contains(&CheckCode::PLC0414) {
|
||||
pylint::plugins::useless_import_alias(self, alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -982,16 +1017,27 @@ where
|
||||
flake8_bugbear::plugins::assert_raises_exception(self, stmt, items);
|
||||
}
|
||||
}
|
||||
StmtKind::While { .. } => {
|
||||
StmtKind::While { body, orelse, .. } => {
|
||||
if self.settings.enabled.contains(&CheckCode::B023) {
|
||||
flake8_bugbear::plugins::function_uses_loop_variable(self, &Node::Stmt(stmt));
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::PLW0120) {
|
||||
pylint::plugins::useless_else_on_loop(self, stmt, body, orelse);
|
||||
}
|
||||
}
|
||||
StmtKind::For {
|
||||
target, body, iter, ..
|
||||
target,
|
||||
body,
|
||||
iter,
|
||||
orelse,
|
||||
..
|
||||
}
|
||||
| StmtKind::AsyncFor {
|
||||
target, body, iter, ..
|
||||
target,
|
||||
body,
|
||||
iter,
|
||||
orelse,
|
||||
..
|
||||
} => {
|
||||
if self.settings.enabled.contains(&CheckCode::B007) {
|
||||
flake8_bugbear::plugins::unused_loop_control_variable(self, target, body);
|
||||
@@ -1002,6 +1048,9 @@ where
|
||||
if self.settings.enabled.contains(&CheckCode::B023) {
|
||||
flake8_bugbear::plugins::function_uses_loop_variable(self, &Node::Stmt(stmt));
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::PLW0120) {
|
||||
pylint::plugins::useless_else_on_loop(self, stmt, body, orelse);
|
||||
}
|
||||
}
|
||||
StmtKind::Try { handlers, .. } => {
|
||||
if self.settings.enabled.contains(&CheckCode::F707) {
|
||||
@@ -1027,7 +1076,7 @@ where
|
||||
pycodestyle::plugins::do_not_assign_lambda(self, target, value, stmt);
|
||||
}
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::U001) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP001) {
|
||||
pyupgrade::plugins::useless_metaclass_type(self, stmt, value, targets);
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::B003) {
|
||||
@@ -1040,12 +1089,12 @@ where
|
||||
self.add_check(check);
|
||||
}
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::U013) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP013) {
|
||||
pyupgrade::plugins::convert_typed_dict_functional_to_class(
|
||||
self, stmt, targets, value,
|
||||
);
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::U014) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP014) {
|
||||
pyupgrade::plugins::convert_named_tuple_functional_to_class(
|
||||
self, stmt, targets, value,
|
||||
);
|
||||
@@ -1087,8 +1136,7 @@ where
|
||||
|
||||
self.deferred_functions.push((
|
||||
stmt,
|
||||
self.scope_stack.clone(),
|
||||
self.parent_stack.clone(),
|
||||
(self.scope_stack.clone(), self.parent_stack.clone()),
|
||||
self.visible_scope.clone(),
|
||||
));
|
||||
}
|
||||
@@ -1135,6 +1183,24 @@ where
|
||||
self.visit_stmt(stmt);
|
||||
}
|
||||
}
|
||||
StmtKind::AnnAssign {
|
||||
target,
|
||||
annotation,
|
||||
value,
|
||||
..
|
||||
} => {
|
||||
self.visit_annotation(annotation);
|
||||
if let Some(expr) = value {
|
||||
if self.match_typing_expr(annotation, "TypeAlias") {
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(expr);
|
||||
self.in_type_definition = false;
|
||||
} else {
|
||||
self.visit_expr(expr);
|
||||
}
|
||||
}
|
||||
self.visit_expr(target);
|
||||
}
|
||||
_ => visitor::walk_stmt(self, stmt),
|
||||
};
|
||||
self.visible_scope = prev_visible_scope;
|
||||
@@ -1157,33 +1223,39 @@ where
|
||||
|
||||
fn visit_annotation(&mut self, expr: &'b Expr) {
|
||||
let prev_in_annotation = self.in_annotation;
|
||||
let prev_in_type_definition = self.in_type_definition;
|
||||
self.in_annotation = true;
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(expr);
|
||||
self.in_annotation = prev_in_annotation;
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'b Expr) {
|
||||
let prev_in_f_string = self.in_f_string;
|
||||
let prev_in_literal = self.in_literal;
|
||||
let prev_in_annotation = self.in_annotation;
|
||||
let prev_in_type_definition = self.in_type_definition;
|
||||
|
||||
if self.in_annotation && self.annotations_future_enabled {
|
||||
if !(self.in_deferred_type_definition || self.in_deferred_string_type_definition)
|
||||
&& self.in_type_definition
|
||||
&& self.annotations_future_enabled
|
||||
{
|
||||
if let ExprKind::Constant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} = &expr.node
|
||||
{
|
||||
self.deferred_string_annotations.push((
|
||||
self.deferred_string_type_definitions.push((
|
||||
Range::from_located(expr),
|
||||
value,
|
||||
self.scope_stack.clone(),
|
||||
self.parent_stack.clone(),
|
||||
self.in_annotation,
|
||||
(self.scope_stack.clone(), self.parent_stack.clone()),
|
||||
));
|
||||
} else {
|
||||
self.deferred_annotations.push((
|
||||
self.deferred_type_definitions.push((
|
||||
expr,
|
||||
self.scope_stack.clone(),
|
||||
self.parent_stack.clone(),
|
||||
self.in_annotation,
|
||||
(self.scope_stack.clone(), self.parent_stack.clone()),
|
||||
));
|
||||
}
|
||||
return;
|
||||
@@ -1193,13 +1265,13 @@ where
|
||||
match &expr.node {
|
||||
ExprKind::Subscript { value, slice, .. } => {
|
||||
// Ex) Optional[...]
|
||||
if !self.in_deferred_string_annotation
|
||||
&& self.settings.enabled.contains(&CheckCode::U007)
|
||||
if !self.in_deferred_string_type_definition
|
||||
&& self.settings.enabled.contains(&CheckCode::UP007)
|
||||
&& (self.settings.target_version >= PythonVersion::Py310
|
||||
|| (self.settings.target_version >= PythonVersion::Py37
|
||||
&& !self.settings.pyupgrade.keep_runtime_typing
|
||||
&& self.annotations_future_enabled
|
||||
&& self.in_deferred_annotation))
|
||||
&& self.in_annotation))
|
||||
{
|
||||
pyupgrade::plugins::use_pep604_annotation(self, expr, value, slice);
|
||||
}
|
||||
@@ -1236,13 +1308,13 @@ where
|
||||
match ctx {
|
||||
ExprContext::Load => {
|
||||
// Ex) List[...]
|
||||
if !self.in_deferred_string_annotation
|
||||
&& self.settings.enabled.contains(&CheckCode::U006)
|
||||
if !self.in_deferred_string_type_definition
|
||||
&& self.settings.enabled.contains(&CheckCode::UP006)
|
||||
&& (self.settings.target_version >= PythonVersion::Py39
|
||||
|| (self.settings.target_version >= PythonVersion::Py37
|
||||
&& !self.settings.pyupgrade.keep_runtime_typing
|
||||
&& self.annotations_future_enabled
|
||||
&& self.in_deferred_annotation))
|
||||
&& self.in_annotation))
|
||||
&& typing::is_pep585_builtin(
|
||||
expr,
|
||||
&self.from_imports,
|
||||
@@ -1277,12 +1349,12 @@ where
|
||||
}
|
||||
ExprKind::Attribute { attr, .. } => {
|
||||
// Ex) typing.List[...]
|
||||
if !self.in_deferred_string_annotation
|
||||
&& self.settings.enabled.contains(&CheckCode::U006)
|
||||
if !self.in_deferred_string_type_definition
|
||||
&& self.settings.enabled.contains(&CheckCode::UP006)
|
||||
&& (self.settings.target_version >= PythonVersion::Py39
|
||||
|| (self.settings.target_version >= PythonVersion::Py37
|
||||
&& self.annotations_future_enabled
|
||||
&& self.in_deferred_annotation))
|
||||
&& self.in_annotation))
|
||||
&& typing::is_pep585_builtin(expr, &self.from_imports, &self.import_aliases)
|
||||
{
|
||||
pyupgrade::plugins::use_pep585_annotation(self, expr, attr);
|
||||
@@ -1372,16 +1444,16 @@ where
|
||||
}
|
||||
|
||||
// pyupgrade
|
||||
if self.settings.enabled.contains(&CheckCode::U005) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP005) {
|
||||
pyupgrade::plugins::deprecated_unittest_alias(self, func);
|
||||
}
|
||||
|
||||
// flake8-super
|
||||
if self.settings.enabled.contains(&CheckCode::U008) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP008) {
|
||||
pyupgrade::plugins::super_call_with_parameters(self, expr, func, args);
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::U012) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP012) {
|
||||
pyupgrade::plugins::unnecessary_encode_utf8(self, expr, func, args, keywords);
|
||||
}
|
||||
|
||||
@@ -1640,11 +1712,11 @@ where
|
||||
}
|
||||
|
||||
// pyupgrade
|
||||
if self.settings.enabled.contains(&CheckCode::U003) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP003) {
|
||||
pyupgrade::plugins::type_of_primitive(self, expr, func, args);
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::U015) {
|
||||
if self.settings.enabled.contains(&CheckCode::UP015) {
|
||||
pyupgrade::plugins::redundant_open_modes(self, expr);
|
||||
}
|
||||
|
||||
@@ -1676,9 +1748,17 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
// Ruff
|
||||
if self.settings.enabled.contains(&CheckCode::RUF101) {
|
||||
rules::plugins::convert_exit_to_sys_exit(self, func);
|
||||
// pygrep-hooks
|
||||
if self.settings.enabled.contains(&CheckCode::PGH001) {
|
||||
pygrep_hooks::checks::no_eval(self, func);
|
||||
}
|
||||
|
||||
// pylint
|
||||
if self.settings.enabled.contains(&CheckCode::PLC3002) {
|
||||
pylint::plugins::unnecessary_direct_lambda_call(self, expr, func);
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::PLR1722) {
|
||||
pylint::plugins::consider_using_sys_exit(self, func);
|
||||
}
|
||||
}
|
||||
ExprKind::Dict { keys, .. } => {
|
||||
@@ -1941,17 +2021,27 @@ where
|
||||
.into_iter(),
|
||||
);
|
||||
}
|
||||
|
||||
if self.settings.enabled.contains(&CheckCode::PLC2201) {
|
||||
pylint::plugins::misplaced_comparison_constant(
|
||||
self,
|
||||
expr,
|
||||
left,
|
||||
ops,
|
||||
comparators,
|
||||
);
|
||||
}
|
||||
}
|
||||
ExprKind::Constant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} => {
|
||||
if self.in_annotation && !self.in_literal {
|
||||
self.deferred_string_annotations.push((
|
||||
if self.in_type_definition && !self.in_literal {
|
||||
self.deferred_string_type_definitions.push((
|
||||
Range::from_located(expr),
|
||||
value,
|
||||
self.scope_stack.clone(),
|
||||
self.parent_stack.clone(),
|
||||
self.in_annotation,
|
||||
(self.scope_stack.clone(), self.parent_stack.clone()),
|
||||
));
|
||||
}
|
||||
if self.settings.enabled.contains(&CheckCode::S104) {
|
||||
@@ -2022,17 +2112,19 @@ where
|
||||
}
|
||||
self.push_scope(Scope::new(ScopeKind::Generator));
|
||||
}
|
||||
ExprKind::BoolOp { op, values } => {
|
||||
if self.settings.enabled.contains(&CheckCode::PLR1701) {
|
||||
pylint::plugins::consider_merging_isinstance(self, expr, op, values);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
// Recurse.
|
||||
match &expr.node {
|
||||
ExprKind::Lambda { .. } => {
|
||||
self.deferred_lambdas.push((
|
||||
expr,
|
||||
self.scope_stack.clone(),
|
||||
self.parent_stack.clone(),
|
||||
));
|
||||
self.deferred_lambdas
|
||||
.push((expr, (self.scope_stack.clone(), self.parent_stack.clone())));
|
||||
}
|
||||
ExprKind::Call {
|
||||
func,
|
||||
@@ -2043,12 +2135,16 @@ where
|
||||
if self.match_typing_call_path(&call_path, "ForwardRef") {
|
||||
self.visit_expr(func);
|
||||
for expr in args {
|
||||
self.visit_annotation(expr);
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(expr);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
} else if self.match_typing_call_path(&call_path, "cast") {
|
||||
self.visit_expr(func);
|
||||
if !args.is_empty() {
|
||||
self.visit_annotation(&args[0]);
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(&args[0]);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
for expr in args.iter().skip(1) {
|
||||
self.visit_expr(expr);
|
||||
@@ -2056,22 +2152,28 @@ where
|
||||
} else if self.match_typing_call_path(&call_path, "NewType") {
|
||||
self.visit_expr(func);
|
||||
for expr in args.iter().skip(1) {
|
||||
self.visit_annotation(expr);
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(expr);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
} else if self.match_typing_call_path(&call_path, "TypeVar") {
|
||||
self.visit_expr(func);
|
||||
for expr in args.iter().skip(1) {
|
||||
self.visit_annotation(expr);
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(expr);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
for keyword in keywords {
|
||||
let KeywordData { arg, value } = &keyword.node;
|
||||
if let Some(id) = arg {
|
||||
if id == "bound" {
|
||||
self.visit_annotation(value);
|
||||
} else {
|
||||
self.in_annotation = false;
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(value);
|
||||
self.in_annotation = prev_in_annotation;
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
} else {
|
||||
self.in_type_definition = false;
|
||||
self.visit_expr(value);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2087,11 +2189,13 @@ where
|
||||
ExprKind::List { elts, .. }
|
||||
| ExprKind::Tuple { elts, .. } => {
|
||||
if elts.len() == 2 {
|
||||
self.in_annotation = false;
|
||||
self.in_type_definition = false;
|
||||
self.visit_expr(&elts[0]);
|
||||
self.in_annotation = prev_in_annotation;
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
|
||||
self.visit_annotation(&elts[1]);
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(&elts[1]);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
@@ -2105,7 +2209,9 @@ where
|
||||
// Ex) NamedTuple("a", a=int)
|
||||
for keyword in keywords {
|
||||
let KeywordData { value, .. } = &keyword.node;
|
||||
self.visit_annotation(value);
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(value);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
} else if self.match_typing_call_path(&call_path, "TypedDict") {
|
||||
self.visit_expr(func);
|
||||
@@ -2114,12 +2220,14 @@ where
|
||||
if args.len() > 1 {
|
||||
if let ExprKind::Dict { keys, values } = &args[1].node {
|
||||
for key in keys {
|
||||
self.in_annotation = false;
|
||||
self.in_type_definition = false;
|
||||
self.visit_expr(key);
|
||||
self.in_annotation = prev_in_annotation;
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
for value in values {
|
||||
self.visit_annotation(value);
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(value);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2127,7 +2235,9 @@ where
|
||||
// Ex) TypedDict("a", a=int)
|
||||
for keyword in keywords {
|
||||
let KeywordData { value, .. } = &keyword.node;
|
||||
self.visit_annotation(value);
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(value);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
}
|
||||
} else {
|
||||
visitor::walk_expr(self, expr);
|
||||
@@ -2157,7 +2267,9 @@ where
|
||||
// Ex) Optional[int]
|
||||
SubscriptKind::AnnotatedSubscript => {
|
||||
self.visit_expr(value);
|
||||
self.visit_annotation(slice);
|
||||
self.in_type_definition = true;
|
||||
self.visit_expr(slice);
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
self.visit_expr_context(ctx);
|
||||
}
|
||||
// Ex) Annotated[int, "Hello, world!"]
|
||||
@@ -2169,11 +2281,11 @@ where
|
||||
if let ExprKind::Tuple { elts, ctx } = &slice.node {
|
||||
if let Some(expr) = elts.first() {
|
||||
self.visit_expr(expr);
|
||||
self.in_annotation = false;
|
||||
self.in_type_definition = false;
|
||||
for expr in elts.iter().skip(1) {
|
||||
self.visit_expr(expr);
|
||||
}
|
||||
self.in_annotation = true;
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
self.visit_expr_context(ctx);
|
||||
}
|
||||
} else {
|
||||
@@ -2205,7 +2317,7 @@ where
|
||||
_ => {}
|
||||
};
|
||||
|
||||
self.in_annotation = prev_in_annotation;
|
||||
self.in_type_definition = prev_in_type_definition;
|
||||
self.in_literal = prev_in_literal;
|
||||
self.in_f_string = prev_in_f_string;
|
||||
}
|
||||
@@ -2777,28 +2889,33 @@ impl<'a> Checker<'a> {
|
||||
docstring.is_some()
|
||||
}
|
||||
|
||||
fn check_deferred_annotations(&mut self) {
|
||||
while let Some((expr, scopes, parents)) = self.deferred_annotations.pop() {
|
||||
fn check_deferred_type_definitions(&mut self) {
|
||||
while let Some((expr, in_annotation, (scopes, parents))) =
|
||||
self.deferred_type_definitions.pop()
|
||||
{
|
||||
self.scope_stack = scopes;
|
||||
self.parent_stack = parents;
|
||||
self.in_deferred_annotation = true;
|
||||
self.in_annotation = in_annotation;
|
||||
self.in_type_definition = true;
|
||||
self.in_deferred_type_definition = true;
|
||||
self.visit_expr(expr);
|
||||
self.in_deferred_annotation = false;
|
||||
self.in_deferred_type_definition = false;
|
||||
self.in_type_definition = false;
|
||||
}
|
||||
}
|
||||
|
||||
fn check_deferred_string_annotations<'b>(&mut self, allocator: &'b mut Vec<Expr>)
|
||||
fn check_deferred_string_type_definitions<'b>(&mut self, allocator: &'b mut Vec<Expr>)
|
||||
where
|
||||
'b: 'a,
|
||||
{
|
||||
let mut stacks = vec![];
|
||||
while let Some((range, expression, scopes, parents)) =
|
||||
self.deferred_string_annotations.pop()
|
||||
while let Some((range, expression, in_annotation, context)) =
|
||||
self.deferred_string_type_definitions.pop()
|
||||
{
|
||||
if let Ok(mut expr) = parser::parse_expression(expression, "<filename>") {
|
||||
relocate_expr(&mut expr, range);
|
||||
allocator.push(expr);
|
||||
stacks.push((scopes, parents));
|
||||
stacks.push((in_annotation, context));
|
||||
} else {
|
||||
if self.settings.enabled.contains(&CheckCode::F722) {
|
||||
self.add_check(Check::new(
|
||||
@@ -2808,19 +2925,22 @@ impl<'a> Checker<'a> {
|
||||
}
|
||||
}
|
||||
}
|
||||
for (expr, (scopes, parents)) in allocator.iter().zip(stacks) {
|
||||
for (expr, (in_annotation, (scopes, parents))) in allocator.iter().zip(stacks) {
|
||||
self.scope_stack = scopes;
|
||||
self.parent_stack = parents;
|
||||
self.in_deferred_string_annotation = true;
|
||||
self.in_annotation = in_annotation;
|
||||
self.in_type_definition = true;
|
||||
self.in_deferred_string_type_definition = true;
|
||||
self.visit_expr(expr);
|
||||
self.in_deferred_string_annotation = false;
|
||||
self.in_deferred_string_type_definition = false;
|
||||
self.in_type_definition = false;
|
||||
}
|
||||
}
|
||||
|
||||
fn check_deferred_functions(&mut self) {
|
||||
while let Some((stmt, scopes, parents, visibility)) = self.deferred_functions.pop() {
|
||||
self.parent_stack = parents;
|
||||
while let Some((stmt, (scopes, parents), visibility)) = self.deferred_functions.pop() {
|
||||
self.scope_stack = scopes;
|
||||
self.parent_stack = parents;
|
||||
self.visible_scope = visibility;
|
||||
self.push_scope(Scope::new(ScopeKind::Function(FunctionScope {
|
||||
async_: matches!(stmt.node, StmtKind::AsyncFunctionDef { .. }),
|
||||
@@ -2846,9 +2966,9 @@ impl<'a> Checker<'a> {
|
||||
}
|
||||
|
||||
fn check_deferred_lambdas(&mut self) {
|
||||
while let Some((expr, scopes, parents)) = self.deferred_lambdas.pop() {
|
||||
self.parent_stack = parents;
|
||||
while let Some((expr, (scopes, parents))) = self.deferred_lambdas.pop() {
|
||||
self.scope_stack = scopes;
|
||||
self.parent_stack = parents;
|
||||
self.push_scope(Scope::new(ScopeKind::Lambda));
|
||||
|
||||
if let ExprKind::Lambda { args, body } = &expr.node {
|
||||
@@ -2975,8 +3095,9 @@ impl<'a> Checker<'a> {
|
||||
let child = self.parents[defined_by];
|
||||
let parent = defined_in.map(|defined_in| self.parents[defined_in]);
|
||||
|
||||
let in_init_py = self.path.ends_with("__init__.py");
|
||||
let fix = if !in_init_py && self.patch(&CheckCode::F401) {
|
||||
let ignore_init = self.settings.ignore_init_module_imports
|
||||
&& self.path.ends_with("__init__.py");
|
||||
let fix = if !ignore_init && self.patch(&CheckCode::F401) {
|
||||
let deleted: Vec<&Stmt> = self
|
||||
.deletions
|
||||
.iter()
|
||||
@@ -2996,7 +3117,7 @@ impl<'a> Checker<'a> {
|
||||
Some(fix)
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to remove unused imports: {}", e);
|
||||
error!("Failed to remove unused imports: {e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -3006,7 +3127,7 @@ impl<'a> Checker<'a> {
|
||||
|
||||
for (full_name, range) in unused_imports {
|
||||
let mut check = Check::new(
|
||||
CheckKind::UnusedImport(full_name.clone(), in_init_py),
|
||||
CheckKind::UnusedImport(full_name.clone(), ignore_init),
|
||||
*range,
|
||||
);
|
||||
if let Some(fix) = fix.as_ref() {
|
||||
@@ -3185,9 +3306,9 @@ pub fn check_ast(
|
||||
checker.check_deferred_functions();
|
||||
checker.check_deferred_lambdas();
|
||||
checker.check_deferred_assignments();
|
||||
checker.check_deferred_annotations();
|
||||
checker.check_deferred_type_definitions();
|
||||
let mut allocator = vec![];
|
||||
checker.check_deferred_string_annotations(&mut allocator);
|
||||
checker.check_deferred_string_type_definitions(&mut allocator);
|
||||
|
||||
// Reset the scope to module-level, and check all consumed scopes.
|
||||
checker.scope_stack = vec![GLOBAL_SCOPE_INDEX];
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
//! Lint rules based on import analysis.
|
||||
|
||||
use nohash_hasher::IntSet;
|
||||
use rustpython_parser::ast::Suite;
|
||||
|
||||
use crate::ast::visitor::Visitor;
|
||||
use crate::checks::Check;
|
||||
use crate::directives::IsortDirectives;
|
||||
use crate::isort;
|
||||
use crate::isort::track::ImportTracker;
|
||||
use crate::settings::Settings;
|
||||
@@ -18,7 +18,7 @@ fn check_import_blocks(
|
||||
) -> Vec<Check> {
|
||||
let mut checks = vec![];
|
||||
for block in tracker.into_iter() {
|
||||
if !block.is_empty() {
|
||||
if !block.imports.is_empty() {
|
||||
if let Some(check) = isort::plugins::check_imports(&block, locator, settings, autofix) {
|
||||
checks.push(check);
|
||||
}
|
||||
@@ -30,11 +30,11 @@ fn check_import_blocks(
|
||||
pub fn check_imports(
|
||||
python_ast: &Suite,
|
||||
locator: &SourceCodeLocator,
|
||||
exclusions: &IntSet<usize>,
|
||||
directives: &IsortDirectives,
|
||||
settings: &Settings,
|
||||
autofix: bool,
|
||||
) -> Vec<Check> {
|
||||
let mut tracker = ImportTracker::new(exclusions);
|
||||
let mut tracker = ImportTracker::new(directives);
|
||||
for stmt in python_ast {
|
||||
tracker.visit_stmt(stmt);
|
||||
}
|
||||
|
||||
@@ -7,12 +7,12 @@ use rustpython_parser::ast::Location;
|
||||
|
||||
use crate::ast::types::Range;
|
||||
use crate::autofix::Fix;
|
||||
use crate::checks::{Check, CheckCode, CheckKind};
|
||||
use crate::checks::{Check, CheckCode, CheckKind, REDIRECTS};
|
||||
use crate::noqa;
|
||||
use crate::noqa::Directive;
|
||||
use crate::noqa::{is_file_exempt, Directive};
|
||||
use crate::settings::Settings;
|
||||
|
||||
// Regex from PEP263
|
||||
// Regex from PEP263.
|
||||
static CODING_COMMENT_REGEX: Lazy<Regex> =
|
||||
Lazy::new(|| Regex::new(r"^[ \t\f]*#.*?coding[:=][ \t]*utf-?8").unwrap());
|
||||
|
||||
@@ -43,9 +43,9 @@ pub fn check_lines(
|
||||
autofix: bool,
|
||||
ignore_noqa: bool,
|
||||
) {
|
||||
let enforce_unnecessary_coding_comment = settings.enabled.contains(&CheckCode::U009);
|
||||
let enforce_unnecessary_coding_comment = settings.enabled.contains(&CheckCode::UP009);
|
||||
let enforce_line_too_long = settings.enabled.contains(&CheckCode::E501);
|
||||
let enforce_noqa = settings.enabled.contains(&CheckCode::M001);
|
||||
let enforce_noqa = settings.enabled.contains(&CheckCode::RUF100);
|
||||
|
||||
let mut noqa_directives: IntMap<usize, (Directive, Vec<&str>)> = IntMap::default();
|
||||
let mut line_checks = vec![];
|
||||
@@ -58,8 +58,11 @@ pub fn check_lines(
|
||||
}
|
||||
|
||||
macro_rules! add_if {
|
||||
($check:expr, $noqa:expr) => {{
|
||||
match $noqa {
|
||||
($check:expr, $noqa_lineno:expr, $line:expr) => {{
|
||||
match noqa_directives
|
||||
.entry($noqa_lineno)
|
||||
.or_insert_with(|| (noqa::extract_noqa_directive($line), vec![]))
|
||||
{
|
||||
(Directive::All(..), matches) => {
|
||||
matches.push($check.kind.code().as_ref());
|
||||
if ignore_noqa {
|
||||
@@ -67,7 +70,7 @@ pub fn check_lines(
|
||||
}
|
||||
}
|
||||
(Directive::Codes(.., codes), matches) => {
|
||||
if codes.contains(&$check.kind.code().as_ref()) {
|
||||
if noqa::includes($check.kind.code(), codes) {
|
||||
matches.push($check.kind.code().as_ref());
|
||||
if ignore_noqa {
|
||||
line_checks.push($check);
|
||||
@@ -83,12 +86,18 @@ pub fn check_lines(
|
||||
|
||||
let lines: Vec<&str> = contents.lines().collect();
|
||||
for (lineno, line) in lines.iter().enumerate() {
|
||||
// If we hit an exemption for the entire file, bail.
|
||||
if is_file_exempt(line) {
|
||||
checks.drain(..);
|
||||
return;
|
||||
}
|
||||
|
||||
// Grab the noqa (logical) line number for the current (physical) line.
|
||||
// If there are newlines at the end of the file, they won't be represented in
|
||||
// `noqa_line_for`, so fallback to the current line.
|
||||
let noqa_lineno = noqa_line_for.get(&(lineno + 1)).unwrap_or(&(lineno + 1)) - 1;
|
||||
|
||||
// Enforce unnecessary coding comments (U009).
|
||||
// Enforce unnecessary coding comments (UP009).
|
||||
if enforce_unnecessary_coding_comment {
|
||||
if lineno < 2 {
|
||||
// PEP3120 makes utf-8 the default encoding.
|
||||
@@ -106,11 +115,7 @@ pub fn check_lines(
|
||||
Location::new(lineno + 2, 0),
|
||||
));
|
||||
}
|
||||
|
||||
let noqa = noqa_directives.entry(noqa_lineno).or_insert_with(|| {
|
||||
(noqa::extract_noqa_directive(lines[noqa_lineno]), vec![])
|
||||
});
|
||||
add_if!(check, noqa);
|
||||
add_if!(check, noqa_lineno, lines[noqa_lineno]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -135,7 +140,7 @@ pub fn check_lines(
|
||||
ignored.push(index);
|
||||
}
|
||||
(Directive::Codes(.., codes), matches) => {
|
||||
if codes.contains(&check.kind.code().as_ref()) {
|
||||
if noqa::includes(check.kind.code(), codes) {
|
||||
matches.push(check.kind.code().as_ref());
|
||||
ignored.push(index);
|
||||
}
|
||||
@@ -155,11 +160,7 @@ pub fn check_lines(
|
||||
end_location: Location::new(lineno + 1, line_length),
|
||||
},
|
||||
);
|
||||
|
||||
let noqa = noqa_directives
|
||||
.entry(noqa_lineno)
|
||||
.or_insert_with(|| (noqa::extract_noqa_directive(lines[noqa_lineno]), vec![]));
|
||||
add_if!(check, noqa);
|
||||
add_if!(check, noqa_lineno, lines[noqa_lineno]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -179,14 +180,11 @@ pub fn check_lines(
|
||||
|
||||
let lineno = lines.len() - 1;
|
||||
let noqa_lineno = noqa_line_for.get(&(lineno + 1)).unwrap_or(&(lineno + 1)) - 1;
|
||||
let noqa = noqa_directives
|
||||
.entry(noqa_lineno)
|
||||
.or_insert_with(|| (noqa::extract_noqa_directive(lines[noqa_lineno]), vec![]));
|
||||
add_if!(check, noqa);
|
||||
add_if!(check, noqa_lineno, lines[noqa_lineno]);
|
||||
}
|
||||
}
|
||||
|
||||
// Enforce that the noqa directive was actually used (M001).
|
||||
// Enforce that the noqa directive was actually used (RUF100).
|
||||
if enforce_noqa {
|
||||
for (row, (directive, matches)) in noqa_directives {
|
||||
match directive {
|
||||
@@ -212,6 +210,7 @@ pub fn check_lines(
|
||||
let mut invalid_codes = vec![];
|
||||
let mut valid_codes = vec![];
|
||||
for code in codes {
|
||||
let code = REDIRECTS.get(code).map_or(code, AsRef::as_ref);
|
||||
if matches.contains(&code) || settings.external.contains(code) {
|
||||
valid_codes.push(code.to_string());
|
||||
} else {
|
||||
@@ -269,13 +268,12 @@ mod tests {
|
||||
#[test]
|
||||
fn e501_non_ascii_char() {
|
||||
let line = "'\u{4e9c}' * 2"; // 7 in UTF-32, 9 in UTF-8.
|
||||
let noqa_line_for: IntMap<usize, usize> = IntMap::default();
|
||||
let check_with_max_line_length = |line_length: usize| {
|
||||
let mut checks: Vec<Check> = vec![];
|
||||
check_lines(
|
||||
&mut checks,
|
||||
line,
|
||||
&noqa_line_for,
|
||||
&IntMap::default(),
|
||||
&Settings {
|
||||
line_length,
|
||||
..Settings::for_rule(CheckCode::E501)
|
||||
|
||||
505
src/checks.rs
505
src/checks.rs
@@ -2,6 +2,8 @@ use std::fmt;
|
||||
use std::str::FromStr;
|
||||
|
||||
use itertools::Itertools;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_parser::ast::Location;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum_macros::{AsRefStr, Display, EnumIter, EnumString};
|
||||
@@ -90,8 +92,16 @@ pub enum CheckCode {
|
||||
F831,
|
||||
F841,
|
||||
F901,
|
||||
// pylint errors
|
||||
// pylint
|
||||
PLC0414,
|
||||
PLC2201,
|
||||
PLC3002,
|
||||
PLE1142,
|
||||
PLR0206,
|
||||
PLR0402,
|
||||
PLR1701,
|
||||
PLR1722,
|
||||
PLW0120,
|
||||
// flake8-builtins
|
||||
A001,
|
||||
A002,
|
||||
@@ -149,6 +159,15 @@ pub enum CheckCode {
|
||||
C901,
|
||||
// flake8-tidy-imports
|
||||
I252,
|
||||
// flake8-return
|
||||
RET501,
|
||||
RET502,
|
||||
RET503,
|
||||
RET504,
|
||||
RET505,
|
||||
RET506,
|
||||
RET507,
|
||||
RET508,
|
||||
// flake8-print
|
||||
T201,
|
||||
T203,
|
||||
@@ -181,20 +200,20 @@ pub enum CheckCode {
|
||||
YTT302,
|
||||
YTT303,
|
||||
// pyupgrade
|
||||
U001,
|
||||
U003,
|
||||
U004,
|
||||
U005,
|
||||
U006,
|
||||
U007,
|
||||
U008,
|
||||
U009,
|
||||
U010,
|
||||
U011,
|
||||
U012,
|
||||
U013,
|
||||
U014,
|
||||
U015,
|
||||
UP001,
|
||||
UP003,
|
||||
UP004,
|
||||
UP005,
|
||||
UP006,
|
||||
UP007,
|
||||
UP008,
|
||||
UP009,
|
||||
UP010,
|
||||
UP011,
|
||||
UP012,
|
||||
UP013,
|
||||
UP014,
|
||||
UP015,
|
||||
// pydocstyle
|
||||
D100,
|
||||
D101,
|
||||
@@ -275,36 +294,51 @@ pub enum CheckCode {
|
||||
RUF001,
|
||||
RUF002,
|
||||
RUF003,
|
||||
RUF101,
|
||||
// Meta
|
||||
M001,
|
||||
RUF100,
|
||||
// pygrep-hooks
|
||||
PGH001,
|
||||
}
|
||||
|
||||
#[derive(EnumIter, Debug, PartialEq, Eq)]
|
||||
pub enum CheckCategory {
|
||||
Pyflakes,
|
||||
Pycodestyle,
|
||||
McCabe,
|
||||
Isort,
|
||||
Pydocstyle,
|
||||
Pyupgrade,
|
||||
PEP8Naming,
|
||||
Eradicate,
|
||||
Flake82020,
|
||||
Flake8Annotations,
|
||||
Flake8Bandit,
|
||||
Flake8Comprehensions,
|
||||
Flake8Debugger,
|
||||
Flake8BlindExcept,
|
||||
Flake8BooleanTrap,
|
||||
Flake8Bugbear,
|
||||
Flake8Builtins,
|
||||
Flake8TidyImports,
|
||||
Flake8Comprehensions,
|
||||
Flake8Debugger,
|
||||
Flake8Print,
|
||||
Flake8Quotes,
|
||||
Flake8Annotations,
|
||||
Flake82020,
|
||||
Flake8BlindExcept,
|
||||
McCabe,
|
||||
Flake8Return,
|
||||
Flake8TidyImports,
|
||||
Eradicate,
|
||||
PygrepHooks,
|
||||
Pylint,
|
||||
Ruff,
|
||||
Meta,
|
||||
}
|
||||
|
||||
pub enum Platform {
|
||||
PyPI,
|
||||
GitHub,
|
||||
}
|
||||
|
||||
impl fmt::Display for Platform {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Platform::PyPI => fmt.write_str("PyPI"),
|
||||
Platform::GitHub => fmt.write_str("GitHub"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl CheckCategory {
|
||||
@@ -322,60 +356,109 @@ impl CheckCategory {
|
||||
CheckCategory::Flake8Debugger => "flake8-debugger",
|
||||
CheckCategory::Flake8Print => "flake8-print",
|
||||
CheckCategory::Flake8Quotes => "flake8-quotes",
|
||||
CheckCategory::Flake8Return => "flake8-return",
|
||||
CheckCategory::Flake8TidyImports => "flake8-tidy-imports",
|
||||
CheckCategory::Isort => "isort",
|
||||
CheckCategory::McCabe => "mccabe",
|
||||
CheckCategory::Meta => "Meta rules",
|
||||
CheckCategory::PEP8Naming => "pep8-naming",
|
||||
CheckCategory::Pycodestyle => "pycodestyle",
|
||||
CheckCategory::Pydocstyle => "pydocstyle",
|
||||
CheckCategory::Pyflakes => "Pyflakes",
|
||||
CheckCategory::PygrepHooks => "pygrep-hooks",
|
||||
CheckCategory::Pylint => "Pylint",
|
||||
CheckCategory::Pyupgrade => "pyupgrade",
|
||||
CheckCategory::Ruff => "Ruff-specific rules",
|
||||
}
|
||||
}
|
||||
|
||||
pub fn url(&self) -> Option<&'static str> {
|
||||
pub fn url(&self) -> Option<(&'static str, &'static Platform)> {
|
||||
match self {
|
||||
CheckCategory::Eradicate => Some("https://pypi.org/project/eradicate/2.1.0/"),
|
||||
CheckCategory::Flake82020 => Some("https://pypi.org/project/flake8-2020/1.7.0/"),
|
||||
CheckCategory::Flake8Annotations => {
|
||||
Some("https://pypi.org/project/flake8-annotations/2.9.1/")
|
||||
CheckCategory::Eradicate => {
|
||||
Some(("https://pypi.org/project/eradicate/2.1.0/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Flake8Bandit => Some("https://pypi.org/project/flake8-bandit/4.1.1/"),
|
||||
CheckCategory::Flake8BlindExcept => {
|
||||
Some("https://pypi.org/project/flake8-blind-except/0.2.1/")
|
||||
CheckCategory::Flake82020 => Some((
|
||||
"https://pypi.org/project/flake8-2020/1.7.0/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Annotations => Some((
|
||||
"https://pypi.org/project/flake8-annotations/2.9.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Bandit => Some((
|
||||
"https://pypi.org/project/flake8-bandit/4.1.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8BlindExcept => Some((
|
||||
"https://pypi.org/project/flake8-blind-except/0.2.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8BooleanTrap => Some((
|
||||
"https://pypi.org/project/flake8-boolean-trap/0.1.0/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Bugbear => Some((
|
||||
"https://pypi.org/project/flake8-bugbear/22.10.27/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Builtins => Some((
|
||||
"https://pypi.org/project/flake8-builtins/2.0.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Comprehensions => Some((
|
||||
"https://pypi.org/project/flake8-comprehensions/3.10.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Debugger => Some((
|
||||
"https://pypi.org/project/flake8-debugger/4.1.2/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Print => Some((
|
||||
"https://pypi.org/project/flake8-print/5.0.0/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Quotes => Some((
|
||||
"https://pypi.org/project/flake8-quotes/3.3.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8Return => Some((
|
||||
"https://pypi.org/project/flake8-return/1.2.0/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Flake8TidyImports => Some((
|
||||
"https://pypi.org/project/flake8-tidy-imports/4.8.0/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Isort => {
|
||||
Some(("https://pypi.org/project/isort/5.10.1/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Flake8BooleanTrap => {
|
||||
Some("https://pypi.org/project/flake8-boolean-trap/0.1.0/")
|
||||
CheckCategory::McCabe => {
|
||||
Some(("https://pypi.org/project/mccabe/0.7.0/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Flake8Bugbear => {
|
||||
Some("https://pypi.org/project/flake8-bugbear/22.10.27/")
|
||||
CheckCategory::PEP8Naming => Some((
|
||||
"https://pypi.org/project/pep8-naming/0.13.2/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Pycodestyle => Some((
|
||||
"https://pypi.org/project/pycodestyle/2.9.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Pydocstyle => Some((
|
||||
"https://pypi.org/project/pydocstyle/6.1.1/",
|
||||
&Platform::PyPI,
|
||||
)),
|
||||
CheckCategory::Pyflakes => {
|
||||
Some(("https://pypi.org/project/pyflakes/2.5.0/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Flake8Builtins => {
|
||||
Some("https://pypi.org/project/flake8-builtins/2.0.1/")
|
||||
CheckCategory::Pylint => {
|
||||
Some(("https://pypi.org/project/pylint/2.15.7/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Flake8Comprehensions => {
|
||||
Some("https://pypi.org/project/flake8-comprehensions/3.10.1/")
|
||||
CheckCategory::PygrepHooks => Some((
|
||||
"https://github.com/pre-commit/pygrep-hooks",
|
||||
&Platform::GitHub,
|
||||
)),
|
||||
CheckCategory::Pyupgrade => {
|
||||
Some(("https://pypi.org/project/pyupgrade/3.2.0/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Flake8Debugger => {
|
||||
Some("https://pypi.org/project/flake8-debugger/4.1.2/")
|
||||
}
|
||||
CheckCategory::Flake8Print => Some("https://pypi.org/project/flake8-print/5.0.0/"),
|
||||
CheckCategory::Flake8Quotes => Some("https://pypi.org/project/flake8-quotes/3.3.1/"),
|
||||
CheckCategory::Flake8TidyImports => {
|
||||
Some("https://pypi.org/project/flake8-tidy-imports/4.8.0/")
|
||||
}
|
||||
CheckCategory::Isort => Some("https://pypi.org/project/isort/5.10.1/"),
|
||||
CheckCategory::McCabe => Some("https://pypi.org/project/mccabe/0.7.0/"),
|
||||
CheckCategory::Meta => None,
|
||||
CheckCategory::PEP8Naming => Some("https://pypi.org/project/pep8-naming/0.13.2/"),
|
||||
CheckCategory::Pycodestyle => Some("https://pypi.org/project/pycodestyle/2.9.1/"),
|
||||
CheckCategory::Pydocstyle => Some("https://pypi.org/project/pydocstyle/6.1.1/"),
|
||||
CheckCategory::Pyflakes => Some("https://pypi.org/project/pyflakes/2.5.0/"),
|
||||
CheckCategory::Pylint => Some("https://pypi.org/project/pylint/2.15.7/"),
|
||||
CheckCategory::Pyupgrade => Some("https://pypi.org/project/pyupgrade/3.2.0/"),
|
||||
CheckCategory::Ruff => None,
|
||||
}
|
||||
}
|
||||
@@ -413,6 +496,21 @@ impl fmt::Display for DeferralKeyword {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum Branch {
|
||||
Elif,
|
||||
Else,
|
||||
}
|
||||
|
||||
impl fmt::Display for Branch {
|
||||
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
|
||||
match self {
|
||||
Branch::Elif => fmt.write_str("elif"),
|
||||
Branch::Else => fmt.write_str("else"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(AsRefStr, Debug, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub enum CheckKind {
|
||||
// pycodestyle errors
|
||||
@@ -476,8 +574,16 @@ pub enum CheckKind {
|
||||
UnusedImport(String, bool),
|
||||
UnusedVariable(String),
|
||||
YieldOutsideFunction(DeferralKeyword),
|
||||
// pylint errors
|
||||
// pylint
|
||||
ConsiderMergingIsinstance(String, Vec<String>),
|
||||
UselessImportAlias,
|
||||
MisplacedComparisonConstant(String),
|
||||
UnnecessaryDirectLambdaCall,
|
||||
PropertyWithParameters,
|
||||
ConsiderUsingFromImport(String, String),
|
||||
AwaitOutsideAsync,
|
||||
UselessElseOnLoop,
|
||||
ConsiderUsingSysExit,
|
||||
// flake8-builtins
|
||||
BuiltinVariableShadowing(String),
|
||||
BuiltinArgumentShadowing(String),
|
||||
@@ -533,6 +639,15 @@ pub enum CheckKind {
|
||||
Debugger(DebuggerUsingType),
|
||||
// flake8-tidy-imports
|
||||
BannedRelativeImport(Strictness),
|
||||
// flake8-return
|
||||
UnnecessaryReturnNone,
|
||||
ImplicitReturnValue,
|
||||
ImplicitReturn,
|
||||
UnnecessaryAssign,
|
||||
SuperfluousElseReturn(Branch),
|
||||
SuperfluousElseRaise(Branch),
|
||||
SuperfluousElseContinue(Branch),
|
||||
SuperfluousElseBreak(Branch),
|
||||
// flake8-print
|
||||
PrintFound,
|
||||
PPrintFound,
|
||||
@@ -657,12 +772,12 @@ pub enum CheckKind {
|
||||
BooleanPositionalArgInFunctionDefinition,
|
||||
BooleanDefaultValueInFunctionDefinition,
|
||||
BooleanPositionalValueInFunctionCall,
|
||||
// pygrep-hooks
|
||||
NoEval,
|
||||
// Ruff
|
||||
AmbiguousUnicodeCharacterString(char, char),
|
||||
AmbiguousUnicodeCharacterDocstring(char, char),
|
||||
AmbiguousUnicodeCharacterComment(char, char),
|
||||
ConvertExitToSysExit,
|
||||
// Meta
|
||||
UnusedNOQA(Option<Vec<String>>),
|
||||
}
|
||||
|
||||
@@ -671,7 +786,7 @@ impl CheckCode {
|
||||
/// physical lines).
|
||||
pub fn lint_source(&self) -> &'static LintSource {
|
||||
match self {
|
||||
CheckCode::E501 | CheckCode::W292 | CheckCode::M001 | CheckCode::U009 => {
|
||||
CheckCode::E501 | CheckCode::W292 | CheckCode::RUF100 | CheckCode::UP009 => {
|
||||
&LintSource::Lines
|
||||
}
|
||||
CheckCode::ERA001
|
||||
@@ -759,8 +874,20 @@ impl CheckCode {
|
||||
CheckCode::F831 => CheckKind::DuplicateArgumentName,
|
||||
CheckCode::F841 => CheckKind::UnusedVariable("...".to_string()),
|
||||
CheckCode::F901 => CheckKind::RaiseNotImplemented,
|
||||
// pylint errors
|
||||
// pylint
|
||||
CheckCode::PLC0414 => CheckKind::UselessImportAlias,
|
||||
CheckCode::PLC2201 => CheckKind::MisplacedComparisonConstant("...".to_string()),
|
||||
CheckCode::PLC3002 => CheckKind::UnnecessaryDirectLambdaCall,
|
||||
CheckCode::PLE1142 => CheckKind::AwaitOutsideAsync,
|
||||
CheckCode::PLR0402 => {
|
||||
CheckKind::ConsiderUsingFromImport("...".to_string(), "...".to_string())
|
||||
}
|
||||
CheckCode::PLR0206 => CheckKind::PropertyWithParameters,
|
||||
CheckCode::PLR1701 => {
|
||||
CheckKind::ConsiderMergingIsinstance("...".to_string(), vec!["...".to_string()])
|
||||
}
|
||||
CheckCode::PLR1722 => CheckKind::ConsiderUsingSysExit,
|
||||
CheckCode::PLW0120 => CheckKind::UselessElseOnLoop,
|
||||
// flake8-builtins
|
||||
CheckCode::A001 => CheckKind::BuiltinVariableShadowing("...".to_string()),
|
||||
CheckCode::A002 => CheckKind::BuiltinArgumentShadowing("...".to_string()),
|
||||
@@ -831,6 +958,15 @@ impl CheckCode {
|
||||
CheckCode::T100 => CheckKind::Debugger(DebuggerUsingType::Import("...".to_string())),
|
||||
// flake8-tidy-imports
|
||||
CheckCode::I252 => CheckKind::BannedRelativeImport(Strictness::All),
|
||||
// flake8-return
|
||||
CheckCode::RET501 => CheckKind::UnnecessaryReturnNone,
|
||||
CheckCode::RET502 => CheckKind::ImplicitReturnValue,
|
||||
CheckCode::RET503 => CheckKind::ImplicitReturn,
|
||||
CheckCode::RET504 => CheckKind::UnnecessaryAssign,
|
||||
CheckCode::RET505 => CheckKind::SuperfluousElseReturn(Branch::Else),
|
||||
CheckCode::RET506 => CheckKind::SuperfluousElseRaise(Branch::Else),
|
||||
CheckCode::RET507 => CheckKind::SuperfluousElseContinue(Branch::Else),
|
||||
CheckCode::RET508 => CheckKind::SuperfluousElseBreak(Branch::Else),
|
||||
// flake8-print
|
||||
CheckCode::T201 => CheckKind::PrintFound,
|
||||
CheckCode::T203 => CheckKind::PPrintFound,
|
||||
@@ -865,23 +1001,23 @@ impl CheckCode {
|
||||
// flake8-blind-except
|
||||
CheckCode::BLE001 => CheckKind::BlindExcept,
|
||||
// pyupgrade
|
||||
CheckCode::U001 => CheckKind::UselessMetaclassType,
|
||||
CheckCode::U003 => CheckKind::TypeOfPrimitive(Primitive::Str),
|
||||
CheckCode::U004 => CheckKind::UselessObjectInheritance("...".to_string()),
|
||||
CheckCode::U005 => CheckKind::DeprecatedUnittestAlias(
|
||||
CheckCode::UP001 => CheckKind::UselessMetaclassType,
|
||||
CheckCode::UP003 => CheckKind::TypeOfPrimitive(Primitive::Str),
|
||||
CheckCode::UP004 => CheckKind::UselessObjectInheritance("...".to_string()),
|
||||
CheckCode::UP005 => CheckKind::DeprecatedUnittestAlias(
|
||||
"assertEquals".to_string(),
|
||||
"assertEqual".to_string(),
|
||||
),
|
||||
CheckCode::U006 => CheckKind::UsePEP585Annotation("List".to_string()),
|
||||
CheckCode::U007 => CheckKind::UsePEP604Annotation,
|
||||
CheckCode::U008 => CheckKind::SuperCallWithParameters,
|
||||
CheckCode::U009 => CheckKind::PEP3120UnnecessaryCodingComment,
|
||||
CheckCode::U010 => CheckKind::UnnecessaryFutureImport(vec!["...".to_string()]),
|
||||
CheckCode::U011 => CheckKind::UnnecessaryLRUCacheParams,
|
||||
CheckCode::U012 => CheckKind::UnnecessaryEncodeUTF8,
|
||||
CheckCode::U013 => CheckKind::ConvertTypedDictFunctionalToClass("...".to_string()),
|
||||
CheckCode::U014 => CheckKind::ConvertNamedTupleFunctionalToClass("...".to_string()),
|
||||
CheckCode::U015 => CheckKind::RedundantOpenModes,
|
||||
CheckCode::UP006 => CheckKind::UsePEP585Annotation("List".to_string()),
|
||||
CheckCode::UP007 => CheckKind::UsePEP604Annotation,
|
||||
CheckCode::UP008 => CheckKind::SuperCallWithParameters,
|
||||
CheckCode::UP009 => CheckKind::PEP3120UnnecessaryCodingComment,
|
||||
CheckCode::UP010 => CheckKind::UnnecessaryFutureImport(vec!["...".to_string()]),
|
||||
CheckCode::UP011 => CheckKind::UnnecessaryLRUCacheParams,
|
||||
CheckCode::UP012 => CheckKind::UnnecessaryEncodeUTF8,
|
||||
CheckCode::UP013 => CheckKind::ConvertTypedDictFunctionalToClass("...".to_string()),
|
||||
CheckCode::UP014 => CheckKind::ConvertNamedTupleFunctionalToClass("...".to_string()),
|
||||
CheckCode::UP015 => CheckKind::RedundantOpenModes,
|
||||
// pydocstyle
|
||||
CheckCode::D100 => CheckKind::PublicModule,
|
||||
CheckCode::D101 => CheckKind::PublicClass,
|
||||
@@ -975,13 +1111,13 @@ impl CheckCode {
|
||||
CheckCode::FBT001 => CheckKind::BooleanPositionalArgInFunctionDefinition,
|
||||
CheckCode::FBT002 => CheckKind::BooleanDefaultValueInFunctionDefinition,
|
||||
CheckCode::FBT003 => CheckKind::BooleanPositionalValueInFunctionCall,
|
||||
// pygrep-hooks
|
||||
CheckCode::PGH001 => CheckKind::NoEval,
|
||||
// Ruff
|
||||
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),
|
||||
CheckCode::RUF100 => CheckKind::UnusedNOQA(None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1153,7 +1289,6 @@ impl CheckCode {
|
||||
CheckCode::FBT003 => CheckCategory::Flake8BooleanTrap,
|
||||
CheckCode::I001 => CheckCategory::Isort,
|
||||
CheckCode::I252 => CheckCategory::Flake8TidyImports,
|
||||
CheckCode::M001 => CheckCategory::Meta,
|
||||
CheckCode::N801 => CheckCategory::PEP8Naming,
|
||||
CheckCode::N802 => CheckCategory::PEP8Naming,
|
||||
CheckCode::N803 => CheckCategory::PEP8Naming,
|
||||
@@ -1169,15 +1304,32 @@ impl CheckCode {
|
||||
CheckCode::N816 => CheckCategory::PEP8Naming,
|
||||
CheckCode::N817 => CheckCategory::PEP8Naming,
|
||||
CheckCode::N818 => CheckCategory::PEP8Naming,
|
||||
CheckCode::PGH001 => CheckCategory::PygrepHooks,
|
||||
CheckCode::PLC0414 => CheckCategory::Pylint,
|
||||
CheckCode::PLC2201 => CheckCategory::Pylint,
|
||||
CheckCode::PLC3002 => CheckCategory::Pylint,
|
||||
CheckCode::PLE1142 => CheckCategory::Pylint,
|
||||
CheckCode::PLR0206 => CheckCategory::Pylint,
|
||||
CheckCode::PLR0402 => CheckCategory::Pylint,
|
||||
CheckCode::PLR1701 => CheckCategory::Pylint,
|
||||
CheckCode::PLR1722 => CheckCategory::Pylint,
|
||||
CheckCode::PLW0120 => CheckCategory::Pylint,
|
||||
CheckCode::Q000 => CheckCategory::Flake8Quotes,
|
||||
CheckCode::Q001 => CheckCategory::Flake8Quotes,
|
||||
CheckCode::Q002 => CheckCategory::Flake8Quotes,
|
||||
CheckCode::Q003 => CheckCategory::Flake8Quotes,
|
||||
CheckCode::RET501 => CheckCategory::Flake8Return,
|
||||
CheckCode::RET502 => CheckCategory::Flake8Return,
|
||||
CheckCode::RET503 => CheckCategory::Flake8Return,
|
||||
CheckCode::RET504 => CheckCategory::Flake8Return,
|
||||
CheckCode::RET505 => CheckCategory::Flake8Return,
|
||||
CheckCode::RET506 => CheckCategory::Flake8Return,
|
||||
CheckCode::RET507 => CheckCategory::Flake8Return,
|
||||
CheckCode::RET508 => CheckCategory::Flake8Return,
|
||||
CheckCode::RUF001 => CheckCategory::Ruff,
|
||||
CheckCode::RUF002 => CheckCategory::Ruff,
|
||||
CheckCode::RUF003 => CheckCategory::Ruff,
|
||||
CheckCode::RUF101 => CheckCategory::Ruff,
|
||||
CheckCode::RUF100 => CheckCategory::Ruff,
|
||||
CheckCode::S101 => CheckCategory::Flake8Bandit,
|
||||
CheckCode::S102 => CheckCategory::Flake8Bandit,
|
||||
CheckCode::S104 => CheckCategory::Flake8Bandit,
|
||||
@@ -1187,20 +1339,20 @@ impl CheckCode {
|
||||
CheckCode::T100 => CheckCategory::Flake8Debugger,
|
||||
CheckCode::T201 => CheckCategory::Flake8Print,
|
||||
CheckCode::T203 => CheckCategory::Flake8Print,
|
||||
CheckCode::U001 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U003 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U004 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U005 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U006 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U007 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U008 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U009 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U010 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U011 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U012 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U013 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U014 => CheckCategory::Pyupgrade,
|
||||
CheckCode::U015 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP001 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP003 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP004 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP005 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP006 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP007 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP008 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP009 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP010 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP011 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP012 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP013 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP014 => CheckCategory::Pyupgrade,
|
||||
CheckCode::UP015 => CheckCategory::Pyupgrade,
|
||||
CheckCode::W292 => CheckCategory::Pycodestyle,
|
||||
CheckCode::W605 => CheckCategory::Pycodestyle,
|
||||
CheckCode::YTT101 => CheckCategory::Flake82020,
|
||||
@@ -1281,8 +1433,16 @@ impl CheckKind {
|
||||
// pycodestyle warnings
|
||||
CheckKind::NoNewLineAtEndOfFile => &CheckCode::W292,
|
||||
CheckKind::InvalidEscapeSequence(_) => &CheckCode::W605,
|
||||
// pylint errors
|
||||
// pylint
|
||||
CheckKind::UselessImportAlias => &CheckCode::PLC0414,
|
||||
CheckKind::MisplacedComparisonConstant(..) => &CheckCode::PLC2201,
|
||||
CheckKind::UnnecessaryDirectLambdaCall => &CheckCode::PLC3002,
|
||||
CheckKind::AwaitOutsideAsync => &CheckCode::PLE1142,
|
||||
CheckKind::ConsiderMergingIsinstance(..) => &CheckCode::PLR1701,
|
||||
CheckKind::PropertyWithParameters => &CheckCode::PLR0206,
|
||||
CheckKind::ConsiderUsingFromImport(..) => &CheckCode::PLR0402,
|
||||
CheckKind::ConsiderUsingSysExit => &CheckCode::PLR1722,
|
||||
CheckKind::UselessElseOnLoop => &CheckCode::PLW0120,
|
||||
// flake8-builtins
|
||||
CheckKind::BuiltinVariableShadowing(_) => &CheckCode::A001,
|
||||
CheckKind::BuiltinArgumentShadowing(_) => &CheckCode::A002,
|
||||
@@ -1338,6 +1498,15 @@ impl CheckKind {
|
||||
CheckKind::Debugger(_) => &CheckCode::T100,
|
||||
// flake8-tidy-imports
|
||||
CheckKind::BannedRelativeImport(_) => &CheckCode::I252,
|
||||
// flake8-return
|
||||
CheckKind::UnnecessaryReturnNone => &CheckCode::RET501,
|
||||
CheckKind::ImplicitReturnValue => &CheckCode::RET502,
|
||||
CheckKind::ImplicitReturn => &CheckCode::RET503,
|
||||
CheckKind::UnnecessaryAssign => &CheckCode::RET504,
|
||||
CheckKind::SuperfluousElseReturn(_) => &CheckCode::RET505,
|
||||
CheckKind::SuperfluousElseRaise(_) => &CheckCode::RET506,
|
||||
CheckKind::SuperfluousElseContinue(_) => &CheckCode::RET507,
|
||||
CheckKind::SuperfluousElseBreak(_) => &CheckCode::RET508,
|
||||
// flake8-print
|
||||
CheckKind::PrintFound => &CheckCode::T201,
|
||||
CheckKind::PPrintFound => &CheckCode::T203,
|
||||
@@ -1370,20 +1539,20 @@ impl CheckKind {
|
||||
CheckKind::SysVersionCmpStr10 => &CheckCode::YTT302,
|
||||
CheckKind::SysVersionSlice1Referenced => &CheckCode::YTT303,
|
||||
// pyupgrade
|
||||
CheckKind::TypeOfPrimitive(_) => &CheckCode::U003,
|
||||
CheckKind::UselessMetaclassType => &CheckCode::U001,
|
||||
CheckKind::DeprecatedUnittestAlias(..) => &CheckCode::U005,
|
||||
CheckKind::UsePEP585Annotation(_) => &CheckCode::U006,
|
||||
CheckKind::UsePEP604Annotation => &CheckCode::U007,
|
||||
CheckKind::UselessObjectInheritance(_) => &CheckCode::U004,
|
||||
CheckKind::SuperCallWithParameters => &CheckCode::U008,
|
||||
CheckKind::PEP3120UnnecessaryCodingComment => &CheckCode::U009,
|
||||
CheckKind::UnnecessaryFutureImport(_) => &CheckCode::U010,
|
||||
CheckKind::UnnecessaryLRUCacheParams => &CheckCode::U011,
|
||||
CheckKind::UnnecessaryEncodeUTF8 => &CheckCode::U012,
|
||||
CheckKind::ConvertTypedDictFunctionalToClass(_) => &CheckCode::U013,
|
||||
CheckKind::ConvertNamedTupleFunctionalToClass(_) => &CheckCode::U014,
|
||||
CheckKind::RedundantOpenModes => &CheckCode::U015,
|
||||
CheckKind::TypeOfPrimitive(_) => &CheckCode::UP003,
|
||||
CheckKind::UselessMetaclassType => &CheckCode::UP001,
|
||||
CheckKind::DeprecatedUnittestAlias(..) => &CheckCode::UP005,
|
||||
CheckKind::UsePEP585Annotation(_) => &CheckCode::UP006,
|
||||
CheckKind::UsePEP604Annotation => &CheckCode::UP007,
|
||||
CheckKind::UselessObjectInheritance(_) => &CheckCode::UP004,
|
||||
CheckKind::SuperCallWithParameters => &CheckCode::UP008,
|
||||
CheckKind::PEP3120UnnecessaryCodingComment => &CheckCode::UP009,
|
||||
CheckKind::UnnecessaryFutureImport(_) => &CheckCode::UP010,
|
||||
CheckKind::UnnecessaryLRUCacheParams => &CheckCode::UP011,
|
||||
CheckKind::UnnecessaryEncodeUTF8 => &CheckCode::UP012,
|
||||
CheckKind::ConvertTypedDictFunctionalToClass(_) => &CheckCode::UP013,
|
||||
CheckKind::ConvertNamedTupleFunctionalToClass(_) => &CheckCode::UP014,
|
||||
CheckKind::RedundantOpenModes => &CheckCode::UP015,
|
||||
// pydocstyle
|
||||
CheckKind::BlankLineAfterLastSection(_) => &CheckCode::D413,
|
||||
CheckKind::BlankLineAfterSection(_) => &CheckCode::D410,
|
||||
@@ -1456,19 +1625,19 @@ impl CheckKind {
|
||||
CheckKind::HardcodedPasswordString(..) => &CheckCode::S105,
|
||||
CheckKind::HardcodedPasswordFuncArg(..) => &CheckCode::S106,
|
||||
CheckKind::HardcodedPasswordDefault(..) => &CheckCode::S107,
|
||||
// McCabe
|
||||
// mccabe
|
||||
CheckKind::FunctionIsTooComplex(..) => &CheckCode::C901,
|
||||
// flake8-boolean-trap
|
||||
CheckKind::BooleanPositionalArgInFunctionDefinition => &CheckCode::FBT001,
|
||||
CheckKind::BooleanDefaultValueInFunctionDefinition => &CheckCode::FBT002,
|
||||
CheckKind::BooleanPositionalValueInFunctionCall => &CheckCode::FBT003,
|
||||
// pygrep-hooks
|
||||
CheckKind::NoEval => &CheckCode::PGH001,
|
||||
// Ruff
|
||||
CheckKind::AmbiguousUnicodeCharacterString(..) => &CheckCode::RUF001,
|
||||
CheckKind::AmbiguousUnicodeCharacterDocstring(..) => &CheckCode::RUF002,
|
||||
CheckKind::AmbiguousUnicodeCharacterComment(..) => &CheckCode::RUF003,
|
||||
CheckKind::ConvertExitToSysExit => &CheckCode::RUF101,
|
||||
// Meta
|
||||
CheckKind::UnusedNOQA(_) => &CheckCode::M001,
|
||||
CheckKind::UnusedNOQA(_) => &CheckCode::RUF100,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1634,9 +1803,12 @@ impl CheckKind {
|
||||
CheckKind::UndefinedName(name) => {
|
||||
format!("Undefined name `{name}`")
|
||||
}
|
||||
CheckKind::UnusedImport(name, in_init_py) => {
|
||||
if *in_init_py {
|
||||
format!("`{name}` imported but unused and missing from `__all__`")
|
||||
CheckKind::UnusedImport(name, ignore_init) => {
|
||||
if *ignore_init {
|
||||
format!(
|
||||
"`{name}` imported but unused; consider adding to `__all__` or using a \
|
||||
redundant alias"
|
||||
)
|
||||
} else {
|
||||
format!("`{name}` imported but unused")
|
||||
}
|
||||
@@ -1652,10 +1824,33 @@ impl CheckKind {
|
||||
CheckKind::InvalidEscapeSequence(char) => {
|
||||
format!("Invalid escape sequence: '\\{char}'")
|
||||
}
|
||||
// pylint errors
|
||||
// pylint
|
||||
CheckKind::UselessImportAlias => {
|
||||
"Import alias does not rename original package".to_string()
|
||||
}
|
||||
CheckKind::ConsiderMergingIsinstance(obj, types) => {
|
||||
let types = types.join(", ");
|
||||
format!("Consider merging these isinstance calls: `isinstance({obj}, ({types}))`")
|
||||
}
|
||||
CheckKind::MisplacedComparisonConstant(comprison) => {
|
||||
format!("Comparison should be {comprison}")
|
||||
}
|
||||
CheckKind::UnnecessaryDirectLambdaCall => "Lambda expression called directly. Execute \
|
||||
the expression inline instead."
|
||||
.to_string(),
|
||||
CheckKind::PropertyWithParameters => {
|
||||
"Cannot have defined parameters for properties".to_string()
|
||||
}
|
||||
CheckKind::ConsiderUsingFromImport(module, name) => {
|
||||
format!("Consider using `from {module} import {name}`")
|
||||
}
|
||||
CheckKind::AwaitOutsideAsync => {
|
||||
"`await` should be used within an async function".to_string()
|
||||
}
|
||||
CheckKind::UselessElseOnLoop => "Else clause on loop without a break statement, \
|
||||
remove the else and de-indent all the code inside it"
|
||||
.to_string(),
|
||||
CheckKind::ConsiderUsingSysExit => "Consider using `sys.exit()`".to_string(),
|
||||
// flake8-builtins
|
||||
CheckKind::BuiltinVariableShadowing(name) => {
|
||||
format!("Variable `{name}` is shadowing a python builtin")
|
||||
@@ -1866,6 +2061,31 @@ impl CheckKind {
|
||||
}
|
||||
Strictness::All => "Relative imports are banned".to_string(),
|
||||
},
|
||||
// flake8-return
|
||||
CheckKind::UnnecessaryReturnNone => "Do not explicitly `return None` in function if \
|
||||
it is the only possible return value"
|
||||
.to_string(),
|
||||
CheckKind::ImplicitReturnValue => "Do not implicitly `return None` in function able \
|
||||
to return non-`None` value"
|
||||
.to_string(),
|
||||
CheckKind::ImplicitReturn => "Missing explicit `return` at the end of function able \
|
||||
to return non-`None` value"
|
||||
.to_string(),
|
||||
CheckKind::UnnecessaryAssign => {
|
||||
"Unnecessary variable assignment before `return` statement".to_string()
|
||||
}
|
||||
CheckKind::SuperfluousElseReturn(branch) => {
|
||||
format!("Unnecessary `{branch}` after `return` statement")
|
||||
}
|
||||
CheckKind::SuperfluousElseRaise(branch) => {
|
||||
format!("Unnecessary `{branch}` after `raise` statement")
|
||||
}
|
||||
CheckKind::SuperfluousElseContinue(branch) => {
|
||||
format!("Unnecessary `{branch}` after `continue` statement")
|
||||
}
|
||||
CheckKind::SuperfluousElseBreak(branch) => {
|
||||
format!("Unnecessary `{branch}` after `break` statement")
|
||||
}
|
||||
// flake8-print
|
||||
CheckKind::PrintFound => "`print` found".to_string(),
|
||||
CheckKind::PPrintFound => "`pprint` found".to_string(),
|
||||
@@ -2183,7 +2403,7 @@ impl CheckKind {
|
||||
}
|
||||
// flake8-blind-except
|
||||
CheckKind::BlindExcept => "Blind except Exception: statement".to_string(),
|
||||
// McCabe
|
||||
// mccabe
|
||||
CheckKind::FunctionIsTooComplex(name, complexity) => {
|
||||
format!("`{name}` is too complex ({complexity})")
|
||||
}
|
||||
@@ -2197,6 +2417,8 @@ impl CheckKind {
|
||||
CheckKind::BooleanPositionalValueInFunctionCall => {
|
||||
"Boolean positional value in function call".to_string()
|
||||
}
|
||||
// pygrep-hooks
|
||||
CheckKind::NoEval => "No builtin `eval()` allowed".to_string(),
|
||||
// Ruff
|
||||
CheckKind::AmbiguousUnicodeCharacterString(confusable, representant) => {
|
||||
format!(
|
||||
@@ -2216,10 +2438,6 @@ 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(),
|
||||
Some(codes) => {
|
||||
@@ -2271,7 +2489,7 @@ impl CheckKind {
|
||||
| CheckKind::BlankLineBeforeSection(..)
|
||||
| CheckKind::CapitalizeSectionName(..)
|
||||
| CheckKind::CommentedOutCode
|
||||
| CheckKind::ConvertExitToSysExit
|
||||
| CheckKind::ConsiderUsingSysExit
|
||||
| CheckKind::ConvertNamedTupleFunctionalToClass(..)
|
||||
| CheckKind::ConvertTypedDictFunctionalToClass(..)
|
||||
| CheckKind::DashedUnderlineAfterSection(..)
|
||||
@@ -2280,7 +2498,10 @@ impl CheckKind {
|
||||
| CheckKind::DoNotAssignLambda
|
||||
| CheckKind::DuplicateHandlerException(..)
|
||||
| CheckKind::GetAttrWithConstant
|
||||
| CheckKind::ImplicitReturn
|
||||
| CheckKind::ImplicitReturnValue
|
||||
| CheckKind::IsLiteral
|
||||
| CheckKind::MisplacedComparisonConstant(..)
|
||||
| CheckKind::NewLineAfterLastParagraph
|
||||
| CheckKind::NewLineAfterSectionName(..)
|
||||
| CheckKind::NoBlankLineAfterFunction(..)
|
||||
@@ -2299,6 +2520,7 @@ impl CheckKind {
|
||||
| CheckKind::PPrintFound
|
||||
| CheckKind::PrintFound
|
||||
| CheckKind::RaiseNotImplemented
|
||||
| CheckKind::RedundantOpenModes
|
||||
| CheckKind::RedundantTupleInExceptionHandler(..)
|
||||
| CheckKind::SectionNameEndsInColon(..)
|
||||
| CheckKind::SectionNotOverIndented(..)
|
||||
@@ -2313,7 +2535,6 @@ impl CheckKind {
|
||||
| CheckKind::UnnecessaryComprehension(..)
|
||||
| CheckKind::UnnecessaryEncodeUTF8
|
||||
| CheckKind::UnnecessaryFutureImport(..)
|
||||
| CheckKind::RedundantOpenModes
|
||||
| CheckKind::UnnecessaryGeneratorDict
|
||||
| CheckKind::UnnecessaryGeneratorList
|
||||
| CheckKind::UnnecessaryGeneratorSet
|
||||
@@ -2325,12 +2546,14 @@ impl CheckKind {
|
||||
| CheckKind::UnnecessaryLiteralSet(..)
|
||||
| CheckKind::UnnecessaryLiteralWithinListCall(..)
|
||||
| CheckKind::UnnecessaryLiteralWithinTupleCall(..)
|
||||
| CheckKind::UnnecessaryReturnNone
|
||||
| CheckKind::UnsortedImports
|
||||
| CheckKind::UnusedImport(_, false)
|
||||
| CheckKind::UnusedLoopControlVariable(..)
|
||||
| CheckKind::UnusedNOQA(..)
|
||||
| CheckKind::UsePEP585Annotation(..)
|
||||
| CheckKind::UsePEP604Annotation
|
||||
| CheckKind::UselessImportAlias
|
||||
| CheckKind::UselessMetaclassType
|
||||
| CheckKind::UselessObjectInheritance(..)
|
||||
)
|
||||
@@ -2360,6 +2583,27 @@ impl Check {
|
||||
}
|
||||
}
|
||||
|
||||
/// A hash map from deprecated to latest `CheckCode`.
|
||||
pub static REDIRECTS: Lazy<FxHashMap<&'static str, CheckCode>> = Lazy::new(|| {
|
||||
FxHashMap::from_iter([
|
||||
// TODO(charlie): Remove by 2023-01-01.
|
||||
("U001", CheckCode::UP001),
|
||||
("U003", CheckCode::UP003),
|
||||
("U004", CheckCode::UP004),
|
||||
("U005", CheckCode::UP005),
|
||||
("U006", CheckCode::UP006),
|
||||
("U007", CheckCode::UP007),
|
||||
("U008", CheckCode::UP008),
|
||||
("U009", CheckCode::UP009),
|
||||
("U010", CheckCode::UP010),
|
||||
("U011", CheckCode::UP011),
|
||||
("U012", CheckCode::UP012),
|
||||
("U013", CheckCode::UP013),
|
||||
("U014", CheckCode::UP014),
|
||||
("U015", CheckCode::UP015),
|
||||
])
|
||||
});
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use std::str::FromStr;
|
||||
@@ -2373,8 +2617,7 @@ mod tests {
|
||||
for check_code in CheckCode::iter() {
|
||||
assert!(
|
||||
CheckCode::from_str(check_code.as_ref()).is_ok(),
|
||||
"{:?} could not be round-trip serialized.",
|
||||
check_code
|
||||
"{check_code:?} could not be round-trip serialized."
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
//! File automatically generated by `examples/generate_check_code_prefix.rs`.
|
||||
|
||||
use colored::Colorize;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum_macros::EnumString;
|
||||
|
||||
@@ -255,10 +256,6 @@ pub enum CheckCodePrefix {
|
||||
I2,
|
||||
I25,
|
||||
I252,
|
||||
M,
|
||||
M0,
|
||||
M00,
|
||||
M001,
|
||||
N,
|
||||
N8,
|
||||
N80,
|
||||
@@ -278,11 +275,47 @@ pub enum CheckCodePrefix {
|
||||
N816,
|
||||
N817,
|
||||
N818,
|
||||
PGH,
|
||||
PGH0,
|
||||
PGH00,
|
||||
PGH001,
|
||||
PLC,
|
||||
PLC0,
|
||||
PLC04,
|
||||
PLC041,
|
||||
PLC0414,
|
||||
PLC2,
|
||||
PLC22,
|
||||
PLC220,
|
||||
PLC2201,
|
||||
PLC3,
|
||||
PLC30,
|
||||
PLC300,
|
||||
PLC3002,
|
||||
PLE,
|
||||
PLE1,
|
||||
PLE11,
|
||||
PLE114,
|
||||
PLE1142,
|
||||
PLR,
|
||||
PLR0,
|
||||
PLR02,
|
||||
PLR020,
|
||||
PLR0206,
|
||||
PLR04,
|
||||
PLR040,
|
||||
PLR0402,
|
||||
PLR1,
|
||||
PLR17,
|
||||
PLR170,
|
||||
PLR1701,
|
||||
PLR172,
|
||||
PLR1722,
|
||||
PLW,
|
||||
PLW0,
|
||||
PLW01,
|
||||
PLW012,
|
||||
PLW0120,
|
||||
Q,
|
||||
Q0,
|
||||
Q00,
|
||||
@@ -290,6 +323,17 @@ pub enum CheckCodePrefix {
|
||||
Q001,
|
||||
Q002,
|
||||
Q003,
|
||||
RET,
|
||||
RET5,
|
||||
RET50,
|
||||
RET501,
|
||||
RET502,
|
||||
RET503,
|
||||
RET504,
|
||||
RET505,
|
||||
RET506,
|
||||
RET507,
|
||||
RET508,
|
||||
RUF,
|
||||
RUF0,
|
||||
RUF00,
|
||||
@@ -298,7 +342,7 @@ pub enum CheckCodePrefix {
|
||||
RUF003,
|
||||
RUF1,
|
||||
RUF10,
|
||||
RUF101,
|
||||
RUF100,
|
||||
S,
|
||||
S1,
|
||||
S10,
|
||||
@@ -334,6 +378,24 @@ pub enum CheckCodePrefix {
|
||||
U013,
|
||||
U014,
|
||||
U015,
|
||||
UP,
|
||||
UP0,
|
||||
UP00,
|
||||
UP001,
|
||||
UP003,
|
||||
UP004,
|
||||
UP005,
|
||||
UP006,
|
||||
UP007,
|
||||
UP008,
|
||||
UP009,
|
||||
UP01,
|
||||
UP010,
|
||||
UP011,
|
||||
UP012,
|
||||
UP013,
|
||||
UP014,
|
||||
UP015,
|
||||
W,
|
||||
W2,
|
||||
W29,
|
||||
@@ -1076,10 +1138,6 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::I2 => vec![CheckCode::I252],
|
||||
CheckCodePrefix::I25 => vec![CheckCode::I252],
|
||||
CheckCodePrefix::I252 => vec![CheckCode::I252],
|
||||
CheckCodePrefix::M => vec![CheckCode::M001],
|
||||
CheckCodePrefix::M0 => vec![CheckCode::M001],
|
||||
CheckCodePrefix::M00 => vec![CheckCode::M001],
|
||||
CheckCodePrefix::M001 => vec![CheckCode::M001],
|
||||
CheckCodePrefix::N => vec![
|
||||
CheckCode::N801,
|
||||
CheckCode::N802,
|
||||
@@ -1148,11 +1206,54 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::N816 => vec![CheckCode::N816],
|
||||
CheckCodePrefix::N817 => vec![CheckCode::N817],
|
||||
CheckCodePrefix::N818 => vec![CheckCode::N818],
|
||||
CheckCodePrefix::PGH => vec![CheckCode::PGH001],
|
||||
CheckCodePrefix::PGH0 => vec![CheckCode::PGH001],
|
||||
CheckCodePrefix::PGH00 => vec![CheckCode::PGH001],
|
||||
CheckCodePrefix::PGH001 => vec![CheckCode::PGH001],
|
||||
CheckCodePrefix::PLC => {
|
||||
vec![CheckCode::PLC0414, CheckCode::PLC2201, CheckCode::PLC3002]
|
||||
}
|
||||
CheckCodePrefix::PLC0 => vec![CheckCode::PLC0414],
|
||||
CheckCodePrefix::PLC04 => vec![CheckCode::PLC0414],
|
||||
CheckCodePrefix::PLC041 => vec![CheckCode::PLC0414],
|
||||
CheckCodePrefix::PLC0414 => vec![CheckCode::PLC0414],
|
||||
CheckCodePrefix::PLC2 => vec![CheckCode::PLC2201],
|
||||
CheckCodePrefix::PLC22 => vec![CheckCode::PLC2201],
|
||||
CheckCodePrefix::PLC220 => vec![CheckCode::PLC2201],
|
||||
CheckCodePrefix::PLC2201 => vec![CheckCode::PLC2201],
|
||||
CheckCodePrefix::PLC3 => vec![CheckCode::PLC3002],
|
||||
CheckCodePrefix::PLC30 => vec![CheckCode::PLC3002],
|
||||
CheckCodePrefix::PLC300 => vec![CheckCode::PLC3002],
|
||||
CheckCodePrefix::PLC3002 => vec![CheckCode::PLC3002],
|
||||
CheckCodePrefix::PLE => vec![CheckCode::PLE1142],
|
||||
CheckCodePrefix::PLE1 => vec![CheckCode::PLE1142],
|
||||
CheckCodePrefix::PLE11 => vec![CheckCode::PLE1142],
|
||||
CheckCodePrefix::PLE114 => vec![CheckCode::PLE1142],
|
||||
CheckCodePrefix::PLE1142 => vec![CheckCode::PLE1142],
|
||||
CheckCodePrefix::PLR => vec![
|
||||
CheckCode::PLR0206,
|
||||
CheckCode::PLR0402,
|
||||
CheckCode::PLR1701,
|
||||
CheckCode::PLR1722,
|
||||
],
|
||||
CheckCodePrefix::PLR0 => vec![CheckCode::PLR0206, CheckCode::PLR0402],
|
||||
CheckCodePrefix::PLR02 => vec![CheckCode::PLR0206],
|
||||
CheckCodePrefix::PLR020 => vec![CheckCode::PLR0206],
|
||||
CheckCodePrefix::PLR0206 => vec![CheckCode::PLR0206],
|
||||
CheckCodePrefix::PLR04 => vec![CheckCode::PLR0402],
|
||||
CheckCodePrefix::PLR040 => vec![CheckCode::PLR0402],
|
||||
CheckCodePrefix::PLR0402 => vec![CheckCode::PLR0402],
|
||||
CheckCodePrefix::PLR1 => vec![CheckCode::PLR1701, CheckCode::PLR1722],
|
||||
CheckCodePrefix::PLR17 => vec![CheckCode::PLR1701, CheckCode::PLR1722],
|
||||
CheckCodePrefix::PLR170 => vec![CheckCode::PLR1701],
|
||||
CheckCodePrefix::PLR1701 => vec![CheckCode::PLR1701],
|
||||
CheckCodePrefix::PLR172 => vec![CheckCode::PLR1722],
|
||||
CheckCodePrefix::PLR1722 => vec![CheckCode::PLR1722],
|
||||
CheckCodePrefix::PLW => vec![CheckCode::PLW0120],
|
||||
CheckCodePrefix::PLW0 => vec![CheckCode::PLW0120],
|
||||
CheckCodePrefix::PLW01 => vec![CheckCode::PLW0120],
|
||||
CheckCodePrefix::PLW012 => vec![CheckCode::PLW0120],
|
||||
CheckCodePrefix::PLW0120 => vec![CheckCode::PLW0120],
|
||||
CheckCodePrefix::Q => vec![
|
||||
CheckCode::Q000,
|
||||
CheckCode::Q001,
|
||||
@@ -1175,20 +1276,58 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::Q001 => vec![CheckCode::Q001],
|
||||
CheckCodePrefix::Q002 => vec![CheckCode::Q002],
|
||||
CheckCodePrefix::Q003 => vec![CheckCode::Q003],
|
||||
CheckCodePrefix::RET => vec![
|
||||
CheckCode::RET501,
|
||||
CheckCode::RET502,
|
||||
CheckCode::RET503,
|
||||
CheckCode::RET504,
|
||||
CheckCode::RET505,
|
||||
CheckCode::RET506,
|
||||
CheckCode::RET507,
|
||||
CheckCode::RET508,
|
||||
],
|
||||
CheckCodePrefix::RET5 => vec![
|
||||
CheckCode::RET501,
|
||||
CheckCode::RET502,
|
||||
CheckCode::RET503,
|
||||
CheckCode::RET504,
|
||||
CheckCode::RET505,
|
||||
CheckCode::RET506,
|
||||
CheckCode::RET507,
|
||||
CheckCode::RET508,
|
||||
],
|
||||
CheckCodePrefix::RET50 => vec![
|
||||
CheckCode::RET501,
|
||||
CheckCode::RET502,
|
||||
CheckCode::RET503,
|
||||
CheckCode::RET504,
|
||||
CheckCode::RET505,
|
||||
CheckCode::RET506,
|
||||
CheckCode::RET507,
|
||||
CheckCode::RET508,
|
||||
],
|
||||
CheckCodePrefix::RET501 => vec![CheckCode::RET501],
|
||||
CheckCodePrefix::RET502 => vec![CheckCode::RET502],
|
||||
CheckCodePrefix::RET503 => vec![CheckCode::RET503],
|
||||
CheckCodePrefix::RET504 => vec![CheckCode::RET504],
|
||||
CheckCodePrefix::RET505 => vec![CheckCode::RET505],
|
||||
CheckCodePrefix::RET506 => vec![CheckCode::RET506],
|
||||
CheckCodePrefix::RET507 => vec![CheckCode::RET507],
|
||||
CheckCodePrefix::RET508 => vec![CheckCode::RET508],
|
||||
CheckCodePrefix::RUF => vec![
|
||||
CheckCode::RUF001,
|
||||
CheckCode::RUF002,
|
||||
CheckCode::RUF003,
|
||||
CheckCode::RUF101,
|
||||
CheckCode::RUF100,
|
||||
],
|
||||
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::RUF1 => vec![CheckCode::RUF100],
|
||||
CheckCodePrefix::RUF10 => vec![CheckCode::RUF100],
|
||||
CheckCodePrefix::RUF100 => vec![CheckCode::RUF100],
|
||||
CheckCodePrefix::S => vec![
|
||||
CheckCode::S101,
|
||||
CheckCode::S102,
|
||||
@@ -1228,69 +1367,245 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::T201 => vec![CheckCode::T201],
|
||||
CheckCodePrefix::T203 => vec![CheckCode::T203],
|
||||
CheckCodePrefix::U => vec![
|
||||
CheckCode::U001,
|
||||
CheckCode::U003,
|
||||
CheckCode::U004,
|
||||
CheckCode::U005,
|
||||
CheckCode::U006,
|
||||
CheckCode::U007,
|
||||
CheckCode::U008,
|
||||
CheckCode::U009,
|
||||
CheckCode::U010,
|
||||
CheckCode::U011,
|
||||
CheckCode::U012,
|
||||
CheckCode::U013,
|
||||
CheckCode::U014,
|
||||
CheckCode::U015,
|
||||
CheckCode::UP001,
|
||||
CheckCode::UP003,
|
||||
CheckCode::UP004,
|
||||
CheckCode::UP005,
|
||||
CheckCode::UP006,
|
||||
CheckCode::UP007,
|
||||
CheckCode::UP008,
|
||||
CheckCode::UP009,
|
||||
CheckCode::UP010,
|
||||
CheckCode::UP011,
|
||||
CheckCode::UP012,
|
||||
CheckCode::UP013,
|
||||
CheckCode::UP014,
|
||||
CheckCode::UP015,
|
||||
],
|
||||
CheckCodePrefix::U0 => vec![
|
||||
CheckCode::U001,
|
||||
CheckCode::U003,
|
||||
CheckCode::U004,
|
||||
CheckCode::U005,
|
||||
CheckCode::U006,
|
||||
CheckCode::U007,
|
||||
CheckCode::U008,
|
||||
CheckCode::U009,
|
||||
CheckCode::U010,
|
||||
CheckCode::U011,
|
||||
CheckCode::U012,
|
||||
CheckCode::U013,
|
||||
CheckCode::U014,
|
||||
CheckCode::U015,
|
||||
CheckCode::UP001,
|
||||
CheckCode::UP003,
|
||||
CheckCode::UP004,
|
||||
CheckCode::UP005,
|
||||
CheckCode::UP006,
|
||||
CheckCode::UP007,
|
||||
CheckCode::UP008,
|
||||
CheckCode::UP009,
|
||||
CheckCode::UP010,
|
||||
CheckCode::UP011,
|
||||
CheckCode::UP012,
|
||||
CheckCode::UP013,
|
||||
CheckCode::UP014,
|
||||
CheckCode::UP015,
|
||||
],
|
||||
CheckCodePrefix::U00 => vec![
|
||||
CheckCode::U001,
|
||||
CheckCode::U003,
|
||||
CheckCode::U004,
|
||||
CheckCode::U005,
|
||||
CheckCode::U006,
|
||||
CheckCode::U007,
|
||||
CheckCode::U008,
|
||||
CheckCode::U009,
|
||||
CheckCode::UP001,
|
||||
CheckCode::UP003,
|
||||
CheckCode::UP004,
|
||||
CheckCode::UP005,
|
||||
CheckCode::UP006,
|
||||
CheckCode::UP007,
|
||||
CheckCode::UP008,
|
||||
CheckCode::UP009,
|
||||
],
|
||||
CheckCodePrefix::U001 => vec![CheckCode::U001],
|
||||
CheckCodePrefix::U003 => vec![CheckCode::U003],
|
||||
CheckCodePrefix::U004 => vec![CheckCode::U004],
|
||||
CheckCodePrefix::U005 => vec![CheckCode::U005],
|
||||
CheckCodePrefix::U006 => vec![CheckCode::U006],
|
||||
CheckCodePrefix::U007 => vec![CheckCode::U007],
|
||||
CheckCodePrefix::U008 => vec![CheckCode::U008],
|
||||
CheckCodePrefix::U009 => vec![CheckCode::U009],
|
||||
CheckCodePrefix::U001 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U001` has been renamed to `UP001`".bold()
|
||||
);
|
||||
vec![CheckCode::UP001]
|
||||
}
|
||||
CheckCodePrefix::U003 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U003` has been renamed to `UP003`".bold()
|
||||
);
|
||||
vec![CheckCode::UP003]
|
||||
}
|
||||
CheckCodePrefix::U004 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U004` has been renamed to `UP004`".bold()
|
||||
);
|
||||
vec![CheckCode::UP004]
|
||||
}
|
||||
CheckCodePrefix::U005 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U005` has been renamed to `UP005`".bold()
|
||||
);
|
||||
vec![CheckCode::UP005]
|
||||
}
|
||||
CheckCodePrefix::U006 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U006` has been renamed to `UP006`".bold()
|
||||
);
|
||||
vec![CheckCode::UP006]
|
||||
}
|
||||
CheckCodePrefix::U007 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U007` has been renamed to `UP007`".bold()
|
||||
);
|
||||
vec![CheckCode::UP007]
|
||||
}
|
||||
CheckCodePrefix::U008 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U008` has been renamed to `UP008`".bold()
|
||||
);
|
||||
vec![CheckCode::UP008]
|
||||
}
|
||||
CheckCodePrefix::U009 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U009` has been renamed to `UP009`".bold()
|
||||
);
|
||||
vec![CheckCode::UP009]
|
||||
}
|
||||
CheckCodePrefix::U01 => vec![
|
||||
CheckCode::U010,
|
||||
CheckCode::U011,
|
||||
CheckCode::U012,
|
||||
CheckCode::U013,
|
||||
CheckCode::U014,
|
||||
CheckCode::U015,
|
||||
CheckCode::UP010,
|
||||
CheckCode::UP011,
|
||||
CheckCode::UP012,
|
||||
CheckCode::UP013,
|
||||
CheckCode::UP014,
|
||||
CheckCode::UP015,
|
||||
],
|
||||
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::U015 => vec![CheckCode::U015],
|
||||
CheckCodePrefix::U010 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U010` has been renamed to `UP010`".bold()
|
||||
);
|
||||
vec![CheckCode::UP010]
|
||||
}
|
||||
CheckCodePrefix::U011 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U011` has been renamed to `UP011`".bold()
|
||||
);
|
||||
vec![CheckCode::UP011]
|
||||
}
|
||||
CheckCodePrefix::U012 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U012` has been renamed to `UP012`".bold()
|
||||
);
|
||||
vec![CheckCode::UP012]
|
||||
}
|
||||
CheckCodePrefix::U013 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U013` has been renamed to `UP013`".bold()
|
||||
);
|
||||
vec![CheckCode::UP013]
|
||||
}
|
||||
CheckCodePrefix::U014 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U014` has been renamed to `UP014`".bold()
|
||||
);
|
||||
vec![CheckCode::UP014]
|
||||
}
|
||||
CheckCodePrefix::U015 => {
|
||||
eprintln!(
|
||||
"{}{} {}",
|
||||
"warning".yellow().bold(),
|
||||
":".bold(),
|
||||
"`U015` has been renamed to `UP015`".bold()
|
||||
);
|
||||
vec![CheckCode::UP015]
|
||||
}
|
||||
CheckCodePrefix::UP => vec![
|
||||
CheckCode::UP001,
|
||||
CheckCode::UP003,
|
||||
CheckCode::UP004,
|
||||
CheckCode::UP005,
|
||||
CheckCode::UP006,
|
||||
CheckCode::UP007,
|
||||
CheckCode::UP008,
|
||||
CheckCode::UP009,
|
||||
CheckCode::UP010,
|
||||
CheckCode::UP011,
|
||||
CheckCode::UP012,
|
||||
CheckCode::UP013,
|
||||
CheckCode::UP014,
|
||||
CheckCode::UP015,
|
||||
],
|
||||
CheckCodePrefix::UP0 => vec![
|
||||
CheckCode::UP001,
|
||||
CheckCode::UP003,
|
||||
CheckCode::UP004,
|
||||
CheckCode::UP005,
|
||||
CheckCode::UP006,
|
||||
CheckCode::UP007,
|
||||
CheckCode::UP008,
|
||||
CheckCode::UP009,
|
||||
CheckCode::UP010,
|
||||
CheckCode::UP011,
|
||||
CheckCode::UP012,
|
||||
CheckCode::UP013,
|
||||
CheckCode::UP014,
|
||||
CheckCode::UP015,
|
||||
],
|
||||
CheckCodePrefix::UP00 => vec![
|
||||
CheckCode::UP001,
|
||||
CheckCode::UP003,
|
||||
CheckCode::UP004,
|
||||
CheckCode::UP005,
|
||||
CheckCode::UP006,
|
||||
CheckCode::UP007,
|
||||
CheckCode::UP008,
|
||||
CheckCode::UP009,
|
||||
],
|
||||
CheckCodePrefix::UP001 => vec![CheckCode::UP001],
|
||||
CheckCodePrefix::UP003 => vec![CheckCode::UP003],
|
||||
CheckCodePrefix::UP004 => vec![CheckCode::UP004],
|
||||
CheckCodePrefix::UP005 => vec![CheckCode::UP005],
|
||||
CheckCodePrefix::UP006 => vec![CheckCode::UP006],
|
||||
CheckCodePrefix::UP007 => vec![CheckCode::UP007],
|
||||
CheckCodePrefix::UP008 => vec![CheckCode::UP008],
|
||||
CheckCodePrefix::UP009 => vec![CheckCode::UP009],
|
||||
CheckCodePrefix::UP01 => vec![
|
||||
CheckCode::UP010,
|
||||
CheckCode::UP011,
|
||||
CheckCode::UP012,
|
||||
CheckCode::UP013,
|
||||
CheckCode::UP014,
|
||||
CheckCode::UP015,
|
||||
],
|
||||
CheckCodePrefix::UP010 => vec![CheckCode::UP010],
|
||||
CheckCodePrefix::UP011 => vec![CheckCode::UP011],
|
||||
CheckCodePrefix::UP012 => vec![CheckCode::UP012],
|
||||
CheckCodePrefix::UP013 => vec![CheckCode::UP013],
|
||||
CheckCodePrefix::UP014 => vec![CheckCode::UP014],
|
||||
CheckCodePrefix::UP015 => vec![CheckCode::UP015],
|
||||
CheckCodePrefix::W => vec![CheckCode::W292, CheckCode::W605],
|
||||
CheckCodePrefix::W2 => vec![CheckCode::W292],
|
||||
CheckCodePrefix::W29 => vec![CheckCode::W292],
|
||||
@@ -1592,10 +1907,6 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::I2 => SuffixLength::One,
|
||||
CheckCodePrefix::I25 => SuffixLength::Two,
|
||||
CheckCodePrefix::I252 => SuffixLength::Three,
|
||||
CheckCodePrefix::M => SuffixLength::Zero,
|
||||
CheckCodePrefix::M0 => SuffixLength::One,
|
||||
CheckCodePrefix::M00 => SuffixLength::Two,
|
||||
CheckCodePrefix::M001 => SuffixLength::Three,
|
||||
CheckCodePrefix::N => SuffixLength::Zero,
|
||||
CheckCodePrefix::N8 => SuffixLength::One,
|
||||
CheckCodePrefix::N80 => SuffixLength::Two,
|
||||
@@ -1615,11 +1926,47 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::N816 => SuffixLength::Three,
|
||||
CheckCodePrefix::N817 => SuffixLength::Three,
|
||||
CheckCodePrefix::N818 => SuffixLength::Three,
|
||||
CheckCodePrefix::PGH => SuffixLength::Zero,
|
||||
CheckCodePrefix::PGH0 => SuffixLength::One,
|
||||
CheckCodePrefix::PGH00 => SuffixLength::Two,
|
||||
CheckCodePrefix::PGH001 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLC => SuffixLength::Zero,
|
||||
CheckCodePrefix::PLC0 => SuffixLength::One,
|
||||
CheckCodePrefix::PLC04 => SuffixLength::Two,
|
||||
CheckCodePrefix::PLC041 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLC0414 => SuffixLength::Four,
|
||||
CheckCodePrefix::PLC2 => SuffixLength::One,
|
||||
CheckCodePrefix::PLC22 => SuffixLength::Two,
|
||||
CheckCodePrefix::PLC220 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLC2201 => SuffixLength::Four,
|
||||
CheckCodePrefix::PLC3 => SuffixLength::One,
|
||||
CheckCodePrefix::PLC30 => SuffixLength::Two,
|
||||
CheckCodePrefix::PLC300 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLC3002 => SuffixLength::Four,
|
||||
CheckCodePrefix::PLE => SuffixLength::Zero,
|
||||
CheckCodePrefix::PLE1 => SuffixLength::One,
|
||||
CheckCodePrefix::PLE11 => SuffixLength::Two,
|
||||
CheckCodePrefix::PLE114 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLE1142 => SuffixLength::Four,
|
||||
CheckCodePrefix::PLR => SuffixLength::Zero,
|
||||
CheckCodePrefix::PLR0 => SuffixLength::One,
|
||||
CheckCodePrefix::PLR02 => SuffixLength::Two,
|
||||
CheckCodePrefix::PLR020 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLR0206 => SuffixLength::Four,
|
||||
CheckCodePrefix::PLR04 => SuffixLength::Two,
|
||||
CheckCodePrefix::PLR040 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLR0402 => SuffixLength::Four,
|
||||
CheckCodePrefix::PLR1 => SuffixLength::One,
|
||||
CheckCodePrefix::PLR17 => SuffixLength::Two,
|
||||
CheckCodePrefix::PLR170 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLR1701 => SuffixLength::Four,
|
||||
CheckCodePrefix::PLR172 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLR1722 => SuffixLength::Four,
|
||||
CheckCodePrefix::PLW => SuffixLength::Zero,
|
||||
CheckCodePrefix::PLW0 => SuffixLength::One,
|
||||
CheckCodePrefix::PLW01 => SuffixLength::Two,
|
||||
CheckCodePrefix::PLW012 => SuffixLength::Three,
|
||||
CheckCodePrefix::PLW0120 => SuffixLength::Four,
|
||||
CheckCodePrefix::Q => SuffixLength::Zero,
|
||||
CheckCodePrefix::Q0 => SuffixLength::One,
|
||||
CheckCodePrefix::Q00 => SuffixLength::Two,
|
||||
@@ -1627,6 +1974,17 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::Q001 => SuffixLength::Three,
|
||||
CheckCodePrefix::Q002 => SuffixLength::Three,
|
||||
CheckCodePrefix::Q003 => SuffixLength::Three,
|
||||
CheckCodePrefix::RET => SuffixLength::Zero,
|
||||
CheckCodePrefix::RET5 => SuffixLength::One,
|
||||
CheckCodePrefix::RET50 => SuffixLength::Two,
|
||||
CheckCodePrefix::RET501 => SuffixLength::Three,
|
||||
CheckCodePrefix::RET502 => SuffixLength::Three,
|
||||
CheckCodePrefix::RET503 => SuffixLength::Three,
|
||||
CheckCodePrefix::RET504 => SuffixLength::Three,
|
||||
CheckCodePrefix::RET505 => SuffixLength::Three,
|
||||
CheckCodePrefix::RET506 => SuffixLength::Three,
|
||||
CheckCodePrefix::RET507 => SuffixLength::Three,
|
||||
CheckCodePrefix::RET508 => SuffixLength::Three,
|
||||
CheckCodePrefix::RUF => SuffixLength::Zero,
|
||||
CheckCodePrefix::RUF0 => SuffixLength::One,
|
||||
CheckCodePrefix::RUF00 => SuffixLength::Two,
|
||||
@@ -1635,7 +1993,7 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::RUF003 => SuffixLength::Three,
|
||||
CheckCodePrefix::RUF1 => SuffixLength::One,
|
||||
CheckCodePrefix::RUF10 => SuffixLength::Two,
|
||||
CheckCodePrefix::RUF101 => SuffixLength::Three,
|
||||
CheckCodePrefix::RUF100 => SuffixLength::Three,
|
||||
CheckCodePrefix::S => SuffixLength::Zero,
|
||||
CheckCodePrefix::S1 => SuffixLength::One,
|
||||
CheckCodePrefix::S10 => SuffixLength::Two,
|
||||
@@ -1671,6 +2029,24 @@ impl CheckCodePrefix {
|
||||
CheckCodePrefix::U013 => SuffixLength::Three,
|
||||
CheckCodePrefix::U014 => SuffixLength::Three,
|
||||
CheckCodePrefix::U015 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP => SuffixLength::Zero,
|
||||
CheckCodePrefix::UP0 => SuffixLength::One,
|
||||
CheckCodePrefix::UP00 => SuffixLength::Two,
|
||||
CheckCodePrefix::UP001 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP003 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP004 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP005 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP006 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP007 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP008 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP009 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP01 => SuffixLength::Two,
|
||||
CheckCodePrefix::UP010 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP011 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP012 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP013 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP014 => SuffixLength::Three,
|
||||
CheckCodePrefix::UP015 => SuffixLength::Three,
|
||||
CheckCodePrefix::W => SuffixLength::Zero,
|
||||
CheckCodePrefix::W2 => SuffixLength::One,
|
||||
CheckCodePrefix::W29 => SuffixLength::Two,
|
||||
@@ -1711,14 +2087,19 @@ pub const CATEGORIES: &[CheckCodePrefix] = &[
|
||||
CheckCodePrefix::F,
|
||||
CheckCodePrefix::FBT,
|
||||
CheckCodePrefix::I,
|
||||
CheckCodePrefix::M,
|
||||
CheckCodePrefix::N,
|
||||
CheckCodePrefix::PGH,
|
||||
CheckCodePrefix::PLC,
|
||||
CheckCodePrefix::PLE,
|
||||
CheckCodePrefix::PLR,
|
||||
CheckCodePrefix::PLW,
|
||||
CheckCodePrefix::Q,
|
||||
CheckCodePrefix::RET,
|
||||
CheckCodePrefix::RUF,
|
||||
CheckCodePrefix::S,
|
||||
CheckCodePrefix::T,
|
||||
CheckCodePrefix::U,
|
||||
CheckCodePrefix::UP,
|
||||
CheckCodePrefix::W,
|
||||
CheckCodePrefix::YTT,
|
||||
];
|
||||
|
||||
@@ -30,9 +30,15 @@ impl Flags {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct IsortDirectives {
|
||||
pub exclusions: IntSet<usize>,
|
||||
pub splits: Vec<usize>,
|
||||
}
|
||||
|
||||
pub struct Directives {
|
||||
pub noqa_line_for: IntMap<usize, usize>,
|
||||
pub isort_exclusions: IntSet<usize>,
|
||||
pub isort: IsortDirectives,
|
||||
}
|
||||
|
||||
pub fn extract_directives(
|
||||
@@ -46,10 +52,10 @@ pub fn extract_directives(
|
||||
} else {
|
||||
IntMap::default()
|
||||
},
|
||||
isort_exclusions: if flags.contains(Flags::ISORT) {
|
||||
extract_isort_exclusions(lxr, locator)
|
||||
isort: if flags.contains(Flags::ISORT) {
|
||||
extract_isort_directives(lxr, locator)
|
||||
} else {
|
||||
IntSet::default()
|
||||
IsortDirectives::default()
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -73,17 +79,32 @@ pub fn extract_noqa_line_for(lxr: &[LexResult]) -> IntMap<usize, usize> {
|
||||
}
|
||||
|
||||
/// Extract a set of lines over which to disable isort.
|
||||
pub fn extract_isort_exclusions(lxr: &[LexResult], locator: &SourceCodeLocator) -> IntSet<usize> {
|
||||
pub fn extract_isort_directives(lxr: &[LexResult], locator: &SourceCodeLocator) -> IsortDirectives {
|
||||
let mut exclusions: IntSet<usize> = IntSet::default();
|
||||
let mut splits: Vec<usize> = Vec::default();
|
||||
let mut skip_file: bool = false;
|
||||
let mut off: Option<Location> = None;
|
||||
let mut last: Option<Location> = None;
|
||||
for &(start, ref tok, end) in lxr.iter().flatten() {
|
||||
// TODO(charlie): Modify RustPython to include the comment text in the token.
|
||||
last = Some(end);
|
||||
|
||||
// No need to keep processing, but we do need to determine the last token.
|
||||
if skip_file {
|
||||
continue;
|
||||
}
|
||||
|
||||
if matches!(tok, Tok::Comment) {
|
||||
// TODO(charlie): Modify RustPython to include the comment text in the token.
|
||||
let comment_text = locator.slice_source_code_range(&Range {
|
||||
location: start,
|
||||
end_location: end,
|
||||
});
|
||||
if off.is_some() {
|
||||
|
||||
if comment_text == "# isort: split" {
|
||||
splits.push(start.row());
|
||||
} else if comment_text == "# isort: skip_file" {
|
||||
skip_file = true;
|
||||
} else if off.is_some() {
|
||||
if comment_text == "# isort: on" {
|
||||
if let Some(start) = off {
|
||||
for row in start.row() + 1..=end.row() {
|
||||
@@ -93,43 +114,50 @@ pub fn extract_isort_exclusions(lxr: &[LexResult], locator: &SourceCodeLocator)
|
||||
off = None;
|
||||
}
|
||||
} else {
|
||||
if comment_text.contains("isort: skip") || comment_text.contains("isort:skip") {
|
||||
if comment_text.contains("isort: skip") {
|
||||
exclusions.insert(start.row());
|
||||
} else if comment_text == "# isort: off" {
|
||||
off = Some(start);
|
||||
}
|
||||
}
|
||||
} else if matches!(tok, Tok::EndOfFile) {
|
||||
if let Some(start) = off {
|
||||
for row in start.row() + 1..=end.row() {
|
||||
exclusions.insert(row);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
exclusions
|
||||
if skip_file {
|
||||
// Enforce `isort: skip_file`.
|
||||
if let Some(end) = last {
|
||||
for row in 1..=end.row() {
|
||||
exclusions.insert(row);
|
||||
}
|
||||
}
|
||||
} else if let Some(start) = off {
|
||||
// Enforce unterminated `isort: off`.
|
||||
if let Some(end) = last {
|
||||
for row in start.row() + 1..=end.row() {
|
||||
exclusions.insert(row);
|
||||
}
|
||||
}
|
||||
}
|
||||
IsortDirectives { exclusions, splits }
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use nohash_hasher::IntMap;
|
||||
use nohash_hasher::{IntMap, IntSet};
|
||||
use rustpython_parser::lexer;
|
||||
use rustpython_parser::lexer::LexResult;
|
||||
|
||||
use crate::directives::extract_noqa_line_for;
|
||||
use crate::directives::{extract_isort_directives, extract_noqa_line_for};
|
||||
use crate::SourceCodeLocator;
|
||||
|
||||
#[test]
|
||||
fn extraction() {
|
||||
let empty: IntMap<usize, usize> = IntMap::default();
|
||||
|
||||
fn noqa_extraction() {
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(
|
||||
"x = 1
|
||||
y = 2
|
||||
z = x + 1",
|
||||
)
|
||||
.collect();
|
||||
assert_eq!(extract_noqa_line_for(&lxr), empty);
|
||||
assert_eq!(extract_noqa_line_for(&lxr), IntMap::default());
|
||||
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(
|
||||
"
|
||||
@@ -138,7 +166,7 @@ y = 2
|
||||
z = x + 1",
|
||||
)
|
||||
.collect();
|
||||
assert_eq!(extract_noqa_line_for(&lxr), empty);
|
||||
assert_eq!(extract_noqa_line_for(&lxr), IntMap::default());
|
||||
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(
|
||||
"x = 1
|
||||
@@ -147,7 +175,7 @@ z = x + 1
|
||||
",
|
||||
)
|
||||
.collect();
|
||||
assert_eq!(extract_noqa_line_for(&lxr), empty);
|
||||
assert_eq!(extract_noqa_line_for(&lxr), IntMap::default());
|
||||
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(
|
||||
"x = 1
|
||||
@@ -157,7 +185,7 @@ z = x + 1
|
||||
",
|
||||
)
|
||||
.collect();
|
||||
assert_eq!(extract_noqa_line_for(&lxr), empty);
|
||||
assert_eq!(extract_noqa_line_for(&lxr), IntMap::default());
|
||||
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(
|
||||
"x = '''abc
|
||||
@@ -200,4 +228,106 @@ z = x + 1",
|
||||
IntMap::from_iter([(2, 5), (3, 5), (4, 5)])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn isort_exclusions() {
|
||||
let contents = "x = 1
|
||||
y = 2
|
||||
z = x + 1";
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(contents).collect();
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
assert_eq!(
|
||||
extract_isort_directives(&lxr, &locator).exclusions,
|
||||
IntSet::default()
|
||||
);
|
||||
|
||||
let contents = "# isort: off
|
||||
x = 1
|
||||
y = 2
|
||||
# isort: on
|
||||
z = x + 1";
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(contents).collect();
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
assert_eq!(
|
||||
extract_isort_directives(&lxr, &locator).exclusions,
|
||||
IntSet::from_iter([2, 3, 4])
|
||||
);
|
||||
|
||||
let contents = "# isort: off
|
||||
x = 1
|
||||
# isort: off
|
||||
y = 2
|
||||
# isort: on
|
||||
z = x + 1
|
||||
# isort: on";
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(contents).collect();
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
assert_eq!(
|
||||
extract_isort_directives(&lxr, &locator).exclusions,
|
||||
IntSet::from_iter([2, 3, 4, 5])
|
||||
);
|
||||
|
||||
let contents = "# isort: off
|
||||
x = 1
|
||||
y = 2
|
||||
z = x + 1";
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(contents).collect();
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
assert_eq!(
|
||||
extract_isort_directives(&lxr, &locator).exclusions,
|
||||
IntSet::from_iter([2, 3, 4])
|
||||
);
|
||||
|
||||
let contents = "# isort: skip_file
|
||||
x = 1
|
||||
y = 2
|
||||
z = x + 1";
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(contents).collect();
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
assert_eq!(
|
||||
extract_isort_directives(&lxr, &locator).exclusions,
|
||||
IntSet::from_iter([1, 2, 3, 4])
|
||||
);
|
||||
|
||||
let contents = "# isort: off
|
||||
x = 1
|
||||
# isort: on
|
||||
y = 2
|
||||
# isort: skip_file
|
||||
z = x + 1";
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(contents).collect();
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
assert_eq!(
|
||||
extract_isort_directives(&lxr, &locator).exclusions,
|
||||
IntSet::from_iter([1, 2, 3, 4, 5, 6])
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn isort_splits() {
|
||||
let contents = "x = 1
|
||||
y = 2
|
||||
z = x + 1";
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(contents).collect();
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
assert_eq!(
|
||||
extract_isort_directives(&lxr, &locator).splits,
|
||||
Vec::<usize>::new()
|
||||
);
|
||||
|
||||
let contents = "x = 1
|
||||
y = 2
|
||||
# isort: split
|
||||
z = x + 1";
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(contents).collect();
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
assert_eq!(extract_isort_directives(&lxr, &locator).splits, vec![3]);
|
||||
|
||||
let contents = "x = 1
|
||||
y = 2 # isort: split
|
||||
z = x + 1";
|
||||
let lxr: Vec<LexResult> = lexer::make_tokenizer(contents).collect();
|
||||
let locator = SourceCodeLocator::new(contents);
|
||||
assert_eq!(extract_isort_directives(&lxr, &locator).splits, vec![2]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,20 +7,20 @@ use crate::visibility::{Modifier, VisibleScope};
|
||||
|
||||
/// Extract a docstring from a function or class body.
|
||||
pub fn docstring_from(suite: &[Stmt]) -> Option<&Expr> {
|
||||
if let Some(stmt) = suite.first() {
|
||||
if let StmtKind::Expr { value } = &stmt.node {
|
||||
if matches!(
|
||||
&value.node,
|
||||
ExprKind::Constant {
|
||||
value: Constant::Str(_),
|
||||
..
|
||||
}
|
||||
) {
|
||||
return Some(value);
|
||||
}
|
||||
let stmt = suite.first()?;
|
||||
let StmtKind::Expr { value } = &stmt.node else {
|
||||
return None;
|
||||
};
|
||||
if !matches!(
|
||||
&value.node,
|
||||
ExprKind::Constant {
|
||||
value: Constant::Str(_),
|
||||
..
|
||||
}
|
||||
) {
|
||||
return None;
|
||||
}
|
||||
None
|
||||
Some(value)
|
||||
}
|
||||
|
||||
/// Extract a `Definition` from the AST node defined by a `Stmt`.
|
||||
|
||||
@@ -211,7 +211,7 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
|
||||
.chain(args.kwonlyargs.iter())
|
||||
.skip(
|
||||
// If this is a non-static method, skip `cls` or `self`.
|
||||
usize::from(!visibility::is_staticmethod(stmt)),
|
||||
usize::from(!visibility::is_staticmethod(checker, stmt)),
|
||||
)
|
||||
{
|
||||
// ANN401 for dynamically typed arguments
|
||||
@@ -283,10 +283,10 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
|
||||
}
|
||||
|
||||
// ANN101, ANN102
|
||||
if !visibility::is_staticmethod(stmt) {
|
||||
if !visibility::is_staticmethod(checker, stmt) {
|
||||
if let Some(arg) = args.args.first() {
|
||||
if arg.node.annotation.is_none() {
|
||||
if visibility::is_classmethod(stmt) {
|
||||
if visibility::is_classmethod(checker, stmt) {
|
||||
if checker.settings.enabled.contains(&CheckCode::ANN102) {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::MissingTypeCls(arg.node.arg.to_string()),
|
||||
@@ -319,14 +319,14 @@ pub fn definition(checker: &mut Checker, definition: &Definition, visibility: &V
|
||||
return;
|
||||
}
|
||||
|
||||
if visibility::is_classmethod(stmt) {
|
||||
if visibility::is_classmethod(checker, stmt) {
|
||||
if checker.settings.enabled.contains(&CheckCode::ANN206) {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::MissingReturnTypeClassMethod(name.to_string()),
|
||||
Range::from_located(stmt),
|
||||
));
|
||||
}
|
||||
} else if visibility::is_staticmethod(stmt) {
|
||||
} else if visibility::is_staticmethod(checker, stmt) {
|
||||
if checker.settings.enabled.contains(&CheckCode::ANN205) {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::MissingReturnTypeStaticMethod(name.to_string()),
|
||||
|
||||
@@ -5,10 +5,11 @@ use crate::checks::{Check, CheckKind};
|
||||
|
||||
/// S102
|
||||
pub fn exec_used(expr: &Expr, func: &Expr) -> Option<Check> {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if id == "exec" {
|
||||
return Some(Check::new(CheckKind::ExecUsed, Range::from_located(expr)));
|
||||
}
|
||||
let ExprKind::Name { id, .. } = &func.node else {
|
||||
return None;
|
||||
};
|
||||
if id != "exec" {
|
||||
return None;
|
||||
}
|
||||
None
|
||||
Some(Check::new(CheckKind::ExecUsed, Range::from_located(expr)))
|
||||
}
|
||||
|
||||
@@ -5,16 +5,15 @@ use crate::checks::{Check, CheckKind};
|
||||
use crate::flake8_bandit::helpers::{matches_password_name, string_literal};
|
||||
|
||||
fn check_password_kwarg(arg: &Located<ArgData>, default: &Expr) -> Option<Check> {
|
||||
if let Some(string) = string_literal(default) {
|
||||
let kwarg_name = &arg.node.arg;
|
||||
if matches_password_name(kwarg_name) {
|
||||
return Some(Check::new(
|
||||
CheckKind::HardcodedPasswordDefault(string.to_string()),
|
||||
Range::from_located(default),
|
||||
));
|
||||
}
|
||||
let string = string_literal(default)?;
|
||||
let kwarg_name = &arg.node.arg;
|
||||
if !matches_password_name(kwarg_name) {
|
||||
return None;
|
||||
}
|
||||
None
|
||||
Some(Check::new(
|
||||
CheckKind::HardcodedPasswordDefault(string.to_string()),
|
||||
Range::from_located(default),
|
||||
))
|
||||
}
|
||||
|
||||
/// S107
|
||||
|
||||
@@ -9,17 +9,15 @@ pub fn hardcoded_password_func_arg(keywords: &[Keyword]) -> Vec<Check> {
|
||||
keywords
|
||||
.iter()
|
||||
.filter_map(|keyword| {
|
||||
if let Some(string) = string_literal(&keyword.node.value) {
|
||||
if let Some(arg) = &keyword.node.arg {
|
||||
if matches_password_name(arg) {
|
||||
return Some(Check::new(
|
||||
CheckKind::HardcodedPasswordFuncArg(string.to_string()),
|
||||
Range::from_located(keyword),
|
||||
));
|
||||
}
|
||||
}
|
||||
let string = string_literal(&keyword.node.value)?;
|
||||
let arg = keyword.node.arg.as_ref()?;
|
||||
if !matches_password_name(arg) {
|
||||
return None;
|
||||
}
|
||||
None
|
||||
Some(Check::new(
|
||||
CheckKind::HardcodedPasswordFuncArg(string.to_string()),
|
||||
Range::from_located(keyword),
|
||||
))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -29,15 +29,14 @@ pub fn compare_to_hardcoded_password_string(left: &Expr, comparators: &[Expr]) -
|
||||
comparators
|
||||
.iter()
|
||||
.filter_map(|comp| {
|
||||
if let Some(string) = string_literal(comp) {
|
||||
if is_password_target(left) {
|
||||
return Some(Check::new(
|
||||
CheckKind::HardcodedPasswordString(string.to_string()),
|
||||
Range::from_located(comp),
|
||||
));
|
||||
}
|
||||
let string = string_literal(comp)?;
|
||||
if !is_password_target(left) {
|
||||
return None;
|
||||
}
|
||||
None
|
||||
Some(Check::new(
|
||||
CheckKind::HardcodedPasswordString(string.to_string()),
|
||||
Range::from_located(comp),
|
||||
))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
@@ -6,17 +6,18 @@ use crate::checks::{Check, CheckKind};
|
||||
|
||||
pub fn blind_except(checker: &mut Checker, handlers: &[Excepthandler]) {
|
||||
for handler in handlers {
|
||||
let ExcepthandlerKind::ExceptHandler { type_, .. } = &handler.node;
|
||||
if let Some(type_) = type_ {
|
||||
if let ExprKind::Name { id, .. } = &type_.node {
|
||||
for exception in ["BaseException", "Exception"] {
|
||||
if id == exception {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::BlindExcept,
|
||||
Range::from_located(type_),
|
||||
));
|
||||
}
|
||||
}
|
||||
let ExcepthandlerKind::ExceptHandler { type_: Some(type_), .. } = &handler.node else {
|
||||
continue;
|
||||
};
|
||||
let ExprKind::Name { id, .. } = &type_.node else {
|
||||
continue;
|
||||
};
|
||||
for exception in ["BaseException", "Exception"] {
|
||||
if id == exception {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::BlindExcept,
|
||||
Range::from_located(type_),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,11 +11,10 @@ const FUNC_NAME_ALLOWLIST: &[&str] = &["get", "setdefault", "pop", "fromkeys"];
|
||||
/// `true`, the function name must be explicitly allowed, and the argument must
|
||||
/// be either the first or second argument in the call.
|
||||
fn allow_boolean_trap(func: &Expr) -> bool {
|
||||
if let ExprKind::Attribute { attr, .. } = &func.node {
|
||||
FUNC_NAME_ALLOWLIST.contains(&attr.as_ref())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
let ExprKind::Attribute { attr, .. } = &func.node else {
|
||||
return false;
|
||||
};
|
||||
FUNC_NAME_ALLOWLIST.contains(&attr.as_ref())
|
||||
}
|
||||
|
||||
fn is_boolean_arg(arg: &Expr) -> bool {
|
||||
@@ -39,24 +38,26 @@ pub fn check_positional_boolean_in_def(checker: &mut Checker, arguments: &Argume
|
||||
if arg.node.annotation.is_none() {
|
||||
continue;
|
||||
}
|
||||
let Some(expr) = &arg.node.annotation else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let Some(expr) = &arg.node.annotation {
|
||||
// check for both bool (python class) and 'bool' (string annotation)
|
||||
let hint = match &expr.node {
|
||||
ExprKind::Name { id, .. } => id == "bool",
|
||||
ExprKind::Constant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} => value == "bool",
|
||||
_ => false,
|
||||
};
|
||||
if hint {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::BooleanPositionalArgInFunctionDefinition,
|
||||
Range::from_located(arg),
|
||||
));
|
||||
}
|
||||
// check for both bool (python class) and 'bool' (string annotation)
|
||||
let hint = match &expr.node {
|
||||
ExprKind::Name { id, .. } => id == "bool",
|
||||
ExprKind::Constant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} => value == "bool",
|
||||
_ => false,
|
||||
};
|
||||
if !hint {
|
||||
continue;
|
||||
}
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::BooleanPositionalArgInFunctionDefinition,
|
||||
Range::from_located(arg),
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,24 +67,28 @@ pub fn abstract_base_class(
|
||||
keywords: &[Keyword],
|
||||
body: &[Stmt],
|
||||
) {
|
||||
if bases.len() + keywords.len() == 1
|
||||
&& is_abc_class(
|
||||
bases,
|
||||
keywords,
|
||||
&checker.from_imports,
|
||||
&checker.import_aliases,
|
||||
)
|
||||
{
|
||||
let mut has_abstract_method = false;
|
||||
for stmt in body {
|
||||
// https://github.com/PyCQA/flake8-bugbear/issues/293
|
||||
// Ignore abc's that declares a class attribute that must be set
|
||||
if let StmtKind::AnnAssign { .. } | StmtKind::Assign { .. } = &stmt.node {
|
||||
has_abstract_method = true;
|
||||
continue;
|
||||
}
|
||||
if bases.len() + keywords.len() != 1 {
|
||||
return;
|
||||
}
|
||||
if !is_abc_class(
|
||||
bases,
|
||||
keywords,
|
||||
&checker.from_imports,
|
||||
&checker.import_aliases,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
if let StmtKind::FunctionDef {
|
||||
let mut has_abstract_method = false;
|
||||
for stmt in body {
|
||||
// https://github.com/PyCQA/flake8-bugbear/issues/293
|
||||
// Ignore abc's that declares a class attribute that must be set
|
||||
if let StmtKind::AnnAssign { .. } | StmtKind::Assign { .. } = &stmt.node {
|
||||
has_abstract_method = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
let (StmtKind::FunctionDef {
|
||||
decorator_list,
|
||||
body,
|
||||
..
|
||||
@@ -93,36 +97,38 @@ pub fn abstract_base_class(
|
||||
decorator_list,
|
||||
body,
|
||||
..
|
||||
} = &stmt.node
|
||||
{
|
||||
let has_abstract_decorator = decorator_list
|
||||
.iter()
|
||||
.any(|d| is_abstractmethod(d, &checker.from_imports, &checker.import_aliases));
|
||||
}) = &stmt.node else {
|
||||
continue;
|
||||
};
|
||||
|
||||
has_abstract_method |= has_abstract_decorator;
|
||||
let has_abstract_decorator = decorator_list
|
||||
.iter()
|
||||
.any(|d| is_abstractmethod(d, &checker.from_imports, &checker.import_aliases));
|
||||
|
||||
if checker.settings.enabled.contains(&CheckCode::B027) {
|
||||
if !has_abstract_decorator
|
||||
&& is_empty_body(body)
|
||||
&& !decorator_list
|
||||
.iter()
|
||||
.any(|d| is_overload(d, &checker.from_imports, &checker.import_aliases))
|
||||
{
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::EmptyMethodWithoutAbstractDecorator(name.to_string()),
|
||||
Range::from_located(stmt),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
has_abstract_method |= has_abstract_decorator;
|
||||
|
||||
if !checker.settings.enabled.contains(&CheckCode::B027) {
|
||||
continue;
|
||||
}
|
||||
if checker.settings.enabled.contains(&CheckCode::B024) {
|
||||
if !has_abstract_method {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::AbstractBaseClassWithoutAbstractMethod(name.to_string()),
|
||||
Range::from_located(stmt),
|
||||
));
|
||||
}
|
||||
|
||||
if !has_abstract_decorator
|
||||
&& is_empty_body(body)
|
||||
&& !decorator_list
|
||||
.iter()
|
||||
.any(|d| is_overload(d, &checker.from_imports, &checker.import_aliases))
|
||||
{
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::EmptyMethodWithoutAbstractDecorator(name.to_string()),
|
||||
Range::from_located(stmt),
|
||||
));
|
||||
}
|
||||
}
|
||||
if checker.settings.enabled.contains(&CheckCode::B024) {
|
||||
if !has_abstract_method {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::AbstractBaseClassWithoutAbstractMethod(name.to_string()),
|
||||
Range::from_located(stmt),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,23 +38,24 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt {
|
||||
|
||||
/// B011
|
||||
pub fn assert_false(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg: Option<&Expr>) {
|
||||
if let ExprKind::Constant {
|
||||
let ExprKind::Constant {
|
||||
value: Constant::Bool(false),
|
||||
..
|
||||
} = &test.node
|
||||
{
|
||||
let mut check = Check::new(CheckKind::DoNotAssertFalse, Range::from_located(test));
|
||||
if checker.patch(check.kind.code()) {
|
||||
let mut generator = SourceGenerator::new();
|
||||
generator.unparse_stmt(&assertion_error(msg));
|
||||
if let Ok(content) = generator.generate() {
|
||||
check.amend(Fix::replacement(
|
||||
content,
|
||||
stmt.location,
|
||||
stmt.end_location.unwrap(),
|
||||
));
|
||||
}
|
||||
} = &test.node else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut check = Check::new(CheckKind::DoNotAssertFalse, Range::from_located(test));
|
||||
if checker.patch(check.kind.code()) {
|
||||
let mut generator = SourceGenerator::new();
|
||||
generator.unparse_stmt(&assertion_error(msg));
|
||||
if let Ok(content) = generator.generate() {
|
||||
check.amend(Fix::replacement(
|
||||
content,
|
||||
stmt.location,
|
||||
stmt.end_location.unwrap(),
|
||||
));
|
||||
}
|
||||
checker.add_check(check);
|
||||
}
|
||||
checker.add_check(check);
|
||||
}
|
||||
|
||||
@@ -1,25 +1,40 @@
|
||||
use rustpython_ast::{ExprKind, Stmt, Withitem};
|
||||
|
||||
use crate::ast::helpers::match_name_or_attr;
|
||||
use crate::ast::helpers::match_module_member;
|
||||
use crate::ast::types::Range;
|
||||
use crate::check_ast::Checker;
|
||||
use crate::checks::{Check, CheckKind};
|
||||
|
||||
/// B017
|
||||
pub fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: &[Withitem]) {
|
||||
if let Some(item) = items.first() {
|
||||
let item_context = &item.context_expr;
|
||||
if let ExprKind::Call { func, args, .. } = &item_context.node {
|
||||
if args.len() == 1
|
||||
&& item.optional_vars.is_none()
|
||||
&& match_name_or_attr(func, "assertRaises")
|
||||
&& match_name_or_attr(args.first().unwrap(), "Exception")
|
||||
{
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::NoAssertRaisesException,
|
||||
Range::from_located(stmt),
|
||||
));
|
||||
}
|
||||
}
|
||||
let Some(item) = items.first() else {
|
||||
return;
|
||||
};
|
||||
let item_context = &item.context_expr;
|
||||
let ExprKind::Call { func, args, .. } = &item_context.node else {
|
||||
return;
|
||||
};
|
||||
if args.len() != 1 {
|
||||
return;
|
||||
}
|
||||
if item.optional_vars.is_some() {
|
||||
return;
|
||||
}
|
||||
if !matches!(&func.node, ExprKind::Attribute { attr, .. } if attr == "assertRaises") {
|
||||
return;
|
||||
}
|
||||
if !match_module_member(
|
||||
args.first().unwrap(),
|
||||
"",
|
||||
"Exception",
|
||||
&checker.from_imports,
|
||||
&checker.import_aliases,
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::NoAssertRaisesException,
|
||||
Range::from_located(stmt),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -6,19 +6,24 @@ use crate::checks::{Check, CheckKind};
|
||||
|
||||
/// B003
|
||||
pub fn assignment_to_os_environ(checker: &mut Checker, targets: &[Expr]) {
|
||||
if targets.len() == 1 {
|
||||
let target = &targets[0];
|
||||
if let ExprKind::Attribute { value, attr, .. } = &target.node {
|
||||
if attr == "environ" {
|
||||
if let ExprKind::Name { id, .. } = &value.node {
|
||||
if id == "os" {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::AssignmentToOsEnviron,
|
||||
Range::from_located(target),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if targets.len() != 1 {
|
||||
return;
|
||||
}
|
||||
let target = &targets[0];
|
||||
let ExprKind::Attribute { value, attr, .. } = &target.node else {
|
||||
return;
|
||||
};
|
||||
if attr != "environ" {
|
||||
return;
|
||||
}
|
||||
let ExprKind::Name { id, .. } = &value.node else {
|
||||
return;
|
||||
};
|
||||
if id != "os" {
|
||||
return;
|
||||
}
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::AssignmentToOsEnviron,
|
||||
Range::from_located(target),
|
||||
));
|
||||
}
|
||||
|
||||
@@ -13,29 +13,30 @@ fn is_cache_func(checker: &Checker, expr: &Expr) -> bool {
|
||||
|
||||
/// B019
|
||||
pub fn cached_instance_method(checker: &mut Checker, decorator_list: &[Expr]) {
|
||||
if matches!(checker.current_scope().kind, ScopeKind::Class(_)) {
|
||||
for decorator in decorator_list {
|
||||
// TODO(charlie): This should take into account `classmethod-decorators` and
|
||||
// `staticmethod-decorators`.
|
||||
if let ExprKind::Name { id, .. } = &decorator.node {
|
||||
if id == "classmethod" || id == "staticmethod" {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
for decorator in decorator_list {
|
||||
if is_cache_func(
|
||||
checker,
|
||||
match &decorator.node {
|
||||
ExprKind::Call { func, .. } => func,
|
||||
_ => decorator,
|
||||
},
|
||||
) {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::CachedInstanceMethod,
|
||||
Range::from_located(decorator),
|
||||
));
|
||||
if !matches!(checker.current_scope().kind, ScopeKind::Class(_)) {
|
||||
return;
|
||||
}
|
||||
for decorator in decorator_list {
|
||||
// TODO(charlie): This should take into account `classmethod-decorators` and
|
||||
// `staticmethod-decorators`.
|
||||
if let ExprKind::Name { id, .. } = &decorator.node {
|
||||
if id == "classmethod" || id == "staticmethod" {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
for decorator in decorator_list {
|
||||
if is_cache_func(
|
||||
checker,
|
||||
match &decorator.node {
|
||||
ExprKind::Call { func, .. } => func,
|
||||
_ => decorator,
|
||||
},
|
||||
) {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::CachedInstanceMethod,
|
||||
Range::from_located(decorator),
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@ use crate::checks::{Check, CheckKind};
|
||||
|
||||
/// B016
|
||||
pub fn cannot_raise_literal(checker: &mut Checker, expr: &Expr) {
|
||||
if let ExprKind::Constant { .. } = &expr.node {
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::CannotRaiseLiteral,
|
||||
Range::from_located(expr),
|
||||
));
|
||||
}
|
||||
let ExprKind::Constant { .. } = &expr.node else {
|
||||
return;
|
||||
};
|
||||
checker.add_check(Check::new(
|
||||
CheckKind::CannotRaiseLiteral,
|
||||
Range::from_located(expr),
|
||||
));
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user