From 0c9d4523705c0b7f156e92611001dfb3ea26424a Mon Sep 17 00:00:00 2001 From: Damien George Date: Fri, 28 Sep 2018 11:35:37 +1000 Subject: [PATCH] py/vm: Fix case of throwing GeneratorExit type into yield-from. mp_make_raise_obj must be used to convert a possible exception type to an instance object, otherwise the VM may raise a non-exception object. An existing test is adjusted to test this case, with the original test already moved to generator_throw.py. --- py/vm.c | 2 +- tests/basics/gen_yield_from_throw2.py | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/py/vm.c b/py/vm.c index a7c9da0ce2..8da40c9b68 100644 --- a/py/vm.c +++ b/py/vm.c @@ -1152,7 +1152,7 @@ yield: MARK_EXC_IP_SELECTIVE(); //#define EXC_MATCH(exc, type) MP_OBJ_IS_TYPE(exc, type) #define EXC_MATCH(exc, type) mp_obj_exception_match(exc, type) -#define GENERATOR_EXIT_IF_NEEDED(t) if (t != MP_OBJ_NULL && EXC_MATCH(t, MP_OBJ_FROM_PTR(&mp_type_GeneratorExit))) { RAISE(t); } +#define GENERATOR_EXIT_IF_NEEDED(t) if (t != MP_OBJ_NULL && EXC_MATCH(t, MP_OBJ_FROM_PTR(&mp_type_GeneratorExit))) { mp_obj_t raise_t = mp_make_raise_obj(t); RAISE(raise_t); } mp_vm_return_kind_t ret_kind; mp_obj_t send_value = POP(); mp_obj_t t_exc = MP_OBJ_NULL; diff --git a/tests/basics/gen_yield_from_throw2.py b/tests/basics/gen_yield_from_throw2.py index 0abfdd8cc3..6b59a7835a 100644 --- a/tests/basics/gen_yield_from_throw2.py +++ b/tests/basics/gen_yield_from_throw2.py @@ -1,18 +1,24 @@ -# generator ignores a thrown GeneratorExit (this is allowed) +# outer generator ignores a thrown GeneratorExit (this is allowed) def gen(): try: yield 123 except GeneratorExit: print('GeneratorExit') - yield 456 - + +def gen2(): + try: + yield from gen() + except GeneratorExit: + print('GeneratorExit outer') + yield 789 + # thrown a class -g = gen() +g = gen2() print(next(g)) print(g.throw(GeneratorExit)) # thrown an instance -g = gen() +g = gen2() print(next(g)) print(g.throw(GeneratorExit()))