Skip to content

Commit 870f26b

Browse files
committed
traceback module refinements
1 parent fb0f258 commit 870f26b

File tree

3 files changed

+140
-58
lines changed

3 files changed

+140
-58
lines changed

shared-bindings/traceback/__init__.c

Lines changed: 11 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727
#include "py/stream.h"
2828
#include "py/runtime.h"
2929

30+
#include "shared-module/traceback/__init__.h"
31+
3032
//| """Traceback Module
3133
//|
3234
//| This module provides a standard interface to print stack traces of programs.
@@ -50,7 +52,7 @@
5052
//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed.
5153
//| :param io.FileIO file: If file is omitted or `None`, the output goes to `sys.stderr`; otherwise it should be an open
5254
//| file or file-like object to receive the output.
53-
//| :param bool chain: If `True` then chained exceptions will be printed.
55+
//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented).
5456
//|
5557
//| """
5658
//| ...
@@ -69,10 +71,10 @@ STATIC mp_obj_t traceback_print_exception(size_t n_args, const mp_obj_t *pos_arg
6971
mp_arg_val_t args[MP_ARRAY_SIZE(allowed_args)];
7072
mp_arg_parse_all(n_args, pos_args, kw_args, MP_ARRAY_SIZE(allowed_args), allowed_args, args);
7173

72-
mp_obj_t exc = args[ARG_value].u_obj;
73-
if (!mp_obj_is_exception_instance(exc)) {
74+
if (!mp_obj_is_exception_instance(args[ARG_value].u_obj)) {
7475
mp_raise_TypeError(translate("invalid exception"));
7576
}
77+
mp_obj_exception_t exc = *(mp_obj_exception_t *)MP_OBJ_TO_PTR(args[ARG_value].u_obj);
7678

7779
mp_print_t print = mp_plat_print;
7880
if (args[ARG_file].u_obj != mp_const_none) {
@@ -91,67 +93,19 @@ STATIC mp_obj_t traceback_print_exception(size_t n_args, const mp_obj_t *pos_arg
9193
if (!mp_obj_get_int_maybe(args[ARG_limit].u_obj, &limit)) {
9294
mp_raise_TypeError(translate("limit should be an int"));
9395
}
94-
print_tb = !(limit == 0);
96+
print_tb = (limit != 0);
9597
}
9698

9799
if (args[ARG_tb].u_obj != mp_const_none && print_tb) {
98100
if (!mp_obj_is_type(args[ARG_tb].u_obj, &mp_type_traceback)) {
99101
mp_raise_TypeError(translate("invalid traceback"));
100102
}
101-
mp_obj_traceback_t *tb = MP_OBJ_TO_PTR(args[ARG_tb].u_obj);
102-
size_t n = (tb->data) ? tb->len : 0;
103-
size_t *values = (tb->data) ? tb->data : NULL;
104-
if (n > 0) {
105-
assert(n % 3 == 0);
106-
// Decompress the format strings
107-
const compressed_string_t *traceback = MP_ERROR_TEXT("Traceback (most recent call last):\n");
108-
char decompressed[decompress_length(traceback)];
109-
decompress(traceback, decompressed);
110-
#if MICROPY_ENABLE_SOURCE_LINE
111-
const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\", line %d");
112-
#else
113-
const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\"");
114-
#endif
115-
char decompressed_frame[decompress_length(frame)];
116-
decompress(frame, decompressed_frame);
117-
const compressed_string_t *block_fmt = MP_ERROR_TEXT(", in %q\n");
118-
char decompressed_block[decompress_length(block_fmt)];
119-
decompress(block_fmt, decompressed_block);
120-
121-
// Set traceback formatting
122-
// Default: Print full traceback
123-
int i = n - 3, j;
124-
if (limit > 0) {
125-
// Print upto limit traceback
126-
// from caller's frame
127-
limit = n - (limit * 3);
128-
} else if (limit < 0) {
129-
// Print upto limit traceback
130-
// from last
131-
i = 0, limit = 3 + (limit * 3);
132-
}
133-
134-
// Print the traceback
135-
mp_print_str(&print, decompressed);
136-
for (; i >= limit; i -= 3) {
137-
j = (i < 0) ? -i : i;
138-
#if MICROPY_ENABLE_SOURCE_LINE
139-
mp_printf(&print, decompressed_frame, values[j], (int)values[j + 1]);
140-
#else
141-
mp_printf(&print, decompressed_frame, values[j]);
142-
#endif
143-
// The block name can be NULL if it's unknown
144-
qstr block = values[j + 2];
145-
if (block == MP_QSTRnull) {
146-
mp_print_str(&print, "\n");
147-
} else {
148-
mp_printf(&print, decompressed_block, block);
149-
}
150-
}
151-
}
103+
exc.traceback = MP_OBJ_TO_PTR(args[ARG_tb].u_obj);
104+
} else {
105+
exc.traceback = NULL;
152106
}
153-
mp_obj_print_helper(&print, exc, PRINT_EXC);
154-
mp_print_str(&print, "\n");
107+
108+
shared_module_traceback_print_exception(&exc, &print, limit);
155109
return mp_const_none;
156110
}
157111
STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_print_exception_obj, 3, traceback_print_exception);

