# [Python-checkins] cpython: PEP 479: Don't let StopIteration bubble out of calls to next() inside a

raymond.hettinger python-checkins at python.org
Sun Nov 23 06:56:38 CET 2014

https://hg.python.org/cpython/rev/9eb0d0eb0992
changeset:   93542:9eb0d0eb0992
parent:      93540:23f8a511050a
user:        Raymond Hettinger <python at rcn.com>
date:        Sat Nov 22 21:56:23 2014 -0800
summary:
PEP 479:  Don't let StopIteration bubble out of calls to next() inside a generator.

files:
Doc/library/itertools.rst    |  20 ++++++++++++++++----
Lib/xml/etree/ElementPath.py |  15 ++++++++++++---
2 files changed, 28 insertions(+), 7 deletions(-)

diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
--- a/Doc/library/itertools.rst
+++ b/Doc/library/itertools.rst
@@ -104,7 +104,10 @@
# accumulate([1,2,3,4,5]) --> 1 3 6 10 15
# accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
it = iter(iterable)
-            total = next(it)
+            try:
+                total = next(it)
+            except StopIteration:
+                return
yield total
for element in it:
total = func(total, element)
@@ -405,7 +408,10 @@
def _grouper(self, tgtkey):
while self.currkey == tgtkey:
yield self.currvalue
-                  self.currvalue = next(self.it)    # Exit on StopIteration
+                  try:
+                      self.currvalue = next(self.it)
+                  except StopIteration:
+                      return
self.currkey = self.keyfunc(self.currvalue)

@@ -429,7 +435,10 @@
# islice('ABCDEFG', 0, None, 2) --> A C E G
s = slice(*args)
it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1))
-          nexti = next(it)
+          try:
+              nexti = next(it)
+          except StopIteration:
+              return
for i, element in enumerate(iterable):
if i == nexti:
yield element
@@ -587,7 +596,10 @@
def gen(mydeque):
while True:
if not mydeque:             # when the local deque is empty
-                        newval = next(it)       # fetch a new value and
+                        try:
+                            newval = next(it)   # fetch a new value and
+                        except StopIteration:
+                            return
for d in deques:        # load it to all the deques
d.append(newval)
yield mydeque.popleft()
diff --git a/Lib/xml/etree/ElementPath.py b/Lib/xml/etree/ElementPath.py
--- a/Lib/xml/etree/ElementPath.py
+++ b/Lib/xml/etree/ElementPath.py
@@ -114,7 +114,10 @@
return select

def prepare_descendant(next, token):
-    token = next()
+    try:
+        token = next()
+    except StopIteration:
+        return
if token[0] == "*":
tag = "*"
elif not token[0]:
@@ -148,7 +151,10 @@
signature = []
predicate = []
while 1:
-        token = next()
+        try:
+            token = next()
+        except StopIteration:
+            return
if token[0] == "]":
break
if token[0] and token[0][:1] in "'\"":
@@ -261,7 +267,10 @@
if path[:1] == "/":
raise SyntaxError("cannot use absolute path on element")
next = iter(xpath_tokenizer(path, namespaces)).__next__
-        token = next()
+        try:
+            token = next()
+        except StopIteration:
+            return
selector = []
while 1:
try:

--
Repository URL: https://hg.python.org/cpython