Commit 1e9a92f8 authored by Damien George's avatar Damien George
Browse files

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.
parent b6b34cd3
......@@ -12,6 +12,8 @@
#define MICROPY_HELPER_REPL (0)
#define MICROPY_HELPER_LEXER_UNIX (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_MEMORYVIEW (0)
#define MICROPY_PY_BUILTINS_FROZENSET (0)
......@@ -31,8 +33,6 @@
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
//#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
// type definitions for the specific machine
#define BYTES_PER_WORD (4)
......
......@@ -34,28 +34,49 @@
#include "obj.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) {
// TODO maybe take the function name as an argument so we can print nicer error messages
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 != n_args_min) {
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));
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_arg_mismatch();
} 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 {
if (n_args < n_args_min) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"function missing %d required positional arguments",
n_args_min - n_args));
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_arg_mismatch();
} 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) {
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
"function expected at most %d arguments, got %d",
n_args_max, n_args));
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
terse_arg_mismatch();
} 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);
if (kw == NULL) {
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;
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) {
// TODO better error message
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) {
// TODO better error message
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "extra keyword 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 keyword arguments given"));
}
}
}
......
......@@ -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);
#endif
} 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);
......@@ -357,8 +364,8 @@ STATIC mp_obj_t mp_builtin_ord(mp_obj_t o_in) {
mp_uint_t len;
const char *str = mp_obj_str_get_data(o_in, &len);
#if MICROPY_PY_BUILTINS_STR_UNICODE
mp_uint_t charlen = unichar_charlen(str, len);
if (charlen == 1) {
len = unichar_charlen(str, len);
if (len == 1) {
if (MP_OBJ_IS_STR(o_in) && UTF8_IS_NONASCII(*str)) {
mp_int_t ord = *str++ & 0x7F;
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 {
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
if (len == 1) {
// don't sign extend when converting to ord
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
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);
......
......@@ -118,7 +118,12 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
if (lex == NULL) {
// 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__
......@@ -277,7 +282,12 @@ mp_obj_t mp_builtin___import__(mp_uint_t n_args, const mp_obj_t *args) {
{
#endif
// 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 {
// found the file, so get the module
......
......@@ -238,7 +238,7 @@ typedef long long mp_longint_impl_t;
#define MICROPY_ENABLE_DOC_STRING (0)
#endif
// Exception messages are short static strings (TODO)
// Exception messages are short static strings
#define MICROPY_ERROR_REPORTING_TERSE (1)
// Exception messages provide basic error details
#define MICROPY_ERROR_REPORTING_NORMAL (2)
......
......@@ -177,7 +177,12 @@ mp_int_t mp_obj_hash(mp_obj_t o_in) {
// TODO delegate to __hash__ method if it exists
} 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,
"Equality for '%s' and '%s' types not yet implemented", mp_obj_get_type_str(o1), mp_obj_get_type_str(o2)));
return false;
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
"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) {
......@@ -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)) {
return mp_obj_int_get_checked(arg);
} 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)) {
return mp_obj_float_get(arg);
} 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)) {
mp_obj_complex_get(arg, real, imag);
} 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
......@@ -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)) {
mp_obj_list_get(o, len, items);
} 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_obj_get_array(o, &seq_len, items);
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)) {
i = MP_OBJ_SMALL_INT_VALUE(index);
} 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) {
......@@ -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 {
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;
......@@ -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 len = mp_obj_len_maybe(o_in);
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 {
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?
}
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) {
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 {
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)));
}
}
}
......
......@@ -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
mp_arg_check_num(n_args, n_kw, 0, 3, false);
switch (n_args) {
case 0:
return MP_OBJ_NEW_QSTR(MP_QSTR_);
case 1:
{
case 1: {
vstr_t *vstr = vstr_new();
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);
......@@ -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;
}
case 2:
case 3:
{
default: // 2 or 3 args
// TODO: validate 2nd/3rd args
if (MP_OBJ_IS_TYPE(args[0], &mp_type_bytes)) {
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);
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);
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
......@@ -831,6 +826,10 @@ static mp_obj_t arg_as_int(mp_obj_t 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) {
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, '}');
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 != '{') {
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')) {
conversion = *str++;
} 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) {
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 != '}') {
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;
if (field_name) {
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;
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;
} else {
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) {
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') {
print_kind = PRINT_REPR;
} 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();
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 (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') {
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 {
sign = '-';
......@@ -1089,8 +1133,13 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
break;
default:
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)));
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 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
default:
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)));
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 format code '%c' for object of type 'float'",
type, mp_obj_get_type_str(arg)));
}
}
} else {
// arg doesn't look like a number
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) {
......@@ -1181,9 +1239,13 @@ mp_obj_t mp_obj_str_format(mp_uint_t n_args, const mp_obj_t *args) {
}
default:
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)));
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 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;
while (*str != ')') {
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 {