Skip to content

Conversation

@danparizher
Copy link
Contributor

@danparizher danparizher commented Jul 4, 2025

Summary

Fixes #19076

An attempt at fixing #19076 where the rule could change program behavior by incorrectly converting from_float/from_decimal method calls to constructor calls.

The fix implements argument validation using Ruff's existing type inference system (ResolvedPythonType, typing::is_int, typing::is_float) to determine when conversions are actually safe, adds logic to detect invalid method calls (wrong argument counts, incorrect keyword names) and suppress fixes for them, and changes the default fix applicability from Safe to Unsafe with safe fixes only offered when the argument type is known to be compatible and no problematic keywords are used.

One uncertainty is whether the type inference catches all possible edge cases in complex codebases, but the new approach is significantly more conservative and safer than the previous implementation.

Test Plan

I updated the existing test fixtures with edge cases from the issue and manually verified behavior with temporary test files for valid/unsafe/invalid scenarios.

@github-actions
Copy link
Contributor

github-actions bot commented Jul 4, 2025

ruff-ecosystem results

Linter (stable)

✅ ecosystem check detected no linter changes.

Linter (preview)

✅ ecosystem check detected no linter changes.

@MichaReiser MichaReiser requested a review from ntBre July 14, 2025 09:19
@ntBre ntBre added bug Something isn't working fixes Related to suggested fixes for violations labels Jul 14, 2025
Copy link
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, this looks good to me. I just had some suggestions for simplifying the code a bit.

}
MethodName::FromDecimal => {
// from_decimal(dec) - should have exactly one positional argument or 'dec' keyword
if call.arguments.args.len() == 1 && call.arguments.keywords.is_empty() {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same as above, if it works above.

Comment on lines 338 to 340
// Must be a call to the `float` builtin.
if !checker.semantic().match_builtin_expr(func, "float") {
return None;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: I'd probably put this right after the let-else checking that it's a Call. I'm not sure which of these checks is most expensive, but that makes sense logically at least.

@danparizher danparizher requested a review from ntBre July 14, 2025 20:26
Copy link
Contributor

@ntBre ntBre left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Just a few more slight simplifications.

danparizher and others added 6 commits July 16, 2025 11:07
…at.rs

Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
…at.rs

Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
…at.rs

Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
…at.rs

Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
…at.rs

Co-authored-by: Brent Westbrook <36778786+ntBre@users.noreply.github.com>
@ntBre ntBre enabled auto-merge (squash) July 16, 2025 15:35
@ntBre ntBre merged commit 291699b into astral-sh:main Jul 16, 2025
34 checks passed
@danparizher danparizher deleted the fix-19076 branch July 16, 2025 15:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working fixes Related to suggested fixes for violations

Projects

None yet

Development

Successfully merging this pull request may close these issues.

FURB164 fix should validate arguments and should usually be marked unsafe

2 participants