Fix generator not being popped from stack on 'yield from'

This commit is contained in:
K. Lange 2021-03-31 19:06:33 +09:00
parent d307de84c0
commit f4ea799d42
3 changed files with 70 additions and 1 deletions

View File

@ -2456,12 +2456,19 @@ _finishReturn: (void)0;
krk_push(krk_peek(0));
krk_push(krk_callSimple(krk_peek(0),0,0));
}
if (!krk_valuesSame(krk_peek(0), krk_peek(1))) break;
if (!krk_valuesSame(krk_peek(0), krk_peek(1))) {
/* Value to yield */
break;
}
krk_pop();
/* Does it have a final value? */
method = krk_valueGetAttribute_default(krk_peek(0), "__finish__", NONE_VAL());
if (!IS_NONE(method)) {
krk_push(method);
krk_swap(1);
krk_pop();
krk_push(krk_callSimple(krk_peek(0),0,0));
} else {
krk_pop();

View File

@ -0,0 +1,47 @@
if not hasattr(__builtins__,'StopIteration'):
class StopIteration(Exception):
pass
__builtins__.StopIteration = StopIteration
class Awaiter:
def __iter__(self):
yield " Awaiter(): awaitable returns an iterator"
return "(all done)"
def foo(i,result=None):
print(' foo(): hi')
result = yield from i()
print(' Awaiting result 1:', result)
result = yield from Awaiter()
print(' Awaiting result 2:', result)
result = yield from i()
print(' Awaiting result 3:', result)
print(' foo(): bi')
return "done"
def bar():
print(" bar(): hello, there, I'm an async function")
return 42
yield 0xdeadbeef
def run(coro, scheduled=None, next=None, result=None):
# Okay, let's see.
scheduled = [coro]
print("Starting run loop.")
while scheduled:
print(" Popping from scheduled list.")
next = scheduled.pop(0) # Yes, that's slow, I know.
try:
print(" Calling",type(next))
result = next.send(None)
if result == next:
raise StopIteration(result.__finish__())
print(" Returned with",result)
scheduled.append(next)
except StopIteration as e:
# Stop iteration value should be return value from foo()
print('Exception:', type(e), e)
print('Done with run loop.')
run(foo(bar))

View File

@ -0,0 +1,15 @@
Starting run loop.
Popping from scheduled list.
Calling <class 'generator'>
foo(): hi
bar(): hello, there, I'm an async function
Awaiting result 1: 42
Returned with Awaiter(): awaitable returns an iterator
Popping from scheduled list.
Calling <class 'generator'>
Awaiting result 2: (all done)
bar(): hello, there, I'm an async function
Awaiting result 3: 42
foo(): bi
Exception: <class '__main__.StopIteration'> done
Done with run loop.