Skip to content

Commit 49cbbd1

Browse files
committed
Fix chaining non-built-in exceptions
1 parent 41eee0d commit 49cbbd1

File tree

3 files changed

+90
-6
lines changed

3 files changed

+90
-6
lines changed

py/obj.c

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,18 +143,28 @@ void mp_obj_print(mp_obj_t o_in, mp_print_kind_t kind) {
143143
mp_obj_print_helper(MP_PYTHON_PRINTER, o_in, kind);
144144
}
145145

146+
// CIRCUITPY-CHANGE
147+
static mp_obj_t mp_load_attr_or_none(mp_obj_t base, qstr attr) {
148+
mp_obj_t dest[2];
149+
mp_load_method_protected(base, attr, dest, true);
150+
return dest[0] == MP_OBJ_NULL ? mp_const_none : dest[0];
151+
}
152+
146153
// CIRCUITPY-CHANGE
147154
static void mp_obj_print_inner_exception(const mp_print_t *print, mp_obj_t self_in, mp_int_t limit) {
148155
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
149156
mp_obj_exception_t *self = mp_obj_exception_get_native(self_in);
150157
mp_rom_error_text_t msg = MP_ERROR_TEXT("During handling of the above exception, another exception occurred:");
151-
mp_obj_exception_t *inner = NULL;
152-
if (self->cause) {
158+
mp_obj_t inner_obj = mp_const_none;
159+
if (!self->suppress_context) {
160+
inner_obj = mp_load_attr_or_none(self_in, MP_QSTR___context__);
161+
}
162+
if (inner_obj == mp_const_none) {
153163
msg = MP_ERROR_TEXT("The above exception was the direct cause of the following exception:");
154-
inner = self->cause;
155-
} else if (!self->suppress_context) {
156-
inner = self->context;
164+
inner_obj = mp_load_attr_or_none(self_in, MP_QSTR___cause__);
157165
}
166+
mp_obj_exception_t *inner = mp_obj_is_exception_instance(inner_obj) ?
167+
mp_obj_exception_get_native(inner_obj) : NULL;
158168
if (inner && !inner->marked) {
159169
inner->marked = true;
160170
mp_obj_print_exception_with_limit(print, MP_OBJ_FROM_PTR(inner), limit);

tests/circuitpython/traceback_test_chained.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,6 @@ class SomeException(RuntimeError):
109109
l = inner
110110
raise Exception("outer") from l
111111
except Exception as e:
112-
print(e, e.__cause__, e.__context__)
113112
print_exc_info(e)
114113
print()
115114

tests/circuitpython/traceback_test_chained.py.exp

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,78 @@ ZeroDivisionError: division by zero
7474
------------------------------------------------------------------------
7575

7676

77+
------------------------------------------------------------------------
78+
Traceback (most recent call last):
79+
File "circuitpython/traceback_test_chained.py", line 81, in <module>
80+
Exception: inner
81+
82+
During handling of the above exception, another exception occurred:
83+
84+
Traceback (most recent call last):
85+
File "circuitpython/traceback_test_chained.py", line 83, in <module>
86+
SomeException: outer
87+
------------------------------------------------------------------------
88+
89+
------------------------------------------------------------------------
90+
Traceback (most recent call last):
91+
File "circuitpython/traceback_test_chained.py", line 89, in <module>
92+
Exception: inner
93+
94+
The above exception was the direct cause of the following exception:
95+
96+
Traceback (most recent call last):
97+
File "circuitpython/traceback_test_chained.py", line 92, in <module>
98+
SomeException: outer
99+
------------------------------------------------------------------------
100+
101+
102+
------------------------------------------------------------------------
103+
Traceback (most recent call last):
104+
File "circuitpython/traceback_test_chained.py", line 99, in <module>
105+
RuntimeError: inner
106+
107+
The above exception was the direct cause of the following exception:
108+
109+
Traceback (most recent call last):
110+
File "circuitpython/traceback_test_chained.py", line 101, in <module>
111+
Exception: outer
112+
------------------------------------------------------------------------
113+
114+
------------------------------------------------------------------------
115+
Traceback (most recent call last):
116+
File "circuitpython/traceback_test_chained.py", line 107, in <module>
117+
RuntimeError: inner
118+
119+
The above exception was the direct cause of the following exception:
120+
121+
Traceback (most recent call last):
122+
File "circuitpython/traceback_test_chained.py", line 110, in <module>
123+
Exception: outer
124+
------------------------------------------------------------------------
125+
126+
127+
------------------------------------------------------------------------
128+
Traceback (most recent call last):
129+
File "circuitpython/traceback_test_chained.py", line 117, in <module>
130+
RuntimeError: inner
131+
132+
During handling of the above exception, another exception occurred:
133+
134+
Traceback (most recent call last):
135+
File "circuitpython/traceback_test_chained.py", line 119, in <module>
136+
SomeException: outer
137+
------------------------------------------------------------------------
138+
139+
------------------------------------------------------------------------
140+
Traceback (most recent call last):
141+
File "circuitpython/traceback_test_chained.py", line 125, in <module>
142+
RuntimeError: inner
143+
144+
The above exception was the direct cause of the following exception:
145+
146+
Traceback (most recent call last):
147+
File "circuitpython/traceback_test_chained.py", line 128, in <module>
148+
SomeException: outer
149+
------------------------------------------------------------------------
150+
151+

0 commit comments

Comments
 (0)