py: Use shorter, static error msgs when ERROR_REPORTING_TERSE enabled.

Going from MICROPY_ERROR_REPORTING_NORMAL to
MICROPY_ERROR_REPORTING_TERSE now saves 2020 bytes ROM for ARM Thumb2,
and 2200 bytes ROM for 32-bit x86.

This is about a 2.5% code size reduction for bare-arm.
This commit is contained in:
Damien George 2014-11-06 17:36:16 +00:00
parent b6b34cd3f6
commit 1e9a92f84f
10 changed files with 436 additions and 123 deletions

View File

@ -12,6 +12,8 @@
#define MICROPY_HELPER_REPL (0) #define MICROPY_HELPER_REPL (0)
#define MICROPY_HELPER_LEXER_UNIX (0) #define MICROPY_HELPER_LEXER_UNIX (0)
#define MICROPY_ENABLE_SOURCE_LINE (0) #define MICROPY_ENABLE_SOURCE_LINE (0)
#define MICROPY_ENABLE_DOC_STRING (0)
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
#define MICROPY_PY_BUILTINS_BYTEARRAY (0) #define MICROPY_PY_BUILTINS_BYTEARRAY (0)
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0) #define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
#define MICROPY_PY_BUILTINS_FROZENSET (0) #define MICROPY_PY_BUILTINS_FROZENSET (0)
@ -31,8 +33,6 @@
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE) #define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE) #define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
//#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
// type definitions for the specific machine // type definitions for the specific machine
#define BYTES_PER_WORD (4) #define BYTES_PER_WORD (4)

View File

@ -34,28 +34,49 @@
#include "obj.h" #include "obj.h"
#include "runtime.h" #include "runtime.h"
STATIC NORETURN void terse_arg_mismatch(void) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "argument num/types mismatch"));
}
void mp_arg_check_num(mp_uint_t n_args, mp_uint_t n_kw, mp_uint_t n_args_min, mp_uint_t n_args_max, bool takes_kw) { void mp_arg_check_num(mp_uint_t n_args, mp_uint_t n_kw, mp_uint_t n_args_min, mp_uint_t n_args_max, bool takes_kw) {
// TODO maybe take the function name as an argument so we can print nicer error messages // TODO maybe take the function name as an argument so we can print nicer error messages
if (n_kw && !takes_kw) { if (n_kw && !takes_kw) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_arg_mismatch();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"function does not take keyword arguments"));
}
} }
if (n_args_min == n_args_max) { if (n_args_min == n_args_max) {
if (n_args != n_args_min) { if (n_args != n_args_min) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
"function takes %d positional arguments but %d were given", terse_arg_mismatch();
n_args_min, n_args)); } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"function takes %d positional arguments but %d were given",
n_args_min, n_args));
}
} }
} else { } else {
if (n_args < n_args_min) { if (n_args < n_args_min) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
"function missing %d required positional arguments", terse_arg_mismatch();
n_args_min - n_args)); } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"function missing %d required positional arguments",
n_args_min - n_args));
}
} else if (n_args > n_args_max) { } else if (n_args > n_args_max) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
"function expected at most %d arguments, got %d", terse_arg_mismatch();
n_args_max, n_args)); } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"function expected at most %d arguments, got %d",
n_args_max, n_args));
}
} }
} }
} }
@ -74,7 +95,13 @@ void mp_arg_parse_all(mp_uint_t n_pos, const mp_obj_t *pos, mp_map_t *kws, mp_ui
mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qstr), MP_MAP_LOOKUP); mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qstr), MP_MAP_LOOKUP);
if (kw == NULL) { if (kw == NULL) {
if (allowed[i].flags & MP_ARG_REQUIRED) { if (allowed[i].flags & MP_ARG_REQUIRED) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' argument required", qstr_str(allowed[i].qstr))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_arg_mismatch();
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' argument required",
qstr_str(allowed[i].qstr)));
}
} }
out_vals[i] = allowed[i].defval; out_vals[i] = allowed[i].defval;
continue; continue;
@ -94,13 +121,23 @@ void mp_arg_parse_all(mp_uint_t n_pos, const mp_obj_t *pos, mp_map_t *kws, mp_ui
} }
} }
if (pos_found < n_pos) { if (pos_found < n_pos) {
// TODO better error message
extra_positional: extra_positional:
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "extra positional arguments given")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_arg_mismatch();
} else {
// TODO better error message
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"extra positional arguments given"));
}
} }
if (kws_found < kws->used) { if (kws_found < kws->used) {
// TODO better error message if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "extra keyword arguments given")); terse_arg_mismatch();
} else {
// TODO better error message
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"extra keyword arguments given"));
}
} }
} }

