diff options
Diffstat (limited to 'py/objexcept.c')
| -rw-r--r-- | py/objexcept.c | 66 |
1 files changed, 43 insertions, 23 deletions
diff --git a/py/objexcept.c b/py/objexcept.c index f96523ed2..c75e3d3a5 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -55,16 +55,31 @@ STATIC mp_obj_t mp_obj_exception_make_new(mp_obj_t type_in, uint n_args, uint n_ o->base.type = type; o->traceback = MP_OBJ_NULL; o->msg = NULL; + o->args.base.type = &tuple_type; o->args.len = n_args; memcpy(o->args.items, args, n_args * sizeof(mp_obj_t)); return o; } +STATIC void exception_load_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) { + mp_obj_exception_t *self = self_in; + if (attr == MP_QSTR_args) { + dest[0] = &self->args; + } else if (self->base.type == &mp_type_StopIteration && attr == MP_QSTR_value) { + if (self->args.len == 0) { + dest[0] = mp_const_none; + } else { + dest[0] = self->args.items[0]; + } + } +} + const mp_obj_type_t mp_type_BaseException = { { &mp_type_type }, .name = MP_QSTR_BaseException, .print = mp_obj_exception_print, .make_new = mp_obj_exception_make_new, + .load_attr = exception_load_attr, }; #define MP_DEFINE_EXCEPTION_BASE(base_name) \ @@ -76,13 +91,14 @@ const mp_obj_type_t mp_type_ ## exc_name = { \ .name = MP_QSTR_ ## exc_name, \ .print = mp_obj_exception_print, \ .make_new = mp_obj_exception_make_new, \ + .load_attr = exception_load_attr, \ .bases_tuple = (mp_obj_t)&mp_type_ ## base_name ## _base_tuple, \ }; // List of all exceptions, arranged as in the table at: // http://docs.python.org/3.3/library/exceptions.html MP_DEFINE_EXCEPTION_BASE(BaseException) -MP_DEFINE_EXCEPTION(SystemExit, BaseException) +//MP_DEFINE_EXCEPTION(SystemExit, BaseException) //MP_DEFINE_EXCEPTION(KeyboardInterrupt, BaseException) MP_DEFINE_EXCEPTION(GeneratorExit, BaseException) MP_DEFINE_EXCEPTION(Exception, BaseException) @@ -96,7 +112,7 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) MP_DEFINE_EXCEPTION(AssertionError, Exception) MP_DEFINE_EXCEPTION(AttributeError, Exception) MP_DEFINE_EXCEPTION(BufferError, Exception) - MP_DEFINE_EXCEPTION(EnvironmentError, Exception) + //MP_DEFINE_EXCEPTION(EnvironmentError, Exception) MP_DEFINE_EXCEPTION(EOFError, Exception) MP_DEFINE_EXCEPTION(ImportError, Exception) MP_DEFINE_EXCEPTION(IOError, Exception) @@ -126,7 +142,7 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) MP_DEFINE_EXCEPTION(TimeoutError, OSError)*/ MP_DEFINE_EXCEPTION(FileExistsError, OSError) MP_DEFINE_EXCEPTION(FileNotFoundError, OSError) - MP_DEFINE_EXCEPTION(ReferenceError, Exception) + //MP_DEFINE_EXCEPTION(ReferenceError, Exception) MP_DEFINE_EXCEPTION(RuntimeError, Exception) MP_DEFINE_EXCEPTION_BASE(RuntimeError) MP_DEFINE_EXCEPTION(NotImplementedError, RuntimeError) @@ -134,7 +150,7 @@ MP_DEFINE_EXCEPTION(Exception, BaseException) MP_DEFINE_EXCEPTION_BASE(SyntaxError) MP_DEFINE_EXCEPTION(IndentationError, SyntaxError) MP_DEFINE_EXCEPTION_BASE(IndentationError) - MP_DEFINE_EXCEPTION(TabError, IndentationError) + //MP_DEFINE_EXCEPTION(TabError, IndentationError) MP_DEFINE_EXCEPTION(SystemError, Exception) MP_DEFINE_EXCEPTION(TypeError, Exception) MP_DEFINE_EXCEPTION(ValueError, Exception) @@ -193,20 +209,20 @@ mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, const char } // return true if the given object is an exception type -// TODO make this work for user defined exceptions bool mp_obj_is_exception_type(mp_obj_t self_in) { if (MP_OBJ_IS_TYPE(self_in, &mp_type_type)) { + // optimisation when self_in is a builtin exception mp_obj_type_t *self = self_in; - return self->make_new == mp_obj_exception_make_new; - } else { - return false; + if (self->make_new == mp_obj_exception_make_new) { + return true; + } } + return mp_obj_is_subclass_fast(self_in, &mp_type_BaseException); } // return true if the given object is an instance of an exception type -// TODO make this work for user defined exceptions bool mp_obj_is_exception_instance(mp_obj_t self_in) { - return mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new; + return mp_obj_is_exception_type(mp_obj_get_type(self_in)); } // return true if exception (type or instance) is a subclass of given @@ -218,26 +234,30 @@ bool mp_obj_exception_match(mp_obj_t exc, const mp_obj_type_t *exc_type) { void mp_obj_exception_clear_traceback(mp_obj_t self_in) { // make sure self_in is an exception instance - assert(mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new); - mp_obj_exception_t *self = self_in; + // TODO add traceback information to user-defined exceptions (need proper builtin subclassing for that) + if (mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new) { + mp_obj_exception_t *self = self_in; - // just set the traceback to the null object - // we don't want to call any memory management functions here - self->traceback = MP_OBJ_NULL; + // just set the traceback to the null object + // we don't want to call any memory management functions here + self->traceback = MP_OBJ_NULL; + } } void mp_obj_exception_add_traceback(mp_obj_t self_in, qstr file, machine_uint_t line, qstr block) { // make sure self_in is an exception instance - assert(mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new); - mp_obj_exception_t *self = self_in; + // TODO add traceback information to user-defined exceptions (need proper builtin subclassing for that) + if (mp_obj_get_type(self_in)->make_new == mp_obj_exception_make_new) { + mp_obj_exception_t *self = self_in; - // for traceback, we are just using the list object for convenience, it's not really a list of Python objects - if (self->traceback == MP_OBJ_NULL) { - self->traceback = mp_obj_new_list(0, NULL); + // for traceback, we are just using the list object for convenience, it's not really a list of Python objects + if (self->traceback == MP_OBJ_NULL) { + self->traceback = mp_obj_new_list(0, NULL); + } + mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)file); + mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)line); + mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)block); } - mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)file); - mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)line); - mp_obj_list_append(self->traceback, (mp_obj_t)(machine_uint_t)block); } void mp_obj_exception_get_traceback(mp_obj_t self_in, machine_uint_t *n, machine_uint_t **values) { |
