mirror of
https://github.com/astral-sh/ruff.git
synced 2025-07-23 13:05:06 +00:00
[refurb
] Further special cases added to verbose-decimal-constructor (FURB157)
(#14216)
This PR accounts for further subtleties in `Decimal` parsing: - Strings which are empty modulo underscores and surrounding whitespace are skipped - `Decimal("-0")` is skipped - `Decimal("{integer literal that is longer than 640 digits}")` are skipped (see linked issue for explanation) NB: The snapshot did not need to be updated since the new test cases are "Ok" instances and added below the diff. Closes #14204
This commit is contained in:
parent
93fdf7ed36
commit
b8dc780bdc
2 changed files with 30 additions and 24 deletions
|
@ -34,4 +34,11 @@ Decimal("1.2")
|
|||
# Ok: even though this is equal to `Decimal(123)`,
|
||||
# we assume that a developer would
|
||||
# only write it this way if they meant to.
|
||||
Decimal("١٢٣")
|
||||
Decimal("١٢٣")
|
||||
|
||||
# Further subtleties
|
||||
# https://github.com/astral-sh/ruff/issues/14204
|
||||
Decimal("-0") # Ok
|
||||
Decimal("_") # Ok
|
||||
Decimal(" ") # Ok
|
||||
Decimal("10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000") # Ok
|
||||
|
|
|
@ -94,6 +94,12 @@ pub(crate) fn verbose_decimal_constructor(checker: &mut Checker, call: &ast::Exp
|
|||
("", trimmed)
|
||||
};
|
||||
|
||||
// Early return if we now have an empty string
|
||||
// or a very long string:
|
||||
if (rest.len() > PYTHONINTMAXSTRDIGITS) || (rest.len() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Skip leading zeros.
|
||||
let rest = rest.trim_start_matches('0');
|
||||
|
||||
|
@ -103,7 +109,15 @@ pub(crate) fn verbose_decimal_constructor(checker: &mut Checker, call: &ast::Exp
|
|||
};
|
||||
|
||||
// If all the characters are zeros, then the value is zero.
|
||||
let rest = if rest.is_empty() { "0" } else { rest };
|
||||
let rest = match (unary, rest.is_empty()) {
|
||||
// `Decimal("-0")` is not the same as `Decimal("0")`
|
||||
// so we return early.
|
||||
("-", true) => {
|
||||
return;
|
||||
}
|
||||
(_, true) => "0",
|
||||
_ => rest,
|
||||
};
|
||||
|
||||
let replacement = format!("{unary}{rest}");
|
||||
let mut diagnostic = Diagnostic::new(
|
||||
|
@ -168,25 +182,10 @@ pub(crate) fn verbose_decimal_constructor(checker: &mut Checker, call: &ast::Exp
|
|||
checker.diagnostics.push(diagnostic);
|
||||
}
|
||||
|
||||
// // Slightly modified from [CPython regex] to ignore https://github.com/python/cpython/blob/ac556a2ad1213b8bb81372fe6fb762f5fcb076de/Lib/_pydecimal.py#L6060-L6077
|
||||
// static DECIMAL_PARSER_REGEX: LazyLock<Regex> = LazyLock::new(|| {
|
||||
// Regex::new(
|
||||
// r"(?x) # Verbose mode for comments
|
||||
// ^ # Start of string
|
||||
// (?P<sign>[-+])? # Optional sign
|
||||
// (?:
|
||||
// (?P<int>\d*) # Integer part (can be empty)
|
||||
// (\.(?P<frac>\d+))? # Optional fractional part
|
||||
// (E(?P<exp>[-+]?\d+))? # Optional exponent
|
||||
// |
|
||||
// Inf(inity)? # Infinity
|
||||
// |
|
||||
// (?P<signal>s)? # Optional signal
|
||||
// NaN # NaN
|
||||
// (?P<diag>\d*) # Optional diagnostic info
|
||||
// )
|
||||
// $ # End of string
|
||||
// ",
|
||||
// )
|
||||
// .unwrap()
|
||||
// });
|
||||
// ```console
|
||||
// $ python
|
||||
// >>> import sys
|
||||
// >>> sys.int_info.str_digits_check_threshold
|
||||
// 640
|
||||
// ```
|
||||
const PYTHONINTMAXSTRDIGITS: usize = 640;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue