Compare commits
76 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f1d3e3698a | ||
|
|
080411bc89 | ||
|
|
f2ad915224 | ||
|
|
71543eeabc | ||
|
|
44025f1c92 | ||
|
|
971bf6d232 | ||
|
|
0acc47386a | ||
|
|
982ac6b0ad | ||
|
|
541440f7a8 | ||
|
|
66dde46e03 | ||
|
|
1339e2a002 | ||
|
|
38ad10f60d | ||
|
|
88e78c5cde | ||
|
|
436aeed20a | ||
|
|
b94169a8bb | ||
|
|
995994be3e | ||
|
|
f001305b2e | ||
|
|
e88093541f | ||
|
|
da41a495f1 | ||
|
|
55b7ec8f85 | ||
|
|
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 |
@@ -1,6 +1,6 @@
|
||||
repos:
|
||||
- repo: https://github.com/charliermarsh/ruff-pre-commit
|
||||
rev: v0.0.152
|
||||
rev: v0.0.165
|
||||
hooks:
|
||||
- id: ruff
|
||||
|
||||
|
||||
411
Cargo.lock
generated
411
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.152-dev.0"
|
||||
version = "0.0.165-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.152"
|
||||
version = "0.0.165"
|
||||
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",
|
||||
@@ -1871,6 +1855,7 @@ dependencies = [
|
||||
"rayon",
|
||||
"regex",
|
||||
"ropey",
|
||||
"ruff_macros",
|
||||
"rustc-hash",
|
||||
"rustpython-ast",
|
||||
"rustpython-common",
|
||||
@@ -1889,13 +1874,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff_dev"
|
||||
version = "0.0.152"
|
||||
version = "0.0.165"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap 4.0.22",
|
||||
"clap 4.0.29",
|
||||
"codegen",
|
||||
"itertools",
|
||||
"libcst",
|
||||
"once_cell",
|
||||
"ruff",
|
||||
"rustpython-ast",
|
||||
"rustpython-common",
|
||||
@@ -1904,12 +1890,36 @@ dependencies = [
|
||||
"strum_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruff_macros"
|
||||
version = "0.0.161"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn",
|
||||
"textwrap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
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 +1935,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 +1945,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 +1968,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 +1985,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 +2058,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 +2078,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 +2089,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 +2099,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 +2172,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 +2192,7 @@ dependencies = [
|
||||
"libc",
|
||||
"redox_syscall",
|
||||
"remove_dir_all",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2202,7 +2203,7 @@ checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
|
||||
dependencies = [
|
||||
"dirs-next",
|
||||
"rustversion",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2221,7 +2222,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "633c1a546cee861a1a6d0dc69ebeca693bf4296661ba7852b9d21d159e0506df"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2304,7 +2305,7 @@ checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"wasi 0.10.0+wasi-snapshot-preview1",
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2567,7 +2568,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 +2690,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 +2700,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 +2712,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 +2778,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 +2793,5 @@ version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1"
|
||||
dependencies = [
|
||||
"winapi 0.3.9",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
11
Cargo.toml
11
Cargo.toml
@@ -6,7 +6,7 @@ members = [
|
||||
|
||||
[package]
|
||||
name = "ruff"
|
||||
version = "0.0.152"
|
||||
version = "0.0.165"
|
||||
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"] }
|
||||
@@ -41,10 +41,11 @@ quick-junit = { version = "0.3.2" }
|
||||
rayon = { version = "1.5.3" }
|
||||
regex = { version = "1.6.0" }
|
||||
ropey = { version = "1.5.0", features = ["cr_lines", "simd"], default-features = false }
|
||||
ruff_macros = { version = "0.0.161", path = "ruff_macros" }
|
||||
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"] }
|
||||
|
||||
25
LICENSE
25
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)
|
||||
|
||||
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.152"
|
||||
version = "0.0.165"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"clap",
|
||||
@@ -1975,7 +1975,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "ruff"
|
||||
version = "0.0.152"
|
||||
version = "0.0.165"
|
||||
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.152-dev.0"
|
||||
version = "0.0.165-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
|
||||
41
resources/test/fixtures/isort/insert_empty_lines.py
vendored
Normal file
41
resources/test/fixtures/isort/insert_empty_lines.py
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
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"""
|
||||
|
||||
if True:
|
||||
import os
|
||||
|
||||
|
||||
def f():
|
||||
pass
|
||||
|
||||
|
||||
if True:
|
||||
import os
|
||||
def f():
|
||||
pass
|
||||
|
||||
if True:
|
||||
x = 1
|
||||
import collections
|
||||
import typing
|
||||
class X: pass
|
||||
|
||||
if True:
|
||||
x = 1
|
||||
import collections
|
||||
import typing
|
||||
def f(): pass
|
||||
1
resources/test/fixtures/isort/no_wrap_star.py
vendored
Normal file
1
resources/test/fixtures/isort/no_wrap_star.py
vendored
Normal file
@@ -0,0 +1 @@
|
||||
from .subscription import * # type: ignore # some very long comment explaining why this needs a type ignore
|
||||
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
|
||||
8
resources/test/fixtures/pydocstyle/D.py
vendored
8
resources/test/fixtures/pydocstyle/D.py
vendored
@@ -571,3 +571,11 @@ def multiline_trailing_and_leading_space():
|
||||
"""
|
||||
|
||||
pass
|
||||
|
||||
|
||||
@expect('D210: No whitespaces allowed surrounding docstring text')
|
||||
@expect("D400: First line should end with a period (not '\"')")
|
||||
@expect("D415: First line should end with a period, question mark, "
|
||||
"or exclamation point (not '\"')")
|
||||
def endswith_quote():
|
||||
"""Whitespace at the end, but also a quote" """
|
||||
|
||||
73
resources/test/fixtures/pydocstyle/D400.py
vendored
Normal file
73
resources/test/fixtures/pydocstyle/D400.py
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
def f():
|
||||
"Here's a line without a period"
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
"""Here's a line without a period"""
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
"""
|
||||
Here's a line without a period,
|
||||
but here's the next line
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
"""Here's a line without a period"""
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
"""
|
||||
Here's a line without a period,
|
||||
but here's the next line"""
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
"""
|
||||
Here's a line without a period,
|
||||
but here's the next line with trailing space """
|
||||
...
|
||||
|
||||
|
||||
|
||||
def f():
|
||||
r"Here's a line without a period"
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
r"""Here's a line without a period"""
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
r"""
|
||||
Here's a line without a period,
|
||||
but here's the next line
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
r"""Here's a line without a period"""
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
r"""
|
||||
Here's a line without a period,
|
||||
but here's the next line"""
|
||||
...
|
||||
|
||||
|
||||
def f():
|
||||
r"""
|
||||
Here's a line without a period,
|
||||
but here's the next line with trailing space """
|
||||
...
|
||||
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
|
||||
|
||||
@@ -65,3 +65,8 @@ def f7():
|
||||
|
||||
with connect() as (connection, cursor):
|
||||
cursor.execute("SELECT * FROM users")
|
||||
|
||||
|
||||
def f8():
|
||||
with open("file") as f, open("") as ((a, b)):
|
||||
print("hello")
|
||||
24
resources/test/fixtures/pyflakes/F841_1.py
vendored
Normal file
24
resources/test/fixtures/pyflakes/F841_1.py
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
def f(tup):
|
||||
x, y = tup # this does NOT trigger F841
|
||||
|
||||
|
||||
def f():
|
||||
x, y = 1, 2 # this triggers F841 as it's just a simple assignment where unpacking isn't needed
|
||||
|
||||
|
||||
def f():
|
||||
(x, y) = coords = 1, 2 # this does NOT trigger F841
|
||||
if x > 1:
|
||||
print(coords)
|
||||
|
||||
|
||||
def f():
|
||||
(x, y) = coords = 1, 2 # this triggers F841 on coords
|
||||
|
||||
|
||||
def f():
|
||||
coords = (x, y) = 1, 2 # this triggers F841 on coords
|
||||
|
||||
|
||||
def f():
|
||||
(a, b) = (x, y) = 1, 2 # this triggers F841 on everything
|
||||
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")
|
||||
7
resources/test/fixtures/ruff/RUF001.py
vendored
7
resources/test/fixtures/ruff/RUF001.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/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: ᜵
|
||||
...
|
||||
@@ -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.152"
|
||||
version = "0.0.165"
|
||||
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;");
|
||||
|
||||
125
ruff_dev/src/generate_options.rs
Normal file
125
ruff_dev/src/generate_options.rs
Normal file
@@ -0,0 +1,125 @@
|
||||
//! Generate a Markdown-compatible listing of configuration options.
|
||||
|
||||
use std::fs;
|
||||
use std::fs::OpenOptions;
|
||||
use std::io::Write;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use anyhow::Result;
|
||||
use clap::Args;
|
||||
use itertools::Itertools;
|
||||
use ruff::settings::options::Options;
|
||||
use ruff::settings::options_base::{ConfigurationOptions, OptionEntry, OptionField};
|
||||
|
||||
const BEGIN_PRAGMA: &str = "<!-- Begin auto-generated options sections. -->";
|
||||
const END_PRAGMA: &str = "<!-- End auto-generated options sections. -->";
|
||||
|
||||
#[derive(Args)]
|
||||
pub struct Cli {
|
||||
/// Write the generated table to stdout (rather than to `README.md`).
|
||||
#[arg(long)]
|
||||
dry_run: bool,
|
||||
}
|
||||
|
||||
fn emit_field(output: &mut String, field: &OptionField, group_name: Option<&str>) {
|
||||
output.push_str(&format!("#### [`{0}`](#{0})\n", field.name));
|
||||
output.push('\n');
|
||||
output.push_str(field.doc);
|
||||
output.push_str("\n\n");
|
||||
output.push_str(&format!("**Default value**: `{}`\n", field.default));
|
||||
output.push('\n');
|
||||
output.push_str(&format!("**Type**: `{}`\n", field.value_type));
|
||||
output.push('\n');
|
||||
output.push_str(&format!(
|
||||
"**Example usage**:\n\n```toml\n[tool.ruff{}]\n{}\n```\n",
|
||||
if group_name.is_some() {
|
||||
format!(".{}", group_name.unwrap())
|
||||
} else {
|
||||
String::new()
|
||||
},
|
||||
field.example
|
||||
));
|
||||
output.push('\n');
|
||||
}
|
||||
|
||||
pub fn main(cli: &Cli) -> Result<()> {
|
||||
let mut output = String::new();
|
||||
|
||||
// Generate all the top-level fields.
|
||||
for field in Options::get_available_options()
|
||||
.into_iter()
|
||||
.filter_map(|entry| {
|
||||
if let OptionEntry::Field(field) = entry {
|
||||
Some(field)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.sorted_by_key(|field| field.name)
|
||||
{
|
||||
emit_field(&mut output, &field, None);
|
||||
output.push_str("---\n\n");
|
||||
}
|
||||
|
||||
// Generate all the sub-groups.
|
||||
for group in Options::get_available_options()
|
||||
.into_iter()
|
||||
.filter_map(|entry| {
|
||||
if let OptionEntry::Group(group) = entry {
|
||||
Some(group)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.sorted_by_key(|group| group.name)
|
||||
{
|
||||
output.push_str(&format!("### `{}`\n", group.name));
|
||||
output.push('\n');
|
||||
for field in group
|
||||
.fields
|
||||
.iter()
|
||||
.filter_map(|entry| {
|
||||
if let OptionEntry::Field(field) = entry {
|
||||
Some(field)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.sorted_by_key(|field| field.name)
|
||||
{
|
||||
emit_field(&mut output, field, Some(group.name));
|
||||
output.push_str("---\n\n");
|
||||
}
|
||||
}
|
||||
|
||||
if cli.dry_run {
|
||||
print!("{output}");
|
||||
} else {
|
||||
// Read the existing file.
|
||||
let file = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
|
||||
.parent()
|
||||
.expect("Failed to find root directory")
|
||||
.join("README.md");
|
||||
let existing = fs::read_to_string(&file)?;
|
||||
|
||||
// Extract the prefix.
|
||||
let index = existing
|
||||
.find(BEGIN_PRAGMA)
|
||||
.expect("Unable to find begin pragma");
|
||||
let prefix = &existing[..index + BEGIN_PRAGMA.len()];
|
||||
|
||||
// Extract the suffix.
|
||||
let index = existing
|
||||
.find(END_PRAGMA)
|
||||
.expect("Unable to find end pragma");
|
||||
let suffix = &existing[index..];
|
||||
|
||||
// Write the prefix, new contents, and suffix.
|
||||
let mut f = OpenOptions::new().write(true).truncate(true).open(&file)?;
|
||||
write!(f, "{prefix}\n\n")?;
|
||||
write!(f, "{output}")?;
|
||||
write!(f, "{suffix}")?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
)]
|
||||
|
||||
pub mod generate_check_code_prefix;
|
||||
pub mod generate_options;
|
||||
pub mod generate_rules_table;
|
||||
pub mod generate_source_code;
|
||||
pub mod print_ast;
|
||||
|
||||
@@ -14,8 +14,8 @@
|
||||
use anyhow::Result;
|
||||
use clap::{Parser, Subcommand};
|
||||
use ruff_dev::{
|
||||
generate_check_code_prefix, generate_rules_table, generate_source_code, print_ast, print_cst,
|
||||
print_tokens,
|
||||
generate_check_code_prefix, generate_options, generate_rules_table, generate_source_code,
|
||||
print_ast, print_cst, print_tokens,
|
||||
};
|
||||
|
||||
#[derive(Parser)]
|
||||
@@ -32,6 +32,8 @@ enum Commands {
|
||||
GenerateCheckCodePrefix(generate_check_code_prefix::Cli),
|
||||
/// Generate a Markdown-compatible table of supported lint rules.
|
||||
GenerateRulesTable(generate_rules_table::Cli),
|
||||
/// Generate a Markdown-compatible listing of configuration options.
|
||||
GenerateOptions(generate_options::Cli),
|
||||
/// Run round-trip source code generation on a given Python file.
|
||||
GenerateSourceCode(generate_source_code::Cli),
|
||||
/// Print the AST for a given Python file.
|
||||
@@ -48,6 +50,7 @@ fn main() -> Result<()> {
|
||||
Commands::GenerateCheckCodePrefix(args) => generate_check_code_prefix::main(args)?,
|
||||
Commands::GenerateRulesTable(args) => generate_rules_table::main(args)?,
|
||||
Commands::GenerateSourceCode(args) => generate_source_code::main(args)?,
|
||||
Commands::GenerateOptions(args) => generate_options::main(args)?,
|
||||
Commands::PrintAST(args) => print_ast::main(args)?,
|
||||
Commands::PrintCST(args) => print_cst::main(args)?,
|
||||
Commands::PrintTokens(args) => print_tokens::main(args)?,
|
||||
|
||||
13
ruff_macros/Cargo.toml
Normal file
13
ruff_macros/Cargo.toml
Normal file
@@ -0,0 +1,13 @@
|
||||
[package]
|
||||
name = "ruff_macros"
|
||||
version = "0.0.161"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2 = { version = "1.0.47" }
|
||||
quote = { version = "1.0.21" }
|
||||
syn = { version = "1.0.103", features = ["derive", "parsing"] }
|
||||
textwrap = { version = "0.16.0" }
|
||||
177
ruff_macros/src/lib.rs
Normal file
177
ruff_macros/src/lib.rs
Normal file
@@ -0,0 +1,177 @@
|
||||
#![allow(
|
||||
clippy::collapsible_else_if,
|
||||
clippy::collapsible_if,
|
||||
clippy::implicit_hasher,
|
||||
clippy::match_same_arms,
|
||||
clippy::missing_errors_doc,
|
||||
clippy::missing_panics_doc,
|
||||
clippy::module_name_repetitions,
|
||||
clippy::must_use_candidate,
|
||||
clippy::similar_names,
|
||||
clippy::too_many_lines
|
||||
)]
|
||||
|
||||
use quote::{quote, quote_spanned};
|
||||
use syn::parse::{Parse, ParseStream};
|
||||
use syn::token::Comma;
|
||||
use syn::{
|
||||
parse_macro_input, AngleBracketedGenericArguments, Attribute, Data, DataStruct, DeriveInput,
|
||||
Field, Fields, Lit, LitStr, Path, PathArguments, PathSegment, Token, Type, TypePath,
|
||||
};
|
||||
|
||||
#[proc_macro_derive(ConfigurationOptions, attributes(option, option_group))]
|
||||
pub fn derive(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
|
||||
let input = parse_macro_input!(input as DeriveInput);
|
||||
|
||||
derive_impl(input)
|
||||
.unwrap_or_else(syn::Error::into_compile_error)
|
||||
.into()
|
||||
}
|
||||
|
||||
fn derive_impl(input: DeriveInput) -> syn::Result<proc_macro2::TokenStream> {
|
||||
let DeriveInput { ident, data, .. } = input;
|
||||
|
||||
match data {
|
||||
Data::Struct(DataStruct {
|
||||
fields: Fields::Named(fields),
|
||||
..
|
||||
}) => {
|
||||
let mut output = vec![];
|
||||
|
||||
for field in fields.named.iter() {
|
||||
if let Some(attr) = field.attrs.iter().find(|a| a.path.is_ident("option")) {
|
||||
output.push(handle_option(field, attr)?);
|
||||
};
|
||||
|
||||
if field.attrs.iter().any(|a| a.path.is_ident("option_group")) {
|
||||
output.push(handle_option_group(field)?);
|
||||
};
|
||||
}
|
||||
|
||||
Ok(quote! {
|
||||
use crate::settings::options_base::{OptionEntry, OptionField, OptionGroup, ConfigurationOptions};
|
||||
|
||||
#[automatically_derived]
|
||||
impl ConfigurationOptions for #ident {
|
||||
fn get_available_options() -> Vec<OptionEntry> {
|
||||
vec![#(#output),*]
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
_ => Err(syn::Error::new(
|
||||
ident.span(),
|
||||
"Can only derive ConfigurationOptions from structs with named fields.",
|
||||
)),
|
||||
}
|
||||
}
|
||||
|
||||
/// For a field with type `Option<Foobar>` where `Foobar` itself is a struct
|
||||
/// deriving `ConfigurationOptions`, create code that calls retrieves options
|
||||
/// from that group: `Foobar::get_available_options()`
|
||||
fn handle_option_group(field: &Field) -> syn::Result<proc_macro2::TokenStream> {
|
||||
// unwrap is safe because we're only going over named fields
|
||||
let ident = field.ident.as_ref().unwrap();
|
||||
|
||||
match &field.ty {
|
||||
Type::Path(TypePath {
|
||||
path: Path { segments, .. },
|
||||
..
|
||||
}) => match segments.first() {
|
||||
Some(PathSegment {
|
||||
ident: type_ident,
|
||||
arguments:
|
||||
PathArguments::AngleBracketed(AngleBracketedGenericArguments { args, .. }),
|
||||
..
|
||||
}) if type_ident == "Option" => {
|
||||
let path = &args[0];
|
||||
let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span());
|
||||
|
||||
Ok(quote_spanned!(
|
||||
ident.span() => OptionEntry::Group(OptionGroup {
|
||||
name: #kebab_name,
|
||||
fields: #path::get_available_options(),
|
||||
})
|
||||
))
|
||||
}
|
||||
_ => Err(syn::Error::new(
|
||||
ident.span(),
|
||||
"Expected `Option<_>` as type.",
|
||||
)),
|
||||
},
|
||||
_ => Err(syn::Error::new(ident.span(), "Expected type.")),
|
||||
}
|
||||
}
|
||||
|
||||
/// Parse an `#[option(doc="...", default="...", value_type="...",
|
||||
/// example="...")]` attribute and return data in the form of an `OptionField`.
|
||||
fn handle_option(field: &Field, attr: &Attribute) -> syn::Result<proc_macro2::TokenStream> {
|
||||
// unwrap is safe because we're only going over named fields
|
||||
let ident = field.ident.as_ref().unwrap();
|
||||
|
||||
let FieldAttributes {
|
||||
doc,
|
||||
default,
|
||||
value_type,
|
||||
example,
|
||||
} = attr.parse_args::<FieldAttributes>()?;
|
||||
let kebab_name = LitStr::new(&ident.to_string().replace('_', "-"), ident.span());
|
||||
|
||||
Ok(quote_spanned!(
|
||||
ident.span() => OptionEntry::Field(OptionField {
|
||||
name: #kebab_name,
|
||||
doc: &#doc,
|
||||
default: &#default,
|
||||
value_type: &#value_type,
|
||||
example: &#example,
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
struct FieldAttributes {
|
||||
doc: String,
|
||||
default: String,
|
||||
value_type: String,
|
||||
example: String,
|
||||
}
|
||||
|
||||
impl Parse for FieldAttributes {
|
||||
fn parse(input: ParseStream) -> syn::Result<Self> {
|
||||
let doc = _parse_key_value(input, "doc")?;
|
||||
input.parse::<Comma>()?;
|
||||
let default = _parse_key_value(input, "default")?;
|
||||
input.parse::<Comma>()?;
|
||||
let value_type = _parse_key_value(input, "value_type")?;
|
||||
input.parse::<Comma>()?;
|
||||
let example = _parse_key_value(input, "example")?;
|
||||
if !input.is_empty() {
|
||||
input.parse::<Comma>()?;
|
||||
}
|
||||
|
||||
Ok(FieldAttributes {
|
||||
doc: textwrap::dedent(&doc).trim_matches('\n').to_string(),
|
||||
default,
|
||||
value_type,
|
||||
example: textwrap::dedent(&example).trim_matches('\n').to_string(),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
fn _parse_key_value(input: ParseStream, name: &str) -> syn::Result<String> {
|
||||
let ident: proc_macro2::Ident = input.parse()?;
|
||||
if ident != name {
|
||||
return Err(syn::Error::new(
|
||||
ident.span(),
|
||||
format!("Expected `{name}` name"),
|
||||
));
|
||||
}
|
||||
|
||||
input.parse::<Token![=]>()?;
|
||||
let value: Lit = input.parse()?;
|
||||
|
||||
match &value {
|
||||
Lit::Str(v) => Ok(v.value()),
|
||||
_ => Err(syn::Error::new(value.span(), "Expected literal string")),
|
||||
}
|
||||
}
|
||||
@@ -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};
|
||||
|
||||
@@ -91,22 +94,275 @@ 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;
|
||||
/// Returns `true` if `parent` contains `child`.
|
||||
fn contains(parent: &Expr, child: &Expr) -> bool {
|
||||
match &parent.node {
|
||||
ExprKind::BoolOp { values, .. } => values.iter().any(|parent| contains(parent, child)),
|
||||
ExprKind::NamedExpr { target, value } => contains(target, child) || contains(value, child),
|
||||
ExprKind::BinOp { left, right, .. } => contains(left, child) || contains(right, child),
|
||||
ExprKind::UnaryOp { operand, .. } => contains(operand, child),
|
||||
ExprKind::Lambda { body, .. } => contains(body, child),
|
||||
ExprKind::IfExp { test, body, orelse } => {
|
||||
contains(test, child) || contains(body, child) || contains(orelse, child)
|
||||
}
|
||||
match &value.node {
|
||||
ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. } => return false,
|
||||
_ => {}
|
||||
ExprKind::Dict { keys, values } => keys
|
||||
.iter()
|
||||
.chain(values.iter())
|
||||
.any(|parent| contains(parent, child)),
|
||||
ExprKind::Set { elts } => elts.iter().any(|parent| contains(parent, child)),
|
||||
ExprKind::ListComp { elt, .. } => contains(elt, child),
|
||||
ExprKind::SetComp { elt, .. } => contains(elt, child),
|
||||
ExprKind::DictComp { key, value, .. } => contains(key, child) || contains(value, child),
|
||||
ExprKind::GeneratorExp { elt, .. } => contains(elt, child),
|
||||
ExprKind::Await { value } => contains(value, child),
|
||||
ExprKind::Yield { value } => value.as_ref().map_or(false, |value| contains(value, child)),
|
||||
ExprKind::YieldFrom { value } => contains(value, child),
|
||||
ExprKind::Compare {
|
||||
left, comparators, ..
|
||||
} => contains(left, child) || comparators.iter().any(|parent| contains(parent, child)),
|
||||
ExprKind::Call {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
} => {
|
||||
contains(func, child)
|
||||
|| args.iter().any(|parent| contains(parent, child))
|
||||
|| keywords
|
||||
.iter()
|
||||
.any(|keyword| contains(&keyword.node.value, child))
|
||||
}
|
||||
ExprKind::FormattedValue {
|
||||
value, format_spec, ..
|
||||
} => {
|
||||
contains(value, child)
|
||||
|| format_spec
|
||||
.as_ref()
|
||||
.map_or(false, |value| contains(value, child))
|
||||
}
|
||||
ExprKind::JoinedStr { values } => values.iter().any(|parent| contains(parent, child)),
|
||||
ExprKind::Constant { .. } => false,
|
||||
ExprKind::Attribute { value, .. } => contains(value, child),
|
||||
ExprKind::Subscript { value, slice, .. } => {
|
||||
contains(value, child) || contains(slice, child)
|
||||
}
|
||||
ExprKind::Starred { value, .. } => contains(value, child),
|
||||
ExprKind::Name { .. } => parent == child,
|
||||
ExprKind::List { elts, .. } => elts.iter().any(|parent| contains(parent, child)),
|
||||
ExprKind::Tuple { elts, .. } => elts.iter().any(|parent| contains(parent, child)),
|
||||
ExprKind::Slice { lower, upper, step } => {
|
||||
lower.as_ref().map_or(false, |value| contains(value, child))
|
||||
|| upper.as_ref().map_or(false, |value| contains(value, child))
|
||||
|| step.as_ref().map_or(false, |value| contains(value, child))
|
||||
}
|
||||
return true;
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
/// Check if a node represents an unpacking assignment.
|
||||
pub fn is_unpacking_assignment(parent: &Stmt, child: &Expr) -> bool {
|
||||
match &parent.node {
|
||||
StmtKind::With { items, .. } => items.iter().any(|item| {
|
||||
if let Some(optional_vars) = &item.optional_vars {
|
||||
if matches!(optional_vars.node, ExprKind::Tuple { .. }) {
|
||||
if contains(optional_vars, child) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
false
|
||||
}),
|
||||
StmtKind::Assign { targets, value, .. } => {
|
||||
// In `(a, b) = (1, 2)`, `(1, 2)` is the target, and it is a tuple.
|
||||
let value_is_tuple = matches!(
|
||||
&value.node,
|
||||
ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. }
|
||||
);
|
||||
// In `(a, b) = coords = (1, 2)`, `(a, b)` and `coords` are the targets, and
|
||||
// `(a, b`) is a tuple. (We use "tuple" as a placeholder for any
|
||||
// unpackable expression.)
|
||||
let targets_are_tuples = targets.iter().all(|item| {
|
||||
matches!(
|
||||
item.node,
|
||||
ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. }
|
||||
)
|
||||
});
|
||||
// If we're looking at `a` in `(a, b) = coords = (1, 2)`, then we should
|
||||
// identify that the current expression is in a tuple.
|
||||
let child_in_tuple = targets_are_tuples
|
||||
|| targets.iter().any(|item| {
|
||||
matches!(
|
||||
item.node,
|
||||
ExprKind::Set { .. } | ExprKind::List { .. } | ExprKind::Tuple { .. }
|
||||
) && contains(item, child)
|
||||
});
|
||||
|
||||
// If our child is a tuple, and value is not, it's always an unpacking
|
||||
// expression. Ex) `x, y = tup`
|
||||
if child_in_tuple && !value_is_tuple {
|
||||
return true;
|
||||
}
|
||||
|
||||
// If our child isn't a tuple, but value is, it's never an unpacking expression.
|
||||
// Ex) `coords = (1, 2)`
|
||||
if !child_in_tuple && value_is_tuple {
|
||||
return false;
|
||||
}
|
||||
|
||||
// If our target and the value are both tuples, then it's an unpacking
|
||||
// expression assuming there's at least one non-tuple child.
|
||||
// Ex) Given `(x, y) = coords = 1, 2`, `(x, y)` is considered an unpacking
|
||||
// expression. Ex) Given `(x, y) = (a, b) = 1, 2`, `(x, y)` isn't
|
||||
// considered an unpacking expression.
|
||||
if child_in_tuple && value_is_tuple {
|
||||
return !targets_are_tuples;
|
||||
}
|
||||
|
||||
false
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
130
src/check_ast.rs
130
src/check_ast.rs
@@ -5,7 +5,6 @@ use std::path::Path;
|
||||
|
||||
use log::error;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_ast::Withitem;
|
||||
use rustpython_parser::ast::{
|
||||
Arg, Arguments, Constant, Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind,
|
||||
KeywordData, Operator, Stmt, StmtKind, Suite,
|
||||
@@ -20,7 +19,7 @@ use crate::ast::relocate::relocate_expr;
|
||||
use crate::ast::types::{
|
||||
Binding, BindingContext, BindingKind, ClassScope, FunctionScope, Node, Range, Scope, ScopeKind,
|
||||
};
|
||||
use crate::ast::visitor::{walk_excepthandler, walk_withitem, Visitor};
|
||||
use crate::ast::visitor::{walk_excepthandler, Visitor};
|
||||
use crate::ast::{helpers, operations, visitor};
|
||||
use crate::checks::{Check, CheckCode, CheckKind, DeferralKeyword};
|
||||
use crate::docstrings::definition::{Definition, DefinitionKind, Documentable};
|
||||
@@ -36,8 +35,8 @@ 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,
|
||||
pygrep_hooks, 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;
|
||||
@@ -82,7 +81,6 @@ pub struct Checker<'a> {
|
||||
in_deferred_type_definition: bool,
|
||||
in_literal: bool,
|
||||
in_subscript: bool,
|
||||
in_withitem: bool,
|
||||
seen_import_boundary: bool,
|
||||
futures_allowed: bool,
|
||||
annotations_future_enabled: bool,
|
||||
@@ -130,7 +128,6 @@ impl<'a> Checker<'a> {
|
||||
in_deferred_type_definition: false,
|
||||
in_literal: false,
|
||||
in_subscript: false,
|
||||
in_withitem: false,
|
||||
seen_import_boundary: false,
|
||||
futures_allowed: true,
|
||||
annotations_future_enabled: false,
|
||||
@@ -412,7 +409,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);
|
||||
@@ -421,9 +418,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,
|
||||
@@ -441,6 +452,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
|
||||
@@ -513,7 +528,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,
|
||||
);
|
||||
@@ -650,6 +665,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 {
|
||||
@@ -737,7 +760,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);
|
||||
}
|
||||
}
|
||||
@@ -942,6 +965,11 @@ where
|
||||
self.add_check(check);
|
||||
}
|
||||
}
|
||||
|
||||
// pylint
|
||||
if self.settings.enabled.contains(&CheckCode::PLC0414) {
|
||||
pylint::plugins::useless_import_alias(self, alias);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -986,16 +1014,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);
|
||||
@@ -1006,6 +1045,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) {
|
||||
@@ -1031,7 +1073,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) {
|
||||
@@ -1044,12 +1086,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,
|
||||
);
|
||||
@@ -1221,7 +1263,7 @@ where
|
||||
ExprKind::Subscript { value, slice, .. } => {
|
||||
// Ex) Optional[...]
|
||||
if !self.in_deferred_string_type_definition
|
||||
&& self.settings.enabled.contains(&CheckCode::U007)
|
||||
&& self.settings.enabled.contains(&CheckCode::UP007)
|
||||
&& (self.settings.target_version >= PythonVersion::Py310
|
||||
|| (self.settings.target_version >= PythonVersion::Py37
|
||||
&& !self.settings.pyupgrade.keep_runtime_typing
|
||||
@@ -1264,7 +1306,7 @@ where
|
||||
ExprContext::Load => {
|
||||
// Ex) List[...]
|
||||
if !self.in_deferred_string_type_definition
|
||||
&& self.settings.enabled.contains(&CheckCode::U006)
|
||||
&& self.settings.enabled.contains(&CheckCode::UP006)
|
||||
&& (self.settings.target_version >= PythonVersion::Py39
|
||||
|| (self.settings.target_version >= PythonVersion::Py37
|
||||
&& !self.settings.pyupgrade.keep_runtime_typing
|
||||
@@ -1305,7 +1347,7 @@ where
|
||||
ExprKind::Attribute { attr, .. } => {
|
||||
// Ex) typing.List[...]
|
||||
if !self.in_deferred_string_type_definition
|
||||
&& self.settings.enabled.contains(&CheckCode::U006)
|
||||
&& self.settings.enabled.contains(&CheckCode::UP006)
|
||||
&& (self.settings.target_version >= PythonVersion::Py39
|
||||
|| (self.settings.target_version >= PythonVersion::Py37
|
||||
&& self.annotations_future_enabled
|
||||
@@ -1399,16 +1441,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);
|
||||
}
|
||||
|
||||
@@ -1667,11 +1709,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);
|
||||
}
|
||||
|
||||
@@ -1708,9 +1750,12 @@ where
|
||||
pygrep_hooks::checks::no_eval(self, func);
|
||||
}
|
||||
|
||||
// Ruff
|
||||
if self.settings.enabled.contains(&CheckCode::RUF101) {
|
||||
rules::plugins::convert_exit_to_sys_exit(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, .. } => {
|
||||
@@ -1973,6 +2018,16 @@ 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),
|
||||
@@ -2054,6 +2109,11 @@ 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);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
};
|
||||
|
||||
@@ -2422,13 +2482,6 @@ where
|
||||
|
||||
self.check_builtin_arg_shadowing(&arg.node.arg, Range::from_located(arg));
|
||||
}
|
||||
|
||||
fn visit_withitem(&mut self, withitem: &'b Withitem) {
|
||||
let prev_in_withitem = self.in_withitem;
|
||||
self.in_withitem = true;
|
||||
walk_withitem(self, withitem);
|
||||
self.in_withitem = prev_in_withitem;
|
||||
}
|
||||
}
|
||||
|
||||
fn try_mark_used(scope: &mut Scope, scope_id: usize, id: &str, expr: &Expr) -> bool {
|
||||
@@ -2735,7 +2788,7 @@ impl<'a> Checker<'a> {
|
||||
return;
|
||||
}
|
||||
|
||||
if self.in_withitem || operations::is_unpacking_assignment(parent) {
|
||||
if operations::is_unpacking_assignment(parent, expr) {
|
||||
self.add_binding(
|
||||
id,
|
||||
Binding {
|
||||
@@ -3032,8 +3085,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()
|
||||
@@ -3053,7 +3107,7 @@ impl<'a> Checker<'a> {
|
||||
Some(fix)
|
||||
}
|
||||
Err(e) => {
|
||||
error!("Failed to remove unused imports: {}", e);
|
||||
error!("Failed to remove unused imports: {e}");
|
||||
None
|
||||
}
|
||||
}
|
||||
@@ -3063,7 +3117,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() {
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -4,9 +4,9 @@ use rustpython_parser::lexer::{LexResult, Tok};
|
||||
|
||||
use crate::checks::{Check, CheckCode};
|
||||
use crate::lex::docstring_detection::StateMachine;
|
||||
use crate::rules::checks::Context;
|
||||
use crate::ruff::checks::Context;
|
||||
use crate::source_code_locator::SourceCodeLocator;
|
||||
use crate::{eradicate, flake8_quotes, pycodestyle, rules, Settings};
|
||||
use crate::{eradicate, flake8_quotes, pycodestyle, ruff, Settings};
|
||||
|
||||
pub fn check_tokens(
|
||||
locator: &SourceCodeLocator,
|
||||
@@ -37,7 +37,7 @@ pub fn check_tokens(
|
||||
// RUF001, RUF002, RUF003
|
||||
if enforce_ambiguous_unicode_character {
|
||||
if matches!(tok, Tok::String { .. } | Tok::Comment) {
|
||||
checks.extend(rules::checks::ambiguous_unicode_character(
|
||||
checks.extend(ruff::checks::ambiguous_unicode_character(
|
||||
locator,
|
||||
start,
|
||||
end,
|
||||
|
||||
369
src/checks.rs
369
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,9 +294,7 @@ pub enum CheckCode {
|
||||
RUF001,
|
||||
RUF002,
|
||||
RUF003,
|
||||
RUF101,
|
||||
// Meta
|
||||
M001,
|
||||
RUF100,
|
||||
// pygrep-hooks
|
||||
PGH001,
|
||||
}
|
||||
@@ -286,28 +303,28 @@ pub enum CheckCode {
|
||||
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 {
|
||||
@@ -339,16 +356,16 @@ 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::Pylint => "Pylint",
|
||||
CheckCategory::PygrepHooks => "pygrep-hooks",
|
||||
CheckCategory::Pylint => "Pylint",
|
||||
CheckCategory::Pyupgrade => "pyupgrade",
|
||||
CheckCategory::Ruff => "Ruff-specific rules",
|
||||
}
|
||||
@@ -403,6 +420,10 @@ impl CheckCategory {
|
||||
"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,
|
||||
@@ -413,7 +434,6 @@ impl CheckCategory {
|
||||
CheckCategory::McCabe => {
|
||||
Some(("https://pypi.org/project/mccabe/0.7.0/", &Platform::PyPI))
|
||||
}
|
||||
CheckCategory::Meta => None,
|
||||
CheckCategory::PEP8Naming => Some((
|
||||
"https://pypi.org/project/pep8-naming/0.13.2/",
|
||||
&Platform::PyPI,
|
||||
@@ -476,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
|
||||
@@ -539,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),
|
||||
@@ -596,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,
|
||||
@@ -726,8 +778,6 @@ pub enum CheckKind {
|
||||
AmbiguousUnicodeCharacterString(char, char),
|
||||
AmbiguousUnicodeCharacterDocstring(char, char),
|
||||
AmbiguousUnicodeCharacterComment(char, char),
|
||||
ConvertExitToSysExit,
|
||||
// Meta
|
||||
UnusedNOQA(Option<Vec<String>>),
|
||||
}
|
||||
|
||||
@@ -736,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
|
||||
@@ -824,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()),
|
||||
@@ -896,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,
|
||||
@@ -930,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,
|
||||
@@ -1046,9 +1117,7 @@ impl CheckCode {
|
||||
CheckCode::RUF001 => CheckKind::AmbiguousUnicodeCharacterString('𝐁', 'B'),
|
||||
CheckCode::RUF002 => CheckKind::AmbiguousUnicodeCharacterDocstring('𝐁', 'B'),
|
||||
CheckCode::RUF003 => CheckKind::AmbiguousUnicodeCharacterComment('𝐁', 'B'),
|
||||
CheckCode::RUF101 => CheckKind::ConvertExitToSysExit,
|
||||
// Meta
|
||||
CheckCode::M001 => CheckKind::UnusedNOQA(None),
|
||||
CheckCode::RUF100 => CheckKind::UnusedNOQA(None),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1220,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,
|
||||
@@ -1237,15 +1305,31 @@ impl CheckCode {
|
||||
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,
|
||||
@@ -1255,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,
|
||||
@@ -1349,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,
|
||||
@@ -1406,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,
|
||||
@@ -1438,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,
|
||||
@@ -1536,9 +1637,7 @@ impl CheckKind {
|
||||
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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1704,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")
|
||||
}
|
||||
@@ -1722,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")
|
||||
@@ -1936,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(),
|
||||
@@ -2288,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) => {
|
||||
@@ -2343,7 +2489,7 @@ impl CheckKind {
|
||||
| CheckKind::BlankLineBeforeSection(..)
|
||||
| CheckKind::CapitalizeSectionName(..)
|
||||
| CheckKind::CommentedOutCode
|
||||
| CheckKind::ConvertExitToSysExit
|
||||
| CheckKind::ConsiderUsingSysExit
|
||||
| CheckKind::ConvertNamedTupleFunctionalToClass(..)
|
||||
| CheckKind::ConvertTypedDictFunctionalToClass(..)
|
||||
| CheckKind::DashedUnderlineAfterSection(..)
|
||||
@@ -2351,8 +2497,13 @@ impl CheckKind {
|
||||
| CheckKind::DoNotAssertFalse
|
||||
| CheckKind::DoNotAssignLambda
|
||||
| CheckKind::DuplicateHandlerException(..)
|
||||
| CheckKind::EndsInPeriod
|
||||
| CheckKind::EndsInPunctuation
|
||||
| CheckKind::GetAttrWithConstant
|
||||
| CheckKind::ImplicitReturn
|
||||
| CheckKind::ImplicitReturnValue
|
||||
| CheckKind::IsLiteral
|
||||
| CheckKind::MisplacedComparisonConstant(..)
|
||||
| CheckKind::NewLineAfterLastParagraph
|
||||
| CheckKind::NewLineAfterSectionName(..)
|
||||
| CheckKind::NoBlankLineAfterFunction(..)
|
||||
@@ -2371,6 +2522,7 @@ impl CheckKind {
|
||||
| CheckKind::PPrintFound
|
||||
| CheckKind::PrintFound
|
||||
| CheckKind::RaiseNotImplemented
|
||||
| CheckKind::RedundantOpenModes
|
||||
| CheckKind::RedundantTupleInExceptionHandler(..)
|
||||
| CheckKind::SectionNameEndsInColon(..)
|
||||
| CheckKind::SectionNotOverIndented(..)
|
||||
@@ -2385,7 +2537,6 @@ impl CheckKind {
|
||||
| CheckKind::UnnecessaryComprehension(..)
|
||||
| CheckKind::UnnecessaryEncodeUTF8
|
||||
| CheckKind::UnnecessaryFutureImport(..)
|
||||
| CheckKind::RedundantOpenModes
|
||||
| CheckKind::UnnecessaryGeneratorDict
|
||||
| CheckKind::UnnecessaryGeneratorList
|
||||
| CheckKind::UnnecessaryGeneratorSet
|
||||
@@ -2397,12 +2548,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(..)
|
||||
)
|
||||
@@ -2432,6 +2585,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;
|
||||
@@ -2445,8 +2619,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,
|
||||
@@ -282,11 +279,43 @@ pub enum CheckCodePrefix {
|
||||
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,
|
||||
@@ -294,6 +323,17 @@ pub enum CheckCodePrefix {
|
||||
Q001,
|
||||
Q002,
|
||||
Q003,
|
||||
RET,
|
||||
RET5,
|
||||
RET50,
|
||||
RET501,
|
||||
RET502,
|
||||
RET503,
|
||||
RET504,
|
||||
RET505,
|
||||
RET506,
|
||||
RET507,
|
||||
RET508,
|
||||
RUF,
|
||||
RUF0,
|
||||
RUF00,
|
||||
@@ -302,7 +342,7 @@ pub enum CheckCodePrefix {
|
||||
RUF003,
|
||||
RUF1,
|
||||
RUF10,
|
||||
RUF101,
|
||||
RUF100,
|
||||
S,
|
||||
S1,
|
||||
S10,
|
||||
@@ -338,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,
|
||||
@@ -1080,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,
|
||||
@@ -1156,11 +1210,50 @@ impl CheckCodePrefix {
|
||||
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,
|
||||
@@ -1183,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,
|
||||
@@ -1236,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],
|
||||
@@ -1600,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,
|
||||
@@ -1627,11 +1930,43 @@ impl CheckCodePrefix {
|
||||
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,
|
||||
@@ -1639,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,
|
||||
@@ -1647,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,
|
||||
@@ -1683,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,
|
||||
@@ -1723,15 +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()),
|
||||
|
||||
@@ -1,22 +1,51 @@
|
||||
//! Settings for the `flake-annotations` plugin.
|
||||
|
||||
use ruff_macros::ConfigurationOptions;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default)]
|
||||
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Default, ConfigurationOptions)]
|
||||
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
|
||||
pub struct Options {
|
||||
/// Allow omission of a return type hint for `__init__` if at least one
|
||||
/// argument is annotated.
|
||||
#[option(
|
||||
doc = r#"
|
||||
Whether to allow the omission of a return type hint for `__init__` if at least one
|
||||
argument is annotated.
|
||||
"#,
|
||||
default = "false",
|
||||
value_type = "bool",
|
||||
example = "mypy-init-return = true"
|
||||
)]
|
||||
pub mypy_init_return: Option<bool>,
|
||||
/// Suppress ANN000-level errors for dummy arguments, like `_`.
|
||||
#[option(
|
||||
doc = r#"
|
||||
Whether to suppress `ANN000`-level errors for arguments matching the "dummy" variable
|
||||
regex (like `_`).
|
||||
"#,
|
||||
default = "false",
|
||||
value_type = "bool",
|
||||
example = "suppress-dummy-args = true"
|
||||
)]
|
||||
pub suppress_dummy_args: Option<bool>,
|
||||
/// Suppress ANN200-level errors for functions that meet one of the
|
||||
/// following criteria:
|
||||
/// - Contain no `return` statement
|
||||
/// - Explicit `return` statement(s) all return `None` (explicitly or
|
||||
/// implicitly).
|
||||
#[option(
|
||||
doc = r#"
|
||||
Whether to suppress `ANN200`-level errors for functions that meet either of the
|
||||
following criteria:
|
||||
|
||||
- Contain no `return` statement.
|
||||
- Explicit `return` statement(s) all return `None` (explicitly or implicitly).
|
||||
"#,
|
||||
default = "false",
|
||||
value_type = "bool",
|
||||
example = "suppress-none-returning = true"
|
||||
)]
|
||||
pub suppress_none_returning: Option<bool>,
|
||||
/// Suppress ANN401 for dynamically typed *args and **kwargs.
|
||||
#[option(
|
||||
doc = "Whether to suppress `ANN401` for dynamically typed `*args` and `**kwargs` \
|
||||
arguments.",
|
||||
default = "false",
|
||||
value_type = "bool",
|
||||
example = "allow-star-arg-any = true"
|
||||
)]
|
||||
pub allow_star_arg_any: Option<bool>,
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user