diff options
author | Raymond Hettinger <python@rcn.com> | 2013-09-15 05:17:39 (GMT) |
---|---|---|
committer | Raymond Hettinger <python@rcn.com> | 2013-09-15 05:17:39 (GMT) |
commit | 39659f22fa6e86039faa92bf0bc5c82cf1650767 (patch) | |
tree | 4a28279e211b08d9af612b05d099e418ad14b6f9 /Lib | |
parent | bf7e8656b56514fe2f65bef563b663dd163ccab5 (diff) | |
download | cpython-39659f22fa6e86039faa92bf0bc5c82cf1650767.zip cpython-39659f22fa6e86039faa92bf0bc5c82cf1650767.tar.gz cpython-39659f22fa6e86039faa92bf0bc5c82cf1650767.tar.bz2 |
Issue #19018: The heapq.merge() function no longer suppresses IndexError
Diffstat (limited to 'Lib')
-rw-r--r-- | Lib/heapq.py | 15 | ||||
-rw-r--r-- | Lib/test/test_heapq.py | 9 |
2 files changed, 19 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 |