View File

@ -272,7 +272,14 @@ STATIC mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
return mp_obj_new_tuple(2, tuple); return mp_obj_new_tuple(2, tuple);
#endif #endif
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported operand type(s) for divmod(): '%s' and '%s'", mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"unsupported operand type(s) for divmod()"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"unsupported operand type(s) for divmod(): '%s' and '%s'",
mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in)));
}
} }
} }
MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_divmod_obj, mp_builtin_divmod); MP_DEFINE_CONST_FUN_OBJ_2(mp_builtin_divmod_obj, mp_builtin_divmod);
@ -357,8 +364,8 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
mp_uint_t len; mp_uint_t len;
const char *str = mp_obj_str_get_data(o_in, &len); const char *str = mp_obj_str_get_data(o_in, &len);
#if MICROPY_PY_BUILTINS_STR_UNICODE #if MICROPY_PY_BUILTINS_STR_UNICODE
mp_uint_t charlen = unichar_charlen(str, len); len = unichar_charlen(str, len);
if (charlen == 1) { if (len == 1) {
if (MP_OBJ_IS_STR(o_in) && UTF8_IS_NONASCII(*str)) { if (MP_OBJ_IS_STR(o_in) && UTF8_IS_NONASCII(*str)) {
mp_int_t ord = *str++ & 0x7F; mp_int_t ord = *str++ & 0x7F;
for (mp_int_t mask = 0x40; ord & mask; mask >>= 1) { for (mp_int_t mask = 0x40; ord & mask; mask >>= 1) {
@ -371,17 +378,21 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
} else { } else {
return mp_obj_new_int(((const byte*)str)[0]); return mp_obj_new_int(((const byte*)str)[0]);
} }
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "ord() expected a character, but string of length %d found", charlen));
} }
#else #else
if (len == 1) { if (len == 1) {
// don't sign extend when converting to ord // don't sign extend when converting to ord
return mp_obj_new_int(((const byte*)str)[0]); return mp_obj_new_int(((const byte*)str)[0]);
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "ord() expected a character, but string of length %d found", len));
} }
#endif #endif
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"ord expects a character"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"ord() expected a character, but string of length %d found", len));
}
} }
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_ord_obj, mp_builtin_ord); MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_ord_obj, mp_builtin_ord);

View File

