From: Raymond Hettinger Date: Sun, 15 Sep 2013 05:17:39 +0000 (-0700) Subject: Issue #19018: The heapq.merge() function no longer suppresses IndexError X-Git-Tag: v2.7.6rc1~152 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=39659f22fa6e86039faa92bf0bc5c82cf1650767;p=python Issue #19018: The heapq.merge() function no longer suppresses IndexError --- diff --git a/Lib/heapq.py b/Lib/heapq.py index ca79db1529..19037ab129 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 73b88f09b9..c4de593bb8 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 6f2b3a76fd..6048ed8dd7 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 e025df630d..c4698f4d7f 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.