mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-23 13:05:06 +00:00
Re-integrate RustPython parser repository (#4359)
Co-authored-by: Micha Reiser <micha@reiser.io>
This commit is contained in:
parent
865205d992
commit
be6e00ef6e
270 changed files with 3061 additions and 3361 deletions
271
Cargo.lock
generated
271
Cargo.lock
generated
|
@ -144,15 +144,6 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d92bec98840b8f03a5ff5413de5293bfcd8bf96467cf5452609f939ec6f5de16"
|
||||
|
||||
[[package]]
|
||||
name = "ascii-canvas"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8824ecca2e851cec16968d54a01dd372ef8f95b244fb84b84e70128be347c3c6"
|
||||
dependencies = [
|
||||
"term",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "assert_cmd"
|
||||
version = "2.0.11"
|
||||
|
@ -200,21 +191,6 @@ dependencies = [
|
|||
"serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-set"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0700ddab506f33b20a03b13996eccd309a48e5ff77d0d95926aa0210fb4e95f1"
|
||||
dependencies = [
|
||||
"bit-vec",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bit-vec"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "349f9b6a179ed607305526ca489b34ad0a41aed5f7980fa90eb03160b69598fb"
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "1.3.2"
|
||||
|
@ -223,9 +199,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
|
|||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.1.0"
|
||||
version = "2.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c70beb79cbb5ce9c4f8e20849978f34225931f665bb49efa6982875a4d5facb3"
|
||||
checksum = "24a6904aef64d73cf10ab17ebace7befb918b82164785cb89907993be7f83813"
|
||||
|
||||
[[package]]
|
||||
name = "bstr"
|
||||
|
@ -700,16 +676,6 @@ dependencies = [
|
|||
"dirs-sys 0.4.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-next"
|
||||
version = "2.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b98cf8ebf19c3d1b223e151f99a4f9f0690dca41414773390fc824184ac833e1"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"dirs-sys-next",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys"
|
||||
version = "0.3.7"
|
||||
|
@ -732,17 +698,6 @@ dependencies = [
|
|||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "dirs-sys-next"
|
||||
version = "0.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4ebda144c4fe02d1f7ea1a7d9641b6fc6b580adcfa024ae48797ecdeb6825b4d"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"redox_users",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "doc-comment"
|
||||
version = "0.3.3"
|
||||
|
@ -767,15 +722,6 @@ version = "1.8.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91"
|
||||
|
||||
[[package]]
|
||||
name = "ena"
|
||||
version = "0.14.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c533630cf40e9caa44bd91aadc88a75d75a4c3a12b4cfde353cbed41daa1e1f1"
|
||||
dependencies = [
|
||||
"log",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encode_unicode"
|
||||
version = "0.3.6"
|
||||
|
@ -833,12 +779,6 @@ dependencies = [
|
|||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ce7134b9999ecaf8bcd65542e436736ef32ddca1b3e06094cb6ec5755203b80"
|
||||
|
||||
[[package]]
|
||||
name = "flake8-to-ruff"
|
||||
version = "0.0.265"
|
||||
|
@ -1168,37 +1108,11 @@ dependencies = [
|
|||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop"
|
||||
version = "0.19.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f34313ec00c2eb5c3c87ca6732ea02dcf3af99c3ff7a8fb622ffb99c9d860a87"
|
||||
dependencies = [
|
||||
"ascii-canvas",
|
||||
"bit-set",
|
||||
"diff",
|
||||
"ena",
|
||||
"is-terminal",
|
||||
"itertools",
|
||||
"lalrpop-util",
|
||||
"petgraph",
|
||||
"pico-args",
|
||||
"regex",
|
||||
"regex-syntax 0.6.29",
|
||||
"string_cache",
|
||||
"term",
|
||||
"tiny-keccak",
|
||||
"unicode-xid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "lalrpop-util"
|
||||
version = "0.19.9"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e5c1f7869c94d214466c5fd432dfed12c379fd87786768d36455892d46b18edd"
|
||||
dependencies = [
|
||||
"regex",
|
||||
]
|
||||
checksum = "3f35c735096c0293d313e8f2a641627472b83d01b937177fe76e5e2708d31e0d"
|
||||
|
||||
[[package]]
|
||||
name = "lazy_static"
|
||||
|
@ -1388,12 +1302,6 @@ version = "1.0.9"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "308d96db8debc727c3fd9744aac51751243420e46edf401010908da7f8d5e57c"
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4a24736216ec316047a1fc4252e27dabb04218aa4a3f37c6e7ddbf1f9782b54"
|
||||
|
||||
[[package]]
|
||||
name = "nextest-workspace-hack"
|
||||
version = "0.1.0"
|
||||
|
@ -1525,29 +1433,6 @@ dependencies = [
|
|||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot"
|
||||
version = "0.12.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f"
|
||||
dependencies = [
|
||||
"lock_api",
|
||||
"parking_lot_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "parking_lot_core"
|
||||
version = "0.9.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9069cbb9f99e3a5083476ccb29ceb1de18b9118cafa53e90c9551235de2b9521"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"redox_syscall 0.2.16",
|
||||
"smallvec",
|
||||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "paste"
|
||||
version = "1.0.12"
|
||||
|
@ -1624,23 +1509,13 @@ version = "2.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||
|
||||
[[package]]
|
||||
name = "petgraph"
|
||||
version = "0.6.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4dd7d28ee937e54fe3080c91faa1c3a46c06de6252988a7f4592ba2310ef22a4"
|
||||
dependencies = [
|
||||
"fixedbitset",
|
||||
"indexmap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf"
|
||||
version = "0.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "928c6535de93548188ef63bb7c4036bd415cd8f36ad25af44b9789b2ee72a48c"
|
||||
dependencies = [
|
||||
"phf_shared 0.11.1",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1650,7 +1525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "a56ac890c5e3ca598bbdeaa99964edb5b0258a583a9eb6ef4e89fc85d9224770"
|
||||
dependencies = [
|
||||
"phf_generator",
|
||||
"phf_shared 0.11.1",
|
||||
"phf_shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1659,19 +1534,10 @@ version = "0.11.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b1181c94580fa345f50f19d738aaa39c0ed30a600d95cb2d3e23f94266f14fbf"
|
||||
dependencies = [
|
||||
"phf_shared 0.11.1",
|
||||
"phf_shared",
|
||||
"rand",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6796ad771acdc0123d2a88dc428b5e38ef24456743ddb1744ed628f9815c096"
|
||||
dependencies = [
|
||||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "phf_shared"
|
||||
version = "0.11.1"
|
||||
|
@ -1681,12 +1547,6 @@ dependencies = [
|
|||
"siphasher",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pico-args"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db8bcd96cb740d03149cbad5518db9fd87126a10ab519c011893b1754134c468"
|
||||
|
||||
[[package]]
|
||||
name = "pin-project-lite"
|
||||
version = "0.2.9"
|
||||
|
@ -1738,12 +1598,6 @@ version = "0.2.17"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
|
||||
|
||||
[[package]]
|
||||
name = "precomputed-hash"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
|
||||
|
||||
[[package]]
|
||||
name = "predicates"
|
||||
version = "3.0.3"
|
||||
|
@ -1944,7 +1798,7 @@ checksum = "af83e617f331cc6ae2da5443c602dfa5af81e517212d9d611a5b3ba1777b5370"
|
|||
dependencies = [
|
||||
"aho-corasick 1.0.1",
|
||||
"memchr",
|
||||
"regex-syntax 0.7.1",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1953,12 +1807,6 @@ version = "0.1.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.6.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.7.1"
|
||||
|
@ -2008,7 +1856,7 @@ version = "0.0.265"
|
|||
dependencies = [
|
||||
"annotate-snippets 0.9.1",
|
||||
"anyhow",
|
||||
"bitflags 2.1.0",
|
||||
"bitflags 2.2.1",
|
||||
"chrono",
|
||||
"clap 4.2.4",
|
||||
"colored",
|
||||
|
@ -2101,7 +1949,7 @@ dependencies = [
|
|||
"assert_cmd",
|
||||
"atty",
|
||||
"bincode",
|
||||
"bitflags 2.1.0",
|
||||
"bitflags 2.2.1",
|
||||
"cachedir",
|
||||
"chrono",
|
||||
"clap 4.2.4",
|
||||
|
@ -2200,7 +2048,7 @@ name = "ruff_python_ast"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"bitflags 2.1.0",
|
||||
"bitflags 2.2.1",
|
||||
"is-macro",
|
||||
"itertools",
|
||||
"log",
|
||||
|
@ -2209,10 +2057,9 @@ dependencies = [
|
|||
"num-traits",
|
||||
"once_cell",
|
||||
"regex",
|
||||
"ruff_rustpython",
|
||||
"ruff_text_size",
|
||||
"rustc-hash",
|
||||
"rustpython-common",
|
||||
"rustpython-literal 0.2.0 (git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666)",
|
||||
"rustpython-parser",
|
||||
"serde",
|
||||
"smallvec",
|
||||
|
@ -2234,7 +2081,6 @@ dependencies = [
|
|||
"ruff_testing_macros",
|
||||
"ruff_text_size",
|
||||
"rustc-hash",
|
||||
"rustpython-common",
|
||||
"rustpython-parser",
|
||||
"similar",
|
||||
"test-case",
|
||||
|
@ -2244,7 +2090,7 @@ dependencies = [
|
|||
name = "ruff_python_semantic"
|
||||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"bitflags 2.1.0",
|
||||
"bitflags 2.2.1",
|
||||
"is-macro",
|
||||
"nohash-hasher",
|
||||
"ruff_python_ast",
|
||||
|
@ -2268,8 +2114,6 @@ name = "ruff_rustpython"
|
|||
version = "0.0.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"once_cell",
|
||||
"rustpython-common",
|
||||
"rustpython-parser",
|
||||
]
|
||||
|
||||
|
@ -2286,7 +2130,7 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "ruff_text_size"
|
||||
version = "0.0.0"
|
||||
source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666"
|
||||
dependencies = [
|
||||
"schemars",
|
||||
"serde",
|
||||
|
@ -2357,75 +2201,92 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "rustpython-ast"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666"
|
||||
dependencies = [
|
||||
"num-bigint",
|
||||
"ruff_text_size",
|
||||
"rustpython-parser-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython-common"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a"
|
||||
source = "git+https://github.com/RustPython/RustPython.git?rev=f3e4d3409253660bd4fa7f3d24d3db747e7dca61#f3e4d3409253660bd4fa7f3d24d3db747e7dca61"
|
||||
dependencies = [
|
||||
"ascii",
|
||||
"bitflags 1.3.2",
|
||||
"bitflags 2.2.1",
|
||||
"bstr 0.2.17",
|
||||
"cfg-if",
|
||||
"getrandom",
|
||||
"hexf-parse",
|
||||
"itertools",
|
||||
"lexical-parse-float",
|
||||
"libc",
|
||||
"lock_api",
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"num-traits",
|
||||
"once_cell",
|
||||
"radium",
|
||||
"rand",
|
||||
"rustpython-literal 0.2.0 (git+https://github.com/youknowone/RustPython-parser.git?rev=5b2af304a2baa53598e594097824165d4ac7a119)",
|
||||
"siphasher",
|
||||
"unic-ucd-category",
|
||||
"volatile",
|
||||
"widestring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython-compiler-core"
|
||||
name = "rustpython-literal"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666"
|
||||
dependencies = [
|
||||
"bitflags 1.3.2",
|
||||
"itertools",
|
||||
"lz4_flex",
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"ruff_text_size",
|
||||
"hexf-parse",
|
||||
"lexical-parse-float",
|
||||
"num-traits",
|
||||
"unic-ucd-category",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython-literal"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/youknowone/RustPython-parser.git?rev=5b2af304a2baa53598e594097824165d4ac7a119#5b2af304a2baa53598e594097824165d4ac7a119"
|
||||
dependencies = [
|
||||
"hexf-parse",
|
||||
"lexical-parse-float",
|
||||
"num-traits",
|
||||
"unic-ucd-category",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython-parser"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/charliermarsh/RustPython.git?rev=c3147d2c1524ebd0e90cf1c2938d770314fd5a5a#c3147d2c1524ebd0e90cf1c2938d770314fd5a5a"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"itertools",
|
||||
"lalrpop",
|
||||
"lalrpop-util",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"num-traits",
|
||||
"phf",
|
||||
"phf_codegen",
|
||||
"ruff_text_size",
|
||||
"rustc-hash",
|
||||
"rustpython-ast",
|
||||
"rustpython-compiler-core",
|
||||
"rustpython-parser-core",
|
||||
"tiny-keccak",
|
||||
"unic-emoji-char",
|
||||
"unic-ucd-ident",
|
||||
"unicode_names2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustpython-parser-core"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/RustPython/Parser.git?rev=2af98056629fbe75ccc0d90c4ee05dfeb403d666#2af98056629fbe75ccc0d90c4ee05dfeb403d666"
|
||||
dependencies = [
|
||||
"itertools",
|
||||
"lz4_flex",
|
||||
"num-bigint",
|
||||
"num-complex",
|
||||
"ruff_text_size",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustversion"
|
||||
version = "1.0.12"
|
||||
|
@ -2613,19 +2474,6 @@ version = "1.1.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f"
|
||||
|
||||
[[package]]
|
||||
name = "string_cache"
|
||||
version = "0.8.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f91138e76242f575eb1d3b38b4f1362f10d3a43f47d182a5b359af488a02293b"
|
||||
dependencies = [
|
||||
"new_debug_unreachable",
|
||||
"once_cell",
|
||||
"parking_lot",
|
||||
"phf_shared 0.10.0",
|
||||
"precomputed-hash",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "strsim"
|
||||
version = "0.10.0"
|
||||
|
@ -2698,17 +2546,6 @@ dependencies = [
|
|||
"windows-sys 0.45.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "term"
|
||||
version = "0.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c59df8ac95d96ff9bede18eb7300b0fda5e5d8d90960e76f8e14ae765eedbf1f"
|
||||
dependencies = [
|
||||
"dirs-next",
|
||||
"rustversion",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "termcolor"
|
||||
version = "1.2.0"
|
||||
|
@ -3061,12 +2898,6 @@ version = "0.1.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b"
|
||||
|
||||
[[package]]
|
||||
name = "unicode-xid"
|
||||
version = "0.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
|
||||
|
||||
[[package]]
|
||||
name = "unicode_names2"
|
||||
version = "0.6.0"
|
||||
|
|
|
@ -11,7 +11,7 @@ authors = ["Charlie Marsh <charlie.r.marsh@gmail.com>"]
|
|||
|
||||
[workspace.dependencies]
|
||||
anyhow = { version = "1.0.69" }
|
||||
bitflags = { version = "2.1.0" }
|
||||
bitflags = { version = "2.2.1" }
|
||||
chrono = { version = "0.4.23", default-features = false, features = ["clock"] }
|
||||
clap = { version = "4.1.8", features = ["derive"] }
|
||||
colored = { version = "2.0.0" }
|
||||
|
@ -30,10 +30,11 @@ path-absolutize = { version = "3.0.14" }
|
|||
proc-macro2 = { version = "1.0.51" }
|
||||
quote = { version = "1.0.23" }
|
||||
regex = { version = "1.7.1" }
|
||||
ruff_text_size = { git = "https://github.com/charliermarsh/RustPython.git", rev = "c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" }
|
||||
ruff_text_size = { git = "https://github.com/RustPython/Parser.git", rev = "2af98056629fbe75ccc0d90c4ee05dfeb403d666" }
|
||||
rustc-hash = { version = "1.1.0" }
|
||||
rustpython-common = { git = "https://github.com/charliermarsh/RustPython.git", rev = "c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" }
|
||||
rustpython-parser = { git = "https://github.com/charliermarsh/RustPython.git", rev = "c3147d2c1524ebd0e90cf1c2938d770314fd5a5a" }
|
||||
rustpython-common = { git = "https://github.com/RustPython/RustPython.git", rev = "f3e4d3409253660bd4fa7f3d24d3db747e7dca61" }
|
||||
rustpython-literal = { git = "https://github.com/RustPython/Parser.git", rev = "2af98056629fbe75ccc0d90c4ee05dfeb403d666" }
|
||||
rustpython-parser = { git = "https://github.com/RustPython/Parser.git", rev = "2af98056629fbe75ccc0d90c4ee05dfeb403d666" , default-features = false}
|
||||
schemars = { version = "0.8.12" }
|
||||
serde = { version = "1.0.152", features = ["derive"] }
|
||||
serde_json = { version = "1.0.93", features = ["preserve_order"] }
|
||||
|
|
|
@ -5,7 +5,7 @@ use libcst_native::{
|
|||
Codegen, CodegenState, ImportNames, ParenthesizableWhitespace, SmallStatement, Statement,
|
||||
};
|
||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||
use rustpython_parser::ast::{ExcepthandlerKind, Expr, Keyword, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, ExcepthandlerKind, Expr, Keyword, Stmt, StmtKind};
|
||||
use rustpython_parser::{lexer, Mode, Tok};
|
||||
|
||||
use ruff_diagnostics::Edit;
|
||||
|
@ -28,21 +28,21 @@ fn has_single_child(body: &[Stmt], deleted: &[&Stmt]) -> bool {
|
|||
/// Determine if a child is the only statement in its body.
|
||||
fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result<bool> {
|
||||
match &parent.node {
|
||||
StmtKind::FunctionDef { body, .. }
|
||||
| StmtKind::AsyncFunctionDef { body, .. }
|
||||
| StmtKind::ClassDef { body, .. }
|
||||
| StmtKind::With { body, .. }
|
||||
| StmtKind::AsyncWith { body, .. } => {
|
||||
StmtKind::FunctionDef(ast::StmtFunctionDef { body, .. })
|
||||
| StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { body, .. })
|
||||
| StmtKind::ClassDef(ast::StmtClassDef { body, .. })
|
||||
| StmtKind::With(ast::StmtWith { body, .. })
|
||||
| StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => {
|
||||
if body.iter().contains(child) {
|
||||
Ok(has_single_child(body, deleted))
|
||||
} else {
|
||||
bail!("Unable to find child in parent body")
|
||||
}
|
||||
}
|
||||
StmtKind::For { body, orelse, .. }
|
||||
| StmtKind::AsyncFor { body, orelse, .. }
|
||||
| StmtKind::While { body, orelse, .. }
|
||||
| StmtKind::If { body, orelse, .. } => {
|
||||
StmtKind::For(ast::StmtFor { body, orelse, .. })
|
||||
| StmtKind::AsyncFor(ast::StmtAsyncFor { body, orelse, .. })
|
||||
| StmtKind::While(ast::StmtWhile { body, orelse, .. })
|
||||
| StmtKind::If(ast::StmtIf { body, orelse, .. }) => {
|
||||
if body.iter().contains(child) {
|
||||
Ok(has_single_child(body, deleted))
|
||||
} else if orelse.iter().contains(child) {
|
||||
|
@ -51,18 +51,18 @@ fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result<bool>
|
|||
bail!("Unable to find child in parent body")
|
||||
}
|
||||
}
|
||||
StmtKind::Try {
|
||||
StmtKind::Try(ast::StmtTry {
|
||||
body,
|
||||
handlers,
|
||||
orelse,
|
||||
finalbody,
|
||||
}
|
||||
| StmtKind::TryStar {
|
||||
})
|
||||
| StmtKind::TryStar(ast::StmtTryStar {
|
||||
body,
|
||||
handlers,
|
||||
orelse,
|
||||
finalbody,
|
||||
} => {
|
||||
}) => {
|
||||
if body.iter().contains(child) {
|
||||
Ok(has_single_child(body, deleted))
|
||||
} else if orelse.iter().contains(child) {
|
||||
|
@ -70,7 +70,9 @@ fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result<bool>
|
|||
} else if finalbody.iter().contains(child) {
|
||||
Ok(has_single_child(finalbody, deleted))
|
||||
} else if let Some(body) = handlers.iter().find_map(|handler| match &handler.node {
|
||||
ExcepthandlerKind::ExceptHandler { body, .. } => {
|
||||
ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
body, ..
|
||||
}) => {
|
||||
if body.iter().contains(child) {
|
||||
Some(body)
|
||||
} else {
|
||||
|
@ -83,7 +85,7 @@ fn is_lone_child(child: &Stmt, parent: &Stmt, deleted: &[&Stmt]) -> Result<bool>
|
|||
bail!("Unable to find child in parent body")
|
||||
}
|
||||
}
|
||||
StmtKind::Match { cases, .. } => {
|
||||
StmtKind::Match(ast::StmtMatch { cases, .. }) => {
|
||||
if let Some(body) = cases.iter().find_map(|case| {
|
||||
if case.body.iter().contains(child) {
|
||||
Some(&case.body)
|
||||
|
@ -350,7 +352,7 @@ pub fn remove_argument(
|
|||
if n_arguments == 1 {
|
||||
// Case 1: there is only one argument.
|
||||
let mut count: usize = 0;
|
||||
for (tok, range) in lexer::lex_located(contents, Mode::Module, call_at).flatten() {
|
||||
for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, call_at).flatten() {
|
||||
if matches!(tok, Tok::Lpar) {
|
||||
if count == 0 {
|
||||
fix_start = Some(if remove_parentheses {
|
||||
|
@ -382,7 +384,7 @@ pub fn remove_argument(
|
|||
{
|
||||
// Case 2: argument or keyword is _not_ the last node.
|
||||
let mut seen_comma = false;
|
||||
for (tok, range) in lexer::lex_located(contents, Mode::Module, call_at).flatten() {
|
||||
for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, call_at).flatten() {
|
||||
if seen_comma {
|
||||
if matches!(tok, Tok::NonLogicalNewline) {
|
||||
// Also delete any non-logical newlines after the comma.
|
||||
|
@ -405,7 +407,7 @@ pub fn remove_argument(
|
|||
} else {
|
||||
// Case 3: argument or keyword is the last node, so we have to find the last
|
||||
// comma in the stmt.
|
||||
for (tok, range) in lexer::lex_located(contents, Mode::Module, call_at).flatten() {
|
||||
for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, call_at).flatten() {
|
||||
if range.start() == expr_range.start() {
|
||||
fix_end = Some(expr_range.end());
|
||||
break;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,7 +2,7 @@
|
|||
use std::borrow::Cow;
|
||||
use std::path::Path;
|
||||
|
||||
use rustpython_parser::ast::{StmtKind, Suite};
|
||||
use rustpython_parser::ast::{self, StmtKind, Suite};
|
||||
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_python_ast::helpers::to_module_path;
|
||||
|
@ -29,20 +29,21 @@ fn extract_import_map(path: &Path, package: Option<&Path>, blocks: &[&Block]) ->
|
|||
let mut module_imports = Vec::with_capacity(num_imports);
|
||||
for stmt in blocks.iter().flat_map(|block| &block.imports) {
|
||||
match &stmt.node {
|
||||
StmtKind::Import { names } => {
|
||||
StmtKind::Import(ast::StmtImport { names }) => {
|
||||
module_imports.extend(
|
||||
names
|
||||
.iter()
|
||||
.map(|name| ModuleImport::new(name.node.name.clone(), stmt.range())),
|
||||
.map(|name| ModuleImport::new(name.node.name.to_string(), stmt.range())),
|
||||
);
|
||||
}
|
||||
StmtKind::ImportFrom {
|
||||
StmtKind::ImportFrom(ast::StmtImportFrom {
|
||||
module,
|
||||
names,
|
||||
level,
|
||||
} => {
|
||||
let level = level.unwrap_or(0);
|
||||
}) => {
|
||||
let level = level.map_or(0, |level| level.to_usize());
|
||||
let module = if let Some(module) = module {
|
||||
let module: &String = module.as_ref();
|
||||
if level == 0 {
|
||||
Cow::Borrowed(module)
|
||||
} else {
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
use std::iter::FusedIterator;
|
||||
|
||||
use ruff_text_size::{TextRange, TextSize};
|
||||
use rustpython_parser::ast::{Constant, ExprKind, Stmt, StmtKind, Suite};
|
||||
use rustpython_parser::ast::{self, Constant, ExprKind, Stmt, StmtKind, Suite};
|
||||
use rustpython_parser::lexer::LexResult;
|
||||
use rustpython_parser::Tok;
|
||||
|
||||
|
@ -76,11 +76,11 @@ struct StringLinesVisitor<'a> {
|
|||
|
||||
impl StatementVisitor<'_> for StringLinesVisitor<'_> {
|
||||
fn visit_stmt(&mut self, stmt: &Stmt) {
|
||||
if let StmtKind::Expr { value } = &stmt.node {
|
||||
if let ExprKind::Constant {
|
||||
if let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(..),
|
||||
..
|
||||
} = &value.node
|
||||
}) = &value.node
|
||||
{
|
||||
for line in UniversalNewlineIterator::with_offset(
|
||||
self.locator.slice(value.range()),
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//! Extract docstrings from an AST.
|
||||
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_python_semantic::analyze::visibility;
|
||||
|
||||
|
@ -10,16 +10,16 @@ use crate::docstrings::definition::{Definition, DefinitionKind, Documentable};
|
|||
pub fn docstring_from(suite: &[Stmt]) -> Option<&Expr> {
|
||||
let stmt = suite.first()?;
|
||||
// Require the docstring to be a standalone expression.
|
||||
let StmtKind::Expr { value } = &stmt.node else {
|
||||
let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node else {
|
||||
return None;
|
||||
};
|
||||
// Only match strings.
|
||||
if !matches!(
|
||||
&value.node,
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(_),
|
||||
..
|
||||
}
|
||||
})
|
||||
) {
|
||||
return None;
|
||||
}
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
use anyhow::Result;
|
||||
use libcst_native::{Codegen, CodegenState, ImportAlias, Name, NameOrAttribute};
|
||||
use ruff_text_size::TextSize;
|
||||
use rustpython_parser::ast::{Stmt, StmtKind, Suite};
|
||||
use rustpython_parser::ast::{self, Stmt, StmtKind, Suite};
|
||||
use rustpython_parser::{lexer, Mode, Tok};
|
||||
|
||||
use ruff_diagnostics::Edit;
|
||||
|
@ -79,13 +79,13 @@ impl<'a> Importer<'a> {
|
|||
if stmt.start() >= at {
|
||||
break;
|
||||
}
|
||||
if let StmtKind::ImportFrom {
|
||||
if let StmtKind::ImportFrom(ast::StmtImportFrom {
|
||||
module: name,
|
||||
level,
|
||||
..
|
||||
} = &stmt.node
|
||||
}) = &stmt.node
|
||||
{
|
||||
if level.map_or(true, |level| level == 0)
|
||||
if level.map_or(true, |level| level.to_u32() == 0)
|
||||
&& name.as_ref().map_or(false, |name| name == module)
|
||||
{
|
||||
import_from = Some(*stmt);
|
||||
|
@ -178,7 +178,8 @@ fn match_docstring_end(body: &[Stmt]) -> Option<TextSize> {
|
|||
/// along with a trailing newline suffix.
|
||||
fn end_of_statement_insertion(stmt: &Stmt, locator: &Locator, stylist: &Stylist) -> Insertion {
|
||||
let location = stmt.end();
|
||||
let mut tokens = lexer::lex_located(locator.after(location), Mode::Module, location).flatten();
|
||||
let mut tokens =
|
||||
lexer::lex_starts_at(locator.after(location), Mode::Module, location).flatten();
|
||||
if let Some((Tok::Semi, range)) = tokens.next() {
|
||||
// If the first token after the docstring is a semicolon, insert after the semicolon as an
|
||||
// inline statement;
|
||||
|
@ -211,7 +212,7 @@ fn top_of_file_insertion(body: &[Stmt], locator: &Locator, stylist: &Stylist) ->
|
|||
let mut location = if let Some(location) = match_docstring_end(body) {
|
||||
// If the first token after the docstring is a semicolon, insert after the semicolon as an
|
||||
// inline statement;
|
||||
let first_token = lexer::lex_located(locator.after(location), Mode::Module, location)
|
||||
let first_token = lexer::lex_starts_at(locator.after(location), Mode::Module, location)
|
||||
.flatten()
|
||||
.next();
|
||||
if let Some((Tok::Semi, range)) = first_token {
|
||||
|
@ -226,7 +227,7 @@ fn top_of_file_insertion(body: &[Stmt], locator: &Locator, stylist: &Stylist) ->
|
|||
|
||||
// Skip over any comments and empty lines.
|
||||
for (tok, range) in
|
||||
lexer::lex_located(locator.after(location), Mode::Module, location).flatten()
|
||||
lexer::lex_starts_at(locator.after(location), Mode::Module, location).flatten()
|
||||
{
|
||||
if matches!(tok, Tok::Comment(..) | Tok::Newline) {
|
||||
location = locator.full_line_end(range.end());
|
||||
|
|
|
@ -145,7 +145,7 @@ impl<'a> DisplayParseError<'a> {
|
|||
|
||||
impl Display for DisplayParseError<'_> {
|
||||
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||
let source_location = self.source_code.source_location(self.error.location);
|
||||
let source_location = self.source_code.source_location(self.error.offset);
|
||||
|
||||
write!(
|
||||
f,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use num_bigint::BigInt;
|
||||
use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind, Located};
|
||||
use rustpython_parser::ast::{self, Attributed, Cmpop, Constant, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -124,16 +124,15 @@ fn is_sys(checker: &Checker, expr: &Expr, target: &str) -> bool {
|
|||
pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
||||
if is_sys(checker, value, "version") {
|
||||
match &slice.node {
|
||||
ExprKind::Slice {
|
||||
ExprKind::Slice(ast::ExprSlice {
|
||||
lower: None,
|
||||
upper: Some(upper),
|
||||
step: None,
|
||||
..
|
||||
} => {
|
||||
if let ExprKind::Constant {
|
||||
}) => {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(i),
|
||||
..
|
||||
} = &upper.node
|
||||
}) = &upper.node
|
||||
{
|
||||
if *i == BigInt::from(1)
|
||||
&& checker.settings.rules.enabled(Rule::SysVersionSlice1)
|
||||
|
@ -151,10 +150,10 @@ pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
|||
}
|
||||
}
|
||||
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(i),
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
if *i == BigInt::from(2) && checker.settings.rules.enabled(Rule::SysVersion2) {
|
||||
checker
|
||||
.diagnostics
|
||||
|
@ -175,21 +174,23 @@ pub fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
|||
/// YTT103, YTT201, YTT203, YTT204, YTT302
|
||||
pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &[Expr]) {
|
||||
match &left.node {
|
||||
ExprKind::Subscript { value, slice, .. } if is_sys(checker, value, "version_info") => {
|
||||
if let ExprKind::Constant {
|
||||
ExprKind::Subscript(ast::ExprSubscript { value, slice, .. })
|
||||
if is_sys(checker, value, "version_info") =>
|
||||
{
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(i),
|
||||
..
|
||||
} = &slice.node
|
||||
}) = &slice.node
|
||||
{
|
||||
if *i == BigInt::from(0) {
|
||||
if let (
|
||||
[Cmpop::Eq | Cmpop::NotEq],
|
||||
[Located {
|
||||
[Attributed {
|
||||
node:
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(n),
|
||||
..
|
||||
},
|
||||
}),
|
||||
..
|
||||
}],
|
||||
) = (ops, comparators)
|
||||
|
@ -205,12 +206,12 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
|
|||
} else if *i == BigInt::from(1) {
|
||||
if let (
|
||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
||||
[Located {
|
||||
[Attributed {
|
||||
node:
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(_),
|
||||
..
|
||||
},
|
||||
}),
|
||||
..
|
||||
}],
|
||||
) = (ops, comparators)
|
||||
|
@ -225,17 +226,17 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
|
|||
}
|
||||
}
|
||||
|
||||
ExprKind::Attribute { value, attr, .. }
|
||||
ExprKind::Attribute(ast::ExprAttribute { value, attr, .. })
|
||||
if is_sys(checker, value, "version_info") && attr == "minor" =>
|
||||
{
|
||||
if let (
|
||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
||||
[Located {
|
||||
[Attributed {
|
||||
node:
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(_),
|
||||
..
|
||||
},
|
||||
}),
|
||||
..
|
||||
}],
|
||||
) = (ops, comparators)
|
||||
|
@ -258,12 +259,12 @@ pub fn compare(checker: &mut Checker, left: &Expr, ops: &[Cmpop], comparators: &
|
|||
if is_sys(checker, left, "version") {
|
||||
if let (
|
||||
[Cmpop::Lt | Cmpop::LtE | Cmpop::Gt | Cmpop::GtE],
|
||||
[Located {
|
||||
[Attributed {
|
||||
node:
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(s),
|
||||
..
|
||||
},
|
||||
}),
|
||||
..
|
||||
}],
|
||||
) = (ops, comparators)
|
||||
|
|
|
@ -13,7 +13,7 @@ pub fn add_return_annotation(locator: &Locator, stmt: &Stmt, annotation: &str) -
|
|||
let mut seen_lpar = false;
|
||||
let mut seen_rpar = false;
|
||||
let mut count: usize = 0;
|
||||
for (tok, range) in lexer::lex_located(contents, Mode::Module, stmt.start()).flatten() {
|
||||
for (tok, range) in lexer::lex_starts_at(contents, Mode::Module, stmt.start()).flatten() {
|
||||
if seen_lpar && seen_rpar {
|
||||
if matches!(tok, Tok::Colon) {
|
||||
return Ok(Edit::insertion(format!(" -> {annotation}"), range.start()));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Arguments, Expr, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Arguments, Expr, Stmt, StmtKind};
|
||||
|
||||
use ruff_python_ast::cast;
|
||||
use ruff_python_semantic::analyze::visibility;
|
||||
|
@ -8,20 +8,20 @@ use crate::docstrings::definition::{Definition, DefinitionKind};
|
|||
|
||||
pub(super) fn match_function_def(stmt: &Stmt) -> (&str, &Arguments, Option<&Expr>, &Vec<Stmt>) {
|
||||
match &stmt.node {
|
||||
StmtKind::FunctionDef {
|
||||
StmtKind::FunctionDef(ast::StmtFunctionDef {
|
||||
name,
|
||||
args,
|
||||
returns,
|
||||
body,
|
||||
..
|
||||
}
|
||||
| StmtKind::AsyncFunctionDef {
|
||||
})
|
||||
| StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef {
|
||||
name,
|
||||
args,
|
||||
returns,
|
||||
body,
|
||||
..
|
||||
} => (name, args, returns.as_ref().map(|expr| &**expr), body),
|
||||
}) => (name, args, returns.as_ref().map(|expr| &**expr), body),
|
||||
_ => panic!("Found non-FunctionDef in match_name"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -420,10 +420,10 @@ fn is_none_returning(body: &[Stmt]) -> bool {
|
|||
for expr in visitor.returns.into_iter().flatten() {
|
||||
if !matches!(
|
||||
expr.node,
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::None,
|
||||
..
|
||||
}
|
||||
})
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
|
||||
|
@ -10,10 +10,10 @@ static PASSWORD_CANDIDATE_REGEX: Lazy<Regex> = Lazy::new(|| {
|
|||
|
||||
pub fn string_literal(expr: &Expr) -> Option<&str> {
|
||||
match &expr.node {
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(string),
|
||||
..
|
||||
} => Some(string),
|
||||
}) => Some(string),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
@ -24,7 +24,7 @@ pub fn matches_password_name(string: &str) -> bool {
|
|||
|
||||
pub fn is_untyped_exception(type_: Option<&Expr>, checker: &Checker) -> bool {
|
||||
type_.map_or(true, |type_| {
|
||||
if let ExprKind::Tuple { elts, .. } = &type_.node {
|
||||
if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &type_.node {
|
||||
elts.iter().any(|type_| {
|
||||
checker
|
||||
.ctx
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use num_traits::ToPrimitive;
|
||||
use once_cell::sync::Lazy;
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, Operator};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword, Operator};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -70,14 +70,14 @@ static PYSTAT_MAPPING: Lazy<FxHashMap<&'static str, u16>> = Lazy::new(|| {
|
|||
|
||||
fn get_int_value(expr: &Expr) -> Option<u16> {
|
||||
match &expr.node {
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(value),
|
||||
..
|
||||
} => value.to_u16(),
|
||||
ExprKind::Attribute { .. } => {
|
||||
}) => value.to_u16(),
|
||||
ExprKind::Attribute(_) => {
|
||||
compose_call_path(expr).and_then(|path| PYSTAT_MAPPING.get(path.as_str()).copied())
|
||||
}
|
||||
ExprKind::BinOp { left, op, right } => {
|
||||
ExprKind::BinOp(ast::ExprBinOp { left, op, right }) => {
|
||||
if let (Some(left_value), Some(right_value)) =
|
||||
(get_int_value(left), get_int_value(right))
|
||||
{
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -15,7 +15,7 @@ impl Violation for ExecBuiltin {
|
|||
|
||||
/// S102
|
||||
pub fn exec_used(expr: &Expr, func: &Expr) -> Option<Diagnostic> {
|
||||
let ExprKind::Name { id, .. } = &func.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else {
|
||||
return None;
|
||||
};
|
||||
if id != "exec" {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -24,17 +24,17 @@ impl Violation for HardcodedPasswordString {
|
|||
fn password_target(target: &Expr) -> Option<&str> {
|
||||
let target_name = match &target.node {
|
||||
// variable = "s3cr3t"
|
||||
ExprKind::Name { id, .. } => id,
|
||||
ExprKind::Name(ast::ExprName { id, .. }) => id.as_str(),
|
||||
// d["password"] = "s3cr3t"
|
||||
ExprKind::Subscript { slice, .. } => match &slice.node {
|
||||
ExprKind::Constant {
|
||||
ExprKind::Subscript(ast::ExprSubscript { slice, .. }) => match &slice.node {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(string),
|
||||
..
|
||||
} => string,
|
||||
}) => string,
|
||||
_ => return None,
|
||||
},
|
||||
// obj.password = "s3cr3t"
|
||||
ExprKind::Attribute { attr, .. } => attr,
|
||||
ExprKind::Attribute(ast::ExprAttribute { attr, .. }) => attr,
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use rustpython_parser::ast::{Expr, ExprKind, Operator};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Operator};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -56,10 +56,10 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio
|
|||
match &expr.node {
|
||||
// "select * from table where val = " + "str" + ...
|
||||
// "select * from table where val = %s" % ...
|
||||
ExprKind::BinOp {
|
||||
ExprKind::BinOp(ast::ExprBinOp {
|
||||
op: Operator::Add | Operator::Mod,
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
let Some(parent) = checker.ctx.expr_parent() else {
|
||||
if any_over_expr(expr, &has_string_literal) {
|
||||
return Some(unparse_expr(expr, checker.stylist));
|
||||
|
@ -67,7 +67,7 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio
|
|||
return None;
|
||||
};
|
||||
// Only evaluate the full BinOp, not the nested components.
|
||||
let ExprKind::BinOp { .. } = &parent.node else {
|
||||
let ExprKind::BinOp(_ )= &parent.node else {
|
||||
if any_over_expr(expr, &has_string_literal) {
|
||||
return Some(unparse_expr(expr, checker.stylist));
|
||||
}
|
||||
|
@ -75,8 +75,8 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio
|
|||
};
|
||||
None
|
||||
}
|
||||
ExprKind::Call { func, .. } => {
|
||||
let ExprKind::Attribute{ attr, value, .. } = &func.node else {
|
||||
ExprKind::Call(ast::ExprCall { func, .. }) => {
|
||||
let ExprKind::Attribute(ast::ExprAttribute { attr, value, .. }) = &func.node else {
|
||||
return None;
|
||||
};
|
||||
// "select * from table where val = {}".format(...)
|
||||
|
@ -86,7 +86,7 @@ fn unparse_string_format_expression(checker: &mut Checker, expr: &Expr) -> Optio
|
|||
None
|
||||
}
|
||||
// f"select * from table where val = {val}"
|
||||
ExprKind::JoinedStr { .. } => Some(unparse_expr(expr, checker.stylist)),
|
||||
ExprKind::JoinedStr(_) => Some(unparse_expr(expr, checker.stylist)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -27,10 +27,10 @@ fn is_used_for_security(call_args: &SimpleCallArgs) -> bool {
|
|||
match call_args.keyword_argument("usedforsecurity") {
|
||||
Some(expr) => !matches!(
|
||||
&expr.node,
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Bool(false),
|
||||
..
|
||||
}
|
||||
})
|
||||
),
|
||||
_ => true,
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -47,13 +47,13 @@ pub fn jinja2_autoescape_false(
|
|||
|
||||
if let Some(autoescape_arg) = call_args.keyword_argument("autoescape") {
|
||||
match &autoescape_arg.node {
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Bool(true),
|
||||
..
|
||||
} => (),
|
||||
ExprKind::Call { func, .. } => {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if id.as_str() != "select_autoescape" {
|
||||
}) => (),
|
||||
ExprKind::Call(ast::ExprCall { func, .. }) => {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node {
|
||||
if id != "select_autoescape" {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
Jinja2AutoescapeFalse { value: true },
|
||||
autoescape_arg.range(),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -56,10 +56,10 @@ pub fn request_with_no_cert_validation(
|
|||
}) {
|
||||
let call_args = SimpleCallArgs::new(args, keywords);
|
||||
if let Some(verify_arg) = call_args.keyword_argument("verify") {
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Bool(false),
|
||||
..
|
||||
} = &verify_arg.node
|
||||
}) = &verify_arg.node
|
||||
{
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
RequestWithNoCertValidation {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -45,10 +45,10 @@ pub fn request_without_timeout(
|
|||
let call_args = SimpleCallArgs::new(args, keywords);
|
||||
if let Some(timeout_arg) = call_args.keyword_argument("timeout") {
|
||||
if let Some(timeout) = match &timeout_arg.node {
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: value @ Constant::None,
|
||||
..
|
||||
} => Some(unparse_constant(value, checker.stylist)),
|
||||
}) => Some(unparse_constant(value, checker.stylist)),
|
||||
_ => None,
|
||||
} {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -159,17 +159,17 @@ fn find_shell_keyword<'a>(ctx: &Context, keywords: &'a [Keyword]) -> Option<Shel
|
|||
fn shell_call_seems_safe(arg: &Expr) -> bool {
|
||||
matches!(
|
||||
arg.node,
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(_),
|
||||
..
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
/// Return the [`Expr`] as a string literal, if it's a string or a list of strings.
|
||||
fn try_string_literal(expr: &Expr) -> Option<&str> {
|
||||
match &expr.node {
|
||||
ExprKind::List { elts, .. } => {
|
||||
ExprKind::List(ast::ExprList { elts, .. }) => {
|
||||
if elts.is_empty() {
|
||||
None
|
||||
} else {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use num_traits::{One, Zero};
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -33,10 +33,10 @@ pub fn snmp_insecure_version(
|
|||
{
|
||||
let call_args = SimpleCallArgs::new(args, keywords);
|
||||
if let Some(mp_model_arg) = call_args.keyword_argument("mpModel") {
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(value),
|
||||
..
|
||||
} = &mp_model_arg.node
|
||||
}) = &mp_model_arg.node
|
||||
{
|
||||
if value.is_zero() || value.is_one() {
|
||||
checker
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
//! Check for calls to suspicious functions, or calls into suspicious modules.
|
||||
//!
|
||||
//! See: <https://bandit.readthedocs.io/en/latest/blacklists/blacklist_calls.html>
|
||||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, DiagnosticKind, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -466,7 +466,7 @@ const SUSPICIOUS_MODULES: &[SuspiciousModule] = &[
|
|||
|
||||
/// S001
|
||||
pub fn suspicious_function_call(checker: &mut Checker, expr: &Expr) {
|
||||
let ExprKind::Call { func, .. } = &expr.node else {
|
||||
let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -48,8 +48,8 @@ pub fn unsafe_yaml_load(checker: &mut Checker, func: &Expr, args: &[Expr], keywo
|
|||
})
|
||||
{
|
||||
let loader = match &loader_arg.node {
|
||||
ExprKind::Attribute { attr, .. } => Some(attr.to_string()),
|
||||
ExprKind::Name { id, .. } => Some(id.to_string()),
|
||||
ExprKind::Attribute(ast::ExprAttribute { attr, .. }) => Some(attr.to_string()),
|
||||
ExprKind::Name(ast::ExprName { id, .. }) => Some(id.to_string()),
|
||||
_ => None,
|
||||
};
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -30,17 +30,17 @@ pub fn blind_except(
|
|||
let Some(type_) = type_ else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Name { id, .. } = &type_.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. }) = &type_.node else {
|
||||
return;
|
||||
};
|
||||
for exception in ["BaseException", "Exception"] {
|
||||
if id == exception && checker.ctx.is_builtin(exception) {
|
||||
// If the exception is re-raised, don't flag an error.
|
||||
if body.iter().any(|stmt| {
|
||||
if let StmtKind::Raise { exc, .. } = &stmt.node {
|
||||
if let StmtKind::Raise(ast::StmtRaise { exc, .. }) = &stmt.node {
|
||||
if let Some(exc) = exc {
|
||||
if let ExprKind::Name { id, .. } = &exc.node {
|
||||
name.map_or(false, |name| name == id)
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &exc.node {
|
||||
name.map_or(false, |name| id == name)
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -56,10 +56,12 @@ pub fn blind_except(
|
|||
|
||||
// If the exception is logged, don't flag an error.
|
||||
if body.iter().any(|stmt| {
|
||||
if let StmtKind::Expr { value } = &stmt.node {
|
||||
if let ExprKind::Call { func, keywords, .. } = &value.node {
|
||||
if let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node {
|
||||
if let ExprKind::Call(ast::ExprCall { func, keywords, .. }) = &value.node {
|
||||
if logging::is_logger_candidate(&checker.ctx, func) {
|
||||
if let ExprKind::Attribute { attr, .. } = &func.node {
|
||||
if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node
|
||||
{
|
||||
let attr = attr.as_str();
|
||||
if attr == "exception" {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Arguments, Constant, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Arguments, Constant, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_diagnostics::{Diagnostic, DiagnosticKind};
|
||||
|
@ -67,11 +67,11 @@ const FUNC_DEF_NAME_ALLOWLIST: &[&str] = &["__setitem__"];
|
|||
/// `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 {
|
||||
if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node {
|
||||
return FUNC_CALL_NAME_ALLOWLIST.contains(&attr.as_ref());
|
||||
}
|
||||
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node {
|
||||
return FUNC_CALL_NAME_ALLOWLIST.contains(&id.as_ref());
|
||||
}
|
||||
|
||||
|
@ -81,10 +81,10 @@ fn allow_boolean_trap(func: &Expr) -> bool {
|
|||
const fn is_boolean_arg(arg: &Expr) -> bool {
|
||||
matches!(
|
||||
&arg.node,
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Bool(_),
|
||||
..
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -120,11 +120,11 @@ pub fn check_positional_boolean_in_def(
|
|||
|
||||
// check for both bool (python class) and 'bool' (string annotation)
|
||||
let hint = match &expr.node {
|
||||
ExprKind::Name { id, .. } => id == "bool",
|
||||
ExprKind::Constant {
|
||||
ExprKind::Name(ast::ExprName { id, .. }) => id == "bool",
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} => value == "bool",
|
||||
}) => value == "bool",
|
||||
_ => false,
|
||||
};
|
||||
if !hint {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -57,8 +57,8 @@ fn is_abc_class(context: &Context, bases: &[Expr], keywords: &[Keyword]) -> bool
|
|||
fn is_empty_body(body: &[Stmt]) -> bool {
|
||||
body.iter().all(|stmt| match &stmt.node {
|
||||
StmtKind::Pass => true,
|
||||
StmtKind::Expr { value } => match &value.node {
|
||||
ExprKind::Constant { value, .. } => {
|
||||
StmtKind::Expr(ast::StmtExpr { value }) => match &value.node {
|
||||
ExprKind::Constant(ast::ExprConstant { value, .. }) => {
|
||||
matches!(value, Constant::Str(..) | Constant::Ellipsis)
|
||||
}
|
||||
_ => false,
|
||||
|
@ -88,23 +88,23 @@ pub fn abstract_base_class(
|
|||
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 {
|
||||
if let StmtKind::AnnAssign(_) | StmtKind::Assign(_) = &stmt.node {
|
||||
has_abstract_method = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
let (
|
||||
StmtKind::FunctionDef {
|
||||
StmtKind::FunctionDef(ast::StmtFunctionDef {
|
||||
decorator_list,
|
||||
body,
|
||||
name: method_name,
|
||||
..
|
||||
} | StmtKind::AsyncFunctionDef {
|
||||
}) | StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef {
|
||||
decorator_list,
|
||||
body,
|
||||
name: method_name,
|
||||
..
|
||||
}
|
||||
})
|
||||
) = &stmt.node else {
|
||||
continue;
|
||||
};
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use ruff_text_size::TextSize;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -24,20 +24,17 @@ impl AlwaysAutofixableViolation for AssertFalse {
|
|||
|
||||
fn assertion_error(msg: Option<&Expr>) -> Stmt {
|
||||
Stmt::new(
|
||||
TextSize::default(),
|
||||
TextSize::default(),
|
||||
StmtKind::Raise {
|
||||
TextRange::default(),
|
||||
StmtKind::Raise(ast::StmtRaise {
|
||||
exc: Some(Box::new(Expr::new(
|
||||
TextSize::default(),
|
||||
TextSize::default(),
|
||||
ExprKind::Call {
|
||||
TextRange::default(),
|
||||
ExprKind::Call(ast::ExprCall {
|
||||
func: Box::new(Expr::new(
|
||||
TextSize::default(),
|
||||
TextSize::default(),
|
||||
ExprKind::Name {
|
||||
id: "AssertionError".to_string(),
|
||||
TextRange::default(),
|
||||
ExprKind::Name(ast::ExprName {
|
||||
id: "AssertionError".into(),
|
||||
ctx: ExprContext::Load,
|
||||
},
|
||||
}),
|
||||
)),
|
||||
args: if let Some(msg) = msg {
|
||||
vec![msg.clone()]
|
||||
|
@ -45,19 +42,19 @@ fn assertion_error(msg: Option<&Expr>) -> Stmt {
|
|||
vec![]
|
||||
},
|
||||
keywords: vec![],
|
||||
},
|
||||
}),
|
||||
))),
|
||||
cause: None,
|
||||
},
|
||||
}),
|
||||
)
|
||||
}
|
||||
|
||||
/// B011
|
||||
pub fn assert_false(checker: &mut Checker, stmt: &Stmt, test: &Expr, msg: Option<&Expr>) {
|
||||
let ExprKind::Constant {
|
||||
let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Bool(false),
|
||||
..
|
||||
} = &test.node else {
|
||||
} )= &test.node else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{ExprKind, Stmt, Withitem};
|
||||
use rustpython_parser::ast::{self, ExprKind, Stmt, Withitem};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -55,7 +55,7 @@ pub fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: &[With
|
|||
return;
|
||||
};
|
||||
let item_context = &item.context_expr;
|
||||
let ExprKind::Call { func, args, keywords } = &item_context.node else {
|
||||
let ExprKind::Call(ast::ExprCall { func, args, keywords }) = &item_context.node else {
|
||||
return;
|
||||
};
|
||||
if args.len() != 1 {
|
||||
|
@ -74,7 +74,8 @@ pub fn assert_raises_exception(checker: &mut Checker, stmt: &Stmt, items: &[With
|
|||
}
|
||||
|
||||
let kind = {
|
||||
if matches!(&func.node, ExprKind::Attribute { attr, .. } if attr == "assertRaises") {
|
||||
if matches!(&func.node, ExprKind::Attribute(ast::ExprAttribute { attr, .. }) if attr == "assertRaises")
|
||||
{
|
||||
AssertionKind::AssertRaises
|
||||
} else if checker
|
||||
.ctx
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -20,13 +20,13 @@ pub fn assignment_to_os_environ(checker: &mut Checker, targets: &[Expr]) {
|
|||
return;
|
||||
}
|
||||
let target = &targets[0];
|
||||
let ExprKind::Attribute { value, attr, .. } = &target.node else {
|
||||
let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &target.node else {
|
||||
return;
|
||||
};
|
||||
if attr != "environ" {
|
||||
return;
|
||||
}
|
||||
let ExprKind::Name { id, .. } = &value.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. } )= &value.node else {
|
||||
return;
|
||||
};
|
||||
if id != "os" {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -36,7 +36,7 @@ pub fn cached_instance_method(checker: &mut Checker, decorator_list: &[Expr]) {
|
|||
for decorator in decorator_list {
|
||||
// TODO(charlie): This should take into account `classmethod-decorators` and
|
||||
// `staticmethod-decorators`.
|
||||
if let ExprKind::Name { id, .. } = &decorator.node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &decorator.node {
|
||||
if id == "classmethod" || id == "staticmethod" {
|
||||
return;
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ pub fn cached_instance_method(checker: &mut Checker, decorator_list: &[Expr]) {
|
|||
if is_cache_func(
|
||||
checker,
|
||||
match &decorator.node {
|
||||
ExprKind::Call { func, .. } => func,
|
||||
ExprKind::Call(ast::ExprCall { func, .. }) => func,
|
||||
_ => decorator,
|
||||
},
|
||||
) {
|
||||
|
|
|
@ -17,7 +17,7 @@ impl Violation for CannotRaiseLiteral {
|
|||
|
||||
/// B016
|
||||
pub fn cannot_raise_literal(checker: &mut Checker, expr: &Expr) {
|
||||
let ExprKind::Constant { .. } = &expr.node else {
|
||||
let ExprKind::Constant ( _) = &expr.node else {
|
||||
return;
|
||||
};
|
||||
checker
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use itertools::Itertools;
|
||||
use ruff_text_size::TextSize;
|
||||
use ruff_text_size::TextRange;
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind};
|
||||
use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, Expr, ExprContext, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
||||
|
@ -50,9 +50,8 @@ impl AlwaysAutofixableViolation for DuplicateHandlerException {
|
|||
|
||||
fn type_pattern(elts: Vec<&Expr>) -> Expr {
|
||||
Expr::new(
|
||||
TextSize::default(),
|
||||
TextSize::default(),
|
||||
ExprKind::Tuple {
|
||||
TextRange::default(),
|
||||
ast::ExprTuple {
|
||||
elts: elts.into_iter().cloned().collect(),
|
||||
ctx: ExprContext::Load,
|
||||
},
|
||||
|
@ -117,11 +116,11 @@ pub fn duplicate_exceptions(checker: &mut Checker, handlers: &[Excepthandler]) {
|
|||
let mut seen: FxHashSet<CallPath> = FxHashSet::default();
|
||||
let mut duplicates: FxHashMap<CallPath, Vec<&Expr>> = FxHashMap::default();
|
||||
for handler in handlers {
|
||||
let ExcepthandlerKind::ExceptHandler { type_: Some(type_), .. } = &handler.node else {
|
||||
let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_: Some(type_), .. }) = &handler.node else {
|
||||
continue;
|
||||
};
|
||||
match &type_.node {
|
||||
ExprKind::Attribute { .. } | ExprKind::Name { .. } => {
|
||||
ExprKind::Attribute(_) | ExprKind::Name(_) => {
|
||||
if let Some(call_path) = call_path::collect_call_path(type_) {
|
||||
if seen.contains(&call_path) {
|
||||
duplicates.entry(call_path).or_default().push(type_);
|
||||
|
@ -130,7 +129,7 @@ pub fn duplicate_exceptions(checker: &mut Checker, handlers: &[Excepthandler]) {
|
|||
}
|
||||
}
|
||||
}
|
||||
ExprKind::Tuple { elts, .. } => {
|
||||
ExprKind::Tuple(ast::ExprTuple { elts, .. }) => {
|
||||
for (name, expr) in duplicate_handler_exceptions(checker, type_, elts) {
|
||||
if seen.contains(&name) {
|
||||
duplicates.entry(name).or_default().push(expr);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustpython_parser::ast::Excepthandler;
|
||||
use rustpython_parser::ast::{ExcepthandlerKind, ExprKind};
|
||||
use rustpython_parser::ast::{self, ExcepthandlerKind, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -18,11 +18,12 @@ impl Violation for ExceptWithEmptyTuple {
|
|||
|
||||
/// B029
|
||||
pub fn except_with_empty_tuple(checker: &mut Checker, excepthandler: &Excepthandler) {
|
||||
let ExcepthandlerKind::ExceptHandler { type_, .. } = &excepthandler.node;
|
||||
let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) =
|
||||
&excepthandler.node;
|
||||
let Some(type_) = type_ else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Tuple { elts, .. } = &type_.node else {
|
||||
let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &type_.node else {
|
||||
return;
|
||||
};
|
||||
if elts.is_empty() {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::collections::VecDeque;
|
||||
|
||||
use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -21,15 +21,16 @@ impl Violation for ExceptWithNonExceptionClasses {
|
|||
/// This should leave any unstarred iterables alone (subsequently raising a
|
||||
/// warning for B029).
|
||||
fn flatten_starred_iterables(expr: &Expr) -> Vec<&Expr> {
|
||||
let ExprKind::Tuple { elts, .. } = &expr.node else {
|
||||
let ExprKind::Tuple(ast::ExprTuple { elts, .. } )= &expr.node else {
|
||||
return vec![expr];
|
||||
};
|
||||
let mut flattened_exprs: Vec<&Expr> = Vec::with_capacity(elts.len());
|
||||
let mut exprs_to_process: VecDeque<&Expr> = elts.iter().collect();
|
||||
while let Some(expr) = exprs_to_process.pop_front() {
|
||||
match &expr.node {
|
||||
ExprKind::Starred { value, .. } => match &value.node {
|
||||
ExprKind::Tuple { elts, .. } | ExprKind::List { elts, .. } => {
|
||||
ExprKind::Starred(ast::ExprStarred { value, .. }) => match &value.node {
|
||||
ExprKind::Tuple(ast::ExprTuple { elts, .. })
|
||||
| ExprKind::List(ast::ExprList { elts, .. }) => {
|
||||
exprs_to_process.append(&mut elts.iter().collect());
|
||||
}
|
||||
_ => flattened_exprs.push(value),
|
||||
|
@ -42,17 +43,15 @@ fn flatten_starred_iterables(expr: &Expr) -> Vec<&Expr> {
|
|||
|
||||
/// B030
|
||||
pub fn except_with_non_exception_classes(checker: &mut Checker, excepthandler: &Excepthandler) {
|
||||
let ExcepthandlerKind::ExceptHandler { type_, .. } = &excepthandler.node;
|
||||
let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_, .. }) =
|
||||
&excepthandler.node;
|
||||
let Some(type_) = type_ else {
|
||||
return;
|
||||
};
|
||||
for expr in flatten_starred_iterables(type_) {
|
||||
if !matches!(
|
||||
&expr.node,
|
||||
ExprKind::Subscript { .. }
|
||||
| ExprKind::Attribute { .. }
|
||||
| ExprKind::Name { .. }
|
||||
| ExprKind::Call { .. },
|
||||
ExprKind::Subscript(_) | ExprKind::Attribute(_) | ExprKind::Name(_) | ExprKind::Call(_),
|
||||
) {
|
||||
checker
|
||||
.diagnostics
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -23,10 +23,10 @@ pub fn f_string_docstring(checker: &mut Checker, body: &[Stmt]) {
|
|||
let Some(stmt) = body.first() else {
|
||||
return;
|
||||
};
|
||||
let StmtKind::Expr { value } = &stmt.node else {
|
||||
let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::JoinedStr { .. } = value.node else {
|
||||
let ExprKind::JoinedStr ( _) = value.node else {
|
||||
return;
|
||||
};
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::{Arguments, Constant, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Arguments, Constant, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_diagnostics::{Diagnostic, DiagnosticKind};
|
||||
|
@ -84,7 +84,7 @@ where
|
|||
{
|
||||
fn visit_expr(&mut self, expr: &'b Expr) {
|
||||
match &expr.node {
|
||||
ExprKind::Call { func, args, .. } => {
|
||||
ExprKind::Call(ast::ExprCall { func, args, .. }) => {
|
||||
if !is_mutable_func(self.checker, func)
|
||||
&& !is_immutable_func(&self.checker.ctx, func, &self.extend_immutable_calls)
|
||||
&& !is_nan_or_infinity(func, args)
|
||||
|
@ -99,14 +99,14 @@ where
|
|||
}
|
||||
visitor::walk_expr(self, expr);
|
||||
}
|
||||
ExprKind::Lambda { .. } => {}
|
||||
ExprKind::Lambda(_) => {}
|
||||
_ => visitor::walk_expr(self, expr),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn is_nan_or_infinity(expr: &Expr, args: &[Expr]) -> bool {
|
||||
let ExprKind::Name { id, .. } = &expr.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. }) = &expr.node else {
|
||||
return false;
|
||||
};
|
||||
if id != "float" {
|
||||
|
@ -115,10 +115,10 @@ fn is_nan_or_infinity(expr: &Expr, args: &[Expr]) -> bool {
|
|||
let Some(arg) = args.first() else {
|
||||
return false;
|
||||
};
|
||||
let ExprKind::Constant {
|
||||
let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} = &arg.node else {
|
||||
} )= &arg.node else {
|
||||
return false;
|
||||
};
|
||||
let lowercased = value.to_lowercase();
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use ruff_text_size::TextRange;
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustpython_parser::ast::{Comprehension, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Comprehension, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -36,7 +36,7 @@ struct LoadedNamesVisitor<'a> {
|
|||
impl<'a> Visitor<'a> for LoadedNamesVisitor<'a> {
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
match &expr.node {
|
||||
ExprKind::Name { id, ctx } => match ctx {
|
||||
ExprKind::Name(ast::ExprName { id, ctx }) => match ctx {
|
||||
ExprContext::Load => self.loaded.push((id, expr, expr.range())),
|
||||
ExprContext::Store => self.stored.push((id, expr, expr.range())),
|
||||
ExprContext::Del => {}
|
||||
|
@ -57,8 +57,8 @@ struct SuspiciousVariablesVisitor<'a> {
|
|||
impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
|
||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||
match &stmt.node {
|
||||
StmtKind::FunctionDef { args, body, .. }
|
||||
| StmtKind::AsyncFunctionDef { args, body, .. } => {
|
||||
StmtKind::FunctionDef(ast::StmtFunctionDef { args, body, .. })
|
||||
| StmtKind::AsyncFunctionDef(ast::StmtAsyncFunctionDef { args, body, .. }) => {
|
||||
// Collect all loaded variable names.
|
||||
let mut visitor = LoadedNamesVisitor::default();
|
||||
visitor.visit_body(body);
|
||||
|
@ -76,9 +76,9 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
|
|||
);
|
||||
return;
|
||||
}
|
||||
StmtKind::Return { value: Some(value) } => {
|
||||
StmtKind::Return(ast::StmtReturn { value: Some(value) }) => {
|
||||
// Mark `return lambda: x` as safe.
|
||||
if matches!(value.node, ExprKind::Lambda { .. }) {
|
||||
if matches!(value.node, ExprKind::Lambda(_)) {
|
||||
self.safe_functions.push(value);
|
||||
}
|
||||
}
|
||||
|
@ -89,26 +89,27 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
|
|||
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
match &expr.node {
|
||||
ExprKind::Call {
|
||||
ExprKind::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
} => {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
}) => {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node {
|
||||
let id = id.as_str();
|
||||
if id == "filter" || id == "reduce" || id == "map" {
|
||||
for arg in args {
|
||||
if matches!(arg.node, ExprKind::Lambda { .. }) {
|
||||
if matches!(arg.node, ExprKind::Lambda(_)) {
|
||||
self.safe_functions.push(arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if let ExprKind::Attribute { value, attr, .. } = &func.node {
|
||||
if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node {
|
||||
if attr == "reduce" {
|
||||
if let ExprKind::Name { id, .. } = &value.node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node {
|
||||
if id == "functools" {
|
||||
for arg in args {
|
||||
if matches!(arg.node, ExprKind::Lambda { .. }) {
|
||||
if matches!(arg.node, ExprKind::Lambda(_)) {
|
||||
self.safe_functions.push(arg);
|
||||
}
|
||||
}
|
||||
|
@ -118,13 +119,13 @@ impl<'a> Visitor<'a> for SuspiciousVariablesVisitor<'a> {
|
|||
}
|
||||
for keyword in keywords {
|
||||
if keyword.node.arg.as_ref().map_or(false, |arg| arg == "key")
|
||||
&& matches!(keyword.node.value.node, ExprKind::Lambda { .. })
|
||||
&& matches!(keyword.node.value.node, ExprKind::Lambda(_))
|
||||
{
|
||||
self.safe_functions.push(&keyword.node.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
ExprKind::Lambda { args, body } => {
|
||||
ExprKind::Lambda(ast::ExprLambda { args, body }) => {
|
||||
if !self.safe_functions.contains(&expr) {
|
||||
// Collect all loaded variable names.
|
||||
let mut visitor = LoadedNamesVisitor::default();
|
||||
|
@ -160,13 +161,14 @@ struct NamesFromAssignmentsVisitor<'a> {
|
|||
impl<'a> Visitor<'a> for NamesFromAssignmentsVisitor<'a> {
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
match &expr.node {
|
||||
ExprKind::Name { id, .. } => {
|
||||
ExprKind::Name(ast::ExprName { id, .. }) => {
|
||||
self.names.insert(id.as_str());
|
||||
}
|
||||
ExprKind::Starred { value, .. } => {
|
||||
ExprKind::Starred(ast::ExprStarred { value, .. }) => {
|
||||
self.visit_expr(value);
|
||||
}
|
||||
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } => {
|
||||
ExprKind::List(ast::ExprList { elts, .. })
|
||||
| ExprKind::Tuple(ast::ExprTuple { elts, .. }) => {
|
||||
for expr in elts {
|
||||
self.visit_expr(expr);
|
||||
}
|
||||
|
@ -186,24 +188,24 @@ impl<'a> Visitor<'a> for AssignedNamesVisitor<'a> {
|
|||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||
if matches!(
|
||||
&stmt.node,
|
||||
StmtKind::FunctionDef { .. } | StmtKind::AsyncFunctionDef { .. }
|
||||
StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_)
|
||||
) {
|
||||
// Don't recurse.
|
||||
return;
|
||||
}
|
||||
|
||||
match &stmt.node {
|
||||
StmtKind::Assign { targets, .. } => {
|
||||
StmtKind::Assign(ast::StmtAssign { targets, .. }) => {
|
||||
let mut visitor = NamesFromAssignmentsVisitor::default();
|
||||
for expr in targets {
|
||||
visitor.visit_expr(expr);
|
||||
}
|
||||
self.names.extend(visitor.names);
|
||||
}
|
||||
StmtKind::AugAssign { target, .. }
|
||||
| StmtKind::AnnAssign { target, .. }
|
||||
| StmtKind::For { target, .. }
|
||||
| StmtKind::AsyncFor { target, .. } => {
|
||||
StmtKind::AugAssign(ast::StmtAugAssign { target, .. })
|
||||
| StmtKind::AnnAssign(ast::StmtAnnAssign { target, .. })
|
||||
| StmtKind::For(ast::StmtFor { target, .. })
|
||||
| StmtKind::AsyncFor(ast::StmtAsyncFor { target, .. }) => {
|
||||
let mut visitor = NamesFromAssignmentsVisitor::default();
|
||||
visitor.visit_expr(target);
|
||||
self.names.extend(visitor.names);
|
||||
|
@ -215,7 +217,7 @@ impl<'a> Visitor<'a> for AssignedNamesVisitor<'a> {
|
|||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
if matches!(&expr.node, ExprKind::Lambda { .. }) {
|
||||
if matches!(&expr.node, ExprKind::Lambda(_)) {
|
||||
// Don't recurse.
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use ruff_text_size::TextSize;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind};
|
||||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -27,11 +27,10 @@ impl AlwaysAutofixableViolation for GetAttrWithConstant {
|
|||
}
|
||||
fn attribute(value: &Expr, attr: &str) -> Expr {
|
||||
Expr::new(
|
||||
TextSize::default(),
|
||||
TextSize::default(),
|
||||
ExprKind::Attribute {
|
||||
TextRange::default(),
|
||||
ast::ExprAttribute {
|
||||
value: Box::new(value.clone()),
|
||||
attr: attr.to_string(),
|
||||
attr: attr.into(),
|
||||
ctx: ExprContext::Load,
|
||||
},
|
||||
)
|
||||
|
@ -39,7 +38,7 @@ fn attribute(value: &Expr, attr: &str) -> Expr {
|
|||
|
||||
/// B009
|
||||
pub fn getattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
||||
let ExprKind::Name { id, .. } = &func.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. } )= &func.node else {
|
||||
return;
|
||||
};
|
||||
if id != "getattr" {
|
||||
|
@ -48,10 +47,10 @@ pub fn getattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, ar
|
|||
let [obj, arg] = args else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Constant {
|
||||
let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} = &arg.node else {
|
||||
} )= &arg.node else {
|
||||
return;
|
||||
};
|
||||
if !is_identifier(value) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -24,33 +24,34 @@ fn walk_stmt(checker: &mut Checker, body: &[Stmt], f: fn(&Stmt) -> bool) {
|
|||
checker.diagnostics.push(Diagnostic::new(
|
||||
JumpStatementInFinally {
|
||||
name: match &stmt.node {
|
||||
StmtKind::Break { .. } => "break".to_string(),
|
||||
StmtKind::Continue { .. } => "continue".to_string(),
|
||||
StmtKind::Return { .. } => "return".to_string(),
|
||||
StmtKind::Break => "break",
|
||||
StmtKind::Continue => "continue",
|
||||
StmtKind::Return(_) => "return",
|
||||
_ => unreachable!(
|
||||
"Expected StmtKind::Break | StmtKind::Continue | StmtKind::Return"
|
||||
),
|
||||
},
|
||||
}
|
||||
.to_owned(),
|
||||
},
|
||||
stmt.range(),
|
||||
));
|
||||
}
|
||||
match &stmt.node {
|
||||
StmtKind::While { body, .. }
|
||||
| StmtKind::For { body, .. }
|
||||
| StmtKind::AsyncFor { body, .. } => {
|
||||
StmtKind::While(ast::StmtWhile { body, .. })
|
||||
| StmtKind::For(ast::StmtFor { body, .. })
|
||||
| StmtKind::AsyncFor(ast::StmtAsyncFor { body, .. }) => {
|
||||
walk_stmt(checker, body, |stmt| {
|
||||
matches!(stmt.node, StmtKind::Return { .. })
|
||||
matches!(stmt.node, StmtKind::Return(_))
|
||||
});
|
||||
}
|
||||
StmtKind::If { body, .. }
|
||||
| StmtKind::Try { body, .. }
|
||||
| StmtKind::TryStar { body, .. }
|
||||
| StmtKind::With { body, .. }
|
||||
| StmtKind::AsyncWith { body, .. } => {
|
||||
StmtKind::If(ast::StmtIf { body, .. })
|
||||
| StmtKind::Try(ast::StmtTry { body, .. })
|
||||
| StmtKind::TryStar(ast::StmtTryStar { body, .. })
|
||||
| StmtKind::With(ast::StmtWith { body, .. })
|
||||
| StmtKind::AsyncWith(ast::StmtAsyncWith { body, .. }) => {
|
||||
walk_stmt(checker, body, f);
|
||||
}
|
||||
StmtKind::Match { cases, .. } => {
|
||||
StmtKind::Match(ast::StmtMatch { cases, .. }) => {
|
||||
for case in cases {
|
||||
walk_stmt(checker, &case.body, f);
|
||||
}
|
||||
|
@ -65,7 +66,7 @@ pub fn jump_statement_in_finally(checker: &mut Checker, finalbody: &[Stmt]) {
|
|||
walk_stmt(checker, finalbody, |stmt| {
|
||||
matches!(
|
||||
stmt.node,
|
||||
StmtKind::Break | StmtKind::Continue | StmtKind::Return { .. }
|
||||
StmtKind::Break | StmtKind::Continue | StmtKind::Return(_)
|
||||
)
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_hash::FxHashMap;
|
||||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -32,18 +32,18 @@ where
|
|||
{
|
||||
fn visit_expr(&mut self, expr: &'b Expr) {
|
||||
match &expr.node {
|
||||
ExprKind::Name { id, .. } => {
|
||||
ExprKind::Name(ast::ExprName { id, .. }) => {
|
||||
self.names.insert(id, expr);
|
||||
}
|
||||
ExprKind::ListComp { generators, .. }
|
||||
| ExprKind::DictComp { generators, .. }
|
||||
| ExprKind::SetComp { generators, .. }
|
||||
| ExprKind::GeneratorExp { generators, .. } => {
|
||||
ExprKind::ListComp(ast::ExprListComp { generators, .. })
|
||||
| ExprKind::DictComp(ast::ExprDictComp { generators, .. })
|
||||
| ExprKind::SetComp(ast::ExprSetComp { generators, .. })
|
||||
| ExprKind::GeneratorExp(ast::ExprGeneratorExp { generators, .. }) => {
|
||||
for comp in generators {
|
||||
self.visit_expr(&comp.iter);
|
||||
}
|
||||
}
|
||||
ExprKind::Lambda { args, body } => {
|
||||
ExprKind::Lambda(ast::ExprLambda { args, body }) => {
|
||||
visitor::walk_expr(self, body);
|
||||
for arg in &args.args {
|
||||
self.names.remove(arg.node.arg.as_str());
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Arguments, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Arguments, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -38,13 +38,13 @@ pub fn is_mutable_func(checker: &Checker, func: &Expr) -> bool {
|
|||
|
||||
fn is_mutable_expr(checker: &Checker, expr: &Expr) -> bool {
|
||||
match &expr.node {
|
||||
ExprKind::List { .. }
|
||||
| ExprKind::Dict { .. }
|
||||
| ExprKind::Set { .. }
|
||||
| ExprKind::ListComp { .. }
|
||||
| ExprKind::DictComp { .. }
|
||||
| ExprKind::SetComp { .. } => true,
|
||||
ExprKind::Call { func, .. } => is_mutable_func(checker, func),
|
||||
ExprKind::List(_)
|
||||
| ExprKind::Dict(_)
|
||||
| ExprKind::Set(_)
|
||||
| ExprKind::ListComp(_)
|
||||
| ExprKind::DictComp(_)
|
||||
| ExprKind::SetComp(_) => true,
|
||||
ExprKind::Call(ast::ExprCall { func, .. }) => is_mutable_func(checker, func),
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{ExprKind, Stmt};
|
||||
use rustpython_parser::ast::{self, ExprKind, Stmt};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -33,7 +33,7 @@ pub fn raise_without_from_inside_except(checker: &mut Checker, body: &[Stmt]) {
|
|||
if cause.is_none() {
|
||||
if let Some(exc) = exc {
|
||||
match &exc.node {
|
||||
ExprKind::Name { id, .. } if is_lower(id) => {}
|
||||
ExprKind::Name(ast::ExprName { id, .. }) if is_lower(id) => {}
|
||||
_ => {
|
||||
checker
|
||||
.diagnostics
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Excepthandler, ExcepthandlerKind, ExprKind};
|
||||
use rustpython_parser::ast::{self, Excepthandler, ExcepthandlerKind, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -31,10 +31,10 @@ impl AlwaysAutofixableViolation for RedundantTupleInExceptionHandler {
|
|||
/// B013
|
||||
pub fn redundant_tuple_in_exception_handler(checker: &mut Checker, handlers: &[Excepthandler]) {
|
||||
for handler in handlers {
|
||||
let ExcepthandlerKind::ExceptHandler { type_: Some(type_), .. } = &handler.node else {
|
||||
let ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler { type_: Some(type_), .. }) = &handler.node else {
|
||||
continue;
|
||||
};
|
||||
let ExprKind::Tuple { elts, .. } = &type_.node else {
|
||||
let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &type_.node else {
|
||||
continue;
|
||||
};
|
||||
let [elt] = &elts[..] else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Comprehension, Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Comprehension, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -84,7 +84,7 @@ impl<'a> GroupNameFinder<'a> {
|
|||
}
|
||||
|
||||
fn name_matches(&self, expr: &Expr) -> bool {
|
||||
if let ExprKind::Name { id, .. } = &expr.node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &expr.node {
|
||||
id == self.group_name
|
||||
} else {
|
||||
false
|
||||
|
@ -113,9 +113,9 @@ where
|
|||
return;
|
||||
}
|
||||
match &stmt.node {
|
||||
StmtKind::For {
|
||||
StmtKind::For(ast::StmtFor {
|
||||
target, iter, body, ..
|
||||
} => {
|
||||
}) => {
|
||||
if self.name_matches(target) {
|
||||
self.overridden = true;
|
||||
} else {
|
||||
|
@ -138,15 +138,15 @@ where
|
|||
self.nested = false;
|
||||
}
|
||||
}
|
||||
StmtKind::While { body, .. } => {
|
||||
StmtKind::While(ast::StmtWhile { body, .. }) => {
|
||||
self.nested = true;
|
||||
visitor::walk_body(self, body);
|
||||
self.nested = false;
|
||||
}
|
||||
StmtKind::If { test, body, orelse } => {
|
||||
StmtKind::If(ast::StmtIf { test, body, orelse }) => {
|
||||
// Determine whether we're on an `if` arm (as opposed to an `elif`).
|
||||
let is_if_arm = !self.parent_ifs.iter().any(|parent| {
|
||||
if let StmtKind::If { orelse, .. } = &parent.node {
|
||||
if let StmtKind::If(ast::StmtIf { orelse, .. }) = &parent.node {
|
||||
orelse.len() == 1 && &orelse[0] == stmt
|
||||
} else {
|
||||
false
|
||||
|
@ -166,7 +166,7 @@ where
|
|||
|
||||
let has_else = orelse
|
||||
.first()
|
||||
.map_or(false, |expr| !matches!(expr.node, StmtKind::If { .. }));
|
||||
.map_or(false, |expr| !matches!(expr.node, StmtKind::If(_)));
|
||||
|
||||
self.parent_ifs.push(stmt);
|
||||
if has_else {
|
||||
|
@ -193,7 +193,7 @@ where
|
|||
}
|
||||
}
|
||||
}
|
||||
StmtKind::Match { subject, cases } => {
|
||||
StmtKind::Match(ast::StmtMatch { subject, cases }) => {
|
||||
self.counter_stack.push(Vec::with_capacity(cases.len()));
|
||||
self.visit_expr(subject);
|
||||
for match_case in cases {
|
||||
|
@ -207,14 +207,14 @@ where
|
|||
self.increment_usage_count(max_count);
|
||||
}
|
||||
}
|
||||
StmtKind::Assign { targets, value, .. } => {
|
||||
StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => {
|
||||
if targets.iter().any(|target| self.name_matches(target)) {
|
||||
self.overridden = true;
|
||||
} else {
|
||||
self.visit_expr(value);
|
||||
}
|
||||
}
|
||||
StmtKind::AnnAssign { target, value, .. } => {
|
||||
StmtKind::AnnAssign(ast::StmtAnnAssign { target, value, .. }) => {
|
||||
if self.name_matches(target) {
|
||||
self.overridden = true;
|
||||
} else if let Some(expr) = value {
|
||||
|
@ -241,7 +241,7 @@ where
|
|||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
if let ExprKind::NamedExpr { target, .. } = &expr.node {
|
||||
if let ExprKind::NamedExpr(ast::ExprNamedExpr { target, .. }) = &expr.node {
|
||||
if self.name_matches(target) {
|
||||
self.overridden = true;
|
||||
}
|
||||
|
@ -251,7 +251,8 @@ where
|
|||
}
|
||||
|
||||
match &expr.node {
|
||||
ExprKind::ListComp { elt, generators } | ExprKind::SetComp { elt, generators } => {
|
||||
ExprKind::ListComp(ast::ExprListComp { elt, generators })
|
||||
| ExprKind::SetComp(ast::ExprSetComp { elt, generators }) => {
|
||||
for comprehension in generators {
|
||||
self.visit_comprehension(comprehension);
|
||||
}
|
||||
|
@ -261,11 +262,11 @@ where
|
|||
self.nested = false;
|
||||
}
|
||||
}
|
||||
ExprKind::DictComp {
|
||||
ExprKind::DictComp(ast::ExprDictComp {
|
||||
key,
|
||||
value,
|
||||
generators,
|
||||
} => {
|
||||
}) => {
|
||||
for comprehension in generators {
|
||||
self.visit_comprehension(comprehension);
|
||||
}
|
||||
|
@ -307,10 +308,10 @@ pub fn reuse_of_groupby_generator(
|
|||
body: &[Stmt],
|
||||
iter: &Expr,
|
||||
) {
|
||||
let ExprKind::Call { func, .. } = &iter.node else {
|
||||
let ExprKind::Call(ast::ExprCall { func, .. }) = &iter.node else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Tuple { elts, .. } = &target.node else {
|
||||
let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &target.node else {
|
||||
// Ignore any `groupby()` invocation that isn't unpacked
|
||||
return;
|
||||
};
|
||||
|
@ -318,7 +319,7 @@ pub fn reuse_of_groupby_generator(
|
|||
return;
|
||||
}
|
||||
// We have an invocation of groupby which is a simple unpacking
|
||||
let ExprKind::Name { id: group_name, .. } = &elts[1].node else {
|
||||
let ExprKind::Name(ast::ExprName { id: group_name, .. }) = &elts[1].node else {
|
||||
return;
|
||||
};
|
||||
// Check if the function call is `itertools.groupby`
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use ruff_text_size::TextSize;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -29,28 +29,26 @@ impl AlwaysAutofixableViolation for SetAttrWithConstant {
|
|||
|
||||
fn assignment(obj: &Expr, name: &str, value: &Expr, stylist: &Stylist) -> String {
|
||||
let stmt = Stmt::new(
|
||||
TextSize::default(),
|
||||
TextSize::default(),
|
||||
StmtKind::Assign {
|
||||
TextRange::default(),
|
||||
StmtKind::Assign(ast::StmtAssign {
|
||||
targets: vec![Expr::new(
|
||||
TextSize::default(),
|
||||
TextSize::default(),
|
||||
ExprKind::Attribute {
|
||||
TextRange::default(),
|
||||
ExprKind::Attribute(ast::ExprAttribute {
|
||||
value: Box::new(obj.clone()),
|
||||
attr: name.to_string(),
|
||||
attr: name.into(),
|
||||
ctx: ExprContext::Store,
|
||||
},
|
||||
}),
|
||||
)],
|
||||
value: Box::new(value.clone()),
|
||||
type_comment: None,
|
||||
},
|
||||
}),
|
||||
);
|
||||
unparse_stmt(&stmt, stylist)
|
||||
}
|
||||
|
||||
/// B010
|
||||
pub fn setattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
||||
let ExprKind::Name { id, .. } = &func.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else {
|
||||
return;
|
||||
};
|
||||
if id != "setattr" {
|
||||
|
@ -59,10 +57,10 @@ pub fn setattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, ar
|
|||
let [obj, name, value] = args else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Constant {
|
||||
let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(name),
|
||||
..
|
||||
} = &name.node else {
|
||||
} )= &name.node else {
|
||||
return;
|
||||
};
|
||||
if !is_identifier(name) {
|
||||
|
@ -74,7 +72,7 @@ pub fn setattr_with_constant(checker: &mut Checker, expr: &Expr, func: &Expr, ar
|
|||
// We can only replace a `setattr` call (which is an `Expr`) with an assignment
|
||||
// (which is a `Stmt`) if the `Expr` is already being used as a `Stmt`
|
||||
// (i.e., it's directly within an `StmtKind::Expr`).
|
||||
if let StmtKind::Expr { value: child } = &checker.ctx.stmt().node {
|
||||
if let StmtKind::Expr(ast::StmtExpr { value: child }) = &checker.ctx.stmt().node {
|
||||
if expr == child.as_ref() {
|
||||
let mut diagnostic = Diagnostic::new(SetAttrWithConstant, expr.range());
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ pub fn star_arg_unpacking_after_keyword_arg(
|
|||
return;
|
||||
};
|
||||
for arg in args {
|
||||
let ExprKind::Starred { .. } = arg.node else {
|
||||
let ExprKind::Starred (_) = arg.node else {
|
||||
continue;
|
||||
};
|
||||
if arg.start() <= keyword.start() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use itertools::Itertools;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -18,7 +18,7 @@ impl Violation for StripWithMultiCharacters {
|
|||
|
||||
/// B005
|
||||
pub fn strip_with_multi_characters(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
||||
let ExprKind::Attribute { attr, .. } = &func.node else {
|
||||
let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node else {
|
||||
return;
|
||||
};
|
||||
if !matches!(attr.as_str(), "strip" | "lstrip" | "rstrip") {
|
||||
|
@ -28,10 +28,10 @@ pub fn strip_with_multi_characters(checker: &mut Checker, expr: &Expr, func: &Ex
|
|||
return;
|
||||
}
|
||||
|
||||
let ExprKind::Constant {
|
||||
let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} = &args[0].node else {
|
||||
} )= &args[0].node else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
//! n += 1
|
||||
//! ```
|
||||
|
||||
use rustpython_parser::ast::{Expr, ExprKind, Unaryop};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Unaryop};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -39,7 +39,7 @@ pub fn unary_prefix_increment(checker: &mut Checker, expr: &Expr, op: &Unaryop,
|
|||
if !matches!(op, Unaryop::UAdd) {
|
||||
return;
|
||||
}
|
||||
let ExprKind::UnaryOp { op, .. } = &operand.node else {
|
||||
let ExprKind::UnaryOp(ast::ExprUnaryOp { op, .. })= &operand.node else {
|
||||
return;
|
||||
};
|
||||
if !matches!(op, Unaryop::UAdd) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Stmt};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Stmt};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -44,15 +44,15 @@ pub fn unintentional_type_annotation(
|
|||
return;
|
||||
}
|
||||
match &target.node {
|
||||
ExprKind::Subscript { value, .. } => {
|
||||
if matches!(&value.node, ExprKind::Name { .. }) {
|
||||
ExprKind::Subscript(ast::ExprSubscript { value, .. }) => {
|
||||
if matches!(&value.node, ExprKind::Name(_)) {
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(UnintentionalTypeAnnotation, stmt.range()));
|
||||
}
|
||||
}
|
||||
ExprKind::Attribute { value, .. } => {
|
||||
if let ExprKind::Name { id, .. } = &value.node {
|
||||
ExprKind::Attribute(ast::ExprAttribute { value, .. }) => {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &value.node {
|
||||
if id != "self" {
|
||||
checker
|
||||
.diagnostics
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -20,7 +20,7 @@ impl Violation for UnreliableCallableCheck {
|
|||
|
||||
/// B004
|
||||
pub fn unreliable_callable_check(checker: &mut Checker, expr: &Expr, func: &Expr, args: &[Expr]) {
|
||||
let ExprKind::Name { id, .. } = &func.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. }) = &func.node else {
|
||||
return;
|
||||
};
|
||||
if id != "getattr" && id != "hasattr" {
|
||||
|
@ -29,10 +29,10 @@ pub fn unreliable_callable_check(checker: &mut Checker, expr: &Expr, func: &Expr
|
|||
if args.len() < 2 {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Constant {
|
||||
let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(s),
|
||||
..
|
||||
} = &args[1].node else
|
||||
}) = &args[1].node else
|
||||
{
|
||||
return;
|
||||
};
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
//! ```
|
||||
|
||||
use rustc_hash::FxHashMap;
|
||||
use rustpython_parser::ast::{Expr, ExprKind, Stmt};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Stmt};
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||
|
@ -93,7 +93,7 @@ where
|
|||
'b: 'a,
|
||||
{
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
if let ExprKind::Name { id, .. } = &expr.node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &expr.node {
|
||||
self.names.insert(id, expr);
|
||||
}
|
||||
visitor::walk_expr(self, expr);
|
||||
|
|
|
@ -20,7 +20,7 @@ impl Violation for UselessComparison {
|
|||
|
||||
/// B015
|
||||
pub fn useless_comparison(checker: &mut Checker, expr: &Expr) {
|
||||
if matches!(expr.node, ExprKind::Compare { .. }) {
|
||||
if matches!(expr.node, ExprKind::Compare(_)) {
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(UselessComparison, expr.range()));
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -36,18 +36,18 @@ impl Violation for UselessExpression {
|
|||
/// B018
|
||||
pub fn useless_expression(checker: &mut Checker, value: &Expr) {
|
||||
// Ignore comparisons, as they're handled by `useless_comparison`.
|
||||
if matches!(value.node, ExprKind::Compare { .. }) {
|
||||
if matches!(value.node, ExprKind::Compare(_)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Ignore strings, to avoid false positives with docstrings.
|
||||
if matches!(
|
||||
value.node,
|
||||
ExprKind::JoinedStr { .. }
|
||||
| ExprKind::Constant {
|
||||
ExprKind::JoinedStr(_)
|
||||
| ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(..) | Constant::Ellipsis,
|
||||
..
|
||||
}
|
||||
})
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
@ -56,7 +56,7 @@ pub fn useless_expression(checker: &mut Checker, value: &Expr) {
|
|||
if contains_effect(value, |id| checker.ctx.is_builtin(id)) {
|
||||
// Flag attributes as useless expressions, even if they're attached to calls or other
|
||||
// expressions.
|
||||
if matches!(value.node, ExprKind::Attribute { .. }) {
|
||||
if matches!(value.node, ExprKind::Attribute(_)) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
UselessExpression {
|
||||
kind: Kind::Attribute,
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Keyword};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
|
@ -21,7 +21,7 @@ pub fn zip_without_explicit_strict(
|
|||
func: &Expr,
|
||||
kwargs: &[Keyword],
|
||||
) {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node {
|
||||
if id == "zip"
|
||||
&& checker.ctx.is_builtin("zip")
|
||||
&& !kwargs.iter().any(|keyword| {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::Located;
|
||||
use rustpython_parser::ast::Attributed;
|
||||
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_diagnostics::{Diagnostic, DiagnosticKind};
|
||||
|
@ -170,7 +170,7 @@ impl Violation for BuiltinAttributeShadowing {
|
|||
/// Check builtin name shadowing.
|
||||
pub fn builtin_shadowing<T>(
|
||||
name: &str,
|
||||
located: &Located<T>,
|
||||
located: &Attributed<T>,
|
||||
node_type: ShadowingType,
|
||||
ignorelist: &[String],
|
||||
) -> Option<Diagnostic> {
|
||||
|
|
|
@ -116,7 +116,7 @@ pub fn fix_unnecessary_generator_set(
|
|||
// If the expression is embedded in an f-string, surround it with spaces to avoid
|
||||
// syntax errors.
|
||||
if let Some(parent_element) = parent {
|
||||
if let &rustpython_parser::ast::ExprKind::FormattedValue { .. } = &parent_element.node {
|
||||
if let &rustpython_parser::ast::ExprKind::FormattedValue(_) = &parent_element.node {
|
||||
content = format!(" {content} ");
|
||||
}
|
||||
}
|
||||
|
@ -186,7 +186,7 @@ pub fn fix_unnecessary_generator_dict(
|
|||
// If the expression is embedded in an f-string, surround it with spaces to avoid
|
||||
// syntax errors.
|
||||
if let Some(parent_element) = parent {
|
||||
if let &rustpython_parser::ast::ExprKind::FormattedValue { .. } = &parent_element.node {
|
||||
if let &rustpython_parser::ast::ExprKind::FormattedValue(_) = &parent_element.node {
|
||||
content = format!(" {content} ");
|
||||
}
|
||||
}
|
||||
|
@ -1101,9 +1101,7 @@ pub fn fix_unnecessary_map(
|
|||
// syntax errors.
|
||||
if kind == "set" || kind == "dict" {
|
||||
if let Some(parent_element) = parent {
|
||||
if let &rustpython_parser::ast::ExprKind::FormattedValue { .. } =
|
||||
&parent_element.node
|
||||
{
|
||||
if let &rustpython_parser::ast::ExprKind::FormattedValue(_) = &parent_element.node {
|
||||
content = format!(" {content} ");
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Keyword};
|
||||
|
||||
pub fn expr_name(func: &Expr) -> Option<&str> {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node {
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::AsRule;
|
||||
|
@ -65,7 +65,7 @@ pub fn unnecessary_call_around_sorted(
|
|||
let Some(arg) = args.first() else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Call { func, .. } = &arg.node else {
|
||||
let ExprKind::Call(ast::ExprCall { func, .. }) = &arg.node else {
|
||||
return;
|
||||
};
|
||||
let Some(inner) = helpers::expr_name(func) else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Comprehension, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Comprehension, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -51,9 +51,9 @@ impl AlwaysAutofixableViolation for UnnecessaryComprehension {
|
|||
/// Add diagnostic for C416 based on the expression node id.
|
||||
fn add_diagnostic(checker: &mut Checker, expr: &Expr) {
|
||||
let id = match &expr.node {
|
||||
ExprKind::ListComp { .. } => "list",
|
||||
ExprKind::SetComp { .. } => "set",
|
||||
ExprKind::DictComp { .. } => "dict",
|
||||
ExprKind::ListComp(_) => "list",
|
||||
ExprKind::SetComp(_) => "set",
|
||||
ExprKind::DictComp(_) => "dict",
|
||||
_ => return,
|
||||
};
|
||||
if !checker.ctx.is_builtin(id) {
|
||||
|
@ -86,7 +86,7 @@ pub fn unnecessary_dict_comprehension(
|
|||
return;
|
||||
}
|
||||
let generator = &generators[0];
|
||||
if !(generator.ifs.is_empty() && generator.is_async == 0) {
|
||||
if !generator.ifs.is_empty() || generator.is_async {
|
||||
return;
|
||||
}
|
||||
let Some(key_id) = helpers::expr_name(key) else {
|
||||
|
@ -95,7 +95,7 @@ pub fn unnecessary_dict_comprehension(
|
|||
let Some(value_id) = helpers::expr_name(value) else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Tuple { elts, .. } = &generator.target.node else {
|
||||
let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &generator.target.node else {
|
||||
return;
|
||||
};
|
||||
if elts.len() != 2 {
|
||||
|
@ -127,7 +127,7 @@ pub fn unnecessary_list_set_comprehension(
|
|||
return;
|
||||
}
|
||||
let generator = &generators[0];
|
||||
if !(generator.ifs.is_empty() && generator.is_async == 0) {
|
||||
if !generator.ifs.is_empty() || generator.is_async {
|
||||
return;
|
||||
}
|
||||
let Some(elt_id) = helpers::expr_name(elt) else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::Violation;
|
||||
use ruff_diagnostics::{AutofixKind, Diagnostic};
|
||||
|
@ -66,11 +66,11 @@ pub fn unnecessary_comprehension_any_all(
|
|||
if !keywords.is_empty() {
|
||||
return;
|
||||
}
|
||||
let ExprKind::Name { id, .. } = &func.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. } )= &func.node else {
|
||||
return;
|
||||
};
|
||||
if (matches!(id.as_str(), "all" | "any")) && args.len() == 1 {
|
||||
let (ExprKind::ListComp { elt, .. } | ExprKind::SetComp { elt, .. }) = &args[0].node else {
|
||||
let (ExprKind::ListComp(ast::ExprListComp { elt, .. } )| ExprKind::SetComp(ast::ExprSetComp { elt, .. })) = &args[0].node else {
|
||||
return;
|
||||
};
|
||||
if is_async_generator(elt) {
|
||||
|
@ -92,5 +92,5 @@ pub fn unnecessary_comprehension_any_all(
|
|||
|
||||
/// Return `true` if the `Expr` contains an `await` expression.
|
||||
fn is_async_generator(expr: &Expr) -> bool {
|
||||
any_over_expr(expr, &|expr| matches!(expr.node, ExprKind::Await { .. }))
|
||||
any_over_expr(expr, &|expr| matches!(expr.node, ExprKind::Await(_)))
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -84,7 +84,7 @@ pub fn unnecessary_double_cast_or_process(
|
|||
let Some(arg) = args.first() else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Call { func, ..} = &arg.node else {
|
||||
let ExprKind::Call(ast::ExprCall { func, ..} )= &arg.node else {
|
||||
return;
|
||||
};
|
||||
let Some(inner) = helpers::expr_name(func) else {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -53,9 +53,9 @@ pub fn unnecessary_generator_dict(
|
|||
let Some(argument) = helpers::exactly_one_argument_with_matching_function("dict", func, args, keywords) else {
|
||||
return;
|
||||
};
|
||||
if let ExprKind::GeneratorExp { elt, .. } = argument {
|
||||
if let ExprKind::GeneratorExp(ast::ExprGeneratorExp { elt, .. }) = argument {
|
||||
match &elt.node {
|
||||
ExprKind::Tuple { elts, .. } if elts.len() == 2 => {
|
||||
ExprKind::Tuple(ast::ExprTuple { elts, .. }) if elts.len() == 2 => {
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorDict, expr.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
#[allow(deprecated)]
|
||||
|
|
|
@ -55,7 +55,7 @@ pub fn unnecessary_generator_list(
|
|||
if !checker.ctx.is_builtin("list") {
|
||||
return;
|
||||
}
|
||||
if let ExprKind::GeneratorExp { .. } = argument {
|
||||
if let ExprKind::GeneratorExp(_) = argument {
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorList, expr.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
#[allow(deprecated)]
|
||||
|
|
|
@ -56,7 +56,7 @@ pub fn unnecessary_generator_set(
|
|||
if !checker.ctx.is_builtin("set") {
|
||||
return;
|
||||
}
|
||||
if let ExprKind::GeneratorExp { .. } = argument {
|
||||
if let ExprKind::GeneratorExp(_) = argument {
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryGeneratorSet, expr.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
#[allow(deprecated)]
|
||||
|
|
|
@ -45,7 +45,7 @@ pub fn unnecessary_list_call(checker: &mut Checker, expr: &Expr, func: &Expr, ar
|
|||
if !checker.ctx.is_builtin("list") {
|
||||
return;
|
||||
}
|
||||
if !matches!(argument, ExprKind::ListComp { .. }) {
|
||||
if !matches!(argument, ExprKind::ListComp(_)) {
|
||||
return;
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryListCall, expr.range());
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Keyword};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::AsRule;
|
||||
|
@ -52,10 +52,10 @@ pub fn unnecessary_list_comprehension_dict(
|
|||
if !checker.ctx.is_builtin("dict") {
|
||||
return;
|
||||
}
|
||||
let ExprKind::ListComp { elt, .. } = &argument else {
|
||||
let ExprKind::ListComp(ast::ExprListComp { elt, .. }) = &argument else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Tuple { elts, .. } = &elt.node else {
|
||||
let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &elt.node else {
|
||||
return;
|
||||
};
|
||||
if elts.len() != 2 {
|
||||
|
|
|
@ -53,7 +53,7 @@ pub fn unnecessary_list_comprehension_set(
|
|||
if !checker.ctx.is_builtin("set") {
|
||||
return;
|
||||
}
|
||||
if let ExprKind::ListComp { .. } = &argument {
|
||||
if let ExprKind::ListComp(_) = &argument {
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryListComprehensionSet, expr.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
#[allow(deprecated)]
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Keyword};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use crate::registry::AsRule;
|
||||
|
@ -60,15 +60,14 @@ pub fn unnecessary_literal_dict(
|
|||
return;
|
||||
}
|
||||
let (kind, elts) = match argument {
|
||||
ExprKind::Tuple { elts, .. } => ("tuple", elts),
|
||||
ExprKind::List { elts, .. } => ("list", elts),
|
||||
ExprKind::Tuple(ast::ExprTuple { elts, .. }) => ("tuple", elts),
|
||||
ExprKind::List(ast::ExprList { elts, .. }) => ("list", elts),
|
||||
_ => return,
|
||||
};
|
||||
// Accept `dict((1, 2), ...))` `dict([(1, 2), ...])`.
|
||||
if !elts
|
||||
.iter()
|
||||
.all(|elt| matches!(&elt.node, ExprKind::Tuple { elts, .. } if elts.len() == 2))
|
||||
{
|
||||
if !elts.iter().all(
|
||||
|elt| matches!(&elt.node, ExprKind::Tuple(ast::ExprTuple { elts, .. } )if elts.len() == 2),
|
||||
) {
|
||||
return;
|
||||
}
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
|
|
|
@ -61,8 +61,8 @@ pub fn unnecessary_literal_set(
|
|||
return;
|
||||
}
|
||||
let kind = match argument {
|
||||
ExprKind::List { .. } => "list",
|
||||
ExprKind::Tuple { .. } => "tuple",
|
||||
ExprKind::List(_) => "list",
|
||||
ExprKind::Tuple(_) => "tuple",
|
||||
_ => return,
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
|
|
|
@ -79,8 +79,8 @@ pub fn unnecessary_literal_within_dict_call(
|
|||
return;
|
||||
}
|
||||
let argument_kind = match argument {
|
||||
ExprKind::DictComp { .. } => DictKind::Comprehension,
|
||||
ExprKind::Dict { .. } => DictKind::Literal,
|
||||
ExprKind::DictComp(_) => DictKind::Comprehension,
|
||||
ExprKind::Dict(_) => DictKind::Literal,
|
||||
_ => return,
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
|
|
|
@ -82,8 +82,8 @@ pub fn unnecessary_literal_within_list_call(
|
|||
return;
|
||||
}
|
||||
let argument_kind = match argument {
|
||||
ExprKind::Tuple { .. } => "tuple",
|
||||
ExprKind::List { .. } => "list",
|
||||
ExprKind::Tuple(_) => "tuple",
|
||||
ExprKind::List(_) => "list",
|
||||
_ => return,
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
|
|
|
@ -83,8 +83,8 @@ pub fn unnecessary_literal_within_tuple_call(
|
|||
return;
|
||||
}
|
||||
let argument_kind = match argument {
|
||||
ExprKind::Tuple { .. } => "tuple",
|
||||
ExprKind::List { .. } => "list",
|
||||
ExprKind::Tuple(_) => "tuple",
|
||||
ExprKind::List(_) => "list",
|
||||
_ => return,
|
||||
};
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::Diagnostic;
|
||||
use ruff_diagnostics::{AutofixKind, Violation};
|
||||
|
@ -94,7 +94,7 @@ pub fn unnecessary_map(
|
|||
|
||||
// Exclude the parent if already matched by other arms
|
||||
if let Some(parent) = parent {
|
||||
if let ExprKind::Call { func: f, .. } = &parent.node {
|
||||
if let ExprKind::Call(ast::ExprCall { func: f, .. }) = &parent.node {
|
||||
if let Some(id_parent) = helpers::expr_name(f) {
|
||||
if id_parent == "dict" || id_parent == "set" || id_parent == "list" {
|
||||
return;
|
||||
|
@ -103,7 +103,7 @@ pub fn unnecessary_map(
|
|||
};
|
||||
};
|
||||
|
||||
if args.len() == 2 && matches!(&args[0].node, ExprKind::Lambda { .. }) {
|
||||
if args.len() == 2 && matches!(&args[0].node, ExprKind::Lambda(_)) {
|
||||
let mut diagnostic = create_diagnostic("generator", expr.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
#[allow(deprecated)]
|
||||
|
@ -126,14 +126,14 @@ pub fn unnecessary_map(
|
|||
}
|
||||
|
||||
if let Some(arg) = args.first() {
|
||||
if let ExprKind::Call { func, args, .. } = &arg.node {
|
||||
if let ExprKind::Call(ast::ExprCall { func, args, .. }) = &arg.node {
|
||||
if args.len() != 2 {
|
||||
return;
|
||||
}
|
||||
let Some(argument) = helpers::first_argument_with_matching_function("map", func, args) else {
|
||||
return;
|
||||
};
|
||||
if let ExprKind::Lambda { .. } = argument {
|
||||
if let ExprKind::Lambda(_) = argument {
|
||||
let mut diagnostic = create_diagnostic(id, expr.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
#[allow(deprecated)]
|
||||
|
@ -158,12 +158,12 @@ pub fn unnecessary_map(
|
|||
}
|
||||
|
||||
if args.len() == 1 {
|
||||
if let ExprKind::Call { func, args, .. } = &args[0].node {
|
||||
if let ExprKind::Call(ast::ExprCall { func, args, .. }) = &args[0].node {
|
||||
let Some(argument) = helpers::first_argument_with_matching_function("map", func, args) else {
|
||||
return;
|
||||
};
|
||||
if let ExprKind::Lambda { body, .. } = &argument {
|
||||
if matches!(&body.node, ExprKind::Tuple { elts, .. } | ExprKind::List { elts, .. } if elts.len() == 2)
|
||||
if let ExprKind::Lambda(ast::ExprLambda { body, .. }) = &argument {
|
||||
if matches!(&body.node, ExprKind::Tuple(ast::ExprTuple { elts, .. }) | ExprKind::List(ast::ExprList { elts, .. } )if elts.len() == 2)
|
||||
{
|
||||
let mut diagnostic = create_diagnostic(id, expr.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use num_bigint::BigInt;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Unaryop};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Unaryop};
|
||||
|
||||
use crate::checkers::ast::Checker;
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
|
@ -60,10 +60,10 @@ pub fn unnecessary_subscript_reversal(
|
|||
if !checker.ctx.is_builtin(id) {
|
||||
return;
|
||||
}
|
||||
let ExprKind::Subscript { slice, .. } = &first_arg.node else {
|
||||
let ExprKind::Subscript(ast::ExprSubscript { slice, .. }) = &first_arg.node else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Slice { lower, upper, step } = &slice.node else {
|
||||
let ExprKind::Slice(ast::ExprSlice { lower, upper, step }) = &slice.node else {
|
||||
return;
|
||||
};
|
||||
if lower.is_some() || upper.is_some() {
|
||||
|
@ -72,16 +72,16 @@ pub fn unnecessary_subscript_reversal(
|
|||
let Some(step) = step.as_ref() else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::UnaryOp {
|
||||
let ExprKind::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::USub,
|
||||
operand,
|
||||
} = &step.node else {
|
||||
}) = &step.node else {
|
||||
return;
|
||||
};
|
||||
let ExprKind::Constant {
|
||||
let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(val),
|
||||
..
|
||||
} = &operand.node else {
|
||||
}) = &operand.node else {
|
||||
return;
|
||||
};
|
||||
if *val != BigInt::from(1) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -317,10 +317,10 @@ pub fn call_datetime_strptime_without_zone(
|
|||
}
|
||||
|
||||
// Does the `strptime` call contain a format string with a timezone specifier?
|
||||
if let Some(ExprKind::Constant {
|
||||
if let Some(ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(format),
|
||||
kind: None,
|
||||
}) = args.get(1).as_ref().map(|arg| &arg.node)
|
||||
})) = args.get(1).as_ref().map(|arg| &arg.node)
|
||||
{
|
||||
if format.contains("%z") {
|
||||
return;
|
||||
|
@ -335,8 +335,9 @@ pub fn call_datetime_strptime_without_zone(
|
|||
return;
|
||||
};
|
||||
|
||||
if let ExprKind::Call { keywords, .. } = &grandparent.node {
|
||||
if let ExprKind::Attribute { attr, .. } = &parent.node {
|
||||
if let ExprKind::Call(ast::ExprCall { keywords, .. }) = &grandparent.node {
|
||||
if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &parent.node {
|
||||
let attr = attr.as_str();
|
||||
// Ex) `datetime.strptime(...).astimezone()`
|
||||
if attr == "astimezone" {
|
||||
return;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -52,24 +52,24 @@ pub fn all_with_model_form(checker: &Checker, bases: &[Expr], body: &[Stmt]) ->
|
|||
return None;
|
||||
}
|
||||
for element in body.iter() {
|
||||
let StmtKind::ClassDef { name, body, .. } = &element.node else {
|
||||
let StmtKind::ClassDef(ast::StmtClassDef { name, body, .. }) = &element.node else {
|
||||
continue;
|
||||
};
|
||||
if name != "Meta" {
|
||||
continue;
|
||||
}
|
||||
for element in body.iter() {
|
||||
let StmtKind::Assign { targets, value, .. } = &element.node else {
|
||||
let StmtKind::Assign(ast::StmtAssign { targets, value, .. }) = &element.node else {
|
||||
continue;
|
||||
};
|
||||
for target in targets.iter() {
|
||||
let ExprKind::Name { id, .. } = &target.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. }) = &target.node else {
|
||||
continue;
|
||||
};
|
||||
if id != "fields" {
|
||||
continue;
|
||||
}
|
||||
let ExprKind::Constant { value, .. } = &value.node else {
|
||||
let ExprKind::Constant(ast::ExprConstant { value, .. }) = &value.node else {
|
||||
continue;
|
||||
};
|
||||
match &value {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -54,18 +54,18 @@ pub fn exclude_with_model_form(
|
|||
return None;
|
||||
}
|
||||
for element in body.iter() {
|
||||
let StmtKind::ClassDef { name, body, .. } = &element.node else {
|
||||
let StmtKind::ClassDef(ast::StmtClassDef { name, body, .. }) = &element.node else {
|
||||
continue;
|
||||
};
|
||||
if name != "Meta" {
|
||||
continue;
|
||||
}
|
||||
for element in body.iter() {
|
||||
let StmtKind::Assign { targets, .. } = &element.node else {
|
||||
let StmtKind::Assign(ast::StmtAssign { targets, .. }) = &element.node else {
|
||||
continue;
|
||||
};
|
||||
for target in targets.iter() {
|
||||
let ExprKind::Name { id, .. } = &target.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. }) = &target.node else {
|
||||
continue;
|
||||
};
|
||||
if id == "exclude" {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -86,7 +86,7 @@ pub fn locals_in_render_function(
|
|||
}
|
||||
|
||||
fn is_locals_call(checker: &Checker, expr: &Expr) -> bool {
|
||||
let ExprKind::Call { func, .. } = &expr.node else {
|
||||
let ExprKind::Call(ast::ExprCall { func, .. }) = &expr.node else {
|
||||
return false
|
||||
};
|
||||
checker
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, StmtKind};
|
||||
use rustpython_parser::ast::{ExprKind, Stmt};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -70,7 +69,7 @@ pub fn model_without_dunder_str(
|
|||
|
||||
fn has_dunder_method(body: &[Stmt]) -> bool {
|
||||
body.iter().any(|val| match &val.node {
|
||||
StmtKind::FunctionDef { name, .. } => {
|
||||
StmtKind::FunctionDef(ast::StmtFunctionDef { name, .. }) => {
|
||||
if name == "__str__" {
|
||||
return true;
|
||||
}
|
||||
|
@ -95,24 +94,24 @@ fn checker_applies(checker: &Checker, bases: &[Expr], body: &[Stmt]) -> bool {
|
|||
/// Check if class is abstract, in terms of Django model inheritance.
|
||||
fn is_model_abstract(body: &[Stmt]) -> bool {
|
||||
for element in body.iter() {
|
||||
let StmtKind::ClassDef {name, body, ..} = &element.node else {
|
||||
let StmtKind::ClassDef(ast::StmtClassDef {name, body, ..}) = &element.node else {
|
||||
continue
|
||||
};
|
||||
if name != "Meta" {
|
||||
continue;
|
||||
}
|
||||
for element in body.iter() {
|
||||
let StmtKind::Assign {targets, value, ..} = &element.node else {
|
||||
let StmtKind::Assign(ast::StmtAssign {targets, value, ..}) = &element.node else {
|
||||
continue;
|
||||
};
|
||||
for target in targets.iter() {
|
||||
let ExprKind::Name {id , ..} = &target.node else {
|
||||
let ExprKind::Name(ast::ExprName {id , ..}) = &target.node else {
|
||||
continue;
|
||||
};
|
||||
if id != "abstract" {
|
||||
continue;
|
||||
}
|
||||
let ExprKind::Constant{value: Constant::Bool(true), ..} = &value.node else {
|
||||
let ExprKind::Constant(ast::ExprConstant{value: Constant::Bool(true), ..}) = &value.node else {
|
||||
continue;
|
||||
};
|
||||
return true;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -59,9 +59,10 @@ where
|
|||
let mut seen_receiver = false;
|
||||
for (i, decorator) in decorator_list.iter().enumerate() {
|
||||
let is_receiver = match &decorator.node {
|
||||
ExprKind::Call { func, .. } => resolve_call_path(func).map_or(false, |call_path| {
|
||||
call_path.as_slice() == ["django", "dispatch", "receiver"]
|
||||
}),
|
||||
ExprKind::Call(ast::ExprCall { func, .. }) => resolve_call_path(func)
|
||||
.map_or(false, |call_path| {
|
||||
call_path.as_slice() == ["django", "dispatch", "receiver"]
|
||||
}),
|
||||
_ => false,
|
||||
};
|
||||
if i > 0 && is_receiver && !seen_receiver {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustpython_parser::ast::Constant::Bool;
|
||||
use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -64,7 +64,7 @@ const NOT_NULL_TRUE_FIELDS: [&str; 6] = [
|
|||
pub fn nullable_model_string_field(checker: &Checker, body: &[Stmt]) -> Vec<Diagnostic> {
|
||||
let mut errors = Vec::new();
|
||||
for statement in body.iter() {
|
||||
let StmtKind::Assign {value, ..} = &statement.node else {
|
||||
let StmtKind::Assign(ast::StmtAssign {value, ..}) = &statement.node else {
|
||||
continue
|
||||
};
|
||||
if let Some(field_name) = is_nullable_field(checker, value) {
|
||||
|
@ -80,7 +80,7 @@ pub fn nullable_model_string_field(checker: &Checker, body: &[Stmt]) -> Vec<Diag
|
|||
}
|
||||
|
||||
fn is_nullable_field<'a>(checker: &'a Checker, value: &'a Expr) -> Option<&'a str> {
|
||||
let ExprKind::Call {func, keywords, ..} = &value.node else {
|
||||
let ExprKind::Call(ast::ExprCall {func, keywords, ..}) = &value.node else {
|
||||
return None;
|
||||
};
|
||||
|
||||
|
@ -96,7 +96,7 @@ fn is_nullable_field<'a>(checker: &'a Checker, value: &'a Expr) -> Option<&'a st
|
|||
let mut blank_key = false;
|
||||
let mut unique_key = false;
|
||||
for keyword in keywords.iter() {
|
||||
let ExprKind::Constant {value: Bool(true), ..} = &keyword.node.value.node else {
|
||||
let ExprKind::Constant(ast::ExprConstant {value: Bool(true), ..}) = &keyword.node.value.node else {
|
||||
continue
|
||||
};
|
||||
let Some(argument) = &keyword.node.arg else {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt;
|
||||
|
||||
use rustpython_parser::ast::{Expr, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -101,8 +101,8 @@ impl fmt::Display for ContentType {
|
|||
|
||||
fn get_element_type(checker: &Checker, element: &StmtKind) -> Option<ContentType> {
|
||||
match element {
|
||||
StmtKind::Assign { targets, value, .. } => {
|
||||
if let ExprKind::Call { func, .. } = &value.node {
|
||||
StmtKind::Assign(ast::StmtAssign { targets, value, .. }) => {
|
||||
if let ExprKind::Call(ast::ExprCall { func, .. }) = &value.node {
|
||||
if helpers::is_model_field(&checker.ctx, func) {
|
||||
return Some(ContentType::FieldDeclaration);
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ fn get_element_type(checker: &Checker, element: &StmtKind) -> Option<ContentType
|
|||
let Some(expr) = targets.first() else {
|
||||
return None;
|
||||
};
|
||||
let ExprKind::Name { id, .. } = &expr.node else {
|
||||
let ExprKind::Name(ast::ExprName { id, .. }) = &expr.node else {
|
||||
return None;
|
||||
};
|
||||
if id == "objects" {
|
||||
|
@ -119,14 +119,14 @@ fn get_element_type(checker: &Checker, element: &StmtKind) -> Option<ContentType
|
|||
None
|
||||
}
|
||||
}
|
||||
StmtKind::ClassDef { name, .. } => {
|
||||
StmtKind::ClassDef(ast::StmtClassDef { name, .. }) => {
|
||||
if name == "Meta" {
|
||||
Some(ContentType::MetaClass)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
StmtKind::FunctionDef { name, .. } => match name.as_str() {
|
||||
StmtKind::FunctionDef(ast::StmtFunctionDef { name, .. }) => match name.as_str() {
|
||||
"__str__" => Some(ContentType::StrMethod),
|
||||
"save" => Some(ContentType::SaveMethod),
|
||||
"get_absolute_url" => Some(ContentType::GetAbsoluteUrlMethod),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprContext, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -184,14 +184,14 @@ impl Violation for DotFormatInException {
|
|||
/// 2. Replace the exception argument with the variable name.
|
||||
fn generate_fix(stylist: &Stylist, stmt: &Stmt, exc_arg: &Expr, indentation: &str) -> Fix {
|
||||
let assignment = unparse_stmt(
|
||||
&create_stmt(StmtKind::Assign {
|
||||
targets: vec![create_expr(ExprKind::Name {
|
||||
id: String::from("msg"),
|
||||
&create_stmt(StmtKind::Assign(ast::StmtAssign {
|
||||
targets: vec![create_expr(ExprKind::Name(ast::ExprName {
|
||||
id: "msg".into(),
|
||||
ctx: ExprContext::Store,
|
||||
})],
|
||||
}))],
|
||||
value: Box::new(exc_arg.clone()),
|
||||
type_comment: None,
|
||||
}),
|
||||
})),
|
||||
stylist,
|
||||
);
|
||||
#[allow(deprecated)]
|
||||
|
@ -214,14 +214,14 @@ fn generate_fix(stylist: &Stylist, stmt: &Stmt, exc_arg: &Expr, indentation: &st
|
|||
|
||||
/// EM101, EM102, EM103
|
||||
pub fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
|
||||
if let ExprKind::Call { args, .. } = &exc.node {
|
||||
if let ExprKind::Call(ast::ExprCall { args, .. }) = &exc.node {
|
||||
if let Some(first) = args.first() {
|
||||
match &first.node {
|
||||
// Check for string literals
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(string),
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
if checker.settings.rules.enabled(Rule::RawStringInException) {
|
||||
if string.len() > checker.settings.flake8_errmsg.max_string_length {
|
||||
let indentation = whitespace::indentation(checker.locator, stmt)
|
||||
|
@ -249,7 +249,7 @@ pub fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
|
|||
}
|
||||
}
|
||||
// Check for f-strings
|
||||
ExprKind::JoinedStr { .. } => {
|
||||
ExprKind::JoinedStr(_) => {
|
||||
if checker.settings.rules.enabled(Rule::FStringInException) {
|
||||
let indentation = whitespace::indentation(checker.locator, stmt).and_then(
|
||||
|indentation| {
|
||||
|
@ -275,10 +275,12 @@ pub fn string_in_exception(checker: &mut Checker, stmt: &Stmt, exc: &Expr) {
|
|||
}
|
||||
}
|
||||
// Check for .format() calls
|
||||
ExprKind::Call { func, .. } => {
|
||||
ExprKind::Call(ast::ExprCall { func, .. }) => {
|
||||
if checker.settings.rules.enabled(Rule::DotFormatInException) {
|
||||
if let ExprKind::Attribute { value, attr, .. } = &func.node {
|
||||
if attr == "format" && matches!(value.node, ExprKind::Constant { .. }) {
|
||||
if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) =
|
||||
&func.node
|
||||
{
|
||||
if attr == "format" && matches!(value.node, ExprKind::Constant(_)) {
|
||||
let indentation = whitespace::indentation(checker.locator, stmt)
|
||||
.and_then(|indentation| {
|
||||
if checker.ctx.find_binding("msg").is_none() {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Operator};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Operator};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -34,8 +34,8 @@ impl Violation for PrintfInGetTextFuncCall {
|
|||
|
||||
/// Returns true if the [`Expr`] is an internationalization function call.
|
||||
pub fn is_gettext_func_call(func: &Expr, functions_names: &[String]) -> bool {
|
||||
if let ExprKind::Name { id, .. } = &func.node {
|
||||
functions_names.contains(id)
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &func.node {
|
||||
functions_names.contains(id.as_ref())
|
||||
} else {
|
||||
false
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ pub fn is_gettext_func_call(func: &Expr, functions_names: &[String]) -> bool {
|
|||
/// INT001
|
||||
pub fn f_string_in_gettext_func_call(args: &[Expr]) -> Option<Diagnostic> {
|
||||
if let Some(first) = args.first() {
|
||||
if matches!(first.node, ExprKind::JoinedStr { .. }) {
|
||||
if matches!(first.node, ExprKind::JoinedStr(_)) {
|
||||
return Some(Diagnostic::new(FStringInGetTextFuncCall {}, first.range()));
|
||||
}
|
||||
}
|
||||
|
@ -54,8 +54,8 @@ pub fn f_string_in_gettext_func_call(args: &[Expr]) -> Option<Diagnostic> {
|
|||
/// INT002
|
||||
pub fn format_in_gettext_func_call(args: &[Expr]) -> Option<Diagnostic> {
|
||||
if let Some(first) = args.first() {
|
||||
if let ExprKind::Call { func, .. } = &first.node {
|
||||
if let ExprKind::Attribute { attr, .. } = &func.node {
|
||||
if let ExprKind::Call(ast::ExprCall { func, .. }) = &first.node {
|
||||
if let ExprKind::Attribute(ast::ExprAttribute { attr, .. }) = &func.node {
|
||||
if attr == "format" {
|
||||
return Some(Diagnostic::new(FormatInGetTextFuncCall {}, first.range()));
|
||||
}
|
||||
|
@ -68,16 +68,16 @@ pub fn format_in_gettext_func_call(args: &[Expr]) -> Option<Diagnostic> {
|
|||
/// INT003
|
||||
pub fn printf_in_gettext_func_call(args: &[Expr]) -> Option<Diagnostic> {
|
||||
if let Some(first) = args.first() {
|
||||
if let ExprKind::BinOp {
|
||||
if let ExprKind::BinOp(ast::ExprBinOp {
|
||||
op: Operator::Mod { .. },
|
||||
left,
|
||||
..
|
||||
} = &first.node
|
||||
}) = &first.node
|
||||
{
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(_),
|
||||
..
|
||||
} = left.node
|
||||
}) = left.node
|
||||
{
|
||||
return Some(Diagnostic::new(PrintfInGetTextFuncCall {}, first.range()));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use itertools::Itertools;
|
||||
use ruff_text_size::TextRange;
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Operator};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Operator};
|
||||
use rustpython_parser::lexer::LexResult;
|
||||
use rustpython_parser::Tok;
|
||||
|
||||
|
@ -149,22 +149,22 @@ pub fn implicit(tokens: &[LexResult], settings: &Settings, locator: &Locator) ->
|
|||
|
||||
/// ISC003
|
||||
pub fn explicit(expr: &Expr) -> Option<Diagnostic> {
|
||||
if let ExprKind::BinOp { left, op, right } = &expr.node {
|
||||
if let ExprKind::BinOp(ast::ExprBinOp { left, op, right }) = &expr.node {
|
||||
if matches!(op, Operator::Add) {
|
||||
if matches!(
|
||||
left.node,
|
||||
ExprKind::JoinedStr { .. }
|
||||
| ExprKind::Constant {
|
||||
ExprKind::JoinedStr(_)
|
||||
| ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(..) | Constant::Bytes(..),
|
||||
..
|
||||
}
|
||||
})
|
||||
) && matches!(
|
||||
right.node,
|
||||
ExprKind::JoinedStr { .. }
|
||||
| ExprKind::Constant {
|
||||
ExprKind::JoinedStr(_)
|
||||
| ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(..) | Constant::Bytes(..),
|
||||
..
|
||||
}
|
||||
})
|
||||
) {
|
||||
return Some(Diagnostic::new(ExplicitStringConcatenation, expr.range()));
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
use ruff_text_size::{TextRange, TextSize};
|
||||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword, Operator};
|
||||
use std::ops::Add;
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword, Operator};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Edit, Fix};
|
||||
use ruff_python_ast::helpers::{find_keyword, SimpleCallArgs};
|
||||
|
@ -43,7 +42,7 @@ const RESERVED_ATTRS: &[&str; 22] = &[
|
|||
fn check_msg(checker: &mut Checker, msg: &Expr) {
|
||||
match &msg.node {
|
||||
// Check for string concatenation and percent format.
|
||||
ExprKind::BinOp { op, .. } => match op {
|
||||
ExprKind::BinOp(ast::ExprBinOp { op, .. }) => match op {
|
||||
Operator::Add => {
|
||||
if checker.settings.rules.enabled(Rule::LoggingStringConcat) {
|
||||
checker
|
||||
|
@ -61,7 +60,7 @@ fn check_msg(checker: &mut Checker, msg: &Expr) {
|
|||
_ => {}
|
||||
},
|
||||
// Check for f-strings.
|
||||
ExprKind::JoinedStr { .. } => {
|
||||
ExprKind::JoinedStr(_) => {
|
||||
if checker.settings.rules.enabled(Rule::LoggingFString) {
|
||||
checker
|
||||
.diagnostics
|
||||
|
@ -69,10 +68,10 @@ fn check_msg(checker: &mut Checker, msg: &Expr) {
|
|||
}
|
||||
}
|
||||
// Check for .format() calls.
|
||||
ExprKind::Call { func, .. } => {
|
||||
ExprKind::Call(ast::ExprCall { func, .. }) => {
|
||||
if checker.settings.rules.enabled(Rule::LoggingStringFormat) {
|
||||
if let ExprKind::Attribute { value, attr, .. } = &func.node {
|
||||
if attr == "format" && matches!(value.node, ExprKind::Constant { .. }) {
|
||||
if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node {
|
||||
if attr == "format" && matches!(value.node, ExprKind::Constant(_)) {
|
||||
checker
|
||||
.diagnostics
|
||||
.push(Diagnostic::new(LoggingStringFormat, msg.range()));
|
||||
|
@ -87,13 +86,13 @@ fn check_msg(checker: &mut Checker, msg: &Expr) {
|
|||
/// Check contents of the `extra` argument to logging calls.
|
||||
fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
|
||||
match &extra.node.value.node {
|
||||
ExprKind::Dict { keys, .. } => {
|
||||
ExprKind::Dict(ast::ExprDict { keys, .. }) => {
|
||||
for key in keys {
|
||||
if let Some(key) = &key {
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(string),
|
||||
..
|
||||
} = &key.node
|
||||
}) = &key.node
|
||||
{
|
||||
if RESERVED_ATTRS.contains(&string.as_str()) {
|
||||
checker.diagnostics.push(Diagnostic::new(
|
||||
|
@ -105,7 +104,7 @@ fn check_log_record_attr_clash(checker: &mut Checker, extra: &Keyword) {
|
|||
}
|
||||
}
|
||||
}
|
||||
ExprKind::Call { func, keywords, .. } => {
|
||||
ExprKind::Call(ast::ExprCall { func, keywords, .. }) => {
|
||||
if checker
|
||||
.ctx
|
||||
.resolve_call_path(func)
|
||||
|
@ -151,10 +150,10 @@ pub fn logging_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords:
|
|||
return;
|
||||
}
|
||||
|
||||
if let ExprKind::Attribute { value, attr, .. } = &func.node {
|
||||
if let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. }) = &func.node {
|
||||
if let Some(logging_call_type) = LoggingCallType::from_attribute(attr.as_str()) {
|
||||
let call_args = SimpleCallArgs::new(args, keywords);
|
||||
let level_call_range = TextRange::new(value.end().add(TextSize::from(1)), func.end());
|
||||
let level_call_range = TextRange::new(value.end() + TextSize::from(1), func.end());
|
||||
|
||||
// G001 - G004
|
||||
let msg_pos = usize::from(matches!(logging_call_type, LoggingCallType::LogCall));
|
||||
|
@ -202,11 +201,13 @@ pub fn logging_call(checker: &mut Checker, func: &Expr, args: &[Expr], keywords:
|
|||
// return.
|
||||
if !(matches!(
|
||||
exc_info.node.value.node,
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Bool(true),
|
||||
..
|
||||
}
|
||||
) || if let ExprKind::Call { func, .. } = &exc_info.node.value.node {
|
||||
})
|
||||
) || if let ExprKind::Call(ast::ExprCall { func, .. }) =
|
||||
&exc_info.node.value.node
|
||||
{
|
||||
checker
|
||||
.ctx
|
||||
.resolve_call_path(func)
|
||||
|
|
|
@ -5,7 +5,7 @@ use itertools::Either::{Left, Right};
|
|||
use log::error;
|
||||
use rustc_hash::FxHashSet;
|
||||
use rustpython_parser::ast::{
|
||||
Boolop, Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind,
|
||||
self, Boolop, Constant, Expr, ExprContext, ExprKind, Keyword, Stmt, StmtKind,
|
||||
};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
||||
|
@ -301,15 +301,15 @@ pub fn no_unnecessary_pass(checker: &mut Checker, body: &[Stmt]) {
|
|||
// redundant. Consider removing all `pass` statements instead.
|
||||
let docstring_stmt = &body[0];
|
||||
let pass_stmt = &body[1];
|
||||
let StmtKind::Expr { value } = &docstring_stmt.node else {
|
||||
let StmtKind::Expr(ast::StmtExpr { value } )= &docstring_stmt.node else {
|
||||
return;
|
||||
};
|
||||
if matches!(
|
||||
value.node,
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(..),
|
||||
..
|
||||
}
|
||||
})
|
||||
) {
|
||||
if matches!(pass_stmt.node, StmtKind::Pass) {
|
||||
let mut diagnostic = Diagnostic::new(UnnecessaryPass, pass_stmt.range());
|
||||
|
@ -351,18 +351,18 @@ pub fn duplicate_class_field_definition<'a, 'b>(
|
|||
for stmt in body {
|
||||
// Extract the property name from the assignment statement.
|
||||
let target = match &stmt.node {
|
||||
StmtKind::Assign { targets, .. } => {
|
||||
StmtKind::Assign(ast::StmtAssign { targets, .. }) => {
|
||||
if targets.len() != 1 {
|
||||
continue;
|
||||
}
|
||||
if let ExprKind::Name { id, .. } = &targets[0].node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &targets[0].node {
|
||||
id
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
StmtKind::AnnAssign { target, .. } => {
|
||||
if let ExprKind::Name { id, .. } = &target.node {
|
||||
StmtKind::AnnAssign(ast::StmtAnnAssign { target, .. }) => {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node {
|
||||
id
|
||||
} else {
|
||||
continue;
|
||||
|
@ -407,7 +407,7 @@ pub fn non_unique_enums<'a, 'b>(checker: &mut Checker<'a>, parent: &'b Stmt, bod
|
|||
where
|
||||
'b: 'a,
|
||||
{
|
||||
let StmtKind::ClassDef { bases, .. } = &parent.node else {
|
||||
let StmtKind::ClassDef(ast::StmtClassDef { bases, .. }) = &parent.node else {
|
||||
return;
|
||||
};
|
||||
|
||||
|
@ -422,11 +422,11 @@ where
|
|||
|
||||
let mut seen_targets: FxHashSet<ComparableExpr> = FxHashSet::default();
|
||||
for stmt in body {
|
||||
let StmtKind::Assign { value, .. } = &stmt.node else {
|
||||
let StmtKind::Assign(ast::StmtAssign { value, .. }) = &stmt.node else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if let ExprKind::Call { func, .. } = &value.node {
|
||||
if let ExprKind::Call(ast::ExprCall { func, .. }) = &value.node {
|
||||
if checker
|
||||
.ctx
|
||||
.resolve_call_path(func)
|
||||
|
@ -454,7 +454,7 @@ pub fn unnecessary_spread(checker: &mut Checker, keys: &[Option<Expr>], values:
|
|||
if let (None, value) = item {
|
||||
// We only care about when the key is None which indicates a spread `**`
|
||||
// inside a dict.
|
||||
if let ExprKind::Dict { .. } = value.node {
|
||||
if let ExprKind::Dict(_) = value.node {
|
||||
let diagnostic = Diagnostic::new(UnnecessarySpread, value.range());
|
||||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
@ -464,10 +464,10 @@ pub fn unnecessary_spread(checker: &mut Checker, keys: &[Option<Expr>], values:
|
|||
|
||||
/// Return `true` if a key is a valid keyword argument name.
|
||||
fn is_valid_kwarg_name(key: &Expr) -> bool {
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} = &key.node
|
||||
}) = &key.node
|
||||
{
|
||||
is_identifier(value)
|
||||
} else {
|
||||
|
@ -480,7 +480,7 @@ pub fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs: &[Key
|
|||
for kw in kwargs {
|
||||
// keyword is a spread operator (indicated by None)
|
||||
if kw.node.arg.is_none() {
|
||||
if let ExprKind::Dict { keys, .. } = &kw.node.value.node {
|
||||
if let ExprKind::Dict(ast::ExprDict { keys, .. }) = &kw.node.value.node {
|
||||
// ensure foo(**{"bar-bar": 1}) doesn't error
|
||||
if keys.iter().all(|expr| expr.as_ref().map_or(false, is_valid_kwarg_name)) ||
|
||||
// handle case of foo(**{**bar})
|
||||
|
@ -496,18 +496,17 @@ pub fn unnecessary_dict_kwargs(checker: &mut Checker, expr: &Expr, kwargs: &[Key
|
|||
|
||||
/// PIE810
|
||||
pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
||||
let ExprKind::BoolOp { op: Boolop::Or, values } = &expr.node else {
|
||||
let ExprKind::BoolOp(ast::ExprBoolOp { op: Boolop::Or, values }) = &expr.node else {
|
||||
return;
|
||||
};
|
||||
|
||||
let mut duplicates = BTreeMap::new();
|
||||
for (index, call) in values.iter().enumerate() {
|
||||
let ExprKind::Call {
|
||||
let ExprKind::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
..
|
||||
} = &call.node else {
|
||||
}) = &call.node else {
|
||||
continue
|
||||
};
|
||||
|
||||
|
@ -515,15 +514,14 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
|||
continue;
|
||||
}
|
||||
|
||||
let ExprKind::Attribute { value, attr, .. } = &func.node else {
|
||||
let ExprKind::Attribute(ast::ExprAttribute { value, attr, .. } )= &func.node else {
|
||||
continue
|
||||
};
|
||||
|
||||
if attr != "startswith" && attr != "endswith" {
|
||||
continue;
|
||||
}
|
||||
|
||||
let ExprKind::Name { id: arg_name, .. } = &value.node else {
|
||||
let ExprKind::Name(ast::ExprName { id: arg_name, .. } )= &value.node else {
|
||||
continue
|
||||
};
|
||||
|
||||
|
@ -547,7 +545,7 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
|||
.iter()
|
||||
.map(|index| &values[*index])
|
||||
.map(|expr| {
|
||||
let ExprKind::Call { func: _, args, keywords: _} = &expr.node else {
|
||||
let ExprKind::Call(ast::ExprCall { func: _, args, keywords: _}) = &expr.node else {
|
||||
unreachable!("{}", format!("Indices should only contain `{attr_name}` calls"))
|
||||
};
|
||||
args.get(0)
|
||||
|
@ -555,20 +553,20 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
|||
})
|
||||
.collect();
|
||||
|
||||
let call = create_expr(ExprKind::Call {
|
||||
func: Box::new(create_expr(ExprKind::Attribute {
|
||||
value: Box::new(create_expr(ExprKind::Name {
|
||||
id: arg_name.to_string(),
|
||||
let call = create_expr(ExprKind::Call(ast::ExprCall {
|
||||
func: Box::new(create_expr(ExprKind::Attribute(ast::ExprAttribute {
|
||||
value: Box::new(create_expr(ExprKind::Name(ast::ExprName {
|
||||
id: arg_name.into(),
|
||||
ctx: ExprContext::Load,
|
||||
})),
|
||||
attr: attr_name.to_string(),
|
||||
}))),
|
||||
attr: attr_name.into(),
|
||||
ctx: ExprContext::Load,
|
||||
})),
|
||||
args: vec![create_expr(ExprKind::Tuple {
|
||||
}))),
|
||||
args: vec![create_expr(ExprKind::Tuple(ast::ExprTuple {
|
||||
elts: words
|
||||
.iter()
|
||||
.flat_map(|value| {
|
||||
if let ExprKind::Tuple { elts, .. } = &value.node {
|
||||
if let ExprKind::Tuple(ast::ExprTuple { elts, .. }) = &value.node {
|
||||
Left(elts.iter())
|
||||
} else {
|
||||
Right(iter::once(*value))
|
||||
|
@ -577,13 +575,13 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
|||
.map(Clone::clone)
|
||||
.collect(),
|
||||
ctx: ExprContext::Load,
|
||||
})],
|
||||
}))],
|
||||
keywords: vec![],
|
||||
});
|
||||
}));
|
||||
|
||||
// Generate the combined `BoolOp`.
|
||||
let mut call = Some(call);
|
||||
let bool_op = create_expr(ExprKind::BoolOp {
|
||||
let bool_op = create_expr(ExprKind::BoolOp(ast::ExprBoolOp {
|
||||
op: Boolop::Or,
|
||||
values: values
|
||||
.iter()
|
||||
|
@ -596,7 +594,7 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
|||
}
|
||||
})
|
||||
.collect(),
|
||||
});
|
||||
}));
|
||||
#[allow(deprecated)]
|
||||
diagnostic.set_fix(Fix::unspecified(Edit::range_replacement(
|
||||
unparse_expr(&bool_op, checker.stylist),
|
||||
|
@ -610,7 +608,7 @@ pub fn multiple_starts_ends_with(checker: &mut Checker, expr: &Expr) {
|
|||
|
||||
/// PIE807
|
||||
pub fn reimplemented_list_builtin(checker: &mut Checker, expr: &Expr) {
|
||||
let ExprKind::Lambda { args, body } = &expr.node else {
|
||||
let ExprKind::Lambda(ast::ExprLambda { args, body }) = &expr.node else {
|
||||
panic!("Expected ExprKind::Lambda");
|
||||
};
|
||||
if args.args.is_empty()
|
||||
|
@ -619,7 +617,7 @@ pub fn reimplemented_list_builtin(checker: &mut Checker, expr: &Expr) {
|
|||
&& args.vararg.is_none()
|
||||
&& args.kwarg.is_none()
|
||||
{
|
||||
if let ExprKind::List { elts, .. } = &body.node {
|
||||
if let ExprKind::List(ast::ExprList { elts, .. }) = &body.node {
|
||||
if elts.is_empty() {
|
||||
let mut diagnostic = Diagnostic::new(ReimplementedListBuiltin, expr.range());
|
||||
if checker.patch(diagnostic.kind.rule()) {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
use rustc_hash::FxHashSet;
|
||||
use rustpython_parser::ast::{Expr, ExprKind, Operator};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind, Operator};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -45,11 +45,11 @@ fn traverse_union<'a>(
|
|||
//
|
||||
// So we have to traverse both branches in order (left, then right), to report duplicates
|
||||
// in the order they appear in the source code.
|
||||
if let ExprKind::BinOp {
|
||||
if let ExprKind::BinOp(ast::ExprBinOp {
|
||||
op: Operator::BitOr,
|
||||
left,
|
||||
right,
|
||||
} = &expr.node
|
||||
}) = &expr.node
|
||||
{
|
||||
// Traverse left subtree, then the right subtree, propagating the previous node.
|
||||
traverse_union(seen_nodes, checker, left, Some(expr));
|
||||
|
@ -72,7 +72,7 @@ fn traverse_union<'a>(
|
|||
let parent = parent.expect("Parent node must exist");
|
||||
|
||||
// SAFETY: Parent node must have been a `BinOp` in order for us to have traversed it.
|
||||
let ExprKind::BinOp { left, right, .. } = &parent.node else {
|
||||
let ExprKind::BinOp(ast::ExprBinOp { left, right, .. }) = &parent.node else {
|
||||
panic!("Parent node must be a BinOp");
|
||||
};
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, ExprKind, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Constant, ExprKind, Stmt, StmtKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -20,8 +20,8 @@ pub fn non_empty_stub_body(checker: &mut Checker, body: &[Stmt]) {
|
|||
if body.len() != 1 {
|
||||
return;
|
||||
}
|
||||
if let StmtKind::Expr { value } = &body[0].node {
|
||||
if let ExprKind::Constant { value, .. } = &value.node {
|
||||
if let StmtKind::Expr(ast::StmtExpr { value }) = &body[0].node {
|
||||
if let ExprKind::Constant(ast::ExprConstant { value, .. }) = &value.node {
|
||||
if matches!(value, Constant::Ellipsis | Constant::Str(_)) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use std::fmt;
|
||||
|
||||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -63,13 +63,13 @@ pub fn prefix_type_params(checker: &mut Checker, value: &Expr, targets: &[Expr])
|
|||
if targets.len() != 1 {
|
||||
return;
|
||||
}
|
||||
if let ExprKind::Name { id, .. } = &targets[0].node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &targets[0].node {
|
||||
if id.starts_with('_') {
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
if let ExprKind::Call { func, .. } = &value.node {
|
||||
if let ExprKind::Call(ast::ExprCall { func, .. }) = &value.node {
|
||||
let Some(kind) = checker.ctx.resolve_call_path(func).and_then(|call_path| {
|
||||
if checker.ctx.match_typing_call_path(&call_path, "ParamSpec") {
|
||||
Some(VarKind::ParamSpec)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Arguments, Constant, Expr, ExprKind, Operator, Unaryop};
|
||||
use rustpython_parser::ast::{self, Arguments, Constant, Expr, ExprKind, Operator, Unaryop};
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -80,14 +80,16 @@ fn is_valid_default_value_with_annotation(
|
|||
allow_container: bool,
|
||||
) -> bool {
|
||||
match &default.node {
|
||||
ExprKind::List { elts, .. } | ExprKind::Tuple { elts, .. } | ExprKind::Set { elts, .. } => {
|
||||
ExprKind::List(ast::ExprList { elts, .. })
|
||||
| ExprKind::Tuple(ast::ExprTuple { elts, .. })
|
||||
| ExprKind::Set(ast::ExprSet { elts }) => {
|
||||
return allow_container
|
||||
&& elts.len() <= 10
|
||||
&& elts
|
||||
.iter()
|
||||
.all(|e| is_valid_default_value_with_annotation(e, checker, false));
|
||||
}
|
||||
ExprKind::Dict { keys, values, .. } => {
|
||||
ExprKind::Dict(ast::ExprDict { keys, values }) => {
|
||||
return allow_container
|
||||
&& keys.len() <= 10
|
||||
&& keys.iter().zip(values).all(|(k, v)| {
|
||||
|
@ -96,60 +98,60 @@ fn is_valid_default_value_with_annotation(
|
|||
}) && is_valid_default_value_with_annotation(v, checker, false)
|
||||
});
|
||||
}
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Ellipsis | Constant::None,
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
return true;
|
||||
}
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(..),
|
||||
..
|
||||
} => return checker.locator.slice(default.range()).len() <= 50,
|
||||
ExprKind::Constant {
|
||||
}) => return checker.locator.slice(default.range()).len() <= 50,
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Bytes(..),
|
||||
..
|
||||
} => return checker.locator.slice(default.range()).len() <= 50,
|
||||
}) => return checker.locator.slice(default.range()).len() <= 50,
|
||||
// Ex) `123`, `True`, `False`, `3.14`
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(..) | Constant::Bool(..) | Constant::Float(..),
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
return checker.locator.slice(default.range()).len() <= 10;
|
||||
}
|
||||
// Ex) `2j`
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Complex { real, .. },
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
if *real == 0.0 {
|
||||
return checker.locator.slice(default.range()).len() <= 10;
|
||||
}
|
||||
}
|
||||
ExprKind::UnaryOp {
|
||||
ExprKind::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::USub,
|
||||
operand,
|
||||
} => {
|
||||
}) => {
|
||||
// Ex) `-1`, `-3.14`
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(..) | Constant::Float(..),
|
||||
..
|
||||
} = &operand.node
|
||||
}) = &operand.node
|
||||
{
|
||||
return checker.locator.slice(operand.range()).len() <= 10;
|
||||
}
|
||||
// Ex) `-2j`
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Complex { real, .. },
|
||||
..
|
||||
} = &operand.node
|
||||
}) = &operand.node
|
||||
{
|
||||
if *real == 0.0 {
|
||||
return checker.locator.slice(operand.range()).len() <= 10;
|
||||
}
|
||||
}
|
||||
// Ex) `-math.inf`, `-math.pi`, etc.
|
||||
if let ExprKind::Attribute { .. } = &operand.node {
|
||||
if let ExprKind::Attribute(_) = &operand.node {
|
||||
if checker
|
||||
.ctx
|
||||
.resolve_call_path(operand)
|
||||
|
@ -164,34 +166,34 @@ fn is_valid_default_value_with_annotation(
|
|||
}
|
||||
}
|
||||
}
|
||||
ExprKind::BinOp {
|
||||
ExprKind::BinOp(ast::ExprBinOp {
|
||||
left,
|
||||
op: Operator::Add | Operator::Sub,
|
||||
right,
|
||||
} => {
|
||||
}) => {
|
||||
// Ex) `1 + 2j`, `1 - 2j`, `-1 - 2j`, `-1 + 2j`
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Complex { .. },
|
||||
..
|
||||
} = right.node
|
||||
}) = right.node
|
||||
{
|
||||
// Ex) `1 + 2j`, `1 - 2j`
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(..) | Constant::Float(..),
|
||||
..
|
||||
} = &left.node
|
||||
}) = &left.node
|
||||
{
|
||||
return checker.locator.slice(left.range()).len() <= 10;
|
||||
} else if let ExprKind::UnaryOp {
|
||||
} else if let ExprKind::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::USub,
|
||||
operand,
|
||||
} = &left.node
|
||||
}) = &left.node
|
||||
{
|
||||
// Ex) `-1 + 2j`, `-1 - 2j`
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Int(..) | Constant::Float(..),
|
||||
..
|
||||
} = &operand.node
|
||||
}) = &operand.node
|
||||
{
|
||||
return checker.locator.slice(operand.range()).len() <= 10;
|
||||
}
|
||||
|
@ -199,7 +201,7 @@ fn is_valid_default_value_with_annotation(
|
|||
}
|
||||
}
|
||||
// Ex) `math.inf`, `sys.stdin`, etc.
|
||||
ExprKind::Attribute { .. } => {
|
||||
ExprKind::Attribute(_) => {
|
||||
if checker
|
||||
.ctx
|
||||
.resolve_call_path(default)
|
||||
|
@ -221,18 +223,18 @@ fn is_valid_default_value_with_annotation(
|
|||
/// Returns `true` if an [`Expr`] appears to be a valid PEP 604 union. (e.g. `int | None`)
|
||||
fn is_valid_pep_604_union(annotation: &Expr) -> bool {
|
||||
match &annotation.node {
|
||||
ExprKind::BinOp {
|
||||
ExprKind::BinOp(ast::ExprBinOp {
|
||||
left,
|
||||
op: Operator::BitOr,
|
||||
right,
|
||||
} => is_valid_pep_604_union(left) && is_valid_pep_604_union(right),
|
||||
ExprKind::Name { .. }
|
||||
| ExprKind::Subscript { .. }
|
||||
| ExprKind::Attribute { .. }
|
||||
| ExprKind::Constant {
|
||||
}) => is_valid_pep_604_union(left) && is_valid_pep_604_union(right),
|
||||
ExprKind::Name(_)
|
||||
| ExprKind::Subscript(_)
|
||||
| ExprKind::Attribute(_)
|
||||
| ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::None,
|
||||
..
|
||||
} => true,
|
||||
}) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
@ -241,21 +243,21 @@ fn is_valid_pep_604_union(annotation: &Expr) -> bool {
|
|||
fn is_valid_default_value_without_annotation(default: &Expr) -> bool {
|
||||
matches!(
|
||||
&default.node,
|
||||
ExprKind::Call { .. }
|
||||
| ExprKind::Name { .. }
|
||||
| ExprKind::Attribute { .. }
|
||||
| ExprKind::Subscript { .. }
|
||||
| ExprKind::Constant {
|
||||
ExprKind::Call(_)
|
||||
| ExprKind::Name(_)
|
||||
| ExprKind::Attribute(_)
|
||||
| ExprKind::Subscript(_)
|
||||
| ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Ellipsis | Constant::None,
|
||||
..
|
||||
}
|
||||
})
|
||||
) || is_valid_pep_604_union(default)
|
||||
}
|
||||
|
||||
/// Returns `true` if an [`Expr`] appears to be `TypeVar`, `TypeVarTuple`, `NewType`, or `ParamSpec`
|
||||
/// call.
|
||||
fn is_type_var_like_call(context: &Context, expr: &Expr) -> bool {
|
||||
let ExprKind::Call { func, .. } = &expr.node else {
|
||||
let ExprKind::Call(ast::ExprCall { func, .. } )= &expr.node else {
|
||||
return false;
|
||||
};
|
||||
context.resolve_call_path(func).map_or(false, |call_path| {
|
||||
|
@ -272,7 +274,7 @@ fn is_type_var_like_call(context: &Context, expr: &Expr) -> bool {
|
|||
/// Returns `true` if this is a "special" assignment which must have a value (e.g., an assignment to
|
||||
/// `__all__`).
|
||||
fn is_special_assignment(context: &Context, target: &Expr) -> bool {
|
||||
if let ExprKind::Name { id, .. } = &target.node {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = &target.node {
|
||||
match id.as_str() {
|
||||
"__all__" => context.scope().kind.is_module(),
|
||||
"__match_args__" | "__slots__" => context.scope().kind.is_class(),
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -60,7 +60,7 @@ fn is_t_suffixed_type_alias(name: &str) -> bool {
|
|||
|
||||
/// PYI042
|
||||
pub fn snake_case_type_alias(checker: &mut Checker, target: &Expr) {
|
||||
if let ExprKind::Name { id, .. } = target.node() {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = target.node() {
|
||||
if !is_snake_case_type_alias(id) {
|
||||
return;
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ pub fn snake_case_type_alias(checker: &mut Checker, target: &Expr) {
|
|||
|
||||
/// PYI043
|
||||
pub fn t_suffixed_type_alias(checker: &mut Checker, target: &Expr) {
|
||||
if let ExprKind::Name { id, .. } = target.node() {
|
||||
if let ExprKind::Name(ast::ExprName { id, .. }) = target.node() {
|
||||
if !is_t_suffixed_type_alias(id) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Cmpop, Constant, Expr, ExprKind};
|
||||
use rustpython_parser::ast::{self, Cmpop, Constant, Expr, ExprKind};
|
||||
|
||||
use ruff_diagnostics::{Diagnostic, Violation};
|
||||
use ruff_macros::{derive_message_formats, violation};
|
||||
|
@ -126,10 +126,10 @@ pub fn unrecognized_platform(
|
|||
}
|
||||
|
||||
match &right.node {
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(value),
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
// Other values are possible but we don't need them right now.
|
||||
// This protects against typos.
|
||||
if !["linux", "win32", "cygwin", "darwin"].contains(&value.as_str())
|
||||
|
|
|
@ -6,7 +6,8 @@ use libcst_native::{
|
|||
SmallStatement, Statement, Suite, TrailingWhitespace, UnaryOp, UnaryOperation,
|
||||
};
|
||||
use rustpython_parser::ast::{
|
||||
Boolop, Excepthandler, ExcepthandlerKind, Expr, ExprKind, Keyword, Stmt, StmtKind, Unaryop,
|
||||
self, Boolop, Excepthandler, ExcepthandlerKind, Expr, ExprKind, Keyword, Stmt, StmtKind,
|
||||
Unaryop,
|
||||
};
|
||||
|
||||
use ruff_diagnostics::{AutofixKind, Diagnostic, Edit, Fix, Violation};
|
||||
|
@ -135,7 +136,7 @@ where
|
|||
{
|
||||
fn visit_stmt(&mut self, stmt: &'a Stmt) {
|
||||
match &stmt.node {
|
||||
StmtKind::Assert { .. } => {
|
||||
StmtKind::Assert(_) => {
|
||||
self.current_assert = Some(stmt);
|
||||
visitor::walk_stmt(self, stmt);
|
||||
self.current_assert = None;
|
||||
|
@ -146,9 +147,9 @@ where
|
|||
|
||||
fn visit_expr(&mut self, expr: &'a Expr) {
|
||||
match &expr.node {
|
||||
ExprKind::Name { id, .. } => {
|
||||
ExprKind::Name(ast::ExprName { id, .. }) => {
|
||||
if let Some(current_assert) = self.current_assert {
|
||||
if id.as_str() == self.exception_name {
|
||||
if id == self.exception_name {
|
||||
self.errors.push(Diagnostic::new(
|
||||
PytestAssertInExcept {
|
||||
name: id.to_string(),
|
||||
|
@ -181,11 +182,11 @@ pub fn unittest_assertion(
|
|||
keywords: &[Keyword],
|
||||
) -> Option<Diagnostic> {
|
||||
match &func.node {
|
||||
ExprKind::Attribute { attr, .. } => {
|
||||
ExprKind::Attribute(ast::ExprAttribute { attr, .. }) => {
|
||||
if let Ok(unittest_assert) = UnittestAssert::try_from(attr.as_str()) {
|
||||
// We're converting an expression to a statement, so avoid applying the fix if
|
||||
// the assertion is part of a larger expression.
|
||||
let fixable = matches!(checker.ctx.stmt().node, StmtKind::Expr { .. })
|
||||
let fixable = matches!(checker.ctx.stmt().node, StmtKind::Expr(_))
|
||||
&& checker.ctx.expr_parent().is_none()
|
||||
&& !checker.ctx.scope().kind.is_lambda()
|
||||
&& !has_comments_in(expr.range(), checker.locator);
|
||||
|
@ -227,7 +228,11 @@ pub fn assert_in_exception_handler(handlers: &[Excepthandler]) -> Vec<Diagnostic
|
|||
handlers
|
||||
.iter()
|
||||
.flat_map(|handler| match &handler.node {
|
||||
ExcepthandlerKind::ExceptHandler { name, body, .. } => {
|
||||
ExcepthandlerKind::ExceptHandler(ast::ExcepthandlerExceptHandler {
|
||||
name,
|
||||
body,
|
||||
..
|
||||
}) => {
|
||||
if let Some(name) = name {
|
||||
check_assert_in_except(name, body)
|
||||
} else {
|
||||
|
@ -255,28 +260,28 @@ enum CompositionKind {
|
|||
/// `not a and not b` by De Morgan's laws.
|
||||
fn is_composite_condition(test: &Expr) -> CompositionKind {
|
||||
match &test.node {
|
||||
ExprKind::BoolOp {
|
||||
ExprKind::BoolOp(ast::ExprBoolOp {
|
||||
op: Boolop::And, ..
|
||||
} => {
|
||||
}) => {
|
||||
return CompositionKind::Simple;
|
||||
}
|
||||
ExprKind::UnaryOp {
|
||||
ExprKind::UnaryOp(ast::ExprUnaryOp {
|
||||
op: Unaryop::Not,
|
||||
operand,
|
||||
} => {
|
||||
if let ExprKind::BoolOp {
|
||||
}) => {
|
||||
if let ExprKind::BoolOp(ast::ExprBoolOp {
|
||||
op: Boolop::Or,
|
||||
values,
|
||||
} = &operand.node
|
||||
}) = &operand.node
|
||||
{
|
||||
// Only split cases without mixed `and` and `or`.
|
||||
return if values.iter().all(|expr| {
|
||||
!matches!(
|
||||
expr.node,
|
||||
ExprKind::BoolOp {
|
||||
ExprKind::BoolOp(ast::ExprBoolOp {
|
||||
op: Boolop::And,
|
||||
..
|
||||
}
|
||||
})
|
||||
)
|
||||
}) {
|
||||
CompositionKind::Simple
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
use anyhow::Result;
|
||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||
use rustpython_parser::ast::{Arguments, Expr, ExprKind, Keyword, Stmt, StmtKind};
|
||||
use rustpython_parser::ast::{self, Arguments, Expr, ExprKind, Keyword, Stmt, StmtKind};
|
||||
use std::fmt;
|
||||
|
||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Violation};
|
||||
|
@ -208,28 +208,28 @@ where
|
|||
{
|
||||
fn visit_stmt(&mut self, stmt: &'b Stmt) {
|
||||
match &stmt.node {
|
||||
StmtKind::Return { value, .. } => {
|
||||
StmtKind::Return(ast::StmtReturn { value }) => {
|
||||
if value.is_some() {
|
||||
self.has_return_with_value = true;
|
||||
}
|
||||
}
|
||||
StmtKind::FunctionDef { .. } | StmtKind::AsyncFunctionDef { .. } => {}
|
||||
StmtKind::FunctionDef(_) | StmtKind::AsyncFunctionDef(_) => {}
|
||||
_ => visitor::walk_stmt(self, stmt),
|
||||
}
|
||||
}
|
||||
|
||||
fn visit_expr(&mut self, expr: &'b Expr) {
|
||||
match &expr.node {
|
||||
ExprKind::YieldFrom { .. } => {
|
||||
ExprKind::YieldFrom(_) => {
|
||||
self.has_yield_from = true;
|
||||
}
|
||||
ExprKind::Yield { value, .. } => {
|
||||
ExprKind::Yield(ast::ExprYield { value }) => {
|
||||
self.yield_statements.push(expr);
|
||||
if value.is_some() {
|
||||
self.has_return_with_value = true;
|
||||
}
|
||||
}
|
||||
ExprKind::Call { func, .. } => {
|
||||
ExprKind::Call(ast::ExprCall { func, .. }) => {
|
||||
if collect_call_path(func).map_or(false, |call_path| {
|
||||
call_path.as_slice() == ["request", "addfinalizer"]
|
||||
}) {
|
||||
|
@ -278,12 +278,11 @@ pub fn fix_extraneous_scope_function(
|
|||
/// PT001, PT002, PT003
|
||||
fn check_fixture_decorator(checker: &mut Checker, func_name: &str, decorator: &Expr) {
|
||||
match &decorator.node {
|
||||
ExprKind::Call {
|
||||
ExprKind::Call(ast::ExprCall {
|
||||
func,
|
||||
args,
|
||||
keywords,
|
||||
..
|
||||
} => {
|
||||
}) => {
|
||||
if checker
|
||||
.settings
|
||||
.rules
|
||||
|
@ -415,8 +414,8 @@ fn check_fixture_returns(checker: &mut Checker, stmt: &Stmt, name: &str, body: &
|
|||
.enabled(Rule::PytestUselessYieldFixture)
|
||||
{
|
||||
if let Some(stmt) = body.last() {
|
||||
if let StmtKind::Expr { value, .. } = &stmt.node {
|
||||
if let ExprKind::Yield { .. } = value.node {
|
||||
if let StmtKind::Expr(ast::StmtExpr { value }) = &stmt.node {
|
||||
if let ExprKind::Yield(_) = value.node {
|
||||
if visitor.yield_statements.len() == 1 {
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
PytestUselessYieldFixture {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rustpython_parser::ast::{Constant, Expr, ExprKind, Keyword};
|
||||
use rustpython_parser::ast::{self, Constant, Expr, ExprKind, Keyword};
|
||||
|
||||
use ruff_python_ast::call_path::{collect_call_path, CallPath};
|
||||
use ruff_python_ast::helpers::map_callable;
|
||||
|
@ -48,10 +48,10 @@ pub(super) fn is_pytest_parametrize(context: &Context, decorator: &Expr) -> bool
|
|||
}
|
||||
|
||||
pub(super) fn keyword_is_literal(kw: &Keyword, literal: &str) -> bool {
|
||||
if let ExprKind::Constant {
|
||||
if let ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(string),
|
||||
..
|
||||
} = &kw.node.value.node
|
||||
}) = &kw.node.value.node
|
||||
{
|
||||
string == literal
|
||||
} else {
|
||||
|
@ -61,15 +61,17 @@ pub(super) fn keyword_is_literal(kw: &Keyword, literal: &str) -> bool {
|
|||
|
||||
pub(super) fn is_empty_or_null_string(expr: &Expr) -> bool {
|
||||
match &expr.node {
|
||||
ExprKind::Constant {
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::Str(string),
|
||||
..
|
||||
} => string.is_empty(),
|
||||
ExprKind::Constant {
|
||||
}) => string.is_empty(),
|
||||
ExprKind::Constant(ast::ExprConstant {
|
||||
value: Constant::None,
|
||||
..
|
||||
} => true,
|
||||
ExprKind::JoinedStr { values } => values.iter().all(is_empty_or_null_string),
|
||||
}) => true,
|
||||
ExprKind::JoinedStr(ast::ExprJoinedStr { values }) => {
|
||||
values.iter().all(is_empty_or_null_string)
|
||||
}
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ pub fn import(import_from: &Stmt, name: &str, asname: Option<&str>) -> Option<Di
|
|||
pub fn import_from(
|
||||
import_from: &Stmt,
|
||||
module: Option<&str>,
|
||||
level: Option<usize>,
|
||||
level: Option<u32>,
|
||||
) -> Option<Diagnostic> {
|
||||
// If level is not zero or module is none, return
|
||||
if let Some(level) = level {
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue