Skip to content

Commit 1e9a92f

Browse files
committed
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.
1 parent b6b34cd commit 1e9a92f

10 files changed

Lines changed: 436 additions & 123 deletions

File tree

bare-arm/mpconfigport.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
#define MICROPY_HELPER_REPL (0)
1313
#define MICROPY_HELPER_LEXER_UNIX (0)
1414
#define MICROPY_ENABLE_SOURCE_LINE (0)
15+
#define MICROPY_ENABLE_DOC_STRING (0)
16+
#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
1517
#define MICROPY_PY_BUILTINS_BYTEARRAY (0)
1618
#define MICROPY_PY_BUILTINS_MEMORYVIEW (0)
1719
#define MICROPY_PY_BUILTINS_FROZENSET (0)
@@ -31,8 +33,6 @@
3133
#define MICROPY_LONGINT_IMPL (MICROPY_LONGINT_IMPL_NONE)
3234
#define MICROPY_FLOAT_IMPL (MICROPY_FLOAT_IMPL_NONE)
3335

34-
//#define MICROPY_ERROR_REPORTING (MICROPY_ERROR_REPORTING_TERSE)
35-
3636
// type definitions for the specific machine
3737

3838
#define BYTES_PER_WORD (4)

py/argcheck.c

Lines changed: 52 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -34,28 +34,49 @@
3434
#include "obj.h"
3535
#include "runtime.h"
3636

37+
STATIC NORETURN void terse_arg_mismatch(void) {
38+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "argument num/types mismatch"));
39+
}
40+
3741
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) {
3842
// TODO maybe take the function name as an argument so we can print nicer error messages
3943

4044
if (n_kw && !takes_kw) {
41-
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "function does not take keyword arguments"));
45+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
46+
terse_arg_mismatch();
47+
} else {
48+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
49+
"function does not take keyword arguments"));
50+
}
4251
}
4352

4453
if (n_args_min == n_args_max) {
4554
if (n_args != n_args_min) {
46-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
47-
"function takes %d positional arguments but %d were given",
48-
n_args_min, n_args));
55+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
56+
terse_arg_mismatch();
57+
} else {
58+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
59+
"function takes %d positional arguments but %d were given",
60+
n_args_min, n_args));
61+
}
4962
}
5063
} else {
5164
if (n_args < n_args_min) {
52-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
53-
"function missing %d required positional arguments",
54-
n_args_min - n_args));
65+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
66+
terse_arg_mismatch();
67+
} else {
68+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
69+
"function missing %d required positional arguments",
70+
n_args_min - n_args));
71+
}
5572
} else if (n_args > n_args_max) {
56-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
57-
"function expected at most %d arguments, got %d",
58-
n_args_max, n_args));
73+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
74+
terse_arg_mismatch();
75+
} else {
76+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
77+
"function expected at most %d arguments, got %d",
78+
n_args_max, n_args));
79+
}
5980
}
6081
}
6182
}
@@ -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
7495
mp_map_elem_t *kw = mp_map_lookup(kws, MP_OBJ_NEW_QSTR(allowed[i].qstr), MP_MAP_LOOKUP);
7596
if (kw == NULL) {
7697
if (allowed[i].flags & MP_ARG_REQUIRED) {
77-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' argument required", qstr_str(allowed[i].qstr)));
98+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
99+
terse_arg_mismatch();
100+
} else {
101+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
102+
"'%s' argument required",
103+
qstr_str(allowed[i].qstr)));
104+
}
78105
}
79106
out_vals[i] = allowed[i].defval;
80107
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
94121
}
95122
}
96123
if (pos_found < n_pos) {
97-
// TODO better error message
98124
extra_positional:
99-
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "extra positional arguments given"));
125+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
126+
terse_arg_mismatch();
127+
} else {
128+
// TODO better error message
129+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
130+
"extra positional arguments given"));
131+
}
100132
}
101133
if (kws_found < kws->used) {
102-
// TODO better error message
103-
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "extra keyword arguments given"));
134+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
135+
terse_arg_mismatch();
136+
} else {
137+
// TODO better error message
138+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
139+
"extra keyword arguments given"));
140+
}
104141
}
105142
}
106143