@ -118,7 +118,12 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
if (lex == NULL) { if (lex == NULL) {
// we verified the file exists using stat, but lexer could still fail // we verified the file exists using stat, but lexer could still fail
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "No module named '%s'", vstr_str(file))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "module not found"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
"no module named '%s'", vstr_str(file)));
}
} }
#if MICROPY_PY___FILE__ #if MICROPY_PY___FILE__
@ -277,7 +282,12 @@ mp_obj_t mp_builtin___import__(mp_uint_t n_args, const mp_obj_t *args) {
{ {
#endif #endif
// couldn't find the file, so fail // couldn't find the file, so fail
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "No module named '%s'", qstr_str(mod_name))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "module not found"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
"no module named '%s'", qstr_str(mod_name)));
}
} }
} else { } else {
// found the file, so get the module // found the file, so get the module

View File

@ -238,7 +238,7 @@ typedef long long mp_longint_impl_t;
#define MICROPY_ENABLE_DOC_STRING (0) #define MICROPY_ENABLE_DOC_STRING (0)
#endif #endif
// Exception messages are short static strings (TODO) // Exception messages are short static strings
#define MICROPY_ERROR_REPORTING_TERSE (1) #define MICROPY_ERROR_REPORTING_TERSE (1)
// Exception messages provide basic error details // Exception messages provide basic error details
#define MICROPY_ERROR_REPORTING_NORMAL (2) #define MICROPY_ERROR_REPORTING_NORMAL (2)

106
py/obj.c
View File

@ -177,7 +177,12 @@ mp_int_t mp_obj_hash(mp_obj_t o_in) {
// TODO delegate to __hash__ method if it exists // TODO delegate to __hash__ method if it exists
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unhashable type: '%s'", mp_obj_get_type_str(o_in))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unhashable type"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"unhashable type: '%s'", mp_obj_get_type_str(o_in)));
}
} }
} }
@ -230,9 +235,14 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
} }
} }
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NotImplementedError, if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
"Equality for '%s' and '%s' types not yet implemented", mp_obj_get_type_str(o1), mp_obj_get_type_str(o2))); nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
return false; "equality for given types not yet implemented"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NotImplementedError,
"equality for '%s' and '%s' types not yet implemented",
mp_obj_get_type_str(o1), mp_obj_get_type_str(o2)));
}
} }
mp_int_t mp_obj_get_int(mp_const_obj_t arg) { mp_int_t mp_obj_get_int(mp_const_obj_t arg) {
@ -248,7 +258,13 @@ mp_int_t mp_obj_get_int(mp_const_obj_t arg) {
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) { } else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) {
return mp_obj_int_get_checked(arg); return mp_obj_int_get_checked(arg);
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"can't convert to int"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"can't convert %s to int", mp_obj_get_type_str(arg)));
}
} }
} }
@ -283,7 +299,13 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) {
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) { } else if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
return mp_obj_float_get(arg); return mp_obj_float_get(arg);
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"can't convert to float"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"can't convert %s to float", mp_obj_get_type_str(arg)));
}
} }
} }
@ -307,7 +329,13 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_complex)) { } else if (MP_OBJ_IS_TYPE(arg, &mp_type_complex)) {
mp_obj_complex_get(arg, real, imag); mp_obj_complex_get(arg, real, imag);
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"can't convert to complex"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"can't convert %s to complex", mp_obj_get_type_str(arg)));
}
} }
} }
#endif #endif
@ -319,7 +347,13 @@ void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items) {
} else if (MP_OBJ_IS_TYPE(o, &mp_type_list)) { } else if (MP_OBJ_IS_TYPE(o, &mp_type_list)) {
mp_obj_list_get(o, len, items); mp_obj_list_get(o, len, items);
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"expected tuple/list"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"object '%s' is not a tuple or list", mp_obj_get_type_str(o)));
}
} }
} }
@ -327,7 +361,13 @@ void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items) {
mp_uint_t seq_len; mp_uint_t seq_len;
mp_obj_get_array(o, &seq_len, items); mp_obj_get_array(o, &seq_len, items);
if (seq_len != len) { if (seq_len != len) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "requested length %d but object has length %d", len, seq_len)); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"tuple/list has wrong length"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"requested length %d but object has length %d", len, seq_len));
}
} }
} }
@ -337,7 +377,14 @@ mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index,
if (MP_OBJ_IS_SMALL_INT(index)) { if (MP_OBJ_IS_SMALL_INT(index)) {
i = MP_OBJ_SMALL_INT_VALUE(index); i = MP_OBJ_SMALL_INT_VALUE(index);
} else if (!mp_obj_get_int_maybe(index, &i)) { } else if (!mp_obj_get_int_maybe(index, &i)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "%s indices must be integers, not %s", qstr_str(type->name), mp_obj_get_type_str(index))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"indices must be integers"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"%s indices must be integers, not %s",
qstr_str(type->name), mp_obj_get_type_str(index)));
}
} }
if (i < 0) { if (i < 0) {
@ -351,7 +398,12 @@ mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index,
} }
} else { } else {
if (i < 0 || i >= len) { if (i < 0 || i >= len) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "%s index out of range", qstr_str(type->name))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "index out of range"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError,
"%s index out of range", qstr_str(type->name)));
}
} }
} }
return i; return i;
@ -379,7 +431,13 @@ 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 mp_obj_len(mp_obj_t o_in) {
mp_obj_t len = mp_obj_len_maybe(o_in); mp_obj_t len = mp_obj_len_maybe(o_in);
if (len == MP_OBJ_NULL) { if (len == MP_OBJ_NULL) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object of type '%s' has no len()", mp_obj_get_type_str(o_in))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"object has no len"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"object of type '%s' has no len()", mp_obj_get_type_str(o_in)));
}
} else { } else {
return len; return len;
} }
@ -414,11 +472,29 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
// TODO: call base classes here? // TODO: call base classes here?
} }
if (value == MP_OBJ_NULL) { if (value == MP_OBJ_NULL) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item deletion", mp_obj_get_type_str(base))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"object does not support item deletion"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object does not support item deletion", mp_obj_get_type_str(base)));
}
} else if (value == MP_OBJ_SENTINEL) { } else if (value == MP_OBJ_SENTINEL) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not subscriptable", mp_obj_get_type_str(base))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"object is not subscriptable"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not subscriptable", mp_obj_get_type_str(base)));
}
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item assignment", mp_obj_get_type_str(base))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"object does not support item assignment"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object does not support item assignment", mp_obj_get_type_str(base)));
}
} }
} }

