Has your issue already been fixed?
The Bug
The following code:
from bisect import bisect
from collections.abc import Sequence
def f(events: Sequence[int], threshold: int) -> None:
cutoff = bisect(events, threshold)
if cutoff == 0 or events[cutoff - 1] == 0:
pass
Emits the following error:
$ refurb file.py
file.py:6:8 [FURB108]: Replace `x == y or z == y` with `y in (x, z)`
However, this suggestion is unsafe because if events is empty, cutoff - 1 is not a valid index. With or this is fine, as lazy evaluation halts after it finds that cutoff == 0 is true, but the tuple notation always evaluates both expressions.
I don't expect Refurb to understand the details of bisect(), but it could perhaps detect that cutoff is checked in the left hand side and used in the right hand side of or and as a precaution not issue FURB108.
I'm also not sure the suggested change (de-duplicating the 0) would actually make the code more elegant, but that is subjective, while the unsafe behavior is an objective problem.
Version Info
Refurb: v2.0.0
Mypy: v1.13.0
Python Version
Python 3.12.7
Config File
Extra Info
The double check:
from bisect import bisect
from collections.abc import Sequence
def f1(events: Sequence[int], threshold: int) -> None:
cutoff = bisect(events, threshold)
if cutoff == 0 or events[cutoff - 1] == 0:
pass
def f2(events: Sequence[int], threshold: int) -> None:
cutoff = bisect(events, threshold)
if 0 in (cutoff, events[cutoff - 1]):
pass
f1([], 123)
f2([], 123)
Here, the f1() call returns, while the f2() call raises IndexError.
Has your issue already been fixed?
masterbranch? See the docs for instructions on how to setup a local build of Refurb.The Bug
The following code:
Emits the following error:
However, this suggestion is unsafe because if
eventsis empty,cutoff - 1is not a valid index. Withorthis is fine, as lazy evaluation halts after it finds thatcutoff == 0is true, but the tuple notation always evaluates both expressions.I don't expect Refurb to understand the details of
bisect(), but it could perhaps detect thatcutoffis checked in the left hand side and used in the right hand side oforand as a precaution not issue FURB108.I'm also not sure the suggested change (de-duplicating the
0) would actually make the code more elegant, but that is subjective, while the unsafe behavior is an objective problem.Version Info
Python Version
Python 3.12.7
Config File
# N/AExtra Info
The double check:
Here, the
f1()call returns, while thef2()call raisesIndexError.