Skip to content

[refurb] Avoid panicking unwrap in verbose-decimal-constructor (FURB157) #16777

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Mar 17, 2025
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion crates/ruff_linter/resources/test/fixtures/refurb/FURB157.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,22 @@
Decimal(float(" +nan ")) # Decimal(" +nan ")
# In this one case, " -nan ", the fix has to be
# `Decimal(" nan ")`` because `Decimal("-nan") != Decimal(float("-nan"))`
Decimal(float(" -nan ")) # Decimal(" nan ")
Decimal(float(" -nan ")) # Decimal("nan")
Decimal(float(" inf ")) # Decimal(" inf ")
Decimal(float(" +inf ")) # Decimal(" +inf ")
Decimal(float(" -inf ")) # Decimal(" -inf ")
Decimal(float(" infinity ")) # Decimal(" infinity ")
Decimal(float(" +infinity ")) # Decimal(" +infinity ")
Decimal(float(" -infinity ")) # Decimal(" -infinity ")

# Escape sequence handling in "-nan" case
# Here we do not bother respecting the original whitespace
# and other trivia when offering a fix.
# https://github.com/astral-sh/ruff/issues/16771
Decimal(float("\x2dnan"))
Decimal(float("\x20\x2dnan"))
Decimal(float("\x20\u002dnan"))
Decimal(float("\x20\U0000002dnan"))
Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))
Decimal(float(" -" "nan"))
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,11 @@ pub(crate) fn verbose_decimal_constructor(checker: &Checker, call: &ast::ExprCal
let mut replacement = checker.locator().slice(float).to_string();
// `Decimal(float("-nan")) == Decimal("nan")`
if trimmed.eq_ignore_ascii_case("-nan") {
replacement.remove(replacement.find('-').unwrap());
// Here we do not attempt to remove just the '-' character.
// It may have been encoded (e.g. as '\N{hyphen-minus}')
// in the original source slice, and the added complexity
// does not make sense for this edge case.
replacement = "\"nan\"".to_string();
}
let mut diagnostic = Diagnostic::new(
VerboseDecimalConstructor {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,33 +247,33 @@ FURB157.py:49:9: FURB157 [*] Verbose expression in `Decimal` constructor
49 |+Decimal(" +nan ") # Decimal(" +nan ")
50 50 | # In this one case, " -nan ", the fix has to be
51 51 | # `Decimal(" nan ")`` because `Decimal("-nan") != Decimal(float("-nan"))`
52 52 | Decimal(float(" -nan ")) # Decimal(" nan ")
52 52 | Decimal(float(" -nan ")) # Decimal("nan")

FURB157.py:52:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
50 | # In this one case, " -nan ", the fix has to be
51 | # `Decimal(" nan ")`` because `Decimal("-nan") != Decimal(float("-nan"))`
52 | Decimal(float(" -nan ")) # Decimal(" nan ")
52 | Decimal(float(" -nan ")) # Decimal("nan")
| ^^^^^^^^^^^^^^^ FURB157
53 | Decimal(float(" inf ")) # Decimal(" inf ")
54 | Decimal(float(" +inf ")) # Decimal(" +inf ")
|
= help: Replace with `" nan "`
= help: Replace with `"nan"`

ℹ Safe fix
49 49 | Decimal(float(" +nan ")) # Decimal(" +nan ")
50 50 | # In this one case, " -nan ", the fix has to be
51 51 | # `Decimal(" nan ")`` because `Decimal("-nan") != Decimal(float("-nan"))`
52 |-Decimal(float(" -nan ")) # Decimal(" nan ")
52 |+Decimal(" nan ") # Decimal(" nan ")
52 |-Decimal(float(" -nan ")) # Decimal("nan")
52 |+Decimal("nan") # Decimal("nan")
53 53 | Decimal(float(" inf ")) # Decimal(" inf ")
54 54 | Decimal(float(" +inf ")) # Decimal(" +inf ")
55 55 | Decimal(float(" -inf ")) # Decimal(" -inf ")

FURB157.py:53:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
51 | # `Decimal(" nan ")`` because `Decimal("-nan") != Decimal(float("-nan"))`
52 | Decimal(float(" -nan ")) # Decimal(" nan ")
52 | Decimal(float(" -nan ")) # Decimal("nan")
53 | Decimal(float(" inf ")) # Decimal(" inf ")
| ^^^^^^^^^^^^^^ FURB157
54 | Decimal(float(" +inf ")) # Decimal(" +inf ")
Expand All @@ -284,7 +284,7 @@ FURB157.py:53:9: FURB157 [*] Verbose expression in `Decimal` constructor
ℹ Safe fix
50 50 | # In this one case, " -nan ", the fix has to be
51 51 | # `Decimal(" nan ")`` because `Decimal("-nan") != Decimal(float("-nan"))`
52 52 | Decimal(float(" -nan ")) # Decimal(" nan ")
52 52 | Decimal(float(" -nan ")) # Decimal("nan")
53 |-Decimal(float(" inf ")) # Decimal(" inf ")
53 |+Decimal(" inf ") # Decimal(" inf ")
54 54 | Decimal(float(" +inf ")) # Decimal(" +inf ")
Expand All @@ -293,7 +293,7 @@ FURB157.py:53:9: FURB157 [*] Verbose expression in `Decimal` constructor

FURB157.py:54:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
52 | Decimal(float(" -nan ")) # Decimal(" nan ")
52 | Decimal(float(" -nan ")) # Decimal("nan")
53 | Decimal(float(" inf ")) # Decimal(" inf ")
54 | Decimal(float(" +inf ")) # Decimal(" +inf ")
| ^^^^^^^^^^^^^^^ FURB157
Expand All @@ -304,7 +304,7 @@ FURB157.py:54:9: FURB157 [*] Verbose expression in `Decimal` constructor

ℹ Safe fix
51 51 | # `Decimal(" nan ")`` because `Decimal("-nan") != Decimal(float("-nan"))`
52 52 | Decimal(float(" -nan ")) # Decimal(" nan ")
52 52 | Decimal(float(" -nan ")) # Decimal("nan")
53 53 | Decimal(float(" inf ")) # Decimal(" inf ")
54 |-Decimal(float(" +inf ")) # Decimal(" +inf ")
54 |+Decimal(" +inf ") # Decimal(" +inf ")
Expand All @@ -324,7 +324,7 @@ FURB157.py:55:9: FURB157 [*] Verbose expression in `Decimal` constructor
= help: Replace with `" -inf "`

ℹ Safe fix
52 52 | Decimal(float(" -nan ")) # Decimal(" nan ")
52 52 | Decimal(float(" -nan ")) # Decimal("nan")
53 53 | Decimal(float(" inf ")) # Decimal(" inf ")
54 54 | Decimal(float(" +inf ")) # Decimal(" +inf ")
55 |-Decimal(float(" -inf ")) # Decimal(" -inf ")
Expand Down Expand Up @@ -352,6 +352,7 @@ FURB157.py:56:9: FURB157 [*] Verbose expression in `Decimal` constructor
56 |+Decimal(" infinity ") # Decimal(" infinity ")
57 57 | Decimal(float(" +infinity ")) # Decimal(" +infinity ")
58 58 | Decimal(float(" -infinity ")) # Decimal(" -infinity ")
59 59 |

FURB157.py:57:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
Expand All @@ -370,13 +371,17 @@ FURB157.py:57:9: FURB157 [*] Verbose expression in `Decimal` constructor
57 |-Decimal(float(" +infinity ")) # Decimal(" +infinity ")
57 |+Decimal(" +infinity ") # Decimal(" +infinity ")
58 58 | Decimal(float(" -infinity ")) # Decimal(" -infinity ")
59 59 |
60 60 | # Escape sequence handling in "-nan" case

FURB157.py:58:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
56 | Decimal(float(" infinity ")) # Decimal(" infinity ")
57 | Decimal(float(" +infinity ")) # Decimal(" +infinity ")
58 | Decimal(float(" -infinity ")) # Decimal(" -infinity ")
| ^^^^^^^^^^^^^^^^^^^^ FURB157
59 |
60 | # Escape sequence handling in "-nan" case
|
= help: Replace with `" -infinity "`

Expand All @@ -386,3 +391,144 @@ FURB157.py:58:9: FURB157 [*] Verbose expression in `Decimal` constructor
57 57 | Decimal(float(" +infinity ")) # Decimal(" +infinity ")
58 |-Decimal(float(" -infinity ")) # Decimal(" -infinity ")
58 |+Decimal(" -infinity ") # Decimal(" -infinity ")
59 59 |
60 60 | # Escape sequence handling in "-nan" case
61 61 | # Here we do not bother respecting the original whitespace

FURB157.py:64:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
62 | # and other trivia when offering a fix.
63 | # https://github.com/astral-sh/ruff/issues/16771
64 | Decimal(float("\x2dnan"))
| ^^^^^^^^^^^^^^^^ FURB157
65 | Decimal(float("\x20\x2dnan"))
66 | Decimal(float("\x20\u002dnan"))
|
= help: Replace with `"nan"`

ℹ Safe fix
61 61 | # Here we do not bother respecting the original whitespace
62 62 | # and other trivia when offering a fix.
63 63 | # https://github.com/astral-sh/ruff/issues/16771
64 |-Decimal(float("\x2dnan"))
64 |+Decimal("nan")
65 65 | Decimal(float("\x20\x2dnan"))
66 66 | Decimal(float("\x20\u002dnan"))
67 67 | Decimal(float("\x20\U0000002dnan"))

FURB157.py:65:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
63 | # https://github.com/astral-sh/ruff/issues/16771
64 | Decimal(float("\x2dnan"))
65 | Decimal(float("\x20\x2dnan"))
| ^^^^^^^^^^^^^^^^^^^^ FURB157
66 | Decimal(float("\x20\u002dnan"))
67 | Decimal(float("\x20\U0000002dnan"))
|
= help: Replace with `"nan"`

ℹ Safe fix
62 62 | # and other trivia when offering a fix.
63 63 | # https://github.com/astral-sh/ruff/issues/16771
64 64 | Decimal(float("\x2dnan"))
65 |-Decimal(float("\x20\x2dnan"))
65 |+Decimal("nan")
66 66 | Decimal(float("\x20\u002dnan"))
67 67 | Decimal(float("\x20\U0000002dnan"))
68 68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))

FURB157.py:66:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
64 | Decimal(float("\x2dnan"))
65 | Decimal(float("\x20\x2dnan"))
66 | Decimal(float("\x20\u002dnan"))
| ^^^^^^^^^^^^^^^^^^^^^^ FURB157
67 | Decimal(float("\x20\U0000002dnan"))
68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
|
= help: Replace with `"nan"`

ℹ Safe fix
63 63 | # https://github.com/astral-sh/ruff/issues/16771
64 64 | Decimal(float("\x2dnan"))
65 65 | Decimal(float("\x20\x2dnan"))
66 |-Decimal(float("\x20\u002dnan"))
66 |+Decimal("nan")
67 67 | Decimal(float("\x20\U0000002dnan"))
68 68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
69 69 | Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))