View File

@ -143,12 +143,13 @@ STATIC mp_obj_t str_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw,
} }
#endif #endif
mp_arg_check_num(n_args, n_kw, 0, 3, false);
switch (n_args) { switch (n_args) {
case 0: case 0:
return MP_OBJ_NEW_QSTR(MP_QSTR_); return MP_OBJ_NEW_QSTR(MP_QSTR_);
case 1: case 1: {
{
vstr_t *vstr = vstr_new(); vstr_t *vstr = vstr_new();
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, args[0], PRINT_STR); mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, vstr, args[0], PRINT_STR);
mp_obj_t s = mp_obj_new_str(vstr->buf, vstr->len, false); mp_obj_t s = mp_obj_new_str(vstr->buf, vstr->len, false);
@ -156,9 +157,7 @@ STATIC mp_obj_t str_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw,
return s; return s;
} }
case 2: default: // 2 or 3 args
case 3:
{
// TODO: validate 2nd/3rd args // TODO: validate 2nd/3rd args
if (MP_OBJ_IS_TYPE(args[0], &mp_type_bytes)) { if (MP_OBJ_IS_TYPE(args[0], &mp_type_bytes)) {
GET_STR_DATA_LEN(args[0], str_data, str_len); GET_STR_DATA_LEN(args[0], str_data, str_len);
@ -172,10 +171,6 @@ STATIC mp_obj_t str_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_kw,
mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ); mp_get_buffer_raise(args[0], &bufinfo, MP_BUFFER_READ);
return mp_obj_new_str(bufinfo.buf, bufinfo.len, false); return mp_obj_new_str(bufinfo.buf, bufinfo.len, false);
} }
}
default:
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "str takes at most 3 arguments"));
} }
} }
@ -251,7 +246,7 @@ STATIC mp_obj_t bytes_make_new(mp_obj_t type_in, mp_uint_t n_args, mp_uint_t n_k
return mp_obj_str_builder_end(o); return mp_obj_str_builder_end(o);
wrong_args: wrong_args:
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "wrong number of arguments")); nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "wrong number of arguments"));
} }
// like strstr but with specified length and allows \0 bytes // like strstr but with specified length and allows \0 bytes
@ -831,6 +826,10 @@ static mp_obj_t arg_as_int(mp_obj_t arg) {
return arg; return arg;
} }
STATIC NORETURN void terse_str_format_value_error(void) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "bad format string"));
}
mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) { mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
assert(MP_OBJ_IS_STR_OR_BYTES(args[0])); assert(MP_OBJ_IS_STR_OR_BYTES(args[0]));
@ -848,7 +847,12 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
vstr_add_char(vstr, '}'); vstr_add_char(vstr, '}');
continue; continue;
} }
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "single '}' encountered in format string")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"single '}' encountered in format string"));
}
} }
if (*str != '{') { if (*str != '{') {
vstr_add_char(vstr, *str); vstr_add_char(vstr, *str);
@ -882,7 +886,12 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
if (str < top && (*str == 'r' || *str == 's')) { if (str < top && (*str == 'r' || *str == 's')) {
conversion = *str++; conversion = *str++;
} else { } else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "end of format while looking for conversion specifier")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"end of format while looking for conversion specifier"));
}
} }
} }
@ -902,17 +911,32 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
} }
} }
if (str >= top) { if (str >= top) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "unmatched '{' in format")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"unmatched '{' in format"));
}
} }
if (*str != '}') { if (*str != '}') {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "expected ':' after format specifier")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"expected ':' after format specifier"));
}
} }
mp_obj_t arg = mp_const_none; mp_obj_t arg = mp_const_none;
if (field_name) { if (field_name) {
if (arg_i > 0) { if (arg_i > 0) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "can't switch from automatic field numbering to manual field specification")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"can't switch from automatic field numbering to manual field specification"));
}
} }
int index = 0; int index = 0;
if (str_to_int(vstr_str(field_name), &index) != vstr_len(field_name) - 1) { if (str_to_int(vstr_str(field_name), &index) != vstr_len(field_name) - 1) {
@ -927,7 +951,12 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
field_name = NULL; field_name = NULL;
} else { } else {
if (arg_i < 0) { if (arg_i < 0) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "can't switch from manual field specification to automatic field numbering")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"can't switch from manual field specification to automatic field numbering"));
}
} }
if (arg_i >= n_args - 1) { if (arg_i >= n_args - 1) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "tuple index out of range")); nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "tuple index out of range"));
@ -945,7 +974,12 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
} else if (conversion == 'r') { } else if (conversion == 'r') {
print_kind = PRINT_REPR; print_kind = PRINT_REPR;
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "unknown conversion specifier %c", conversion)); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"unknown conversion specifier %c", conversion));
}
} }
vstr_t *arg_vstr = vstr_new(); vstr_t *arg_vstr = vstr_new();
mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, arg_vstr, arg, print_kind); mp_obj_print_helper((void (*)(void*, const char*, ...))vstr_printf, arg_vstr, arg, print_kind);
@ -1030,10 +1064,20 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
if (sign) { if (sign) {
if (type == 's') { if (type == 's') {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sign not allowed in string format specifier")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"sign not allowed in string format specifier"));
}
} }
if (type == 'c') { if (type == 'c') {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "Sign not allowed with integer format specifier 'c'")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"sign not allowed with integer format specifier 'c'"));
}
} }
} else { } else {
sign = '-'; sign = '-';
@ -1089,8 +1133,13 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
break; break;
default: default:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
"unknown format code '%c' for object of type '%s'", type, mp_obj_get_type_str(arg))); terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"unknown format code '%c' for object of type '%s'",
type, mp_obj_get_type_str(arg)));
}
} }
} }
@ -1151,15 +1200,24 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
#endif #endif
default: default:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
"unknown format code '%c' for object of type 'float'", terse_str_format_value_error();
type, mp_obj_get_type_str(arg))); } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"unknown format code '%c' for object of type 'float'",
type, mp_obj_get_type_str(arg)));
}
} }
} else { } else {
// arg doesn't look like a number // arg doesn't look like a number
if (align == '=') { if (align == '=') {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "'=' alignment not allowed in string format specifier")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"'=' alignment not allowed in string format specifier"));
}
} }
switch (type) { switch (type) {
@ -1181,9 +1239,13 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
} }
default: default:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
"unknown format code '%c' for object of type 'str'", terse_str_format_value_error();
type, mp_obj_get_type_str(arg))); } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"unknown format code '%c' for object of type 'str'",
type, mp_obj_get_type_str(arg)));
}
} }
} }
} }
@ -1223,7 +1285,12 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, mp_uint_t n_args, const mp_o
const byte *key = ++str; const byte *key = ++str;
while (*str != ')') { while (*str != ')') {
if (str >= top) { if (str >= top) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "incomplete format key")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"incomplete format key"));
}
} }
++str; ++str;
} }
@ -1280,7 +1347,12 @@ STATIC mp_obj_t str_modulo_format(mp_obj_t pattern, mp_uint_t n_args, const mp_o
} }
if (str >= top) { if (str >= top) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "incomplete format")); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_str_format_value_error();
} else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"incomplete format"));
}
} }
// Tuple value lookup // Tuple value lookup
@ -1297,25 +1369,17 @@ not_enough_args:
mp_uint_t len; mp_uint_t len;
const char *s = mp_obj_str_get_data(arg, &len); const char *s = mp_obj_str_get_data(arg, &len);
if (len != 1) { if (len != 1) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "%%c requires int or char")); nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
break; "%%c requires int or char"));
} }
pfenv_print_strn(&pfenv_vstr, s, 1, flags, ' ', width); pfenv_print_strn(&pfenv_vstr, s, 1, flags, ' ', width);
break; } else if (arg_looks_integer(arg)) {
}
if (arg_looks_integer(arg)) {
char ch = mp_obj_get_int(arg); char ch = mp_obj_get_int(arg);
pfenv_print_strn(&pfenv_vstr, &ch, 1, flags, ' ', width); pfenv_print_strn(&pfenv_vstr, &ch, 1, flags, ' ', width);
break; } else {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"integer required"));
} }
#if MICROPY_PY_BUILTINS_FLOAT
// This is what CPython reports, so we report the same.
if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "integer argument expected, got float"));
}
#endif
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "an integer is required"));
break; break;
case 'd': case 'd':
@ -1366,9 +1430,13 @@ not_enough_args:
break; break;
default: default:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
"unsupported format character '%c' (0x%x) at index %d", terse_str_format_value_error();
*str, *str, str - start_str)); } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"unsupported format character '%c' (0x%x) at index %d",
*str, *str, str - start_str));
}
} }
} }
@ -1871,7 +1939,14 @@ bool mp_obj_str_equal(mp_obj_t s1, mp_obj_t s2) {
} }
STATIC void bad_implicit_conversion(mp_obj_t self_in) { STATIC void bad_implicit_conversion(mp_obj_t self_in) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "Can't convert '%s' object to str implicitly", mp_obj_get_type_str(self_in))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"can't convert to str implicitly"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"can't convert '%s' object to str implicitly",
mp_obj_get_type_str(self_in)));
}
} }
STATIC void arg_type_mixup() { STATIC void arg_type_mixup() {

View File

@ -313,7 +313,13 @@ mp_obj_t instance_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, c
m_del(mp_obj_t, args2, 2 + n_args + 2 * n_kw); m_del(mp_obj_t, args2, 2 + n_args + 2 * n_kw);
} }
if (init_ret != mp_const_none) { if (init_ret != mp_const_none) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"__init__() should return None"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"__init__() should return None, not '%s'", mp_obj_get_type_str(init_ret)));
}
} }
} }
@ -617,7 +623,13 @@ mp_obj_t mp_obj_instance_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw
}; };
mp_obj_class_lookup(&lookup, self->base.type); mp_obj_class_lookup(&lookup, self->base.type);
if (member[0] == MP_OBJ_NULL) { if (member[0] == MP_OBJ_NULL) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(self_in))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"object not callable"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not callable", mp_obj_get_type_str(self_in)));
}
} }
if (member[0] == MP_OBJ_SENTINEL) { if (member[0] == MP_OBJ_SENTINEL) {
return mp_call_function_n_kw(self->subobj[0], n_args, n_kw, args); return mp_call_function_n_kw(self->subobj[0], n_args, n_kw, args);
@ -691,7 +703,12 @@ STATIC mp_obj_t type_call(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, co
mp_obj_type_t *self = self_in; mp_obj_type_t *self = self_in;
if (self->make_new == NULL) { if (self->make_new == NULL) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "cannot create '%s' instances", qstr_str(self->name))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "cannot create instance"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"cannot create '%s' instances", qstr_str(self->name)));
}
} }
// make new instance // make new instance
@ -787,7 +804,13 @@ mp_obj_t mp_obj_new_type(qstr name, mp_obj_t bases_tuple, mp_obj_t locals_dict)
mp_obj_type_t *t = items[i]; mp_obj_type_t *t = items[i];
// TODO: Verify with CPy, tested on function type // TODO: Verify with CPy, tested on function type
if (t->make_new == NULL) { if (t->make_new == NULL) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "type '%s' is not an acceptable base type", qstr_str(t->name))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"type is not an acceptable base type"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"type '%s' is not an acceptable base type", qstr_str(t->name)));
}
} }
} }
@ -996,9 +1019,7 @@ mp_obj_t mp_instance_cast_to_native_base(mp_const_obj_t self_in, mp_const_obj_t
STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { STATIC mp_obj_t static_class_method_make_new(mp_obj_t self_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) {
assert(self_in == &mp_type_staticmethod || self_in == &mp_type_classmethod); assert(self_in == &mp_type_staticmethod || self_in == &mp_type_classmethod);
if (n_args != 1 || n_kw != 0) { mp_arg_check_num(n_args, n_kw, 1, 1, false);
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "function takes 1 positional argument but %d were given", n_args));
}
mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t); mp_obj_static_class_method_t *o = m_new_obj(mp_obj_static_class_method_t);
*o = (mp_obj_static_class_method_t){{(mp_obj_type_t*)self_in}, args[0]}; *o = (mp_obj_static_class_method_t){{(mp_obj_type_t*)self_in}, args[0]};

