8000 py/modsys.c: Add sys._exc_traceback. · micropython/micropython@d872e6e · GitHub
[go: up one dir, main page]

Skip to content

Commit d872e6e

Browse files
committed
py/modsys.c: Add sys._exc_traceback.
This makes it easier to provide custom formatting of exception stack traces, e.g. to make them fit on a tiny display. This is an experimental function that exposes internal details of MicroPython and it might change in the future. Signed-off-by: David (Pololu) <dev-david@pololu.com>
1 parent bde222c commit d872e6e

File tree

3 files changed

+50
-0
lines changed

3 files changed

+50
-0
lines changed

docs/library/sys.rst

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,28 @@ Functions
5252
present in pre-built firmware (due to it affecting performance). The relevant
5353
configuration option is *MICROPY_PY_SYS_SETTRACE*.
5454

55+
.. function:: _exc_traceback(exc)
56+
57+
Retrieves traceback information from an exception object, including
58+
the filename, line number, and code block name for every code location
59+
on the call stack when the exception was thrown.
60+
61+
.. admonition:: Difference to CPython
62+
:class: attention
63+
64+
This function is a MicroPython extension intended to provide similar
65+
functionality to the ``__traceback__`` attribute of exception
66+
objects in CPython.
67+
68+
.. admonition:: Unstable
69+
:class: attention
70+
71+
This function directly exposes the internal traceback data used by
72+
MicroPython. Future versions might introduce incompatible changes to
73+
the format.
74+
75+
76+
5577
Constants
5678
---------
5779

py/modsys.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,6 +150,26 @@ STATIC mp_obj_t mp_sys_print_exception(size_t n_args, const mp_obj_t *args) {
150150
}
151151
MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_print_exception);
152152

153+
#if MICROPY_PY_SYS_EXC_TRACEBACK
154+
STATIC mp_obj_t mp_sys_exc_traceback(mp_obj_t exc) {
155+
if (!mp_obj_is_exception_instance(exc)) {
156+
mp_raise_TypeError(MP_ERROR_TEXT("not an exception"));
157+
}
158+
size_t n, *values;
159+
mp_obj_exception_get_traceback(exc, &n, &values);
160+
// Assumption: n is a multiple of 3.
161+
mp_obj_t obj = mp_obj_new_list(n, NULL);
162+
mp_obj_list_t *list = MP_OBJ_TO_PTR(obj);
163+
for (size_t i = 0; i < list->len; i += 3) {
164+
list->items[i + 0] = MP_OBJ_NEW_QSTR(values[i + 0]); // filename
165+
list->items[i + 1] = MP_OBJ_NEW_SMALL_INT(values[i + 1]); // line
166+
list->items[i + 2] = MP_OBJ_NEW_QSTR(values[i + 2]); // block
167+
}
168+
return obj;
169+
}
170+
STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_sys_exc_traceback_obj, mp_sys_exc_traceback);
171+
#endif
172+
153173
#if MICROPY_PY_SYS_EXC_INFO
154174
STATIC mp_obj_t mp_sys_exc_info(void) {
155175
mp_obj_t cur_exc = MP_OBJ_FROM_PTR(MP_STATE_VM(cur_exception));
@@ -277,6 +297,9 @@ STATIC const mp_rom_map_elem_t mp_module_sys_globals_table[] = {
277297
*/
278298

279299
{ MP_ROM_QSTR(MP_QSTR_print_exception), MP_ROM_PTR(&mp_sys_print_exception_obj) },
300+
#if MICROPY_PY_SYS_EXC_TRACEBACK
301+
{ MP_ROM_QSTR(MP_QSTR__exc_traceback), MP_ROM_PTR(&mp_sys_exc_traceback_obj) },
302+
#endif
280303
#if MICROPY_PY_SYS_ATEXIT
281304
{ MP_ROM_QSTR(MP_QSTR_atexit), MP_ROM_PTR(&mp_sys_atexit_obj) },
282305
#endif

py/mpconfig.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1386,6 +1386,11 @@ typedef double mp_float_t;
13861386
#define MICROPY_PY_SYS_MODULES (1)
13871387
#endif
13881388

1389+
// Whether to provide "sys._exc_traceback" function.
1390+
#ifndef MICROPY_PY_SYS_EXC_TRACEBACK
1391+
#define MICROPY_PY_SYS_EXC_TRACEBACK (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES)
1392+
#endif
1393+
13891394
// Whether to provide "sys.exc_info" function
13901395
// Avoid enabling this, this function is Python2 heritage
13911396
#ifndef MICROPY_PY_SYS_EXC_INFO

0 commit comments

Comments
 (0)
0