38
38
//| """
39
39
//| ...
40
40
41
- STATIC void traceback_exception_common (mp_print_t * print , mp_obj_t value , mp_obj_t tb_obj , mp_obj_t limit_obj ) {
41
+ STATIC void traceback_exception_common (bool is_print_exception , mp_print_t * print , size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
42
+ enum { ARG_exc , ARG_value , ARG_tb , ARG_limit , ARG_file , ARG_chain };
43
+ static const mp_arg_t allowed_args [] = {
44
+ { MP_QSTR_ , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = MP_OBJ_NULL } },
45
+ { MP_QSTR_value , MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
46
+ { MP_QSTR_tb , MP_ARG_OBJ , {.u_obj = MP_OBJ_NULL } },
47
+ { MP_QSTR_limit , MP_ARG_OBJ , {.u_obj = mp_const_none } },
48
+ { MP_QSTR_file , MP_ARG_OBJ , {.u_obj = mp_const_none } },
49
+ { MP_QSTR_chain , MP_ARG_BOOL , {.u_bool = true} },
50
+ };
51
+
52
+ mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
53
+ mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
54
+
55
+ mp_obj_t value = args [ARG_value ].u_obj ;
56
+ if (value == MP_OBJ_NULL ) {
57
+ value = args [ARG_exc ].u_obj ;
58
+ }
59
+ mp_obj_t tb_obj = args [ARG_tb ].u_obj ;
60
+ mp_obj_t limit_obj = args [ARG_limit ].u_obj ;
61
+
62
+ if (args [ARG_file ].u_obj != mp_const_none ) {
63
+ if (!is_print_exception ) {
64
+ #if MICROPY_ERROR_REPORTING <= MICROPY_ERROR_REPORTING_TERSE
65
+ mp_arg_error_terse_mismatch ();
66
+ #else
67
+ mp_raise_msg_varg (& mp_type_TypeError , MP_ERROR_TEXT ("unexpected keyword argument '%q'" ), MP_QSTR_file );
68
+ #endif
69
+
70
+ }
71
+ #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
72
+ mp_get_stream_raise (args [ARG_file ].u_obj , MP_STREAM_OP_WRITE );
73
+ print -> data = MP_OBJ_TO_PTR (args [ARG_file ].u_obj );
74
+ print -> print_strn = mp_stream_write_adaptor ;
75
+ #else
76
+ mp_raise_NotImplementedError (translate ("file write is not available" ));
77
+ #endif
78
+ }
79
+
42
80
if (!mp_obj_is_exception_instance (value )) {
43
81
mp_raise_TypeError (translate ("invalid exception" ));
44
82
}
@@ -53,7 +91,9 @@ STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj
53
91
mp_obj_exception_t * exc = mp_obj_exception_get_native (value );
54
92
mp_obj_traceback_t * trace_backup = exc -> traceback ;
55
93
56
- if (tb_obj != mp_const_none && print_tb ) {
94
+ if (tb_obj == MP_OBJ_NULL ) {
95
+ /* Print the traceback's exception as is */
96
+ } else if (tb_obj != mp_const_none && print_tb ) {
57
97
exc -> traceback = mp_arg_validate_type (tb_obj , & mp_type_traceback , MP_QSTR_tb );
58
98
} else {
59
99
exc -> traceback = (mp_obj_traceback_t * )& mp_const_empty_traceback_obj ;
@@ -64,14 +104,24 @@ STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj
64
104
}
65
105
66
106
//| def format_exception(
67
- //| etype: Type[BaseException],
68
- //| value: BaseException,
69
- //| tb: TracebackType,
107
+ //| exc: BaseException | Type[BaseException],
108
+ //| /,
109
+ //| value: Optional[BaseException] = None,
110
+ //| tb: Optional[TracebackType] = None,
70
111
//| limit: Optional[int] = None,
71
112
//| chain: Optional[bool] = True,
72
- //| ) -> None :
113
+ //| ) -> List[str] :
73
114
//| """Format a stack trace and the exception information.
74
115
//|
116
+ //| If the exception value is passed in ``exc``, then this exception value and its
117
+ //| associated traceback are used. This is compatible with CPython 3.10 and newer.
118
+ //|
119
+ //| If the exception value is passed in ``value``, then any value passed in for
120
+ //| ``exc`` is ignored. ``value`` is used as the exception value and the
121
+ //| traceback in the ``tb`` argument is used. In this case, if ``tb`` is None,
122
+ //| no traceback will be shown. This is compatible with CPython 3.5 and
123
+ //| newer.
124
+ //|
75
125
//| The arguments have the same meaning as the corresponding arguments
76
126
//| to print_exception(). The return value is a list of strings, each
77
127
//| ending in a newline and some containing internal newlines. When
@@ -80,54 +130,50 @@ STATIC void traceback_exception_common(mp_print_t *print, mp_obj_t value, mp_obj
80
130
//|
81
131
//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented.
82
132
//|
83
- //| :param Type[BaseException] etype: This is ignored and inferred from the type of `` value`` .
84
- //| :param BaseException value: The exception. Must be an instance of `BaseException `.
85
- //| :param TracebackType tb: The traceback object . If `None`, the traceback will not be printed.
133
+ //| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified .
134
+ //| :param value: If specified, is used in place of ``exc` `.
135
+ //| :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.
86
136
//| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive.
87
137
//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed.
88
138
//| :param bool chain: If `True` then chained exceptions will be printed (note: not yet implemented).
89
- //|
90
139
//| """
91
- //| ...
92
140
//|
93
141
STATIC mp_obj_t traceback_format_exception (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
94
- enum { ARG_etype , ARG_value , ARG_tb , ARG_limit , ARG_chain };
95
- static const mp_arg_t allowed_args [] = {
96
- { MP_QSTR_etype , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = MP_OBJ_NULL } },
97
- { MP_QSTR_value , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = MP_OBJ_NULL } },
98
- { MP_QSTR_tb , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = MP_OBJ_NULL } },
99
- { MP_QSTR_limit , MP_ARG_OBJ , {.u_obj = mp_const_none } },
100
- { MP_QSTR_chain , MP_ARG_BOOL , {.u_bool = true} },
101
- };
102
-
103
- mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
104
- mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
105
-
106
142
mp_print_t print ;
107
143
vstr_t vstr ;
108
144
vstr_init_print (& vstr , 0 , & print );
109
- traceback_exception_common (& print , args [ARG_value ].u_obj , args [ARG_tb ].u_obj , args [ARG_limit ].u_obj );
110
- return mp_obj_new_str_from_vstr (& mp_type_str , & vstr );
145
+ traceback_exception_common (false, & print , n_args , pos_args , kw_args );
146
+ mp_obj_t output = mp_obj_new_str_from_vstr (& mp_type_str , & vstr );
147
+ return mp_obj_new_list (1 , & output );
111
148
}
112
149
113
150
STATIC MP_DEFINE_CONST_FUN_OBJ_KW (traceback_format_exception_obj , 0 , traceback_format_exception );
114
151
115
152
//| def print_exception(
116
- //| etype: Type[BaseException],
117
- //| value: BaseException,
118
- //| tb: TracebackType,
153
+ //| exc: BaseException | Type[BaseException],
154
+ //| /,
155
+ //| value: Optional[BaseException] = None,
156
+ //| tb: Optional[TracebackType] = None,
119
157
//| limit: Optional[int] = None,
120
158
//| file: Optional[io.FileIO] = None,
121
159
//| chain: Optional[bool] = True,
122
160
//| ) -> None:
123
- //|
124
161
//| """Prints exception information and stack trace entries.
125
162
//|
163
+ //| If the exception value is passed in ``exc``, then this exception value and its
164
+ //| associated traceback are used. This is compatible with CPython 3.10 and newer.
165
+ //|
166
+ //| If the exception value is passed in ``value``, then any value passed in for
167
+ //| ``exc`` is ignored. ``value`` is used as the exception value and the
168
+ //| traceback in the ``tb`` argument is used. In this case, if ``tb`` is None,
169
+ //| no traceback will be shown. This is compatible with CPython 3.5 and
170
+ //| newer.
171
+ //|
126
172
//| .. note:: Setting ``chain`` will have no effect as chained exceptions are not yet implemented.
127
173
//|
128
- //| :param Type[BaseException] etype: This is ignored and inferred from the type of `` value`` .
129
- //| :param BaseException value: The exception. Must be an instance of `BaseException `.
130
- //| :param TracebackType tb: The traceback object . If `None`, the traceback will not be printed.
174
+ //| :param exc: The exception. Must be an instance of `BaseException`. Unused if value is specified .
175
+ //| :param value: If specified, is used in place of ``exc` `.
176
+ //| :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.
131
177
//| :param int limit: Print up to limit stack trace entries (starting from the caller’s frame) if limit is positive.
132
178
//| Otherwise, print the last ``abs(limit)`` entries. If limit is omitted or None, all entries are printed.
133
179
//| :param io.FileIO file: If file is omitted or `None`, the output goes to `sys.stderr`; otherwise it should be an open
@@ -139,31 +185,8 @@ STATIC MP_DEFINE_CONST_FUN_OBJ_KW(traceback_format_exception_obj, 0, traceback_f
139
185
//|
140
186
141
187
STATIC mp_obj_t traceback_print_exception (size_t n_args , const mp_obj_t * pos_args , mp_map_t * kw_args ) {
142
- enum { ARG_etype , ARG_value , ARG_tb , ARG_limit , ARG_file , ARG_chain };
143
- static const mp_arg_t allowed_args [] = {
144
- { MP_QSTR_etype , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = MP_OBJ_NULL } },
145
- { MP_QSTR_value , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = MP_OBJ_NULL } },
146
- { MP_QSTR_tb , MP_ARG_OBJ | MP_ARG_REQUIRED , {.u_obj = MP_OBJ_NULL } },
147
- { MP_QSTR_limit , MP_ARG_OBJ , {.u_obj = mp_const_none } },
148
- { MP_QSTR_file , MP_ARG_OBJ , {.u_obj = mp_const_none } },
149
- { MP_QSTR_chain , MP_ARG_BOOL , {.u_bool = true} },
150
- };
151
-
152
- mp_arg_val_t args [MP_ARRAY_SIZE (allowed_args )];
153
- mp_arg_parse_all (n_args , pos_args , kw_args , MP_ARRAY_SIZE (allowed_args ), allowed_args , args );
154
-
155
188
mp_print_t print = mp_plat_print ;
156
- if (args [ARG_file ].u_obj != mp_const_none ) {
157
- #if MICROPY_PY_IO && MICROPY_PY_SYS_STDFILES
158
- mp_get_stream_raise (args [ARG_file ].u_obj , MP_STREAM_OP_WRITE );
159
- print .data = MP_OBJ_TO_PTR (args [ARG_file ].u_obj );
160
- print .print_strn = mp_stream_write_adaptor ;
161
- #else
162
- mp_raise_NotImplementedError (translate ("file write is not available" ));
163
- #endif
164
- }
165
-
166
- traceback_exception_common (& print , args [ARG_value ].u_obj , args [ARG_tb ].u_obj , args [ARG_limit ].u_obj );
189
+ traceback_exception_common (true, & print , n_args , pos_args , kw_args );
167
190
return mp_const_none ;
168
191
}
169
192
STATIC MP_DEFINE_CONST_FUN_OBJ_KW (traceback_print_exception_obj , 0 , traceback_print_exception );
0 commit comments