8000 py/runtime: Fix PEP479 behaviour throwing StopIteration into yield from. · jimmo/micropython@809d89c · GitHub
[go: up one dir, main page]

Skip to content

Commit 809d89c

Browse files
committed
py/runtime: Fix PEP479 behaviour throwing StopIteration into yield from.
Commit 3f6ffe0 implemented PEP479 but did not catch the case fixed in this commit. Found by coverage analysis, that the VM had uncovered code.
1 parent 82c494a commit 809d89c

File tree

4 files changed

+21
-10
lines changed

4 files changed

+21
-10
lines changed

py/runtime.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1319,7 +1319,12 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
13191319
// will be propagated up. This behavior is approved by test_pep380.py
13201320
// test_delegation_of_close_to_non_generator(),
13211321
// test_delegating_throw_to_non_generator()
1322-
*ret_val = mp_make_raise_obj(throw_value);
1322+
if (mp_obj_exception_match(throw_value, MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
1323+
// PEP479: if StopIteration is raised inside a generator it is replaced with RuntimeError
1324+
*ret_val = mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator raised StopIteration");
1325+
} else {
1326+
*ret_val = mp_make_raise_obj(throw_value);
1327+
}
13231328
return MP_VM_RETURN_EXCEPTION;
13241329
}
13251330
}

py/vm.c

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1266,17 +1266,10 @@ unwind_jump:;
12661266
DISPATCH();
12671267
} else {
12681268
assert(ret_kind == MP_VM_RETURN_EXCEPTION);
1269+
assert(!EXC_MATCH(ret_value, MP_OBJ_FROM_PTR(&mp_type_StopIteration)));
12691270
// Pop exhausted gen
12701271
sp--;
1271-
if (EXC_MATCH(ret_value, MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
1272-
PUSH(mp_obj_exception_get_value(ret_value));
1273-
// If we injected GeneratorExit downstream, then even
1274-
// if it was swallowed, we re-raise GeneratorExit
1275-
GENERATOR_EXIT_IF_NEEDED(t_exc);
1276-
DISPATCH();
1277-
} else {
1278-
RAISE(ret_value);
1279-
}
1272+
RAISE(ret_value);
12801273
}
12811274
}
12821275

tests/basics/generator_pep479.py

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,14 @@ def gen():
2727
g.throw(StopIteration)
2828
except RuntimeError:
2929
print('RuntimeError')
30+
31+
# throwing a StopIteration through yield from, will be converted to a RuntimeError
32+
def gen():
33+
yield from range(2)
34+
print('should not get here')
35+
g = gen()
36+
print(next(g))
37+
try:
38+
g.throw(StopIteration)
39+
except RuntimeError:
40+
print('RuntimeError')

tests/basics/generator_pep479.py.exp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ RuntimeError
33
StopIteration
44
1
55
RuntimeError
6+
0
7+
RuntimeError

0 commit comments

Comments
 (0)
0