View File

@ -138,7 +138,13 @@ overflow:
} }
value_error: value_error:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "invalid syntax for integer with base %d: '%s'", base, str)); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"invalid syntax for integer"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"invalid syntax for integer with base %d: '%s'", base, str));
}
} }
typedef enum { typedef enum {

View File

@ -165,7 +165,13 @@ mp_obj_t mp_load_global(qstr qstr) {
// TODO lookup in dynamic table of builtins first // TODO lookup in dynamic table of builtins first
elem = mp_map_lookup((mp_map_t*)&mp_builtin_object_dict_obj.map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP); elem = mp_map_lookup((mp_map_t*)&mp_builtin_object_dict_obj.map, MP_OBJ_NEW_QSTR(qstr), MP_MAP_LOOKUP);
if (elem == NULL) { if (elem == NULL) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NameError, "name '%s' is not defined", qstr_str(qstr))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_NameError,
"name not defined"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NameError,
"name '%s' is not defined", qstr_str(qstr)));
}
} }
} }
return elem->value; return elem->value;
@ -231,8 +237,15 @@ mp_obj_t mp_unary_op(mp_uint_t op, mp_obj_t arg) {
return result; return result;
} }
} }
// TODO specify in error message what the operator is if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "bad operand type for unary operator: '%s'", mp_obj_get_type_str(arg))); nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"unsupported type for operator"));
} else {
// TODO specify in error message what the operator is
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"bad operand type for unary operator: '%s'",
mp_obj_get_type_str(arg)));
}
} }
} }
@ -496,10 +509,13 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) {
return mp_const_false; return mp_const_false;
} }
nlr_raise(mp_obj_new_exception_msg_varg( if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
&mp_type_TypeError, "'%s' object is not iterable", nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
mp_obj_get_type_str(rhs))); "object not iterable"));
return mp_const_none; } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not iterable", mp_obj_get_type_str(rhs)));
}
} }
// generic binary_op supplied by type // generic binary_op supplied by type
@ -515,12 +531,16 @@ generic_binary_op:
// TODO implement dispatch for reverse binary ops // TODO implement dispatch for reverse binary ops
// TODO specify in error message what the operator is
unsupported_op: unsupported_op:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
"unsupported operand types for binary operator: '%s', '%s'", nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs))); "unsupported type for operator"));
return mp_const_none; } else {
// TODO specify in error message what the operator is
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"unsupported operand types for binary operator: '%s', '%s'",
mp_obj_get_type_str(lhs), mp_obj_get_type_str(rhs)));
}
zero_division: zero_division:
nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "division by zero")); nlr_raise(mp_obj_new_exception_msg(&mp_type_ZeroDivisionError, "division by zero"));
@ -556,7 +576,13 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, mp_uint_t n_args, mp_uint_t n_kw
return type->call(fun_in, n_args, n_kw, args); return type->call(fun_in, n_args, n_kw, args);
} }
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(fun_in))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"object not callable"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not callable", mp_obj_get_type_str(fun_in)));
}
} }
// args contains: fun self/NULL arg(0) ... arg(n_args-2) arg(n_args-1) kw_key(0) kw_val(0) ... kw_key(n_kw-1) kw_val(n_kw-1) // args contains: fun self/NULL arg(0) ... arg(n_args-2) arg(n_args-1) kw_key(0) kw_val(0) ... kw_key(n_kw-1) kw_val(n_kw-1)
@ -746,9 +772,21 @@ void mp_unpack_sequence(mp_obj_t seq_in, mp_uint_t num, mp_obj_t *items) {
return; return;
too_short: too_short:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", seq_len)); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"wrong number of values to unpack"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"need more than %d values to unpack", seq_len));
}
too_long: too_long:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "too many values to unpack (expected %d)", num)); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"wrong number of values to unpack"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"too many values to unpack (expected %d)", num));
}
} }
// unpacked items are stored in reverse order into the array pointed to by items // unpacked items are stored in reverse order into the array pointed to by items
@ -809,7 +847,13 @@ void mp_unpack_ex(mp_obj_t seq_in, mp_uint_t num_in, mp_obj_t *items) {
return; return;
too_short: too_short:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", seq_len)); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
"wrong number of values to unpack"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
"need more than %d values to unpack", seq_len));
}
} }
mp_obj_t mp_load_attr(mp_obj_t base, qstr attr) { mp_obj_t mp_load_attr(mp_obj_t base, qstr attr) {
@ -891,12 +935,20 @@ void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest) {
if (dest[0] == MP_OBJ_NULL) { if (dest[0] == MP_OBJ_NULL) {
// no attribute/method called attr // no attribute/method called attr
// following CPython, we give a more detailed error message for type objects if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
if (MP_OBJ_IS_TYPE(base, &mp_type_type)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError,
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, "no such attribute"));
"type object '%s' has no attribute '%s'", qstr_str(((mp_obj_type_t*)base)->name), qstr_str(attr)));
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr))); // following CPython, we give a more detailed error message for type objects
if (MP_OBJ_IS_TYPE(base, &mp_type_type)) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError,
"type object '%s' has no attribute '%s'",
qstr_str(((mp_obj_type_t*)base)->name), qstr_str(attr)));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError,
"'%s' object has no attribute '%s'",
mp_obj_get_type_str(base), qstr_str(attr)));
}
} }
} }
} }
@ -909,7 +961,14 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) {
return; return;
} }
} }
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError, "'%s' object has no attribute '%s'", mp_obj_get_type_str(base), qstr_str(attr))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_AttributeError,
"no such attribute"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_AttributeError,
"'%s' object has no attribute '%s'",
mp_obj_get_type_str(base), qstr_str(attr)));
}
} }
mp_obj_t mp_getiter(mp_obj_t o_in) { mp_obj_t mp_getiter(mp_obj_t o_in) {
@ -936,7 +995,13 @@ mp_obj_t mp_getiter(mp_obj_t o_in) {
} else { } else {
// object not iterable // object not iterable
not_iterable: not_iterable:
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(o_in))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"object not iterable"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not iterable", mp_obj_get_type_str(o_in)));
}
} }
} }
} }
@ -956,7 +1021,13 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
// __next__ exists, call it and return its result // __next__ exists, call it and return its result
return mp_call_method_n_kw(0, 0, dest); return mp_call_method_n_kw(0, 0, dest);
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"object not an iterator"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not an iterator", mp_obj_get_type_str(o_in)));
}
} }
} }
} }
@ -986,7 +1057,13 @@ mp_obj_t mp_iternext(mp_obj_t o_in) {
} }
} }
} else { } else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
"object not an iterator"));
} else {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"'%s' object is not an iterator", mp_obj_get_type_str(o_in)));
}
} }
} }
} }