I am confused by interaction between Python-2 iterators and exceptions.
Specifically, given the following code:
def gen_int():
if not hasattr(gen_int,"x"):
gen_int.x = 0
while True:
gen_int.x += 1
yield gen_int.x
def gen_odd():
for x in gen_int():
if x % 2:
yield x
else:
raise ValueError("gen_odd",x)
(please assume the above are out of my control!), I write
def gen_all():
it = gen_odd()
while True:
try:
yield it.next()
except ValueError as exn:
print exn
func_name, x = exn
assert func_name == "gen_odd"
yield x
in the hope of recovering the full stream generated by gen_int.
However, the iteration stops after the first exception:
def gen_test(top):
for x in gen_all():
print x
if x > top:
break
Here are 3 invocations:
>>> gen_test(20)
1
('gen_odd', 2)
2
>>> gen_test(20)
3
('gen_odd', 4)
4
>>> gen_test(20)
5
('gen_odd', 6)
6
The question is:
How do I modify gen_all so that gen_test will print all ints below top?
PS. apparently, the exception in gen_odd works as return - it marks the iterator as exhausted. is this really the case? is there a workaround?
raiseaValueErrorin the first place ingen_odd?gen_oddis out of my controlgen_intis a strange generator. It saves global state that each new instance uses. The other 99.99% of generators in the wild don't work this way.