Fix generator not being popped from stack on 'yield from'
This commit is contained in:
parent
d307de84c0
commit
f4ea799d42
9
src/vm.c
9
src/vm.c
@ -2456,12 +2456,19 @@ _finishReturn: (void)0;
|
|||||||
krk_push(krk_peek(0));
|
krk_push(krk_peek(0));
|
||||||
krk_push(krk_callSimple(krk_peek(0),0,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? */
|
/* Does it have a final value? */
|
||||||
method = krk_valueGetAttribute_default(krk_peek(0), "__finish__", NONE_VAL());
|
method = krk_valueGetAttribute_default(krk_peek(0), "__finish__", NONE_VAL());
|
||||||
if (!IS_NONE(method)) {
|
if (!IS_NONE(method)) {
|
||||||
krk_push(method);
|
krk_push(method);
|
||||||
|
krk_swap(1);
|
||||||
|
krk_pop();
|
||||||
krk_push(krk_callSimple(krk_peek(0),0,0));
|
krk_push(krk_callSimple(krk_peek(0),0,0));
|
||||||
} else {
|
} else {
|
||||||
krk_pop();
|
krk_pop();
|
||||||
|
47
test/testYieldFromEventLoop.krk
Normal file
47
test/testYieldFromEventLoop.krk
Normal 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))
|
15
test/testYieldFromEventLoop.krk.expect
Normal file
15
test/testYieldFromEventLoop.krk.expect
Normal 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.
|
Loading…
Reference in New Issue
Block a user