py/objexcept: Make mp_obj_exception_get_value support subclassed excs.
Signed-off-by: Damien George <damien@micropython.org>
This commit is contained in:
parent
b8255dd2e0
commit
e3825e28e6
|
@ -111,6 +111,15 @@ mp_obj_t mp_alloc_emergency_exception_buf(mp_obj_t size_in) {
|
|||
#endif
|
||||
#endif // MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
||||
|
||||
STATIC mp_obj_exception_t *get_native_exception(mp_obj_t self_in) {
|
||||
assert(mp_obj_is_exception_instance(self_in));
|
||||
if (mp_obj_is_native_exception_instance(self_in)) {
|
||||
return MP_OBJ_TO_PTR(self_in);
|
||||
} else {
|
||||
return MP_OBJ_TO_PTR(((mp_obj_instance_t *)MP_OBJ_TO_PTR(self_in))->subobj[0]);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC void decompress_error_text_maybe(mp_obj_exception_t *o) {
|
||||
#if MICROPY_ROM_TEXT_COMPRESSION
|
||||
if (o->args->len == 1 && mp_obj_is_type(o->args->items[0], &mp_type_str)) {
|
||||
|
@ -240,7 +249,7 @@ mp_obj_t mp_obj_exception_make_new(const mp_obj_type_t *type, size_t n_args, siz
|
|||
|
||||
// Get exception "value" - that is, first argument, or None
|
||||
mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in) {
|
||||
mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in);
|
||||
mp_obj_exception_t *self = get_native_exception(self_in);
|
||||
if (self->args->len == 0) {
|
||||
return mp_const_none;
|
||||
} else {
|
||||
|
@ -559,25 +568,15 @@ bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type) {
|
|||
|
||||
// traceback handling functions
|
||||
|
||||
#define GET_NATIVE_EXCEPTION(self, self_in) \
|
||||
/* make sure self_in is an exception instance */ \
|
||||
assert(mp_obj_is_exception_instance(self_in)); \
|
||||
mp_obj_exception_t *self; \
|
||||
if (mp_obj_is_native_exception_instance(self_in)) { \
|
||||
self = MP_OBJ_TO_PTR(self_in); \
|
||||
} else { \
|
||||
self = MP_OBJ_TO_PTR(((mp_obj_instance_t *)MP_OBJ_TO_PTR(self_in))->subobj[0]); \
|
||||
}
|
||||
|
||||
void mp_obj_exception_clear_traceback(mp_obj_t self_in) {
|
||||
GET_NATIVE_EXCEPTION(self, self_in);
|
||||
mp_obj_exception_t *self = get_native_exception(self_in);
|
||||
// just set the traceback to the null object
|
||||
// we don't want to call any memory management functions here
|
||||
self->traceback_data = NULL;
|
||||
}
|
||||
|
||||
void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block) {
|
||||
GET_NATIVE_EXCEPTION(self, self_in);
|
||||
mp_obj_exception_t *self = get_native_exception(self_in);
|
||||
|
||||
// append this traceback info to traceback data
|
||||
// if memory allocation fails (eg because gc is locked), just return
|
||||
|
@ -630,7 +629,7 @@ void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qs
|
|||
}
|
||||
|
||||
void mp_obj_exception_get_traceback(mp_obj_t self_in, size_t *n, size_t **values) {
|
||||
GET_NATIVE_EXCEPTION(self, self_in);
|
||||
mp_obj_exception_t *self = get_native_exception(self_in);
|
||||
|
||||
if (self->traceback_data == NULL) {
|
||||
*n = 0;
|
||||
|
|
|
@ -34,6 +34,26 @@ print(MyStopIteration().value)
|
|||
print(MyStopIteration(1).value)
|
||||
|
||||
|
||||
class Iter:
|
||||
def __iter__(self):
|
||||
return self
|
||||
|
||||
def __next__(self):
|
||||
# This exception will stop the "yield from", with a value of 3
|
||||
raise MyStopIteration(3)
|
||||
|
||||
|
||||
def gen():
|
||||
print((yield from Iter()))
|
||||
return 4
|
||||
|
||||
|
||||
try:
|
||||
next(gen())
|
||||
except StopIteration as er:
|
||||
print(er.args)
|
||||
|
||||
|
||||
class MyOSError(OSError):
|
||||
pass
|
||||
|
||||
|
|
Loading…
Reference in New Issue