summaryrefslogtreecommitdiff
path: root/py/objexcept.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/objexcept.c')
-rw-r--r--py/objexcept.c66
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) {