From d4b706c4d01377d42855ff1544ced77536f69caf Mon Sep 17 00:00:00 2001 From: Damien George Date: Thu, 22 Apr 2021 12:13:58 +1000 Subject: [PATCH] py: Add option to compile without any error messages at all. This introduces a new option, MICROPY_ERROR_REPORTING_NONE, which completely disables all error messages. To be used in cases where MicroPython needs to fit in very limited systems. Signed-off-by: Damien George --- py/argcheck.c | 14 ++++++------ py/bc.c | 4 ++-- py/builtinimport.c | 4 ++-- py/compile.c | 4 ++-- py/misc.h | 4 ++++ py/modbuiltins.c | 2 +- py/mpconfig.h | 2 ++ py/obj.c | 20 ++++++++--------- py/obj.h | 5 +++++ py/objexcept.c | 4 ++++ py/objnamedtuple.c | 6 +++--- py/objstr.c | 38 ++++++++++++++++---------------- py/objtype.c | 8 +++---- py/parsenum.c | 2 +- py/runtime.c | 54 ++++++++++++++++++++++++++++++++-------------- py/runtime.h | 13 +++++++++++ 16 files changed, 117 insertions(+), 67 deletions(-) diff --git a/py/argcheck.c b/py/argcheck.c index c333ead05b..ffcca4cb65 100644 --- a/py/argcheck.c +++ b/py/argcheck.c @@ -38,7 +38,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { size_t n_args_max = (sig >> 1) & 0xffff; if (n_kw && !takes_kw) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_TypeError(MP_ERROR_TEXT("function doesn't take keyword arguments")); @@ -47,7 +47,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { if (n_args_min == n_args_max) { if (n_args != n_args_min) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -57,7 +57,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { } } else { if (n_args < n_args_min) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -65,7 +65,7 @@ void mp_arg_check_num_sig(size_t n_args, size_t n_kw, uint32_t sig) { n_args_min - n_args); #endif } else if (n_args > n_args_max) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -90,7 +90,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qst), MP_MAP_LOOKUP); if (kw == NULL) { if (allowed[i].flags & MP_ARG_REQUIRED) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("'%q' argument required"), allowed[i].qst); @@ -114,7 +114,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n } if (pos_found < n_pos) { extra_positional: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else // TODO better error message @@ -122,7 +122,7 @@ void mp_arg_parse_all(size_t n_pos, const mp_obj_t *pos, mp_map_t *kws, size_t n #endif } if (kws_found < kws->used) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else // TODO better error message diff --git a/py/bc.c b/py/bc.c index 34bc78fd3a..58694b97dc 100644 --- a/py/bc.c +++ b/py/bc.c @@ -75,7 +75,7 @@ const byte *mp_decode_uint_skip(const byte *ptr) { #endif STATIC NORETURN void fun_pos_args_mismatch(mp_obj_fun_bc_t *f, size_t expected, size_t given) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE // generic message, used also for other argument issues (void)f; (void)expected; @@ -212,7 +212,7 @@ void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw } // Didn't find name match with positional args if ((scope_flags & MP_SCOPE_FLAG_VARKEYWORDS) == 0) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("unexpected keyword argument")); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/builtinimport.c b/py/builtinimport.c index bdc82e77c8..874d2dd7f0 100644 --- a/py/builtinimport.c +++ b/py/builtinimport.c @@ -396,7 +396,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { #endif if (module_obj == MP_OBJ_NULL) { // couldn't find the file, so fail - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found")); #else mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), mod_name); @@ -499,7 +499,7 @@ mp_obj_t mp_builtin___import__(size_t n_args, const mp_obj_t *args) { #endif // Couldn't find the module, so fail - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_ImportError, MP_ERROR_TEXT("module not found")); #else mp_raise_msg_varg(&mp_type_ImportError, MP_ERROR_TEXT("no module named '%q'"), module_name_qstr); diff --git a/py/compile.c b/py/compile.c index d1a4d65c8b..1182b8b1eb 100644 --- a/py/compile.c +++ b/py/compile.c @@ -2597,7 +2597,7 @@ STATIC void compile_atom_brace_helper(compiler_t *comp, mp_parse_node_struct_t * compile_node(comp, pn_i); if (is_dict) { if (!is_key_value) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("invalid syntax")); #else compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("expecting key:value for dict")); @@ -2607,7 +2607,7 @@ STATIC void compile_atom_brace_helper(compiler_t *comp, mp_parse_node_struct_t * EMIT(store_map); } else { if (is_key_value) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("invalid syntax")); #else compile_syntax_error(comp, (mp_parse_node_t)pns, MP_ERROR_TEXT("expecting just a value for set")); diff --git a/py/misc.h b/py/misc.h index fe2b3b8afa..9538098383 100644 --- a/py/misc.h +++ b/py/misc.h @@ -264,6 +264,10 @@ typedef union _mp_float_union_t { #if MICROPY_ROM_TEXT_COMPRESSION +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE +#error "MICROPY_ERROR_REPORTING_NONE requires MICROPY_ROM_TEXT_COMPRESSION disabled" +#endif + #ifdef NO_QSTR // Compression enabled but doing QSTR extraction. diff --git a/py/modbuiltins.c b/py/modbuiltins.c index cfbfc5a256..ac41942b9c 100644 --- a/py/modbuiltins.c +++ b/py/modbuiltins.c @@ -372,7 +372,7 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) { } } - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("ord expects a character")); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/mpconfig.h b/py/mpconfig.h index 3dd83a34ab..5c7212fd1f 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -667,6 +667,8 @@ typedef long long mp_longint_impl_t; #define MICROPY_ENABLE_DOC_STRING (0) #endif +// Exception messages are removed (requires disabling MICROPY_ROM_TEXT_COMPRESSION) +#define MICROPY_ERROR_REPORTING_NONE (0) // Exception messages are short static strings #define MICROPY_ERROR_REPORTING_TERSE (1) // Exception messages provide basic error details diff --git a/py/obj.c b/py/obj.c index ed047acc39..f66a9d183c 100644 --- a/py/obj.c +++ b/py/obj.c @@ -359,7 +359,7 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) { mp_float_t val; if (!mp_obj_get_float_maybe(arg, &val)) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't convert to float")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -399,7 +399,7 @@ bool mp_obj_get_complex_maybe(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) { if (!mp_obj_get_complex_maybe(arg, real, imag)) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't convert to complex")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -417,7 +417,7 @@ void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { } else if (mp_obj_is_type(o, &mp_type_list)) { mp_obj_list_get(o, len, items); } else { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("expected tuple/list")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -431,7 +431,7 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, size_t len, mp_obj_t **items) { size_t seq_len; mp_obj_get_array(o, &seq_len, items); if (seq_len != len) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_ValueError(MP_ERROR_TEXT("tuple/list has wrong length")); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -446,7 +446,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool if (mp_obj_is_small_int(index)) { i = MP_OBJ_SMALL_INT_VALUE(index); } else if (!mp_obj_get_int_maybe(index, &i)) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("indices must be integers")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -466,7 +466,7 @@ size_t mp_get_index(const mp_obj_type_t *type, size_t len, mp_obj_t index, bool } } else { if (i < 0 || (mp_uint_t)i >= len) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_IndexError, MP_ERROR_TEXT("index out of range")); #else mp_raise_msg_varg(&mp_type_IndexError, MP_ERROR_TEXT("%q index out of range"), type->name); @@ -500,7 +500,7 @@ mp_obj_t mp_obj_id(mp_obj_t o_in) { mp_obj_t mp_obj_len(mp_obj_t o_in) { mp_obj_t len = mp_obj_len_maybe(o_in); if (len == MP_OBJ_NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object has no len")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -541,21 +541,21 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) { // TODO: call base classes here? } if (value == MP_OBJ_NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object doesn't support item deletion")); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("'%s' object doesn't support item deletion"), mp_obj_get_type_str(base)); #endif } else if (value == MP_OBJ_SENTINEL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object isn't subscriptable")); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("'%s' object isn't subscriptable"), mp_obj_get_type_str(base)); #endif } else { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object doesn't support item assignment")); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/obj.h b/py/obj.h index 6a040b7773..86e5d83125 100644 --- a/py/obj.h +++ b/py/obj.h @@ -741,8 +741,13 @@ mp_obj_t mp_obj_new_complex(mp_float_t real, mp_float_t imag); mp_obj_t mp_obj_new_exception(const mp_obj_type_t *exc_type); mp_obj_t mp_obj_new_exception_arg1(const mp_obj_type_t *exc_type, mp_obj_t arg); mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, const mp_obj_t *args); +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE +#define mp_obj_new_exception_msg(exc_type, msg) mp_obj_new_exception(exc_type) +#define mp_obj_new_exception_msg_varg(exc_type, ...) mp_obj_new_exception(exc_type) +#else mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg); mp_obj_t mp_obj_new_exception_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...); // counts args by number of % symbols in fmt, excluding %%; can only handle void* sizes (ie no float/double!) +#endif #ifdef va_start mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, va_list arg); // same fmt restrictions as above #endif diff --git a/py/objexcept.c b/py/objexcept.c index f6bffec383..f03bb1b416 100644 --- a/py/objexcept.c +++ b/py/objexcept.c @@ -373,6 +373,8 @@ mp_obj_t mp_obj_new_exception_args(const mp_obj_type_t *exc_type, size_t n_args, return mp_obj_exception_make_new(exc_type, n_args, 0, args); } +#if MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_NONE + mp_obj_t mp_obj_new_exception_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg) { // Check that the given type is an exception type assert(exc_type->make_new == mp_obj_exception_make_new); @@ -518,6 +520,8 @@ mp_obj_t mp_obj_new_exception_msg_vlist(const mp_obj_type_t *exc_type, mp_rom_er return mp_obj_exception_make_new(exc_type, 1, 0, &arg); } +#endif + // return true if the given object is an exception type bool mp_obj_is_exception_type(mp_obj_t self_in) { if (mp_obj_is_type(self_in, &mp_type_type)) { diff --git a/py/objnamedtuple.c b/py/objnamedtuple.c index e4543f5b9b..214cad2572 100644 --- a/py/objnamedtuple.c +++ b/py/objnamedtuple.c @@ -95,7 +95,7 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, const mp_obj_namedtuple_type_t *type = (const mp_obj_namedtuple_type_t *)type_in; size_t num_fields = type->n_fields; if (n_args + n_kw != num_fields) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL mp_raise_msg_varg(&mp_type_TypeError, @@ -121,14 +121,14 @@ STATIC mp_obj_t namedtuple_make_new(const mp_obj_type_t *type_in, size_t n_args, qstr kw = mp_obj_str_get_qstr(args[i]); size_t id = mp_obj_namedtuple_find_field(type, kw); if (id == (size_t)-1) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("unexpected keyword argument '%q'"), kw); #endif } if (tuple->items[id] != MP_OBJ_NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_arg_error_terse_mismatch(); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/objstr.c b/py/objstr.c index 9f8da873d6..98657bd217 100644 --- a/py/objstr.c +++ b/py/objstr.c @@ -942,7 +942,7 @@ STATIC mp_obj_t arg_as_int(mp_obj_t arg) { } #endif -#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE +#if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE STATIC NORETURN void terse_str_format_value_error(void) { mp_raise_ValueError(MP_ERROR_TEXT("bad format string")); } @@ -963,7 +963,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar vstr_add_byte(&vstr, '}'); continue; } - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("single '}' encountered in format string")); @@ -1002,7 +1002,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (str < top && (*str == 'r' || *str == 's')) { conversion = *str++; } else { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #elif MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NORMAL mp_raise_ValueError(MP_ERROR_TEXT("bad conversion specifier")); @@ -1040,14 +1040,14 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } } if (str >= top) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("unmatched '{' in format")); #endif } if (*str != '}') { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("expected ':' after format specifier")); @@ -1060,7 +1060,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar int index = 0; if (MP_LIKELY(unichar_isdigit(*field_name))) { if (*arg_i > 0) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError( @@ -1090,7 +1090,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } } else { if (*arg_i < 0) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError( @@ -1183,7 +1183,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar type = *s++; } if (*s) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("invalid format specifier")); @@ -1204,14 +1204,14 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar if (flags & (PF_FLAG_SHOW_SIGN | PF_FLAG_SPACE_SIGN)) { if (type == 's') { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("sign not allowed in string format specifier")); #endif } if (type == 'c') { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError( @@ -1275,7 +1275,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar break; default: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -1347,7 +1347,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar #endif default: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -1359,7 +1359,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar // arg doesn't look like a number if (align == '=') { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError( @@ -1383,7 +1383,7 @@ STATIC vstr_t mp_obj_str_format_helper(const char *str, const char *top, int *ar } default: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -1412,7 +1412,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ mp_check_self(mp_obj_is_str_or_bytes(pattern)); GET_STR_DATA_LEN(pattern, str, len); - #if MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING > MICROPY_ERROR_REPORTING_TERSE const byte *start_str = str; #endif bool is_bytes = mp_obj_is_type(pattern, &mp_type_bytes); @@ -1444,7 +1444,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ const byte *key = ++str; while (*str != ')') { if (str >= top) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("incomplete format key")); @@ -1508,7 +1508,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ if (str >= top) { incomplete_format: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_ValueError(MP_ERROR_TEXT("incomplete format")); @@ -1594,7 +1594,7 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, size_t n_args, const mp_obj_ break; default: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE terse_str_format_value_error(); #else mp_raise_msg_varg(&mp_type_ValueError, @@ -2131,7 +2131,7 @@ bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) { } STATIC NORETURN void bad_implicit_conversion(mp_obj_t self_in) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't convert to str implicitly")); #else const qstr src_name = mp_obj_get_type(self_in)->name; diff --git a/py/objtype.c b/py/objtype.c index 7f75232941..508bab99d3 100644 --- a/py/objtype.c +++ b/py/objtype.c @@ -348,7 +348,7 @@ mp_obj_t mp_obj_instance_make_new(const mp_obj_type_t *self, size_t n_args, size m_del(mp_obj_t, args2, 2 + n_args + 2 * n_kw); } if (init_ret != mp_const_none) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("__init__() should return None")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -860,7 +860,7 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons mp_obj_t member[2] = {MP_OBJ_NULL, MP_OBJ_NULL}; mp_obj_t call = mp_obj_instance_get_call(self_in, member); if (call == MP_OBJ_NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not callable")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -985,7 +985,7 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, size_t n_args, size_t n_kw, const mp mp_obj_type_t *self = MP_OBJ_TO_PTR(self_in); if (self->make_new == NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("can't create instance")); #else mp_raise_msg_varg(&mp_type_TypeError, MP_ERROR_TEXT("can't create '%q' instances"), self->name); @@ -1125,7 +1125,7 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict) mp_obj_type_t *t = MP_OBJ_TO_PTR(bases_items[i]); // TODO: Verify with CPy, tested on function type if (t->make_new == NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("type isn't an acceptable base type")); #else mp_raise_msg_varg(&mp_type_TypeError, diff --git a/py/parsenum.c b/py/parsenum.c index e665da7d8c..1cfe842577 100644 --- a/py/parsenum.c +++ b/py/parsenum.c @@ -145,7 +145,7 @@ overflow: value_error: { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_obj_t exc = mp_obj_new_exception_msg(&mp_type_ValueError, MP_ERROR_TEXT("invalid syntax for integer")); raise_exc(exc, lex); diff --git a/py/runtime.c b/py/runtime.c index 0ce6854732..18a7c8565d 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -189,7 +189,7 @@ mp_obj_t mp_load_global(qstr qst) { #endif elem = mp_map_lookup((mp_map_t *)&mp_module_builtins_globals.map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); if (elem == NULL) { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_NameError, MP_ERROR_TEXT("name not defined")); #else mp_raise_msg_varg(&mp_type_NameError, MP_ERROR_TEXT("name '%q' isn't defined"), qst); @@ -289,7 +289,7 @@ mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg) { } // With MP_UNARY_OP_INT, mp_unary_op() becomes a fallback for mp_obj_get_int(). // In this case provide a more focused error message to not confuse, e.g. chr(1.0) - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE if (op == MP_UNARY_OP_INT) { mp_raise_TypeError(MP_ERROR_TEXT("can't convert to int")); } else { @@ -610,7 +610,7 @@ generic_binary_op: } unsupported_op: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("unsupported type for operator")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -652,7 +652,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, cons return type->call(fun_in, n_args, n_kw, args); } - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not callable")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -881,13 +881,13 @@ void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { return; too_short: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack")); #else mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("need more than %d values to unpack"), (int)seq_len); #endif too_long: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack")); #else mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("too many values to unpack (expected %d)"), (int)num); @@ -948,7 +948,7 @@ void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { return; too_short: - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_ValueError(MP_ERROR_TEXT("wrong number of values to unpack")); #else mp_raise_msg_varg(&mp_type_ValueError, MP_ERROR_TEXT("need more than %d values to unpack"), (int)seq_len); @@ -1117,7 +1117,7 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) { if (dest[0] == MP_OBJ_NULL) { // no attribute/method called attr - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute")); #else // following CPython, we give a more detailed error message for type objects @@ -1161,7 +1161,7 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { return; } } - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_msg(&mp_type_AttributeError, MP_ERROR_TEXT("no such attribute")); #else mp_raise_msg_varg(&mp_type_AttributeError, @@ -1206,7 +1206,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { } // object not iterable - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not iterable")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -1229,7 +1229,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { // __next__ exists, call it and return its result return mp_call_method_n_kw(0, 0, dest); } else { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -1265,7 +1265,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) { } } } else { - #if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE + #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE mp_raise_TypeError(MP_ERROR_TEXT("object not an iterator")); #else mp_raise_msg_varg(&mp_type_TypeError, @@ -1512,6 +1512,26 @@ NORETURN void m_malloc_fail(size_t num_bytes) { MP_ERROR_TEXT("memory allocation failed, allocating %u bytes"), (uint)num_bytes); } +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE + +NORETURN void mp_raise_type(const mp_obj_type_t *exc_type) { + nlr_raise(mp_obj_new_exception(exc_type)); +} + +NORETURN void mp_raise_ValueError_no_msg(void) { + mp_raise_type(&mp_type_ValueError); +} + +NORETURN void mp_raise_TypeError_no_msg(void) { + mp_raise_type(&mp_type_TypeError); +} + +NORETURN void mp_raise_NotImplementedError_no_msg(void) { + mp_raise_type(&mp_type_NotImplementedError); +} + +#else + NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg) { if (msg == NULL) { nlr_raise(mp_obj_new_exception(exc_type)); @@ -1536,14 +1556,16 @@ NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_TypeError, msg); } -NORETURN void mp_raise_OSError(int errno_) { - nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_))); -} - NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg) { mp_raise_msg(&mp_type_NotImplementedError, msg); } +#endif + +NORETURN void mp_raise_OSError(int errno_) { + nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_))); +} + #if MICROPY_STACK_CHECK || MICROPY_ENABLE_PYSTACK NORETURN void mp_raise_recursion_depth(void) { nlr_raise(mp_obj_new_exception_arg1(&mp_type_RuntimeError, diff --git a/py/runtime.h b/py/runtime.h index 0bf988b905..0cbbb287ac 100644 --- a/py/runtime.h +++ b/py/runtime.h @@ -159,12 +159,25 @@ mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level); mp_obj_t mp_import_from(mp_obj_t module, qstr name); void mp_import_all(mp_obj_t module); +#if MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_NONE +NORETURN void mp_raise_type(const mp_obj_type_t *exc_type); +NORETURN void mp_raise_ValueError_no_msg(void); +NORETURN void mp_raise_TypeError_no_msg(void); +NORETURN void mp_raise_NotImplementedError_no_msg(void); +#define mp_raise_msg(exc_type, msg) mp_raise_type(exc_type) +#define mp_raise_msg_varg(exc_type, ...) mp_raise_type(exc_type) +#define mp_raise_ValueError(msg) mp_raise_ValueError_no_msg() +#define mp_raise_TypeError(msg) mp_raise_TypeError_no_msg() +#define mp_raise_NotImplementedError(msg) mp_raise_NotImplementedError_no_msg() +#else #define mp_raise_type(exc_type) mp_raise_msg(exc_type, NULL) NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, mp_rom_error_text_t msg); NORETURN void mp_raise_msg_varg(const mp_obj_type_t *exc_type, mp_rom_error_text_t fmt, ...); NORETURN void mp_raise_ValueError(mp_rom_error_text_t msg); NORETURN void mp_raise_TypeError(mp_rom_error_text_t msg); NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg); +#endif + NORETURN void mp_raise_OSError(int errno_); NORETURN void mp_raise_recursion_depth(void);