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
|
||||||
#endif // MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF
|
#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) {
|
STATIC void decompress_error_text_maybe(mp_obj_exception_t *o) {
|
||||||
#if MICROPY_ROM_TEXT_COMPRESSION
|
#if MICROPY_ROM_TEXT_COMPRESSION
|
||||||
if (o->args->len == 1 && mp_obj_is_type(o->args->items[0], &mp_type_str)) {
|
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
|
// Get exception "value" - that is, first argument, or None
|
||||||
mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in) {
|
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) {
|
if (self->args->len == 0) {
|
||||||
return mp_const_none;
|
return mp_const_none;
|
||||||
} else {
|
} else {
|
||||||
|
@ -559,25 +568,15 @@ bool mp_obj_exception_match(mp_obj_t exc, mp_const_obj_t exc_type) {
|
||||||
|
|
||||||
// traceback handling functions
|
// 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) {
|
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
|
// just set the traceback to the null object
|
||||||
// we don't want to call any memory management functions here
|
// we don't want to call any memory management functions here
|
||||||
self->traceback_data = NULL;
|
self->traceback_data = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, size_t line, qstr block) {
|
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
|
// append this traceback info to traceback data
|
||||||
// if memory allocation fails (eg because gc is locked), just return
|
// 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) {
|
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) {
|
if (self->traceback_data == NULL) {
|
||||||
*n = 0;
|
*n = 0;
|
||||||
|
|
|
@ -34,6 +34,26 @@ print(MyStopIteration().value)
|
||||||
print(MyStopIteration(1).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):
|
class MyOSError(OSError):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue