Skip to content

Commit 39babb0

Browse files
committed
py/objexcept: Add __traceback__ attribute getter.
This makes it easier to provide custom formatting of exception stack traces, e.g. to make them fit on a tiny display. Signed-off-by: David (Pololu) <dev-david@pololu.com>
1 parent 570744d commit 39babb0

3 files changed

Lines changed: 33 additions & 1 deletion

File tree

py/objexcept.c

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -280,7 +280,23 @@ void mp_obj_exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
280280
}
281281
return;
282282
}
283-
if (attr == MP_QSTR_args) {
283+
if (attr == MP_QSTR___traceback__) {
284+
// We expose traceback data via 'exc.__traceback__' to allow
285+
// custom formatting of the traceback by user code.
286+
size_t entry_count = self->traceback_len / TRACEBACK_ENTRY_LEN;
287+
size_t *data = self->traceback_data;
288+
mp_obj_t obj = mp_obj_new_list(entry_count, NULL);
289+
mp_obj_list_t *list = MP_OBJ_TO_PTR(obj);
290+
for (size_t i = 0; i < entry_count; i++) {
291+
size_t *src = &data[i * TRACEBACK_ENTRY_LEN];
292+
mp_obj_t entry[3];
293+
entry[0] = MP_OBJ_NEW_QSTR(src[0]); // filename
294+
entry[1] = MP_OBJ_NEW_SMALL_INT(src[1]); // line number
295+
entry[2] = MP_OBJ_NEW_QSTR(src[2]); // block
296+
list->items[i] = mp_obj_new_tuple(3, entry);
297+
}
298+
dest[0] = obj;
299+
} else if (attr == MP_QSTR_args) {
284300
decompress_error_text_maybe(self);
285301
dest[0] = MP_OBJ_FROM_PTR(self->args);
286302
} else if (attr == MP_QSTR_value || attr == MP_QSTR_errno) {

tests/micropython/traceback.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
def foo():
2+
1 / 0
3+
4+
try:
5+
foo()
6+
except Exception as e:
7+
print(e.__traceback__)
8+
e.__traceback__ = None
9+
print(e.__traceback__)
10+
try:
11+
e.args = 77
12+
except AttributeError:
13+
print("setting args not allowed")

tests/micropython/traceback.py.exp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[('/home/runner/work/micropython/micropython/tests/micropython/traceback.py', 2, 'foo'), ('/home/runner/work/micropython/micropython/tests/micropython/traceback.py', 5, '<module>')]
2+
[]
3+
setting args not allowed

0 commit comments

Comments
 (0)