Skip to content

Commit 91e556a

Browse files
committed
objexcept: Support tracebacks for user Exception subclasses.
1 parent 0a7e01a commit 91e556a

1 file changed

Lines changed: 26 additions & 24 deletions

File tree

py/objexcept.c

Lines changed: 26 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
#include "qstr.h"
99
#include "obj.h"
1010
#include "objtuple.h"
11+
#include "objtype.h"
1112
#include "runtime.h"
1213
#include "runtime0.h"
1314

@@ -271,38 +272,39 @@ bool mp_obj_exception_match(mp_obj_t exc, const mp_obj_type_t *exc_type) {
271272
return mp_binary_op(MP_BINARY_OP_EXCEPTION_MATCH, exc, (mp_obj_t)exc_type) == mp_const_true;
272273
}
273274

274-
void mp_obj_exception_clear_traceback(mp_obj_t self_in) {
275-
// make sure self_in is an exception instance
276-
// TODO add traceback information to user-defined exceptions (need proper builtin subclassing for that)
277-
if (mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new) {
278-
mp_obj_exception_t *self = self_in;
279-
280-
// just set the traceback to the null object
281-
// we don't want to call any memory management functions here
282-
self->traceback = MP_OBJ_NULL;
275+
// traceback handling functions
276+
277+
#define GET_NATIVE_EXCEPTION(self, self_in) \
278+
/* make sure self_in is an exception instance */ \
279+
assert(mp_obj_is_exception_instance(self_in)); \
280+
mp_obj_exception_t *self; \
281+
if (mp_obj_is_native_exception_instance(self_in)) { \
282+
self = self_in; \
283+
} else { \
284+
self = ((mp_obj_instance_t*)self_in)->subobj[0]; \
283285
}
286+
287+
void mp_obj_exception_clear_traceback(mp_obj_t self_in) {
288+
GET_NATIVE_EXCEPTION(self, self_in);
289+
// just set the traceback to the null object
290+
// we don't want to call any memory management functions here
291+
self->traceback = MP_OBJ_NULL;
284292
}
285293

286294
void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block) {
287-
// make sure self_in is an exception instance
288-
// TODO add traceback information to user-defined exceptions (need proper builtin subclassing for that)
289-
if (mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new && self_in != &mp_emergency_exception_obj) {
290-
mp_obj_exception_t *self = self_in;
291-
292-
// for traceback, we are just using the list object for convenience, it's not really a list of Python objects
293-
if (self->traceback == MP_OBJ_NULL) {
294-
self->traceback = mp_obj_new_list(0, NULL);
295-
}
296-
mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)file);
297-
mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)line);
298-
mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)block);
295+
GET_NATIVE_EXCEPTION(self, self_in);
296+
297+
// for traceback, we are just using the list object for convenience, it's not really a list of Python objects
298+
if (self->traceback == MP_OBJ_NULL) {
299+
self->traceback = mp_obj_new_list(0, NULL);
299300
}
301+
mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)file);
302+
mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)line);
303+
mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)block);
300304
}
301305

302306
void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine_uint_t **values) {
303-
// make sure self_in is an exception instance
304-
assert(mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new);
305-
mp_obj_exception_t *self = self_in;
307+
GET_NATIVE_EXCEPTION(self, self_in);
306308

307309
if (self->traceback == MP_OBJ_NULL) {
308310
*n = 0;

0 commit comments

Comments
 (0)