From d45e5f8c357d13e66aeac644e2b5ead8c734025f Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 12 May 2016 13:20:40 +0100 Subject: py: Add mp_errno_to_str() and use it to provide nicer OSError msgs. If an OSError is raised with an integer argument, and that integer corresponds to an errno, then the string for the errno is used as the argument to the exception, instead of the integer. Only works if the uerrno module is enabled. --- py/objexcept.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'py/objexcept.c') diff --git a/py/objexcept.c b/py/objexcept.c index adf17b08d0..4c1da1b387 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -36,6 +36,7 @@ #include "py/objtype.h" #include "py/runtime.h" #include "py/gc.h" +#include "py/mperrno.h" // Instance of MemoryError exception - needed by mp_malloc_fail const mp_obj_exception_t mp_const_MemoryError_obj = {{&mp_type_MemoryError}, 0, 0, NULL, (mp_obj_tuple_t*)&mp_const_empty_tuple_obj}; @@ -288,6 +289,10 @@ mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type) { // "Optimized" version for common(?) case of having 1 exception arg mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) { + // try to provide a nice string instead of numeric value for errno's + if (exc_type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(arg)) { + arg = mp_errno_to_str(arg); + } return mp_obj_new_exception_args(exc_type, 1, &arg); } -- cgit v1.2.3 From 9a9249964155f333131bbd728ffc755e80dc68a2 Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 12 May 2016 14:27:52 +0100 Subject: py/objexcept: Don't convert errno to str in constructor, do it in print. OSError's are now printed like: OSError: [Errno 1] EPERM but only if the string corresponding to the errno is found. --- py/moduerrno.c | 6 +++--- py/mperrno.h | 4 +--- py/objexcept.c | 14 ++++++++++---- 3 files changed, 14 insertions(+), 10 deletions(-) (limited to 'py/objexcept.c') diff --git a/py/moduerrno.c b/py/moduerrno.c index 0b543a1934..da3869befd 100644 --- a/py/moduerrno.c +++ b/py/moduerrno.c @@ -89,12 +89,12 @@ const mp_obj_module_t mp_module_uerrno = { .globals = (mp_obj_dict_t*)&mp_module_uerrno_globals, }; -mp_obj_t mp_errno_to_str(mp_obj_t errno_val) { +qstr mp_errno_to_str(mp_obj_t errno_val) { mp_map_elem_t *elem = mp_map_lookup((mp_map_t*)&errorcode_dict.map, errno_val, MP_MAP_LOOKUP); if (elem == NULL) { - return errno_val; + return MP_QSTR_NULL; } else { - return elem->value; + return MP_OBJ_QSTR_VALUE(elem->value); } } diff --git a/py/mperrno.h b/py/mperrno.h index 2dbb7b0a82..f7784f6f73 100644 --- a/py/mperrno.h +++ b/py/mperrno.h @@ -135,9 +135,7 @@ #endif #if MICROPY_PY_UERRNO -mp_obj_t mp_errno_to_str(mp_obj_t errno_val); -#else -static inline mp_obj_t mp_errno_to_str(mp_obj_t errno_val) { return errno_val; } +qstr mp_errno_to_str(mp_obj_t errno_val); #endif #endif // __MICROPY_INCLUDED_PY_MPERRNO_H__ diff --git a/py/objexcept.c b/py/objexcept.c index 4c1da1b387..9ccc9288c9 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -108,6 +108,16 @@ STATIC void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_pr mp_print_str(print, ""); return; } else if (o->args->len == 1) { + #if MICROPY_PY_UERRNO + // try to provide a nice OSError error message + if (o->base.type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(o->args->items[0])) { + qstr qst = mp_errno_to_str(o->args->items[0]); + if (qst != MP_QSTR_NULL) { + mp_printf(print, "[Errno %d] %q", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), qst); + return; + } + } + #endif mp_obj_print_helper(print, o->args->items[0], PRINT_STR); return; } @@ -289,10 +299,6 @@ mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type) { // "Optimized" version for common(?) case of having 1 exception arg mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg) { - // try to provide a nice string instead of numeric value for errno's - if (exc_type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(arg)) { - arg = mp_errno_to_str(arg); - } return mp_obj_new_exception_args(exc_type, 1, &arg); } -- cgit v1.2.3