Today I was debugging a strange issue. The program is complex, but I have simplified the part in question to just few lines reproducing the strange behaviour.
In the example I test a random generator three times in a row. If all three tests return True, the test is completed. If not, the test must be repeated from the beginning.
Function func1
works OK. Function func2
with any()
should be equivalent to func1
, but it isn't. It does not work, it produces an error. The func3
is broken as well, this one is an infinite busy loop.
Where is the problem? It is legal to use yield from
in other ways than value = yield from ...
? I did not found anything in the docs (so far):
When yield from is used, it treats the supplied expression as a subiterator. All values produced by that subiterator are passed directly to the caller of the current generator’s methods.
# Python 3.3 or newer
import random
def yield_random():
if random.choice((True, False)):
yield "OK"
return True
return False
def func1():
# only this function works fine
ok3 = False
while not ok3:
for i in range(3):
ok1 = yield from yield_random()
if not ok1:
print("-- not ok")
break
else:
print("All 3 ok !")
ok3 = True
def func2():
# does not work
ok3 = False
while not ok3:
ok3 = all((yield from yield_random()) for i in range(3))
print("All 3 ok !")
def func3():
# does not work
while any(not (yield from yield_random()) for i in range(3)):
print("-- not ok")
print("All 3 ok !")
for x in func1():
print("got:", x)