py/builtin.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,14 @@ STATIC mp_obj_t mp_builtin_divmod(mp_obj_t o1_in, mp_obj_t o2_in) {
272272
return mp_obj_new_tuple(2, tuple);
273273
#endif
274274
} else {
275-
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)));
275+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
276+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
277+
"unsupported operand type(s) for divmod()"));
278+
} else {
279+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
280+
"unsupported operand type(s) for divmod(): '%s' and '%s'",
281+
mp_obj_get_type_str(o1_in), mp_obj_get_type_str(o2_in)));
282+
}
276283
}
277284
}
278285
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) {
357364
mp_uint_t len;
358365
const char *str = mp_obj_str_get_data(o_in, &len);
359366
#if MICROPY_PY_BUILTINS_STR_UNICODE
360-
mp_uint_t charlen = unichar_charlen(str, len);
361-
if (charlen == 1) {
367+
len = unichar_charlen(str, len);
368+
if (len == 1) {
362369
if (MP_OBJ_IS_STR(o_in) && UTF8_IS_NONASCII(*str)) {
363370
mp_int_t ord = *str++ & 0x7F;
364371
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) {
371378
} else {
372379
return mp_obj_new_int(((const byte*)str)[0]);
373380
}
374-
} else {
375-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "ord() expected a character, but string of length %d found", charlen));
376381
}
377382
#else
378383
if (len == 1) {
379384
// don't sign extend when converting to ord
380385
return mp_obj_new_int(((const byte*)str)[0]);
381-
} else {
382-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "ord() expected a character, but string of length %d found", len));
383386
}
384387
#endif
388+
389+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
390+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
391+
"ord expects a character"));
392+
} else {
393+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
394+
"ord() expected a character, but string of length %d found", len));
395+
}
385396
}
386397
MP_DEFINE_CONST_FUN_OBJ_1(mp_builtin_ord_obj, mp_builtin_ord);
387398

py/builtinimport.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,12 @@ STATIC void do_load(mp_obj_t module_obj, vstr_t *file) {
118118

119119
if (lex == NULL) {
120120
// we verified the file exists using stat, but lexer could still fail
121-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "No module named '%s'", vstr_str(file)));
121+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
122+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "module not found"));
123+
} else {
124+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
125+
"no module named '%s'", vstr_str(file)));
126+
}
122127
}
123128

124129
#if MICROPY_PY___FILE__
@@ -277,7 +282,12 @@ mp_obj_t mp_builtin___import__(mp_uint_t n_args, const mp_obj_t *args) {
277282
{
278283
#endif
279284
// couldn't find the file, so fail
280-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError, "No module named '%s'", qstr_str(mod_name)));
285+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
286+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ImportError, "module not found"));
287+
} else {
288+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ImportError,
289+
"no module named '%s'", qstr_str(mod_name)));
290+
}
281291
}
282292
} else {
283293
// found the file, so get the module

py/mpconfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ typedef long long mp_longint_impl_t;
238238
#define MICROPY_ENABLE_DOC_STRING (0)
239239
#endif
240240

241-
// Exception messages are short static strings (TODO)
241+
// Exception messages are short static strings
242242
#define MICROPY_ERROR_REPORTING_TERSE (1)
243243
// Exception messages provide basic error details
244244
#define MICROPY_ERROR_REPORTING_NORMAL (2)

py/obj.c

Lines changed: 91 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,12 @@ mp_int_t mp_obj_hash(mp_obj_t o_in) {
177177
// TODO delegate to __hash__ method if it exists
178178

179179
} else {
180-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unhashable type: '%s'", mp_obj_get_type_str(o_in)));
180+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
181+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError, "unhashable type"));
182+
} else {
183+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
184+
"unhashable type: '%s'", mp_obj_get_type_str(o_in)));
185+
}
181186
}
182187
}
183188

@@ -230,9 +235,14 @@ bool mp_obj_equal(mp_obj_t o1, mp_obj_t o2) {
230235
}
231236
}
232237

233-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NotImplementedError,
234-
"Equality for '%s' and '%s' types not yet implemented", mp_obj_get_type_str(o1), mp_obj_get_type_str(o2)));
235-
return false;
238+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
239+
nlr_raise(mp_obj_new_exception_msg(&mp_type_NotImplementedError,
240+
"equality for given types not yet implemented"));
241+
} else {
242+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_NotImplementedError,
243+
"equality for '%s' and '%s' types not yet implemented",
244+
mp_obj_get_type_str(o1), mp_obj_get_type_str(o2)));
245+
}
236246
}
237247

238248
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) {
248258
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_int)) {
249259
return mp_obj_int_get_checked(arg);
250260
} else {
251-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to int", mp_obj_get_type_str(arg)));
261+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
262+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
263+
"can't convert to int"));
264+
} else {
265+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
266+
"can't convert %s to int", mp_obj_get_type_str(arg)));
267+
}
252268
}
253269
}
254270

@@ -283,7 +299,13 @@ mp_float_t mp_obj_get_float(mp_obj_t arg) {
283299
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_float)) {
284300
return mp_obj_float_get(arg);
285301
} else {
286-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to float", mp_obj_get_type_str(arg)));
302+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
303+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
304+
"can't convert to float"));
305+
} else {
306+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
307+
"can't convert %s to float", mp_obj_get_type_str(arg)));
308+
}
287309
}
288310
}
289311

