gh-107208: Fix iter_index() recipe to not swallow exceptions (gh-108835)
gh-107208: iter_index now supports "stop" and no longer swallows ValueError
This commit is contained in:
parent
a52213bf83
commit
f373c6b948
@ -865,26 +865,22 @@ which incur interpreter overhead.
|
|||||||
# first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
|
# first_true([a,b], x, f) --> a if f(a) else b if f(b) else x
|
||||||
return next(filter(pred, iterable), default)
|
return next(filter(pred, iterable), default)
|
||||||
|
|
||||||
def iter_index(iterable, value, start=0):
|
def iter_index(iterable, value, start=0, stop=None):
|
||||||
"Return indices where a value occurs in a sequence or iterable."
|
"Return indices where a value occurs in a sequence or iterable."
|
||||||
# iter_index('AABCADEAF', 'A') --> 0 1 4 7
|
# iter_index('AABCADEAF', 'A') --> 0 1 4 7
|
||||||
try:
|
seq_index = getattr(iterable, 'index', None)
|
||||||
seq_index = iterable.index
|
if seq_index is None:
|
||||||
except AttributeError:
|
|
||||||
# Slow path for general iterables
|
# Slow path for general iterables
|
||||||
it = islice(iterable, start, None)
|
it = islice(iterable, start, stop)
|
||||||
i = start - 1
|
for i, element in enumerate(it, start):
|
||||||
try:
|
if element is value or element == value:
|
||||||
while True:
|
yield i
|
||||||
yield (i := i + operator.indexOf(it, value) + 1)
|
|
||||||
except ValueError:
|
|
||||||
pass
|
|
||||||
else:
|
else:
|
||||||
# Fast path for sequences
|
# Fast path for sequences
|
||||||
i = start - 1
|
i = start - 1
|
||||||
try:
|
try:
|
||||||
while True:
|
while True:
|
||||||
yield (i := seq_index(value, i+1))
|
yield (i := seq_index(value, i+1, stop))
|
||||||
except ValueError:
|
except ValueError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -1331,6 +1327,21 @@ The following recipes have a more mathematical flavor:
|
|||||||
[]
|
[]
|
||||||
>>> list(iter_index(iter('AABCADEAF'), 'A', 10))
|
>>> list(iter_index(iter('AABCADEAF'), 'A', 10))
|
||||||
[]
|
[]
|
||||||
|
>>> list(iter_index('AABCADEAF', 'A', 1, 7))
|
||||||
|
[1, 4]
|
||||||
|
>>> list(iter_index(iter('AABCADEAF'), 'A', 1, 7))
|
||||||
|
[1, 4]
|
||||||
|
>>> # Verify that ValueErrors not swallowed (gh-107208)
|
||||||
|
>>> def assert_no_value(iterable, forbidden_value):
|
||||||
|
... for item in iterable:
|
||||||
|
... if item == forbidden_value:
|
||||||
|
... raise ValueError
|
||||||
|
... yield item
|
||||||
|
...
|
||||||
|
>>> list(iter_index(assert_no_value('AABCADEAF', 'B'), 'A'))
|
||||||
|
Traceback (most recent call last):
|
||||||
|
...
|
||||||
|
ValueError
|
||||||
|
|
||||||
>>> list(sieve(30))
|
>>> list(sieve(30))
|
||||||
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
|
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user