Merge pull request #1329 from notro/oserror_errno
Support OSError subclasses and attributes
This commit is contained in:
commit
c47c495aca
@ -163,6 +163,18 @@ typedef long mp_off_t;
|
||||
#define MICROPY_PY_IO (0)
|
||||
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (0)
|
||||
#define MICROPY_PY_SYS_EXC_INFO (0)
|
||||
#define MICROPY_PY_UERRNO_LIST \
|
||||
X(EPERM) \
|
||||
X(ENOENT) \
|
||||
X(EIO) \
|
||||
X(EAGAIN) \
|
||||
X(ENOMEM) \
|
||||
X(EACCES) \
|
||||
X(EEXIST) \
|
||||
X(ENODEV) \
|
||||
X(EISDIR) \
|
||||
X(EINVAL) \
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef SAMD51
|
||||
@ -179,6 +191,7 @@ typedef long mp_off_t;
|
||||
#define MICROPY_PY_IO (1)
|
||||
#define MICROPY_PY_REVERSE_SPECIAL_METHODS (1)
|
||||
#define MICROPY_PY_SYS_EXC_INFO (1)
|
||||
// MICROPY_PY_UERRNO_LIST - Use the default
|
||||
#endif
|
||||
|
||||
#ifdef LONGINT_IMPL_NONE
|
||||
@ -405,18 +418,6 @@ extern const struct _mp_obj_module_t wiznet_module;
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_uheap),(mp_obj_t)&uheap_module }, \
|
||||
{ MP_OBJ_NEW_QSTR(MP_QSTR_ustack),(mp_obj_t)&ustack_module }
|
||||
|
||||
#define MICROPY_PY_UERRNO_LIST \
|
||||
X(EPERM) \
|
||||
X(ENOENT) \
|
||||
X(EIO) \
|
||||
X(EAGAIN) \
|
||||
X(ENOMEM) \
|
||||
X(EACCES) \
|
||||
X(EEXIST) \
|
||||
X(ENODEV) \
|
||||
X(EISDIR) \
|
||||
X(EINVAL) \
|
||||
|
||||
// We need to provide a declaration/definition of alloca()
|
||||
#include <alloca.h>
|
||||
|
||||
|
@ -136,19 +136,28 @@ const char* mp_errno_to_str(mp_obj_t errno_val) {
|
||||
#endif //MICROPY_PY_UERRNO
|
||||
|
||||
|
||||
// For commonly encountered errors, return human readable strings
|
||||
const compressed_string_t* mp_common_errno_to_str(mp_obj_t errno_val) {
|
||||
if (MP_OBJ_IS_SMALL_INT(errno_val)) {
|
||||
switch (MP_OBJ_SMALL_INT_VALUE(errno_val)) {
|
||||
case EPERM: return translate("Permission denied");
|
||||
case ENOENT: return translate("No such file/directory");
|
||||
case EIO: return translate("Input/output error");
|
||||
case EACCES: return translate("Permission denied");
|
||||
case EEXIST: return translate("File exists");
|
||||
case ENODEV: return translate("Unsupported operation");
|
||||
case EINVAL: return translate("Invalid argument");
|
||||
case EROFS: return translate("Read-only filesystem");
|
||||
}
|
||||
}
|
||||
// For commonly encountered errors, return human readable strings, otherwise try errno name
|
||||
const char *mp_common_errno_to_str(mp_obj_t errno_val, char *buf, size_t len) {
|
||||
if (!MP_OBJ_IS_SMALL_INT(errno_val)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const compressed_string_t* desc = NULL;
|
||||
switch (MP_OBJ_SMALL_INT_VALUE(errno_val)) {
|
||||
case EPERM: desc = translate("Permission denied"); break;
|
||||
case ENOENT: desc = translate("No such file/directory"); break;
|
||||
case EIO: desc = translate("Input/output error"); break;
|
||||
case EACCES: desc = translate("Permission denied"); break;
|
||||
case EEXIST: desc = translate("File exists"); break;
|
||||
case ENODEV: desc = translate("Unsupported operation"); break;
|
||||
case EINVAL: desc = translate("Invalid argument"); break;
|
||||
case EROFS: desc = translate("Read-only filesystem"); break;
|
||||
}
|
||||
if (desc != NULL && desc->length <= len) {
|
||||
decompress(desc, buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
const char *msg = mp_errno_to_str(errno_val);
|
||||
return msg[0] != '\0' ? msg : NULL;
|
||||
}
|
||||
|
@ -141,7 +141,6 @@
|
||||
#endif
|
||||
|
||||
const char* mp_errno_to_str(mp_obj_t errno_val);
|
||||
// For commonly encountered errors, return compressed human readable strings
|
||||
const compressed_string_t* mp_common_errno_to_str(mp_obj_t errno_val);
|
||||
const char *mp_common_errno_to_str(mp_obj_t errno_val, char *buf, size_t len);
|
||||
|
||||
#endif // MICROPY_INCLUDED_PY_MPERRNO_H
|
||||
|
@ -114,17 +114,11 @@ void mp_obj_exception_print(const mp_print_t *print, mp_obj_t o_in, mp_print_kin
|
||||
return;
|
||||
} else if (o->args->len == 1) {
|
||||
// try to provide a nice OSError error message
|
||||
if (o->base.type == &mp_type_OSError && MP_OBJ_IS_SMALL_INT(o->args->items[0])) {
|
||||
const compressed_string_t* common = mp_common_errno_to_str(o->args->items[0]);
|
||||
const char* msg;
|
||||
if (MP_OBJ_IS_SMALL_INT(o->args->items[0]) &&
|
||||
mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(o->base.type), MP_OBJ_FROM_PTR(&mp_type_OSError))) {
|
||||
char decompressed[50];
|
||||
if (common != NULL && common->length <= 50) {
|
||||
decompress(common, decompressed);
|
||||
msg = decompressed;
|
||||
} else {
|
||||
msg = mp_errno_to_str(o->args->items[0]);
|
||||
}
|
||||
if (msg[0] != '\0') {
|
||||
const char *msg = mp_common_errno_to_str(o->args->items[0], decompressed, sizeof(decompressed));
|
||||
if (msg != NULL) {
|
||||
mp_printf(print, "[Errno " INT_FMT "] %s", MP_OBJ_SMALL_INT_VALUE(o->args->items[0]), msg);
|
||||
return;
|
||||
}
|
||||
@ -215,6 +209,31 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
|
||||
dest[0] = MP_OBJ_FROM_PTR(self->args);
|
||||
} else if (self->base.type == &mp_type_StopIteration && attr == MP_QSTR_value) {
|
||||
dest[0] = mp_obj_exception_get_value(self_in);
|
||||
#if MICROPY_CPYTHON_COMPAT
|
||||
} else if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(self->base.type), MP_OBJ_FROM_PTR(&mp_type_OSError))) {
|
||||
if (attr == MP_QSTR_errno) {
|
||||
dest[0] = mp_obj_exception_get_value(self_in);
|
||||
} else if (attr == MP_QSTR_strerror) {
|
||||
if (self->args->len > 1) {
|
||||
dest[0] = self->args->items[1];
|
||||
} else if (self->args->len > 0) {
|
||||
char decompressed[50];
|
||||
const char *msg = mp_common_errno_to_str(self->args->items[0], decompressed, sizeof(decompressed));
|
||||
if (msg != NULL) {
|
||||
dest[0] = mp_obj_new_str(msg, strlen(msg));
|
||||
} else {
|
||||
dest[0] = mp_const_none;
|
||||
}
|
||||
} else {
|
||||
dest[0] = mp_const_none;
|
||||
}
|
||||
} else if (attr == MP_QSTR_filename) {
|
||||
dest[0] = self->args->len > 2 ? self->args->items[2] : mp_const_none;
|
||||
// skip winerror
|
||||
} else if (attr == MP_QSTR_filename2) {
|
||||
dest[0] = self->args->len > 4 ? self->args->items[4] : mp_const_none;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user