Skip to content

Commit b83c42e

Browse files
committed
Implement the chain= argument of traceback.print_exception
1 parent 6e40949 commit b83c42e

File tree

3 files changed

+31
-14
lines changed

3 files changed

+31
-14
lines changed

shared-bindings/traceback/__init__.c

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ STATIC void traceback_exception_common(bool is_print_exception, mp_print_t *prin
5858
}
5959
mp_obj_t tb_obj = args[ARG_tb].u_obj;
6060
mp_obj_t limit_obj = args[ARG_limit].u_obj;
61+
bool chain = args[ARG_chain].u_bool;
6162

6263
if (args[ARG_file].u_obj != mp_const_none) {
6364
if (!is_print_exception) {
@@ -90,6 +91,15 @@ STATIC void traceback_exception_common(bool is_print_exception, mp_print_t *prin
9091

9192
mp_obj_exception_t *exc = mp_obj_exception_get_native(value);
9293
mp_obj_traceback_t *trace_backup = exc->traceback;
94+
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
95+
mp_obj_exception_t *context_backup = exc->context;
96+
mp_obj_exception_t *cause_backup = exc->cause;
97+
98+
if (!chain) {
99+
exc->context = NULL;
100+
exc->cause = NULL;
101+
}
102+
#endif
93103

94104
if (tb_obj == MP_OBJ_NULL) {
95105
/* Print the traceback's exception as is */
@@ -101,6 +111,10 @@ STATIC void traceback_exception_common(bool is_print_exception, mp_print_t *prin
101111

102112
shared_module_traceback_print_exception(MP_OBJ_TO_PTR(value), print, limit);
103113
exc->traceback = trace_backup;
114+
#if MICROPY_CPYTHON_EXCEPTION_CHAIN
115+
exc->context = context_backup;
116+
exc->cause = cause_backup;
117+
#endif
104118
}
105119

106120
//| def format_exception(
@@ -128,14 +142,12 @@ STATIC void traceback_exception_common(bool is_print_exception, mp_print_t *prin
128142
//| these lines are concatenated and printed, exactly the same text is
129143
//| printed as does print_exception().
130144
//|
131-
//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented.
132-
//|
133145
//| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified.
134146
//| :param value: If specified, is used in place of ``exc``.
135147
//| :param TracebackType tb: When value is alsp specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed.
136148
//| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive.
137149
//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed.
138-
//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented).
150+
//| :param bool chain: If `True` then chained exceptions will be printed.
139151
//| """
140152
//|
141153
STATIC mp_obj_t traceback_format_exception(size_t n_args, const mp_obj_t *pos_args, mp_map_t *kw_args) {
@@ -169,16 +181,14 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 0, traceback_f
169181
//| no traceback will be shown. This is compatible with CPython 3.5 and
170182
//| newer.
171183
//|
172-
//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented.
173-
//|
174184
//| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified.
175185
//| :param value: If specified, is used in place of ``exc``.
176186
//| :param tb: When value is alsp specified, ``tb`` is used in place of the exception's own traceback. If `None`, the traceback will not be printed.
177187
//| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive.
178188
//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed.
179189
//| :param io.FileIO file: If file is omitted or `None`, the output goes to `sys.stderr`; otherwise it should be an open
180190
//| file or file-like object to receive the output.
181-
//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented).
191+
//| :param bool chain: If `True` then chained exceptions will be printed.
182192
//|
183193
//| """
184194
//| ...

tests/circuitpython/traceback_test_chained.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
raise SystemExit
1212

1313

14-
def print_exc_info(e):
14+
def print_exc_info(e, chain=True):
1515
print("-" * 72)
16-
traceback.print_exception(None, e, e.__traceback__)
16+
traceback.print_exception(None, e, e.__traceback__, chain=chain)
1717
print("-" * 72)
1818
print()
1919

@@ -24,6 +24,7 @@ def print_exc_info(e):
2424
except Exception as inner:
2525
raise RuntimeError() from inner
2626
except Exception as e:
27+
print_exc_info(e, chain=False)
2728
print_exc_info(e)
2829
print()
2930

tests/circuitpython/traceback_test_chained.py.exp

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
------------------------------------------------------------------------
2+
Traceback (most recent call last):
3+
File "circuitpython/traceback_test_chained.py", line 25, in <module>
4+
RuntimeError:
5+
------------------------------------------------------------------------
6+
17
------------------------------------------------------------------------
28
Traceback (most recent call last):
39
File "circuitpython/traceback_test_chained.py", line 23, in <module>
@@ -17,39 +23,39 @@ OSError:
1723
The above exception was the direct cause of the following exception:
1824

1925
Traceback (most recent call last):
20-
File "circuitpython/traceback_test_chained.py", line 34, in <module>
26+
File "circuitpython/traceback_test_chained.py", line 35, in <module>
2127
RuntimeError:
2228
------------------------------------------------------------------------
2329

2430

2531
------------------------------------------------------------------------
2632
Traceback (most recent call last):
27-
File "circuitpython/traceback_test_chained.py", line 42, in <module>
33+
File "circuitpython/traceback_test_chained.py", line 43, in <module>
2834
ZeroDivisionError: division by zero
2935

3036
During handling of the above exception, another exception occurred:
3137

3238
Traceback (most recent call last):
33-
File "circuitpython/traceback_test_chained.py", line 44, in <module>
39+
File "circuitpython/traceback_test_chained.py", line 45, in <module>
3440
RuntimeError:
3541
------------------------------------------------------------------------
3642

3743

3844
------------------------------------------------------------------------
3945
Traceback (most recent call last):
40-
File "circuitpython/traceback_test_chained.py", line 53, in <module>
46+
File "circuitpython/traceback_test_chained.py", line 54, in <module>
4147
RuntimeError:
4248
------------------------------------------------------------------------
4349

4450
------------------------------------------------------------------------
4551
Traceback (most recent call last):
46-
File "circuitpython/traceback_test_chained.py", line 59, in <module>
52+
File "circuitpython/traceback_test_chained.py", line 60, in <module>
4753
RuntimeError:
4854

4955
During handling of the above exception, another exception occurred:
5056

5157
Traceback (most recent call last):
52-
File "circuitpython/traceback_test_chained.py", line 61, in <module>
58+
File "circuitpython/traceback_test_chained.py", line 62, in <module>
5359
ZeroDivisionError: division by zero
5460
------------------------------------------------------------------------
5561

0 commit comments

Comments
 (0)