From 828d932a2c4da5eb7c05e85dfe51f5f6db68084d Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Sat, 22 Nov 2014 21:56:23 -0800 Subject: PEP 479: Don't let StopIteration bubble out of calls to next() inside a generator. --- 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 index c5ba2eb..8c7592d 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -104,7 +104,10 @@ loops that truncate the stream. # 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 @@ loops that truncate the stream. 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 @@ loops that truncate the stream. # 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 @@ loops that truncate the stream. 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 index d914ddb..4b4d8cf 100644 --- a/Lib/xml/etree/ElementPath.py +++ b/Lib/xml/etree/ElementPath.py @@ -114,7 +114,10 @@ def prepare_self(next, token): 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 @@ def prepare_predicate(next, token): 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 @@ def iterfind(elem, path, namespaces=None): 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: -- cgit v0.12