shared-module/traceback/__init__.c

Lines changed: 93 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,93 @@
1-
// empty file
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2021 microDev
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#include "shared-module/traceback/__init__.h"
28+
29+
void shared_module_traceback_print_exception(mp_obj_exception_t *exc, mp_print_t *print, mp_int_t limit) {
30+
// Print traceback
31+
if (exc->traceback != NULL) {
32+
size_t n = exc->traceback->len;
33+
size_t *values = exc->traceback->data;
34+
if (n > 0) {
35+
assert(n % 3 == 0);
36+
// Decompress the format strings
37+
const compressed_string_t *traceback = MP_ERROR_TEXT("Traceback (most recent call last):\n");
38+
char decompressed[decompress_length(traceback)];
39+
decompress(traceback, decompressed);
40+
#if MICROPY_ENABLE_SOURCE_LINE
41+
const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\", line %d");
42+
#else
43+
const compressed_string_t *frame = MP_ERROR_TEXT(" File \"%q\"");
44+
#endif
45+
char decompressed_frame[decompress_length(frame)];
46+
decompress(frame, decompressed_frame);
47+
const compressed_string_t *block_fmt = MP_ERROR_TEXT(", in %q\n");
48+
char decompressed_block[decompress_length(block_fmt)];
49+
decompress(block_fmt, decompressed_block);
50+
51+
// Set traceback formatting
52+
// Default: Print full traceback
53+
limit = limit * 3;
54+
mp_int_t i = n - 3, j;
55+
if (limit > 0) {
56+
// Print upto limit traceback
57+
// entries from caller's frame
58+
if ((unsigned)limit > n) {
59+
limit = n;
60+
}
61+
limit = n - limit;
62+
} else if (limit < 0) {
63+
// Print upto limit traceback
64+
// entries from last
65+
if ((unsigned)-limit > n) {
66+
limit = -n;
67+
}
68+
i = 0, limit = limit + 3;
69+
}
70+
71+
// Print the traceback
72+
mp_print_str(print, decompressed);
73+
for (; i >= limit; i -= 3) {
74+
j = (i < 0) ? -i : i;
75+
#if MICROPY_ENABLE_SOURCE_LINE
76+
mp_printf(print, decompressed_frame, values[j], (int)values[j + 1]);
77+
#else
78+
mp_printf(print, decompressed_frame, values[j]);
79+
#endif
80+
// The block name can be NULL if it's unknown
81+
qstr block = values[j + 2];
82+
if (block == MP_QSTRnull) {
83+
mp_print_str(print, "\n");
84+
} else {
85+
mp_printf(print, decompressed_block, block);
86+
}
87+
}
88+
}
89+
}
90+
// Print exception
91+
mp_obj_print_helper(print, exc, PRINT_EXC);
92+
mp_print_str(print, "\n");
93+
}

shared-module/traceback/__init__.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* This file is part of the Micro Python project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2021 microDev
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*/
26+
27+
#ifndef MICROPY_INCLUDED_SHARED_MODULE_TRACEBACK___INIT___H
28+
#define MICROPY_INCLUDED_SHARED_MODULE_TRACEBACK___INIT___H
29+
30+
#include "py/objexcept.h"
31+
#include "py/objtraceback.h"
32+
33+
extern void shared_module_traceback_print_exception(mp_obj_exception_t *exc,
34+
mp_print_t *print, mp_int_t limit);
35+
36+
#endif // MICROPY_INCLUDED_SHARED_MODULE_TRACEBACK___INIT___H

0 commit comments

Comments
 (0)