From 39659f22fa6e86039faa92bf0bc5c82cf1650767 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 14 Sep 2013 22:17:39 -0700 Subject: Issue #19018: The heapq.merge() function no longer suppresses IndexError --- Lib/heapq.py | 15 ++++++++++----- Lib/test/test_heapq.py | 9 +++++++++ Misc/ACKS | 2 ++ Misc/NEWS | 3 +++ 4 files changed, 24 insertions(+), 5 deletions(-) diff --git a/Lib/heapq.py b/Lib/heapq.py index ca79db1..19037ab 100644 --- a/Lib/heapq.py +++ b/Lib/heapq.py @@ -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 diff --git a/Lib/test/test_heapq.py b/Lib/test/test_heapq.py index 73b88f0..c4de593 100644 --- a/Lib/test/test_heapq.py +++ b/Lib/test/test_heapq.py @@ -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 diff --git a/Misc/ACKS b/Misc/ACKS index 6f2b3a7..6048ed8 100644 --- a/Misc/ACKS +++ b/Misc/ACKS @@ -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 diff --git a/Misc/NEWS b/Misc/NEWS index e025df6..c4698f4 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -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. -- cgit v0.12