diff --git a/docs/library/sys.rst b/docs/library/sys.rst index 3efdce964ce05..35dfc996a6ea4 100644 --- a/docs/library/sys.rst +++ b/docs/library/sys.rst @@ -52,6 +52,28 @@ Functions present in pre-built firmware (due to it affecting performance). The relevant configuration option is *MICROPY_PY_SYS_SETTRACE*. +.. function:: _exc_traceback(exc) + + Retrieves traceback information from an exception object, including + the filename, line number, and code block name for every code location + on the call stack when the exception was thrown. + + .. admonition:: Difference to CPython + :class: attention + + This function is a MicroPython extension intended to provide similar + functionality to the ``__traceback__`` attribute of exception + objects in CPython. + + .. admonition:: Unstable + :class: attention + + This function directly exposes the internal traceback data used by + MicroPython. Future versions might introduce incompatible changes to + the format. + + + Constants --------- diff --git a/py/modsys.c b/py/modsys.c index 35af761a08f12..5bdabdaf787b3 100644 --- a/py/modsys.c +++ b/py/modsys.c @@ -150,6 +150,26 @@ STATIC mp_obj_t mp_sys_print_exception(size_t n_args, const mp_obj_t *args) { } MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(mp_sys_print_exception_obj, 1, 2, mp_sys_print_exception); +#if MICROPY_PY_SYS_EXC_TRACEBACK +STATIC mp_obj_t mp_sys_exc_traceback(mp_obj_t exc) { + if (!mp_obj_is_exception_instance(exc)) { + mp_raise_TypeError(MP_ERROR_TEXT("not an exception")); + } + size_t n, *values; + mp_obj_exception_get_traceback(exc, &n, &values); + // Assumption: n is a multiple of 3. + mp_obj_t obj = mp_obj_new_list(n, NULL); + mp_obj_list_t *list = MP_OBJ_TO_PTR(obj); + for (size_t i = 0; i < list->len; i += 3) { + list->items[i + 0] = MP_OBJ_NEW_QSTR(values[i + 0]); // filename + list->items[i + 1] = MP_OBJ_NEW_SMALL_INT(values[i + 1]); // line + list->items[i + 2] = MP_OBJ_NEW_QSTR(values[i + 2]); // block + } + return obj; +} +STATIC MP_DEFINE_CONST_FUN_OBJ_1(mp_sys_exc_traceback_obj, mp_sys_exc_traceback); +#endif + #if MICROPY_PY_SYS_EXC_INFO STATIC mp_obj_t mp_sys_exc_info(void) { 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[] = { */ { MP_ROM_QSTR(MP_QSTR_print_exception), MP_ROM_PTR(&mp_sys_print_exception_obj) }, + #if MICROPY_PY_SYS_EXC_TRACEBACK + { MP_ROM_QSTR(MP_QSTR__exc_traceback), MP_ROM_PTR(&mp_sys_exc_traceback_obj) }, + #endif #if MICROPY_PY_SYS_ATEXIT { MP_ROM_QSTR(MP_QSTR_atexit), MP_ROM_PTR(&mp_sys_atexit_obj) }, #endif diff --git a/py/mpconfig.h b/py/mpconfig.h index 80e58d1cc41fc..d0aededcbb3e3 100644 --- a/py/mpconfig.h +++ b/py/mpconfig.h @@ -1386,6 +1386,11 @@ typedef double mp_float_t; #define MICROPY_PY_SYS_MODULES (1) #endif +// Whether to provide "sys._exc_traceback" function. +#ifndef MICROPY_PY_SYS_EXC_TRACEBACK +#define MICROPY_PY_SYS_EXC_TRACEBACK (MICROPY_CONFIG_ROM_LEVEL_AT_LEAST_EXTRA_FEATURES) +#endif + // Whether to provide "sys.exc_info" function // Avoid enabling this, this function is Python2 heritage #ifndef MICROPY_PY_SYS_EXC_INFO
Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.
Alternative Proxies: