py3: catch StopIteration from next() in generatorset
authorMartin von Zweigbergk <martinvonz@google.com>
Tue, 20 Jun 2017 14:00:41 -0700
changeset 38279 27ba0d8dc26cac137430618f327969cb83c4d9f4
parent 38278 d39639fb840e110b54faecb33258efe7513f69be
child 38280 41b081ac2145d88ba1fe494630ce69652f016078
push id534
push usergszorc@mozilla.com
push dateSat, 24 Jun 2017 07:33:46 +0000
py3: catch StopIteration from next() in generatorset IIUC, letting the StopIteration through would not cause any bugs, but not doing it makes the test-py3-commands.t pass. I have also diligently gone through all uses of next() in our code base. They either: * are not called from a generator * pass a default value to next() * catch StopException * work on infinite iterators * request a fixed number of items that matches the generated number * are about batching in wireproto which I didn't quite follow I'd appreciate if Augie or someone else could take a look at the wireproto batching and convince themselves that the next(batchable) calls there will not raise a StopIteration.
mercurial/smartset.py
--- a/mercurial/smartset.py
+++ b/mercurial/smartset.py
@@ -866,17 +866,20 @@ class generatorset(abstractsmartset):
         nextgen = self._consumegen()
         _len, _next = len, next # cache global lookup
         def gen():
             i = 0
             while True:
                 if i < _len(genlist):
                     yield genlist[i]
                 else:
-                    yield _next(nextgen)
+                    try:
+                        yield _next(nextgen)
+                    except StopIteration:
+                        return
                 i += 1
         return gen()
 
     def _consumegen(self):
         cache = self._cache
         genlist = self._genlist.append
         for item in self._gen:
             cache[item] = True