FURB157.py:67:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
65 | Decimal(float("\x20\x2dnan"))
66 | Decimal(float("\x20\u002dnan"))
67 | Decimal(float("\x20\U0000002dnan"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB157
68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
69 | Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))
|
= help: Replace with `"nan"`

ℹ Safe fix
64 64 | Decimal(float("\x2dnan"))
65 65 | Decimal(float("\x20\x2dnan"))
66 66 | Decimal(float("\x20\u002dnan"))
67 |-Decimal(float("\x20\U0000002dnan"))
67 |+Decimal("nan")
68 68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
69 69 | Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))
70 70 | Decimal(float(" -" "nan"))

FURB157.py:68:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
66 | Decimal(float("\x20\u002dnan"))
67 | Decimal(float("\x20\U0000002dnan"))
68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB157
69 | Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))
70 | Decimal(float(" -" "nan"))
|
= help: Replace with `"nan"`

ℹ Safe fix
65 65 | Decimal(float("\x20\x2dnan"))
66 66 | Decimal(float("\x20\u002dnan"))
67 67 | Decimal(float("\x20\U0000002dnan"))
68 |-Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
68 |+Decimal("nan")
69 69 | Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))
70 70 | Decimal(float(" -" "nan"))

FURB157.py:69:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
67 | Decimal(float("\x20\U0000002dnan"))
68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
69 | Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ FURB157
70 | Decimal(float(" -" "nan"))
|
= help: Replace with `"nan"`

ℹ Safe fix
66 66 | Decimal(float("\x20\u002dnan"))
67 67 | Decimal(float("\x20\U0000002dnan"))
68 68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
69 |-Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))
69 |+Decimal("nan")
70 70 | Decimal(float(" -" "nan"))

FURB157.py:70:9: FURB157 [*] Verbose expression in `Decimal` constructor
|
68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
69 | Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))
70 | Decimal(float(" -" "nan"))
| ^^^^^^^^^^^^^^^^^^^ FURB157
|
= help: Replace with `"nan"`

ℹ Safe fix
67 67 | Decimal(float("\x20\U0000002dnan"))
68 68 | Decimal(float("\N{space}\N{hyPHen-MINus}nan"))
69 69 | Decimal(float("\x20\N{character tabulation}\N{hyphen-minus}nan"))
70 |-Decimal(float(" -" "nan"))
70 |+Decimal("nan")