diff options
author | Paul Sokolovsky <pfalcon@users.sourceforge.net> | 2014-03-31 04:09:53 +0300 |
---|---|---|
committer | Paul Sokolovsky <pfalcon@users.sourceforge.net> | 2014-03-31 17:22:37 +0300 |
commit | 817e76a1a56f34c6c87ca6196dbeab09ff01ba80 (patch) | |
tree | d75ab44d5edb992f0f09cd7154c0ed1c5896e1ee /py | |
parent | 1eac05d5414678d23cff3d1dde8bd234c4edcc0b (diff) | |
download | micropython-817e76a1a56f34c6c87ca6196dbeab09ff01ba80.tar.gz micropython-817e76a1a56f34c6c87ca6196dbeab09ff01ba80.zip |
objgenerator.throw(GeneratorExit) is not equivalent to .close().
.throw() propagates any exceptions, and .close() swallows them. Yielding
in reponse to .throw(GeneratorExit) is still fatal, and we need to
handle it for .throw() case separately (previously it was handled only
for .close() case).
Obscure corner cases due to test_pep380.py.
Diffstat (limited to 'py')
-rw-r--r-- | py/objgenerator.c | 10 |
1 files changed, 3 insertions, 7 deletions
diff --git a/py/objgenerator.c b/py/objgenerator.c index 5f0f6c3eba..78694c866b 100644 --- a/py/objgenerator.c +++ b/py/objgenerator.c @@ -134,6 +134,9 @@ STATIC mp_obj_t gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_o } case MP_VM_RETURN_YIELD: + if (throw_value != MP_OBJ_NULL && mp_obj_is_subclass_fast(mp_obj_get_type(throw_value), &mp_type_GeneratorExit)) { + nlr_jump(mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit")); + } return ret; case MP_VM_RETURN_EXCEPTION: @@ -171,13 +174,6 @@ STATIC mp_obj_t gen_instance_close(mp_obj_t self_in); STATIC mp_obj_t gen_instance_throw(uint n_args, const mp_obj_t *args) { mp_obj_t exc = (n_args == 2) ? args[1] : args[2]; exc = mp_make_raise_obj(exc); - if (mp_obj_is_subclass_fast(mp_obj_get_type(exc), &mp_type_GeneratorExit)) { - // Throwing GeneratorExit is equivalent of calling close aka - // GeneratorExit should be handled specially - // TODO: Calling .close() will throw new exception instance, not one - // given to throw, which is not ok. - return gen_instance_close(args[0]); - } mp_obj_t ret = gen_resume_and_raise(args[0], mp_const_none, exc); if (ret == MP_OBJ_NULL) { |