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 <rep...@bugs.python.org> <http://bugs.python.org/issue19018> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com