mirror of https://github.com/astral-sh/ruff
Replace num_bigint with malachite
[malachite](https://www.malachite.rs/) is an arbitrary precision crate that unlike num_bigint implement as small integer optimization. This avoids allocating a `Vec` for every single number parse and instead only allocates for rare unusually large numbers. This is also a correctness improvement since we'd previously just ignore the higher parts of unreasonably large numbers. The disadvantage is that malachite is slow to compile.
This commit is contained in:
parent
94b68f201b
commit
6bd83d36ee
|
|
@ -172,6 +172,12 @@ version = "1.1.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "base64"
|
||||||
|
version = "0.13.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "base64"
|
name = "base64"
|
||||||
version = "0.21.3"
|
version = "0.21.3"
|
||||||
|
|
@ -214,6 +220,15 @@ version = "2.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "block-buffer"
|
||||||
|
version = "0.10.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3078c7629b62d3f0439517fa394996acacc5cbc91c5a20d8c658e77abd503a71"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bstr"
|
name = "bstr"
|
||||||
version = "1.6.2"
|
version = "1.6.2"
|
||||||
|
|
@ -495,6 +510,15 @@ version = "3.0.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
|
checksum = "7704b5fdd17b18ae31c4c1da5a2e0305a2bf17b5249300a9ee9ed7b72114c636"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cpufeatures"
|
||||||
|
version = "0.2.9"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a17b76ff3a4162b0b27f354a0c87015ddad39d35f9c0c36607a3bdd175dde1f1"
|
||||||
|
dependencies = [
|
||||||
|
"libc",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "crc32fast"
|
name = "crc32fast"
|
||||||
version = "1.3.2"
|
version = "1.3.2"
|
||||||
|
|
@ -587,6 +611,16 @@ version = "0.2.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
checksum = "7a81dae078cea95a014a339291cec439d2f232ebe854a9d672b796c6afafa9b7"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "crypto-common"
|
||||||
|
version = "0.1.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
"typenum",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "darling"
|
name = "darling"
|
||||||
version = "0.20.3"
|
version = "0.20.3"
|
||||||
|
|
@ -634,6 +668,16 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
checksum = "6184e33543162437515c2e2b48714794e37845ec9851711914eec9d308f6ebe8"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "digest"
|
||||||
|
version = "0.10.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
|
||||||
|
dependencies = [
|
||||||
|
"block-buffer",
|
||||||
|
"crypto-common",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dirs"
|
name = "dirs"
|
||||||
version = "4.0.0"
|
version = "4.0.0"
|
||||||
|
|
@ -720,6 +764,18 @@ version = "1.9.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "embed-doc-image"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "af36f591236d9d822425cb6896595658fa558fcebf5ee8accac1d4b92c47166e"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.13.1",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 1.0.109",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ena"
|
name = "ena"
|
||||||
version = "0.14.2"
|
version = "0.14.2"
|
||||||
|
|
@ -872,6 +928,16 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "generic-array"
|
||||||
|
version = "0.14.7"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a"
|
||||||
|
dependencies = [
|
||||||
|
"typenum",
|
||||||
|
"version_check",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "getrandom"
|
name = "getrandom"
|
||||||
version = "0.2.10"
|
version = "0.2.10"
|
||||||
|
|
@ -1167,6 +1233,15 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "keccak"
|
||||||
|
version = "0.1.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8f6d5ed8676d904364de097082f4e7d240b571b67989ced0240f08b7f966f940"
|
||||||
|
dependencies = [
|
||||||
|
"cpufeatures",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kqueue"
|
name = "kqueue"
|
||||||
version = "1.0.8"
|
version = "1.0.8"
|
||||||
|
|
@ -1320,6 +1395,41 @@ version = "0.4.20"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "malachite"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a9fa232412d927f518cd873073911726943f432bac1bbc1288316d240635dc51"
|
||||||
|
dependencies = [
|
||||||
|
"malachite-base",
|
||||||
|
"malachite-nz",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "malachite-base"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "606a61b226dc58b8b283399b74754460433c193b193f26eaaad92f7966abd72b"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom",
|
||||||
|
"itertools 0.11.0",
|
||||||
|
"rand",
|
||||||
|
"rand_chacha",
|
||||||
|
"ryu",
|
||||||
|
"sha3",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "malachite-nz"
|
||||||
|
version = "0.4.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "863d06218c83cc2269c425186cc15094d6284b1333a1184d0890aecfddb8916b"
|
||||||
|
dependencies = [
|
||||||
|
"embed-doc-image",
|
||||||
|
"itertools 0.11.0",
|
||||||
|
"malachite-base",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "matchers"
|
name = "matchers"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
|
@ -1454,27 +1564,6 @@ dependencies = [
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-bigint"
|
|
||||||
version = "0.4.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "608e7659b5c3d7cba262d894801b9ec9d00de989e8a82bd4bef91d08da45cdc0"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"num-integer",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "num-integer"
|
|
||||||
version = "0.1.45"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9"
|
|
||||||
dependencies = [
|
|
||||||
"autocfg",
|
|
||||||
"num-traits",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "num-traits"
|
name = "num-traits"
|
||||||
version = "0.2.16"
|
version = "0.2.16"
|
||||||
|
|
@ -2047,9 +2136,9 @@ dependencies = [
|
||||||
"itertools 0.11.0",
|
"itertools 0.11.0",
|
||||||
"libcst",
|
"libcst",
|
||||||
"log",
|
"log",
|
||||||
|
"malachite",
|
||||||
"memchr",
|
"memchr",
|
||||||
"natord",
|
"natord",
|
||||||
"num-bigint",
|
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"path-absolutize",
|
"path-absolutize",
|
||||||
|
|
@ -2298,9 +2387,8 @@ dependencies = [
|
||||||
"insta",
|
"insta",
|
||||||
"is-macro",
|
"is-macro",
|
||||||
"itertools 0.11.0",
|
"itertools 0.11.0",
|
||||||
|
"malachite",
|
||||||
"memchr",
|
"memchr",
|
||||||
"num-bigint",
|
|
||||||
"num-traits",
|
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"ruff_python_parser",
|
"ruff_python_parser",
|
||||||
"ruff_python_trivia",
|
"ruff_python_trivia",
|
||||||
|
|
@ -2389,8 +2477,7 @@ dependencies = [
|
||||||
"itertools 0.11.0",
|
"itertools 0.11.0",
|
||||||
"lalrpop",
|
"lalrpop",
|
||||||
"lalrpop-util",
|
"lalrpop-util",
|
||||||
"num-bigint",
|
"malachite",
|
||||||
"num-traits",
|
|
||||||
"ruff_python_ast",
|
"ruff_python_ast",
|
||||||
"ruff_text_size",
|
"ruff_text_size",
|
||||||
"rustc-hash",
|
"rustc-hash",
|
||||||
|
|
@ -2416,7 +2503,6 @@ version = "0.0.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bitflags 2.4.0",
|
"bitflags 2.4.0",
|
||||||
"is-macro",
|
"is-macro",
|
||||||
"num-traits",
|
|
||||||
"ruff_index",
|
"ruff_index",
|
||||||
"ruff_python_ast",
|
"ruff_python_ast",
|
||||||
"ruff_python_parser",
|
"ruff_python_parser",
|
||||||
|
|
@ -2764,6 +2850,16 @@ dependencies = [
|
||||||
"syn 2.0.37",
|
"syn 2.0.37",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "sha3"
|
||||||
|
version = "0.10.8"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "75872d278a8f37ef87fa0ddbda7802605cb18344497949862c0d4dcb291eba60"
|
||||||
|
dependencies = [
|
||||||
|
"digest",
|
||||||
|
"keccak",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sharded-slab"
|
name = "sharded-slab"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
|
|
@ -3176,6 +3272,12 @@ version = "2.0.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
|
checksum = "6af6ae20167a9ece4bcb41af5b80f8a1f1df981f6391189ce00fd257af04126a"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "typenum"
|
||||||
|
version = "1.17.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unic-char-property"
|
name = "unic-char-property"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
|
|
@ -3271,7 +3373,7 @@ version = "2.7.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9"
|
checksum = "0b11c96ac7ee530603dcdf68ed1557050f374ce55a5a07193ebf8cbc9f8927e9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64",
|
"base64 0.21.3",
|
||||||
"flate2",
|
"flate2",
|
||||||
"log",
|
"log",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ insta = { version = "1.31.0", feature = ["filters", "glob"] }
|
||||||
is-macro = { version = "0.3.0" }
|
is-macro = { version = "0.3.0" }
|
||||||
itertools = { version = "0.11.0" }
|
itertools = { version = "0.11.0" }
|
||||||
log = { version = "0.4.17" }
|
log = { version = "0.4.17" }
|
||||||
|
malachite = { version = "0.4.0", default-features = false, features = ["naturals_and_integers"] }
|
||||||
memchr = "2.6.3"
|
memchr = "2.6.3"
|
||||||
num-bigint = { version = "0.4.3" }
|
|
||||||
num-traits = { version = "0.2.15" }
|
num-traits = { version = "0.2.15" }
|
||||||
once_cell = { version = "1.17.1" }
|
once_cell = { version = "1.17.1" }
|
||||||
path-absolutize = { version = "3.1.1" }
|
path-absolutize = { version = "3.1.1" }
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,9 @@ is-macro = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
libcst = { workspace = true }
|
libcst = { workspace = true }
|
||||||
log = { workspace = true }
|
log = { workspace = true }
|
||||||
|
malachite = { workspace = true }
|
||||||
memchr = { workspace = true }
|
memchr = { workspace = true }
|
||||||
natord = { version = "1.0.9" }
|
natord = { version = "1.0.9" }
|
||||||
num-bigint = { workspace = true }
|
|
||||||
num-traits = { workspace = true }
|
num-traits = { workspace = true }
|
||||||
once_cell = { workspace = true }
|
once_cell = { workspace = true }
|
||||||
path-absolutize = { workspace = true, features = [
|
path-absolutize = { workspace = true, features = [
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
use num_bigint::BigInt;
|
|
||||||
use ruff_python_ast::{self as ast, CmpOp, Constant, Expr};
|
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
use ruff_python_ast::{self as ast, CmpOp, Constant, Expr};
|
||||||
use ruff_text_size::Ranged;
|
use ruff_text_size::Ranged;
|
||||||
|
|
||||||
use crate::checkers::ast::Checker;
|
use crate::checkers::ast::Checker;
|
||||||
|
|
@ -237,7 +235,7 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[CmpOp], compara
|
||||||
..
|
..
|
||||||
}) = slice.as_ref()
|
}) = slice.as_ref()
|
||||||
{
|
{
|
||||||
if *i == BigInt::from(0) {
|
if *i == 0 {
|
||||||
if let (
|
if let (
|
||||||
[CmpOp::Eq | CmpOp::NotEq],
|
[CmpOp::Eq | CmpOp::NotEq],
|
||||||
[Expr::Constant(ast::ExprConstant {
|
[Expr::Constant(ast::ExprConstant {
|
||||||
|
|
@ -246,13 +244,13 @@ pub(crate) fn compare(checker: &mut Checker, left: &Expr, ops: &[CmpOp], compara
|
||||||
})],
|
})],
|
||||||
) = (ops, comparators)
|
) = (ops, comparators)
|
||||||
{
|
{
|
||||||
if *n == BigInt::from(3) && checker.enabled(Rule::SysVersionInfo0Eq3) {
|
if *n == 3 && checker.enabled(Rule::SysVersionInfo0Eq3) {
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(SysVersionInfo0Eq3, left.range()));
|
.push(Diagnostic::new(SysVersionInfo0Eq3, left.range()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if *i == BigInt::from(1) {
|
} else if *i == 1 {
|
||||||
if let (
|
if let (
|
||||||
[CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE],
|
[CmpOp::Lt | CmpOp::LtE | CmpOp::Gt | CmpOp::GtE],
|
||||||
[Expr::Constant(ast::ExprConstant {
|
[Expr::Constant(ast::ExprConstant {
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
use num_bigint::BigInt;
|
|
||||||
use ruff_python_ast::{self as ast, Constant, Expr};
|
use ruff_python_ast::{self as ast, Constant, Expr};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
|
|
@ -184,11 +183,11 @@ pub(crate) fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
||||||
..
|
..
|
||||||
}) = upper.as_ref()
|
}) = upper.as_ref()
|
||||||
{
|
{
|
||||||
if *i == BigInt::from(1) && checker.enabled(Rule::SysVersionSlice1) {
|
if *i == 1 && checker.enabled(Rule::SysVersionSlice1) {
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(SysVersionSlice1, value.range()));
|
.push(Diagnostic::new(SysVersionSlice1, value.range()));
|
||||||
} else if *i == BigInt::from(3) && checker.enabled(Rule::SysVersionSlice3) {
|
} else if *i == 3 && checker.enabled(Rule::SysVersionSlice3) {
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(SysVersionSlice3, value.range()));
|
.push(Diagnostic::new(SysVersionSlice3, value.range()));
|
||||||
|
|
@ -200,11 +199,11 @@ pub(crate) fn subscript(checker: &mut Checker, value: &Expr, slice: &Expr) {
|
||||||
value: Constant::Int(i),
|
value: Constant::Int(i),
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
if *i == BigInt::from(2) && checker.enabled(Rule::SysVersion2) {
|
if *i == 2 && checker.enabled(Rule::SysVersion2) {
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(SysVersion2, value.range()));
|
.push(Diagnostic::new(SysVersion2, value.range()));
|
||||||
} else if *i == BigInt::from(0) && checker.enabled(Rule::SysVersion0) {
|
} else if *i == 0 && checker.enabled(Rule::SysVersion0) {
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(SysVersion0, value.range()));
|
.push(Diagnostic::new(SysVersion0, value.range()));
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use num_traits::ToPrimitive;
|
use malachite::Integer;
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
@ -36,7 +36,7 @@ use crate::checkers::ast::Checker;
|
||||||
/// - [Common Weakness Enumeration: CWE-732](https://cwe.mitre.org/data/definitions/732.html)
|
/// - [Common Weakness Enumeration: CWE-732](https://cwe.mitre.org/data/definitions/732.html)
|
||||||
#[violation]
|
#[violation]
|
||||||
pub struct BadFilePermissions {
|
pub struct BadFilePermissions {
|
||||||
mask: u16,
|
mask: Integer,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Violation for BadFilePermissions {
|
impl Violation for BadFilePermissions {
|
||||||
|
|
@ -56,7 +56,9 @@ pub(crate) fn bad_file_permissions(checker: &mut Checker, call: &ast::ExprCall)
|
||||||
{
|
{
|
||||||
if let Some(mode_arg) = call.arguments.find_argument("mode", 1) {
|
if let Some(mode_arg) = call.arguments.find_argument("mode", 1) {
|
||||||
if let Some(int_value) = int_value(mode_arg, checker.semantic()) {
|
if let Some(int_value) = int_value(mode_arg, checker.semantic()) {
|
||||||
if (int_value & WRITE_WORLD > 0) || (int_value & EXECUTE_GROUP > 0) {
|
if (int_value.clone() & Integer::from(WRITE_WORLD) > 0)
|
||||||
|
|| (int_value.clone() & Integer::from(EXECUTE_GROUP) > 0)
|
||||||
|
{
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
BadFilePermissions { mask: int_value },
|
BadFilePermissions { mask: int_value },
|
||||||
mode_arg.range(),
|
mode_arg.range(),
|
||||||
|
|
@ -113,13 +115,17 @@ fn py_stat(call_path: &CallPath) -> Option<u16> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn int_value(expr: &Expr, semantic: &SemanticModel) -> Option<u16> {
|
fn int_value(expr: &Expr, semantic: &SemanticModel) -> Option<Integer> {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Constant(ast::ExprConstant {
|
Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::Int(value),
|
value: Constant::Int(value),
|
||||||
..
|
..
|
||||||
}) => value.to_u16(),
|
}) => Some(value.clone()),
|
||||||
Expr::Attribute(_) => semantic.resolve_call_path(expr).as_ref().and_then(py_stat),
|
Expr::Attribute(_) => semantic
|
||||||
|
.resolve_call_path(expr)
|
||||||
|
.as_ref()
|
||||||
|
.and_then(py_stat)
|
||||||
|
.map(Integer::from),
|
||||||
Expr::BinOp(ast::ExprBinOp {
|
Expr::BinOp(ast::ExprBinOp {
|
||||||
left,
|
left,
|
||||||
op,
|
op,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
use num_traits::{One, Zero};
|
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::{self as ast, Constant, Expr};
|
use ruff_python_ast::{self as ast, Constant, Expr};
|
||||||
|
|
@ -57,7 +55,7 @@ pub(crate) fn snmp_insecure_version(checker: &mut Checker, call: &ast::ExprCall)
|
||||||
..
|
..
|
||||||
}) = &keyword.value
|
}) = &keyword.value
|
||||||
{
|
{
|
||||||
if value.is_zero() || value.is_one() {
|
if *value == 0 || *value == 1 {
|
||||||
checker
|
checker
|
||||||
.diagnostics
|
.diagnostics
|
||||||
.push(Diagnostic::new(SnmpInsecureVersion, keyword.range()));
|
.push(Diagnostic::new(SnmpInsecureVersion, keyword.range()));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
use num_bigint::BigInt;
|
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::{self as ast, Constant, Expr, UnaryOp};
|
use ruff_python_ast::{self as ast, Constant, Expr, UnaryOp};
|
||||||
|
|
@ -93,7 +91,7 @@ pub(crate) fn unnecessary_subscript_reversal(
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if *val != BigInt::from(1) {
|
if *val != 1 {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
checker.diagnostics.push(Diagnostic::new(
|
checker.diagnostics.push(Diagnostic::new(
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
use num_bigint::BigInt;
|
|
||||||
|
|
||||||
use ruff_diagnostics::Diagnostic;
|
use ruff_diagnostics::Diagnostic;
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
@ -75,7 +73,7 @@ pub(crate) fn unnecessary_range_start(checker: &mut Checker, call: &ast::ExprCal
|
||||||
else {
|
else {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if *value != BigInt::from(0) {
|
if *value != 0 {
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,3 @@
|
||||||
use num_bigint::BigInt;
|
|
||||||
use num_traits::{One, Zero};
|
|
||||||
use ruff_python_ast::{self as ast, CmpOp, Constant, Expr};
|
use ruff_python_ast::{self as ast, CmpOp, Constant, Expr};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
|
|
@ -249,10 +247,10 @@ impl ExpectedComparator {
|
||||||
..
|
..
|
||||||
}) = upper.as_ref()
|
}) = upper.as_ref()
|
||||||
{
|
{
|
||||||
if *upper == BigInt::one() {
|
if *upper == 1 {
|
||||||
return Some(ExpectedComparator::MajorTuple);
|
return Some(ExpectedComparator::MajorTuple);
|
||||||
}
|
}
|
||||||
if *upper == BigInt::from(2) {
|
if *upper == 2 {
|
||||||
return Some(ExpectedComparator::MajorMinorTuple);
|
return Some(ExpectedComparator::MajorMinorTuple);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -260,7 +258,7 @@ impl ExpectedComparator {
|
||||||
Expr::Constant(ast::ExprConstant {
|
Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::Int(n),
|
value: Constant::Int(n),
|
||||||
..
|
..
|
||||||
}) if n.is_zero() => {
|
}) if *n == 0 => {
|
||||||
return Some(ExpectedComparator::MajorDigit);
|
return Some(ExpectedComparator::MajorDigit);
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,3 @@
|
||||||
use num_traits::One;
|
|
||||||
use ruff_python_ast::{self as ast, CmpOp, Constant, Expr};
|
use ruff_python_ast::{self as ast, CmpOp, Constant, Expr};
|
||||||
|
|
||||||
use ruff_diagnostics::Diagnostic;
|
use ruff_diagnostics::Diagnostic;
|
||||||
|
|
@ -115,7 +114,7 @@ pub(crate) fn nunique_constant_series_check(
|
||||||
fn is_constant_one(expr: &Expr) -> bool {
|
fn is_constant_one(expr: &Expr) -> bool {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Constant(constant) => match &constant.value {
|
Expr::Constant(constant) => match &constant.value {
|
||||||
Constant::Int(int) => int.is_one(),
|
Constant::Int(int) => *int == 1,
|
||||||
_ => false,
|
_ => false,
|
||||||
},
|
},
|
||||||
_ => false,
|
_ => false,
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
|
use malachite::Integer;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::{self as ast, Constant, Expr};
|
use ruff_python_ast::{self as ast, Constant, Expr};
|
||||||
|
|
@ -47,7 +46,7 @@ impl From<LiteralType> for Constant {
|
||||||
value: Vec::new(),
|
value: Vec::new(),
|
||||||
implicit_concatenated: false,
|
implicit_concatenated: false,
|
||||||
}),
|
}),
|
||||||
LiteralType::Int => Constant::Int(BigInt::from(0)),
|
LiteralType::Int => Constant::Int(Integer::from(0)),
|
||||||
LiteralType::Float => Constant::Float(0.0),
|
LiteralType::Float => Constant::Float(0.0),
|
||||||
LiteralType::Bool => Constant::Bool(false),
|
LiteralType::Bool => Constant::Bool(false),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
|
|
||||||
use num_bigint::{BigInt, Sign};
|
use malachite::Integer;
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
|
|
@ -122,32 +122,25 @@ pub(crate) fn outdated_version_block(checker: &mut Checker, stmt_if: &StmtIf) {
|
||||||
..
|
..
|
||||||
}) => {
|
}) => {
|
||||||
if op == &CmpOp::Eq {
|
if op == &CmpOp::Eq {
|
||||||
match bigint_to_u32(number) {
|
if *number == 2 {
|
||||||
2 => {
|
|
||||||
let mut diagnostic =
|
let mut diagnostic =
|
||||||
Diagnostic::new(OutdatedVersionBlock, branch.test.range());
|
Diagnostic::new(OutdatedVersionBlock, branch.test.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(fix) =
|
if let Some(fix) = fix_always_false_branch(checker, stmt_if, &branch) {
|
||||||
fix_always_false_branch(checker, stmt_if, &branch)
|
|
||||||
{
|
|
||||||
diagnostic.set_fix(fix);
|
diagnostic.set_fix(fix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
} else if *number == 3 {
|
||||||
3 => {
|
|
||||||
let mut diagnostic =
|
let mut diagnostic =
|
||||||
Diagnostic::new(OutdatedVersionBlock, branch.test.range());
|
Diagnostic::new(OutdatedVersionBlock, branch.test.range());
|
||||||
if checker.patch(diagnostic.kind.rule()) {
|
if checker.patch(diagnostic.kind.rule()) {
|
||||||
if let Some(fix) = fix_always_true_branch(checker, stmt_if, &branch)
|
if let Some(fix) = fix_always_true_branch(checker, stmt_if, &branch) {
|
||||||
{
|
|
||||||
diagnostic.set_fix(fix);
|
diagnostic.set_fix(fix);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
checker.diagnostics.push(diagnostic);
|
checker.diagnostics.push(diagnostic);
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => (),
|
_ => (),
|
||||||
|
|
@ -156,7 +149,7 @@ pub(crate) fn outdated_version_block(checker: &mut Checker, stmt_if: &StmtIf) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns true if the `target_version` is always less than the [`PythonVersion`].
|
/// Returns true if the `target_version` is always less than the [`PythonVersion`].
|
||||||
fn compare_version(target_version: &[u32], py_version: PythonVersion, or_equal: bool) -> bool {
|
fn compare_version(target_version: &[Integer], py_version: PythonVersion, or_equal: bool) -> bool {
|
||||||
let mut target_version_iter = target_version.iter();
|
let mut target_version_iter = target_version.iter();
|
||||||
|
|
||||||
let Some(if_major) = target_version_iter.next() else {
|
let Some(if_major) = target_version_iter.next() else {
|
||||||
|
|
@ -165,7 +158,7 @@ fn compare_version(target_version: &[u32], py_version: PythonVersion, or_equal:
|
||||||
|
|
||||||
let (py_major, py_minor) = py_version.as_tuple();
|
let (py_major, py_minor) = py_version.as_tuple();
|
||||||
|
|
||||||
match if_major.cmp(&py_major) {
|
match if_major.cmp(&Integer::from(py_major)) {
|
||||||
Ordering::Less => true,
|
Ordering::Less => true,
|
||||||
Ordering::Greater => false,
|
Ordering::Greater => false,
|
||||||
Ordering::Equal => {
|
Ordering::Equal => {
|
||||||
|
|
@ -353,26 +346,16 @@ fn fix_always_true_branch(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Converts a `BigInt` to a `u32`. If the number is negative, it will return 0.
|
|
||||||
fn bigint_to_u32(number: &BigInt) -> u32 {
|
|
||||||
let the_number = number.to_u32_digits();
|
|
||||||
match the_number.0 {
|
|
||||||
Sign::Minus | Sign::NoSign => 0,
|
|
||||||
Sign::Plus => *the_number.1.first().unwrap(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Gets the version from the tuple
|
/// Gets the version from the tuple
|
||||||
fn extract_version(elts: &[Expr]) -> Vec<u32> {
|
fn extract_version(elts: &[Expr]) -> Vec<Integer> {
|
||||||
let mut version: Vec<u32> = vec![];
|
let mut version = Vec::new();
|
||||||
for elt in elts {
|
for elt in elts {
|
||||||
if let Expr::Constant(ast::ExprConstant {
|
if let Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::Int(item),
|
value: Constant::Int(number),
|
||||||
..
|
..
|
||||||
}) = &elt
|
}) = &elt
|
||||||
{
|
{
|
||||||
let number = bigint_to_u32(item);
|
version.push(number.clone());
|
||||||
version.push(number);
|
|
||||||
} else {
|
} else {
|
||||||
return version;
|
return version;
|
||||||
}
|
}
|
||||||
|
|
@ -403,6 +386,13 @@ mod tests {
|
||||||
or_equal: bool,
|
or_equal: bool,
|
||||||
expected: bool,
|
expected: bool,
|
||||||
) {
|
) {
|
||||||
assert_eq!(compare_version(version_vec, version, or_equal), expected);
|
let version_integers = version_vec
|
||||||
|
.iter()
|
||||||
|
.map(|x| Integer::from(*x))
|
||||||
|
.collect::<Vec<_>>();
|
||||||
|
assert_eq!(
|
||||||
|
compare_version(&version_integers, version, or_equal),
|
||||||
|
expected
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use num_traits::ToPrimitive;
|
use malachite::Integer;
|
||||||
use ruff_python_ast::{self as ast, Constant, Expr, UnaryOp};
|
use ruff_python_ast::{self as ast, Constant, Expr, UnaryOp};
|
||||||
|
|
||||||
use ruff_diagnostics::{Diagnostic, Violation};
|
use ruff_diagnostics::{Diagnostic, Violation};
|
||||||
|
|
@ -46,11 +46,11 @@ impl Violation for PairwiseOverZipped {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct SliceInfo {
|
struct SliceInfo {
|
||||||
arg_name: String,
|
arg_name: String,
|
||||||
slice_start: Option<i64>,
|
slice_start: Option<Integer>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl SliceInfo {
|
impl SliceInfo {
|
||||||
pub(crate) fn new(arg_name: String, slice_start: Option<i64>) -> Self {
|
pub(crate) fn new(arg_name: String, slice_start: Option<Integer>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
arg_name,
|
arg_name,
|
||||||
slice_start,
|
slice_start,
|
||||||
|
|
@ -89,12 +89,12 @@ fn match_slice_info(expr: &Expr) -> Option<SliceInfo> {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_bound(expr: &Expr) -> Option<i64> {
|
fn to_bound(expr: &Expr) -> Option<Integer> {
|
||||||
match expr {
|
match expr {
|
||||||
Expr::Constant(ast::ExprConstant {
|
Expr::Constant(ast::ExprConstant {
|
||||||
value: Constant::Int(value),
|
value: Constant::Int(value),
|
||||||
..
|
..
|
||||||
}) => value.to_i64(),
|
}) => Some(value.clone()),
|
||||||
Expr::UnaryOp(ast::ExprUnaryOp {
|
Expr::UnaryOp(ast::ExprUnaryOp {
|
||||||
op: UnaryOp::USub | UnaryOp::Invert,
|
op: UnaryOp::USub | UnaryOp::Invert,
|
||||||
operand,
|
operand,
|
||||||
|
|
@ -105,7 +105,7 @@ fn to_bound(expr: &Expr) -> Option<i64> {
|
||||||
..
|
..
|
||||||
}) = operand.as_ref()
|
}) = operand.as_ref()
|
||||||
{
|
{
|
||||||
value.to_i64().map(|v| -v)
|
Some(-value.clone())
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +155,10 @@ pub(crate) fn pairwise_over_zipped(checker: &mut Checker, func: &Expr, args: &[E
|
||||||
}
|
}
|
||||||
|
|
||||||
// Verify that the arguments are successive.
|
// Verify that the arguments are successive.
|
||||||
if second_arg_info.slice_start.unwrap_or(0) - first_arg_info.slice_start.unwrap_or(0) != 1 {
|
if second_arg_info.slice_start.unwrap_or(Integer::from(0))
|
||||||
|
- first_arg_info.slice_start.unwrap_or(Integer::from(0))
|
||||||
|
!= 1
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,5 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
|
|
||||||
use num_traits::Zero;
|
|
||||||
|
|
||||||
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
use ruff_diagnostics::{AlwaysAutofixableViolation, Diagnostic, Edit, Fix};
|
||||||
use ruff_macros::{derive_message_formats, violation};
|
use ruff_macros::{derive_message_formats, violation};
|
||||||
use ruff_python_ast::{self as ast, Arguments, Comprehension, Constant, Expr};
|
use ruff_python_ast::{self as ast, Arguments, Comprehension, Constant, Expr};
|
||||||
|
|
@ -115,7 +113,7 @@ fn is_head_slice(expr: &Expr) -> bool {
|
||||||
..
|
..
|
||||||
}) = expr
|
}) = expr
|
||||||
{
|
{
|
||||||
value.is_zero()
|
*value == 0
|
||||||
} else {
|
} else {
|
||||||
false
|
false
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,8 @@ ruff_text_size = { path = "../ruff_text_size" }
|
||||||
bitflags = { workspace = true }
|
bitflags = { workspace = true }
|
||||||
is-macro = { workspace = true }
|
is-macro = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
|
malachite = { workspace = true }
|
||||||
memchr = { workspace = true }
|
memchr = { workspace = true }
|
||||||
num-bigint = { workspace = true }
|
|
||||||
num-traits = { workspace = true }
|
|
||||||
once_cell = { workspace = true }
|
once_cell = { workspace = true }
|
||||||
rustc-hash = { workspace = true }
|
rustc-hash = { workspace = true }
|
||||||
serde = { workspace = true, optional = true }
|
serde = { workspace = true, optional = true }
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,8 @@
|
||||||
//! an implicit concatenation of string literals, as these expressions are considered to
|
//! an implicit concatenation of string literals, as these expressions are considered to
|
||||||
//! have the same shape in that they evaluate to the same value.
|
//! have the same shape in that they evaluate to the same value.
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
|
||||||
|
|
||||||
use crate as ast;
|
use crate as ast;
|
||||||
|
use malachite::Integer;
|
||||||
|
|
||||||
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
#[derive(Debug, PartialEq, Eq, Hash, Copy, Clone)]
|
||||||
pub enum ComparableBoolOp {
|
pub enum ComparableBoolOp {
|
||||||
|
|
@ -334,7 +333,7 @@ pub enum ComparableConstant<'a> {
|
||||||
Bool(&'a bool),
|
Bool(&'a bool),
|
||||||
Str { value: &'a str, unicode: bool },
|
Str { value: &'a str, unicode: bool },
|
||||||
Bytes(&'a [u8]),
|
Bytes(&'a [u8]),
|
||||||
Int(&'a BigInt),
|
Int(&'a Integer),
|
||||||
Tuple(Vec<ComparableConstant<'a>>),
|
Tuple(Vec<ComparableConstant<'a>>),
|
||||||
Float(u64),
|
Float(u64),
|
||||||
Complex { real: u64, imag: u64 },
|
Complex { real: u64, imag: u64 },
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
use std::borrow::Cow;
|
use std::borrow::Cow;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
|
||||||
use num_traits::Zero;
|
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
use ruff_text_size::{Ranged, TextRange};
|
use ruff_text_size::{Ranged, TextRange};
|
||||||
|
|
@ -1073,7 +1072,7 @@ impl Truthiness {
|
||||||
Constant::None => Some(false),
|
Constant::None => Some(false),
|
||||||
Constant::Str(ast::StringConstant { value, .. }) => Some(!value.is_empty()),
|
Constant::Str(ast::StringConstant { value, .. }) => Some(!value.is_empty()),
|
||||||
Constant::Bytes(bytes) => Some(!bytes.is_empty()),
|
Constant::Bytes(bytes) => Some(!bytes.is_empty()),
|
||||||
Constant::Int(int) => Some(!int.is_zero()),
|
Constant::Int(int) => Some(*int != 0),
|
||||||
Constant::Float(float) => Some(*float != 0.0),
|
Constant::Float(float) => Some(*float != 0.0),
|
||||||
Constant::Complex { real, imag } => Some(*real != 0.0 || *imag != 0.0),
|
Constant::Complex { real, imag } => Some(*real != 0.0 || *imag != 0.0),
|
||||||
Constant::Ellipsis => Some(true),
|
Constant::Ellipsis => Some(true),
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,11 @@
|
||||||
#![allow(clippy::derive_partial_eq_without_eq)]
|
#![allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
|
use malachite::Integer;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
|
||||||
|
|
||||||
use ruff_text_size::{Ranged, TextRange, TextSize};
|
use ruff_text_size::{Ranged, TextRange, TextSize};
|
||||||
|
|
||||||
/// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod)
|
/// See also [mod](https://docs.python.org/3/library/ast.html#ast.mod)
|
||||||
|
|
@ -2604,7 +2603,7 @@ pub enum Constant {
|
||||||
Bool(bool),
|
Bool(bool),
|
||||||
Str(StringConstant),
|
Str(StringConstant),
|
||||||
Bytes(BytesConstant),
|
Bytes(BytesConstant),
|
||||||
Int(BigInt),
|
Int(Integer),
|
||||||
Float(f64),
|
Float(f64),
|
||||||
Complex { real: f64, imag: f64 },
|
Complex { real: f64, imag: f64 },
|
||||||
Ellipsis,
|
Ellipsis,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use crate::Case;
|
use crate::Case;
|
||||||
use num_traits::{Float, Zero};
|
use num_traits::Float;
|
||||||
use std::f64;
|
use std::f64;
|
||||||
|
|
||||||
pub fn parse_str(literal: &str) -> Option<f64> {
|
pub fn parse_str(literal: &str) -> Option<f64> {
|
||||||
|
|
@ -248,7 +248,7 @@ pub fn to_hex(value: f64) -> String {
|
||||||
let (mantissa, exponent, sign) = value.integer_decode();
|
let (mantissa, exponent, sign) = value.integer_decode();
|
||||||
let sign_fmt = if sign < 0 { "-" } else { "" };
|
let sign_fmt = if sign < 0 { "-" } else { "" };
|
||||||
match value {
|
match value {
|
||||||
value if value.is_zero() => format!("{sign_fmt}0x0.0p+0"),
|
value if value == 0.0 => format!("{sign_fmt}0x0.0p+0"),
|
||||||
value if value.is_infinite() => format!("{sign_fmt}inf"),
|
value if value.is_infinite() => format!("{sign_fmt}inf"),
|
||||||
value if value.is_nan() => "nan".to_owned(),
|
value if value.is_nan() => "nan".to_owned(),
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
||||||
|
|
@ -21,8 +21,7 @@ anyhow = { workspace = true }
|
||||||
is-macro = { workspace = true }
|
is-macro = { workspace = true }
|
||||||
itertools = { workspace = true }
|
itertools = { workspace = true }
|
||||||
lalrpop-util = { version = "0.20.0", default-features = false }
|
lalrpop-util = { version = "0.20.0", default-features = false }
|
||||||
num-bigint = { workspace = true }
|
malachite = { workspace = true }
|
||||||
num-traits = { workspace = true }
|
|
||||||
unicode-ident = { workspace = true }
|
unicode-ident = { workspace = true }
|
||||||
unicode_names2 = { version = "0.6.0", git = "https://github.com/youknowone/unicode_names2.git", rev = "4ce16aa85cbcdd9cc830410f1a72ef9a235f2fde" }
|
unicode_names2 = { version = "0.6.0", git = "https://github.com/youknowone/unicode_names2.git", rev = "4ce16aa85cbcdd9cc830410f1a72ef9a235f2fde" }
|
||||||
rustc-hash = { workspace = true }
|
rustc-hash = { workspace = true }
|
||||||
|
|
|
||||||
|
|
@ -28,11 +28,11 @@
|
||||||
//!
|
//!
|
||||||
//! [Lexical analysis]: https://docs.python.org/3/reference/lexical_analysis.html
|
//! [Lexical analysis]: https://docs.python.org/3/reference/lexical_analysis.html
|
||||||
|
|
||||||
|
use malachite::num::conversion::traits::FromStringBase;
|
||||||
|
use malachite::Integer;
|
||||||
use std::iter::FusedIterator;
|
use std::iter::FusedIterator;
|
||||||
use std::{char, cmp::Ordering, str::FromStr};
|
use std::{char, cmp::Ordering, str::FromStr};
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
|
||||||
use num_traits::{Num, Zero};
|
|
||||||
use ruff_python_ast::IpyEscapeKind;
|
use ruff_python_ast::IpyEscapeKind;
|
||||||
use ruff_text_size::{TextLen, TextRange, TextSize};
|
use ruff_text_size::{TextLen, TextRange, TextSize};
|
||||||
use unicode_ident::{is_xid_continue, is_xid_start};
|
use unicode_ident::{is_xid_continue, is_xid_start};
|
||||||
|
|
@ -264,10 +264,15 @@ impl<'source> Lexer<'source> {
|
||||||
|
|
||||||
let mut number = LexedText::new(self.offset(), self.source);
|
let mut number = LexedText::new(self.offset(), self.source);
|
||||||
self.radix_run(&mut number, radix);
|
self.radix_run(&mut number, radix);
|
||||||
let value =
|
|
||||||
BigInt::from_str_radix(number.as_str(), radix.as_u32()).map_err(|e| LexicalError {
|
let value = Integer::from_string_base(radix.as_u8(), number.as_str()).ok_or_else(|| {
|
||||||
error: LexicalErrorType::OtherError(format!("{e:?}")),
|
LexicalError {
|
||||||
|
error: LexicalErrorType::OtherError(format!(
|
||||||
|
"'{}' is not a valid integer",
|
||||||
|
number.as_str()
|
||||||
|
)),
|
||||||
location: self.token_range().start(),
|
location: self.token_range().start(),
|
||||||
|
}
|
||||||
})?;
|
})?;
|
||||||
Ok(Tok::Int { value })
|
Ok(Tok::Int { value })
|
||||||
}
|
}
|
||||||
|
|
@ -339,8 +344,19 @@ impl<'source> Lexer<'source> {
|
||||||
let imag = f64::from_str(number.as_str()).unwrap();
|
let imag = f64::from_str(number.as_str()).unwrap();
|
||||||
Ok(Tok::Complex { real: 0.0, imag })
|
Ok(Tok::Complex { real: 0.0, imag })
|
||||||
} else {
|
} else {
|
||||||
let value = number.as_str().parse::<BigInt>().unwrap();
|
// Optimization: `Natural` and thereby `Integer` add up digits from bytes to convert
|
||||||
if start_is_zero && !value.is_zero() {
|
// from string. This is much less efficient than the highly optimized std
|
||||||
|
// string-to-number parser and we know that most numbers are small.
|
||||||
|
// i32::MAX is 2147483647 (10 digits), so all 9 digit numbers are representable as
|
||||||
|
// i32. We can't guarantee that `32_bit_limbs` isn't set, so we limit ourselves to
|
||||||
|
// i32 instead of i64.
|
||||||
|
let value = if number.as_str().len() < 10 {
|
||||||
|
Integer::from(i32::from_str(number.as_str()).unwrap())
|
||||||
|
} else {
|
||||||
|
Integer::from_str(number.as_str()).unwrap()
|
||||||
|
};
|
||||||
|
|
||||||
|
if start_is_zero && value != 0 {
|
||||||
// leading zeros in decimal integer literals are not permitted
|
// leading zeros in decimal integer literals are not permitted
|
||||||
return Err(LexicalError {
|
return Err(LexicalError {
|
||||||
error: LexicalErrorType::OtherError("Invalid Token".to_owned()),
|
error: LexicalErrorType::OtherError("Invalid Token".to_owned()),
|
||||||
|
|
@ -1155,7 +1171,7 @@ impl State {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug)]
|
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
|
||||||
enum Radix {
|
enum Radix {
|
||||||
Binary,
|
Binary,
|
||||||
Octal,
|
Octal,
|
||||||
|
|
@ -1164,7 +1180,7 @@ enum Radix {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Radix {
|
impl Radix {
|
||||||
const fn as_u32(self) -> u32 {
|
const fn as_u8(self) -> u8 {
|
||||||
match self {
|
match self {
|
||||||
Radix::Binary => 2,
|
Radix::Binary => 2,
|
||||||
Radix::Octal => 8,
|
Radix::Octal => 8,
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@
|
||||||
// See also: file:///usr/share/doc/python/html/reference/compound_stmts.html#function-definitions
|
// See also: file:///usr/share/doc/python/html/reference/compound_stmts.html#function-definitions
|
||||||
// See also: https://greentreesnakes.readthedocs.io/en/latest/nodes.html#keyword
|
// See also: https://greentreesnakes.readthedocs.io/en/latest/nodes.html#keyword
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
|
||||||
use ruff_text_size::{Ranged, TextSize};
|
use ruff_text_size::{Ranged, TextSize};
|
||||||
use ruff_python_ast::{self as ast, IpyEscapeKind};
|
use ruff_python_ast::{self as ast, IpyEscapeKind};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -15,6 +14,7 @@ use crate::{
|
||||||
token::{self, StringKind},
|
token::{self, StringKind},
|
||||||
};
|
};
|
||||||
use lalrpop_util::ParseError;
|
use lalrpop_util::ParseError;
|
||||||
|
use malachite::Integer;
|
||||||
|
|
||||||
grammar(mode: Mode);
|
grammar(mode: Mode);
|
||||||
|
|
||||||
|
|
@ -1928,7 +1928,7 @@ extern {
|
||||||
"True" => token::Tok::True,
|
"True" => token::Tok::True,
|
||||||
"False" => token::Tok::False,
|
"False" => token::Tok::False,
|
||||||
"None" => token::Tok::None,
|
"None" => token::Tok::None,
|
||||||
int => token::Tok::Int { value: <BigInt> },
|
int => token::Tok::Int { value: <Integer> },
|
||||||
float => token::Tok::Float { value: <f64> },
|
float => token::Tok::Float { value: <f64> },
|
||||||
complex => token::Tok::Complex { real: <f64>, imag: <f64> },
|
complex => token::Tok::Complex { real: <f64>, imag: <f64> },
|
||||||
string => token::Tok::String {
|
string => token::Tok::String {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
// auto-generated: "lalrpop 0.20.0"
|
// auto-generated: "lalrpop 0.20.0"
|
||||||
// sha3: e8f3229288c1a13387ea6041355e2d8fe9ab788fbc7229032d2de92beb675944
|
// sha3: 5b982370860d3a79f183bc579ec6f5165211b83573141f4c9ceaec27436c30ad
|
||||||
use num_bigint::BigInt;
|
|
||||||
use ruff_text_size::{Ranged, TextSize};
|
use ruff_text_size::{Ranged, TextSize};
|
||||||
use ruff_python_ast::{self as ast, IpyEscapeKind};
|
use ruff_python_ast::{self as ast, IpyEscapeKind};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -12,6 +11,7 @@ use crate::{
|
||||||
token::{self, StringKind},
|
token::{self, StringKind},
|
||||||
};
|
};
|
||||||
use lalrpop_util::ParseError;
|
use lalrpop_util::ParseError;
|
||||||
|
use malachite::Integer;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate lalrpop_util as __lalrpop_util;
|
extern crate lalrpop_util as __lalrpop_util;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
|
@ -23,7 +23,6 @@ extern crate alloc;
|
||||||
#[allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens, clippy::all)]
|
#[allow(non_snake_case, non_camel_case_types, unused_mut, unused_variables, unused_imports, unused_parens, clippy::all)]
|
||||||
mod __parse__Top {
|
mod __parse__Top {
|
||||||
|
|
||||||
use num_bigint::BigInt;
|
|
||||||
use ruff_text_size::{Ranged, TextSize};
|
use ruff_text_size::{Ranged, TextSize};
|
||||||
use ruff_python_ast::{self as ast, IpyEscapeKind};
|
use ruff_python_ast::{self as ast, IpyEscapeKind};
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -35,6 +34,7 @@ mod __parse__Top {
|
||||||
token::{self, StringKind},
|
token::{self, StringKind},
|
||||||
};
|
};
|
||||||
use lalrpop_util::ParseError;
|
use lalrpop_util::ParseError;
|
||||||
|
use malachite::Integer;
|
||||||
#[allow(unused_extern_crates)]
|
#[allow(unused_extern_crates)]
|
||||||
extern crate lalrpop_util as __lalrpop_util;
|
extern crate lalrpop_util as __lalrpop_util;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
|
|
@ -48,7 +48,7 @@ mod __parse__Top {
|
||||||
Variant0(token::Tok),
|
Variant0(token::Tok),
|
||||||
Variant1((f64, f64)),
|
Variant1((f64, f64)),
|
||||||
Variant2(f64),
|
Variant2(f64),
|
||||||
Variant3(BigInt),
|
Variant3(Integer),
|
||||||
Variant4((IpyEscapeKind, String)),
|
Variant4((IpyEscapeKind, String)),
|
||||||
Variant5(String),
|
Variant5(String),
|
||||||
Variant6((String, StringKind, bool)),
|
Variant6((String, StringKind, bool)),
|
||||||
|
|
@ -17716,7 +17716,7 @@ mod __parse__Top {
|
||||||
fn __pop_Variant3<
|
fn __pop_Variant3<
|
||||||
>(
|
>(
|
||||||
__symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>
|
__symbols: &mut alloc::vec::Vec<(TextSize,__Symbol<>,TextSize)>
|
||||||
) -> (TextSize, BigInt, TextSize)
|
) -> (TextSize, Integer, TextSize)
|
||||||
{
|
{
|
||||||
match __symbols.pop() {
|
match __symbols.pop() {
|
||||||
Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r),
|
Some((__l, __Symbol::Variant3(__v), __r)) => (__l, __v, __r),
|
||||||
|
|
@ -34480,7 +34480,7 @@ fn __action232<
|
||||||
fn __action233<
|
fn __action233<
|
||||||
>(
|
>(
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
(_, value, _): (TextSize, BigInt, TextSize),
|
(_, value, _): (TextSize, Integer, TextSize),
|
||||||
) -> ast::Constant
|
) -> ast::Constant
|
||||||
{
|
{
|
||||||
ast::Constant::Int(value)
|
ast::Constant::Int(value)
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
//!
|
//!
|
||||||
//! [CPython source]: https://github.com/python/cpython/blob/dfc2e065a2e71011017077e549cd2f9bf4944c54/Include/internal/pycore_token.h;
|
//! [CPython source]: https://github.com/python/cpython/blob/dfc2e065a2e71011017077e549cd2f9bf4944c54/Include/internal/pycore_token.h;
|
||||||
use crate::Mode;
|
use crate::Mode;
|
||||||
use num_bigint::BigInt;
|
use malachite::Integer;
|
||||||
use ruff_python_ast::IpyEscapeKind;
|
use ruff_python_ast::IpyEscapeKind;
|
||||||
use ruff_text_size::TextSize;
|
use ruff_text_size::TextSize;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
@ -21,7 +21,7 @@ pub enum Tok {
|
||||||
/// Token value for an integer.
|
/// Token value for an integer.
|
||||||
Int {
|
Int {
|
||||||
/// The integer value.
|
/// The integer value.
|
||||||
value: BigInt,
|
value: Integer,
|
||||||
},
|
},
|
||||||
/// Token value for a floating point number.
|
/// Token value for a floating point number.
|
||||||
Float {
|
Float {
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,6 @@ ruff_text_size = { path = "../ruff_text_size" }
|
||||||
|
|
||||||
bitflags = { workspace = true }
|
bitflags = { workspace = true }
|
||||||
is-macro = { workspace = true }
|
is-macro = { workspace = true }
|
||||||
num-traits = { workspace = true }
|
|
||||||
rustc-hash = { workspace = true }
|
rustc-hash = { workspace = true }
|
||||||
smallvec = { workspace = true }
|
smallvec = { workspace = true }
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
//! Analysis rules for the `typing` module.
|
//! Analysis rules for the `typing` module.
|
||||||
|
|
||||||
use num_traits::identities::Zero;
|
|
||||||
use ruff_python_ast::{
|
use ruff_python_ast::{
|
||||||
self as ast, Constant, Expr, Operator, ParameterWithDefault, Parameters, Stmt,
|
self as ast, Constant, Expr, Operator, ParameterWithDefault, Parameters, Stmt,
|
||||||
};
|
};
|
||||||
|
|
@ -319,7 +318,7 @@ pub fn is_type_checking_block(stmt: &ast::StmtIf, semantic: &SemanticModel) -> b
|
||||||
..
|
..
|
||||||
}) = test.as_ref()
|
}) = test.as_ref()
|
||||||
{
|
{
|
||||||
if value.is_zero() {
|
if *value == 0 {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue