Commit 39659f22 authored by Raymond Hettinger's avatar Raymond Hettinger

Issue #19018: The heapq.merge() function no longer suppresses IndexError

parent bf7e8656
......@@ -366,6 +366,7 @@ def merge(*iterables):
'''
_heappop, _heapreplace, _StopIteration = heappop, heapreplace, StopIteration
_len = len
h = []
h_append = h.append
......@@ -377,17 +378,21 @@ def merge(*iterables):
pass
heapify(h)
while 1:
while _len(h) > 1:
try:
while 1:
v, itnum, next = s = h[0] # raises IndexError when h is empty
while True:
v, itnum, next = s = h[0]
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
if h:
# fast case when only a single iterator remains
v, itnum, next = h[0]
yield v
for v in next.__self__:
yield v
# Extend the implementations of nsmallest and nlargest to use a key= argument
_nsmallest = nsmallest
......
......@@ -158,6 +158,15 @@ class TestHeap(TestCase):
self.assertEqual(sorted(chain(*inputs)), list(self.module.merge(*inputs)))
self.assertEqual(list(self.module.merge()), [])
def test_merge_does_not_suppress_index_error(self):
# Issue 19018: Heapq.merge suppresses IndexError from user generator
def iterable():
s = list(range(10))
for i in range(20):
yield s[i] # IndexError when i > 10
with self.assertRaises(IndexError):
list(self.module.merge(iterable(), iterable()))
def test_merge_stability(self):
class Int(int):
pass
......
......@@ -110,6 +110,7 @@ Paul Boddie
Matthew Boedicker
Robin Boerdijk
David Bolen
Wouter Bolsterlee
Gawain Bolton
Gregory Bond
Jurjen Bos
......@@ -313,6 +314,7 @@ Nils Fischbeck
Frederik Fix
Matt Fleming
Hernán Martínez Foffani
Artem Fokin
Arnaud Fontaine
Michael Foord
Amaury Forgeot d'Arc
......
......@@ -35,6 +35,9 @@ Library
- Issue #17324: Fix http.server's request handling case on trailing '/'. Patch
contributed by Vajrasky Kok.
- Issue #19018: The heapq.merge() function no longer suppresses IndexError
in the underlying iterables.
- Issue #18784: The uuid module no more attempts to load libc via ctypes.CDLL,
if all necessary functions are already found in libuuid.
Patch by Evgeny Sologubov.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment