Kaydet (Commit) 828d932a authored tarafından Raymond Hettinger's avatar Raymond Hettinger

PEP 479: Don't let StopIteration bubble out of calls to next() inside a generator.

üst 1bf47293
...@@ -104,7 +104,10 @@ loops that truncate the stream. ...@@ -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]) --> 1 3 6 10 15
# accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120 # accumulate([1,2,3,4,5], operator.mul) --> 1 2 6 24 120
it = iter(iterable) it = iter(iterable)
try:
total = next(it) total = next(it)
except StopIteration:
return
yield total yield total
for element in it: for element in it:
total = func(total, element) total = func(total, element)
...@@ -405,7 +408,10 @@ loops that truncate the stream. ...@@ -405,7 +408,10 @@ loops that truncate the stream.
def _grouper(self, tgtkey): def _grouper(self, tgtkey):
while self.currkey == tgtkey: while self.currkey == tgtkey:
yield self.currvalue 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) self.currkey = self.keyfunc(self.currvalue)
...@@ -429,7 +435,10 @@ loops that truncate the stream. ...@@ -429,7 +435,10 @@ loops that truncate the stream.
# islice('ABCDEFG', 0, None, 2) --> A C E G # islice('ABCDEFG', 0, None, 2) --> A C E G
s = slice(*args) s = slice(*args)
it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1)) it = iter(range(s.start or 0, s.stop or sys.maxsize, s.step or 1))
try:
nexti = next(it) nexti = next(it)
except StopIteration:
return
for i, element in enumerate(iterable): for i, element in enumerate(iterable):
if i == nexti: if i == nexti:
yield element yield element
...@@ -587,7 +596,10 @@ loops that truncate the stream. ...@@ -587,7 +596,10 @@ loops that truncate the stream.
def gen(mydeque): def gen(mydeque):
while True: while True:
if not mydeque: # when the local deque is empty if not mydeque: # when the local deque is empty
try:
newval = next(it) # fetch a new value and newval = next(it) # fetch a new value and
except StopIteration:
return
for d in deques: # load it to all the deques for d in deques: # load it to all the deques
d.append(newval) d.append(newval)
yield mydeque.popleft() yield mydeque.popleft()
......
...@@ -114,7 +114,10 @@ def prepare_self(next, token): ...@@ -114,7 +114,10 @@ def prepare_self(next, token):
return select return select
def prepare_descendant(next, token): def prepare_descendant(next, token):
try:
token = next() token = next()
except StopIteration:
return
if token[0] == "*": if token[0] == "*":
tag = "*" tag = "*"
elif not token[0]: elif not token[0]:
...@@ -148,7 +151,10 @@ def prepare_predicate(next, token): ...@@ -148,7 +151,10 @@ def prepare_predicate(next, token):
signature = [] signature = []
predicate = [] predicate = []
while 1: while 1:
try:
token = next() token = next()
except StopIteration:
return
if token[0] == "]": if token[0] == "]":
break break
if token[0] and token[0][:1] in "'\"": if token[0] and token[0][:1] in "'\"":
...@@ -261,7 +267,10 @@ def iterfind(elem, path, namespaces=None): ...@@ -261,7 +267,10 @@ def iterfind(elem, path, namespaces=None):
if path[:1] == "/": if path[:1] == "/":
raise SyntaxError("cannot use absolute path on element") raise SyntaxError("cannot use absolute path on element")
next = iter(xpath_tokenizer(path, namespaces)).__next__ next = iter(xpath_tokenizer(path, namespaces)).__next__
try:
token = next() token = next()
except StopIteration:
return
selector = [] selector = []
while 1: while 1:
try: try:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment