summaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-03-31 04:14:30 +0300
committerPaul Sokolovsky <pfalcon@users.sourceforge.net>2014-03-31 17:22:37 +0300
commita2109d93210c391d45a0ced2ce8a85f2471d3543 (patch)
tree13adf1d599d74fc1d02aa41768a36e1bfcd8f7f3
parent817e76a1a56f34c6c87ca6196dbeab09ff01ba80 (diff)
downloadmicropython-a2109d93210c391d45a0ced2ce8a85f2471d3543.tar.gz
micropython-a2109d93210c391d45a0ced2ce8a85f2471d3543.zip
mp_resume: Elaborate handling of .throw() for objects which lack it.
In this case, the exception is just re-thrown - the ideas is that object doesn't handle this exception specially, so it will propagated per Python semantics.
-rw-r--r--py/runtime.c17
1 files changed, 14 insertions, 3 deletions
diff --git a/py/runtime.c b/py/runtime.c
index f827fd831e..f7e08e37f5 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -960,9 +960,20 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
return MP_VM_RETURN_NORMAL;
}
}
- mp_load_method(self_in, MP_QSTR_throw, dest);
- *ret_val = mp_call_method_n_kw(1, 0, &throw_value);
- return MP_VM_RETURN_YIELD;
+ mp_load_method_maybe(self_in, MP_QSTR_throw, dest);
+ if (dest[0] != MP_OBJ_NULL) {
+ *ret_val = mp_call_method_n_kw(1, 0, &throw_value);
+ // If .throw() method returned, we assume it's value to yield
+ // - any exception would be thrown with nlr_jump().
+ return MP_VM_RETURN_YIELD;
+ }
+ // If there's nowhere to throw exception into, then we assume that object
+ // is just incapable to handle it, so any exception thrown into it
+ // will be propagated up. This behavior is approved by test_pep380.py
+ // test_delegation_of_close_to_non_generator(),
+ // test_delegating_throw_to_non_generator()
+ *ret_val = throw_value;
+ return MP_VM_RETURN_EXCEPTION;
}
assert(0);