Skip to content

Fix FURB108 false positive when operands depend on short-circuit evaluation#364

Closed
worksbyfriday wants to merge 1 commit into
dosisod:masterfrom
worksbyfriday:fix-furb108-lazy-eval
Closed

Fix FURB108 false positive when operands depend on short-circuit evaluation#364
worksbyfriday wants to merge 1 commit into
dosisod:masterfrom
worksbyfriday:fix-furb108-lazy-eval

Conversation

@worksbyfriday
Copy link
Copy Markdown
Contributor

Summary

Fixes #350.

When comparing values with or, the right-hand operand may depend on short-circuit evaluation for safety. For example:

cutoff = bisect(events, threshold)
if cutoff == 0 or events[cutoff - 1] == 0:
    pass

FURB108 previously suggested 0 in (cutoff, events[cutoff - 1]), which eagerly evaluates both operands and can raise IndexError when cutoff == 0.

This PR skips the FURB108 suggestion when non-common operands contain subscript expressions (IndexExpr) or function calls (CallExpr), as these may raise exceptions or have side effects when eagerly evaluated. Simple comparisons like x == "abc" or x == "def" continue to be flagged normally.

This aligns with the "only allow basic comparisons" approach from the maintainer's comment on #350, as a conservative first step toward better safe/unsafe detection.

Test plan

  • Added test cases to test/data/err_108.py for subscript and call operands
  • Verified original bug report case (cutoff == 0 or events[cutoff - 1] == 0) no longer triggers
  • Verified simple comparisons still trigger as expected
  • All pre-existing tests pass (only pre-existing err_175 failure unrelated to this change)

…valuation

When comparing values with `or`, the right-hand operand may depend on
short-circuit evaluation for safety (e.g., `i == 0 or nums[i-1] == 0`).
Suggesting `0 in (i, nums[i-1])` would eagerly evaluate both operands,
potentially causing IndexError or other exceptions.

Skip the FURB108 suggestion when non-common operands contain subscript
expressions (IndexExpr) or function calls (CallExpr), as these may
raise exceptions or have side effects when eagerly evaluated.

Fixes dosisod#350

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@worksbyfriday
Copy link
Copy Markdown
Contributor Author

Superseded by #369 which uses a cleaner approach: positive allowlist of safe expression types (_is_simple_expr) rather than a visitor-based blocklist, and reuses get_common_expr_positions from common.py instead of manually re-implementing common-operand detection.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unsafe FURB108 when lazy evaluation is required

1 participant