Skip to content

Commit c3d96d3

Browse files
committed
py/objexcept: Allow clearing traceback with 'exc.__traceback__ = None'.
We allow 'exc.__traceback__ = None' assignment as a low-level optimization of pre-allocating exception instance and raising it repeatedly - this avoids memory allocation during raise. However, uPy will keep adding traceback entries to such exception instance, so before throwing it, traceback should be cleared like above. 'exc.__traceback__ = None' syntax is CPython compatible. However, unlike it, reading that attribute or setting it to any other value is not supported (and not intended to be supported, again, the only reason for adding this feature is to allow zero-memalloc exception raising).
1 parent bf31880 commit c3d96d3

1 file changed

Lines changed: 12 additions & 2 deletions

File tree

py/objexcept.c

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -152,11 +152,21 @@ mp_obj_t mp_obj_exception_get_value(mp_obj_t self_in) {
152152
}
153153

154154
STATIC void exception_attr(mp_obj_t self_in, qstr attr, mp_obj_t *dest) {
155+
mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in);
155156
if (dest[0] != MP_OBJ_NULL) {
156-
// not load attribute
157+
// store/delete attribute
158+
if (attr == MP_QSTR___traceback__ && dest[1] == mp_const_none) {
159+
// We allow 'exc.__traceback__ = None' assignment as low-level
160+
// optimization of pre-allocating exception instance and raising
161+
// it repeatedly - this avoids memory allocation during raise.
162+
// However, uPy will keep adding traceback entries to such
163+
// exception instance, so before throwing it, traceback should
164+
// be cleared like above.
165+
self->traceback_len = 0;
166+
dest[0] = MP_OBJ_NULL; // indicate success
167+
}
157168
return;
158169
}
159-
mp_obj_exception_t *self = MP_OBJ_TO_PTR(self_in);
160170
if (attr == MP_QSTR_args) {
161171
dest[0] = MP_OBJ_FROM_PTR(self->args);
162172
} else if (self->base.type == &mp_type_StopIteration && attr == MP_QSTR_value) {

0 commit comments

Comments
 (0)