[refurb] Fix false negative for underscores before sign in Decimal constructor (FURB157)
#21190
+76
−6
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Summary
Fixes FURB157 false negative where
Decimal("_-1")was not flagged as verbose when underscores precede the sign character. This fixes #21186.Problem Analysis
The
verbose-decimal-constructor(FURB157) rule failed to detect verboseDecimalconstructors when the sign character (+or-) was preceded by underscores. For example,Decimal("_-1")was not flagged, even though it can be simplified toDecimal(-1).The bug occurred because the rule checked for the sign character at the start of the string before stripping leading underscores. According to Python's
Decimalparser behavior (as documented in CPython's_pydecimal.py), underscores are removed before parsing the sign. The rule's logic didn't match this behavior, causing a false negative for cases like"_-1"where the underscore came before the sign.This was a regression introduced in version 0.14.3, as these cases were correctly flagged in version 0.14.2.
Approach
The fix updates the sign extraction logic to:
This ensures that cases like
Decimal("_-1"),Decimal("_+1"), andDecimal("_-1_000")are correctly detected and flagged. The normalization logic was also updated to use the string after the sign (without underscores) to avoid double signs in the replacement output.