@@ -307,7 +329,13 @@ void mp_obj_get_complex(mp_obj_t arg, mp_float_t *real, mp_float_t *imag) {
307329
} else if (MP_OBJ_IS_TYPE(arg, &mp_type_complex)) {
308330
mp_obj_complex_get(arg, real, imag);
309331
} else {
310-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "can't convert %s to complex", mp_obj_get_type_str(arg)));
332+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
333+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
334+
"can't convert to complex"));
335+
} else {
336+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
337+
"can't convert %s to complex", mp_obj_get_type_str(arg)));
338+
}
311339
}
312340
}
313341
#endif
@@ -319,15 +347,27 @@ void mp_obj_get_array(mp_obj_t o, mp_uint_t *len, mp_obj_t **items) {
319347
} else if (MP_OBJ_IS_TYPE(o, &mp_type_list)) {
320348
mp_obj_list_get(o, len, items);
321349
} else {
322-
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)));
350+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
351+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
352+
"expected tuple/list"));
353+
} else {
354+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
355+
"object '%s' is not a tuple or list", mp_obj_get_type_str(o)));
356+
}
323357
}
324358
}
325359

326360
void mp_obj_get_array_fixed_n(mp_obj_t o, mp_uint_t len, mp_obj_t **items) {
327361
mp_uint_t seq_len;
328362
mp_obj_get_array(o, &seq_len, items);
329363
if (seq_len != len) {
330-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "requested length %d but object has length %d", len, seq_len));
364+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
365+
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError,
366+
"tuple/list has wrong length"));
367+
} else {
368+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError,
369+
"requested length %d but object has length %d", len, seq_len));
370+
}
331371
}
332372
}
333373

@@ -337,7 +377,14 @@ mp_uint_t mp_get_index(const mp_obj_type_t *type, mp_uint_t len, mp_obj_t index,
337377
if (MP_OBJ_IS_SMALL_INT(index)) {
338378
i = MP_OBJ_SMALL_INT_VALUE(index);
339379
} else if (!mp_obj_get_int_maybe(index, &i)) {
340-
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)));
380+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
381+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
382+
"indices must be integers"));
383+
} else {
384+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
385+
"%s indices must be integers, not %s",
386+
qstr_str(type->name), mp_obj_get_type_str(index)));
387+
}
341388
}
342389

343390
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,
351398
}
352399
} else {
353400
if (i < 0 || i >= len) {
354-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "%s index out of range", qstr_str(type->name)));
401+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
402+
nlr_raise(mp_obj_new_exception_msg(&mp_type_IndexError, "index out of range"));
403+
} else {
404+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError,
405+
"%s index out of range", qstr_str(type->name)));
406+
}
355407
}
356408
}
357409
return i;
@@ -379,7 +431,13 @@ mp_obj_t mp_obj_id(mp_obj_t o_in) {
379431
mp_obj_t mp_obj_len(mp_obj_t o_in) {
380432
mp_obj_t len = mp_obj_len_maybe(o_in);
381433
if (len == MP_OBJ_NULL) {
382-
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)));
434+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
435+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
436+
"object has no len"));
437+
} else {
438+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
439+
"object of type '%s' has no len()", mp_obj_get_type_str(o_in)));
440+
}
383441
} else {
384442
return len;
385443
}
@@ -414,11 +472,29 @@ mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value) {
414472
// TODO: call base classes here?
415473
}
416474
if (value == MP_OBJ_NULL) {
417-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item deletion", mp_obj_get_type_str(base)));
475+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
476+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
477+
"object does not support item deletion"));
478+
} else {
479+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
480+
"'%s' object does not support item deletion", mp_obj_get_type_str(base)));
481+
}
418482
} else if (value == MP_OBJ_SENTINEL) {
419-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not subscriptable", mp_obj_get_type_str(base)));
483+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
484+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
485+
"object is not subscriptable"));
486+
} else {
487+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
488+
"'%s' object is not subscriptable", mp_obj_get_type_str(base)));
489+
}
420490
} else {
421-
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object does not support item assignment", mp_obj_get_type_str(base)));
491+
if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) {
492+
nlr_raise(mp_obj_new_exception_msg(&mp_type_TypeError,
493+
"object does not support item assignment"));
494+
} else {
495+
nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError,
496+
"'%s' object does not support item assignment", mp_obj_get_type_str(base)));
497+
}
422498
}
423499
}
424500

0 commit comments

Comments
 (0)