[issue19018] Heapq.merge suppreses IndexError from user generator
Artem Fokin
report at bugs.python.org
Sat Sep 14 21:16:38 CEST 2013
New submission from Artem Fokin:
Suppose we have the following code:
from heapq import merge
def iterable():
lst = range(10)
for i in xrange(20):
yield lst[i]
it1, it2= iterable(), iterable()
print list(merge(it1, it2)) # no IndexError
#output is: [0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9]
The reason is that in heapq.merge http://hg.python.org/cpython/file/7c18b799841e/Lib/heapq.py#l372 try-catch clause for IndexError is too broad
while 1:
try:
while 1:
v, itnum, next = s = h[0] # raises IndexError when h is empty
yield v
s[0] = next() # raises StopIteration when exhausted,
_heapreplace(h, s) # restore heap condition
except _StopIteration:
_heappop(h) # remove empty iterator
except IndexError:
return
s[0] = next() also may raise different kinds of exceptions including IndexError which will be silently suppressed.
For example, this loop can be rewritten as
while 1:
try:
while 1:
try:
v, itnum, next = s = h[0] # raises IndexError when h is empty
except IndexError:
return
yield v
s[0] = next() # raises StopIteration when exhausted,
_heapreplace(h, s) # restore heap condition
except _StopIteration:
_heappop(h) # remove empty iterator
----------
components: Library (Lib)
messages: 197726
nosy: afn
priority: normal
severity: normal
status: open
title: Heapq.merge suppreses IndexError from user generator
type: behavior
versions: 3rd party, Python 2.6, Python 2.7, Python 3.1, Python 3.2, Python 3.3, Python 3.4, Python 3.5
_______________________________________
Python tracker <report at bugs.python.org>
<http://bugs.python.org/issue19018>
_______________________________________
More information about the Python-bugs-list
mailing list