@@ -228,20 +228,20 @@ PyErr_ExceptionMatches(PyObject *exc)
228
228
XXX: should PyErr_NormalizeException() also call
229
229
PyException_SetTraceback() with the resulting value and tb?
230
230
*/
231
- static void
232
- PyErr_NormalizeExceptionEx (PyObject * * exc , PyObject * * val ,
233
- PyObject * * tb , int recursion_depth )
231
+ void
232
+ PyErr_NormalizeException (PyObject * * exc , PyObject * * val , PyObject * * tb )
234
233
{
235
- PyObject * type = * exc ;
236
- PyObject * value = * val ;
237
- PyObject * inclass = NULL ;
238
- PyObject * initial_tb = NULL ;
234
+ int recursion_depth = 0 ;
235
+ PyObject * type , * value , * initial_tb ;
239
236
237
+ restart :
238
+ type = * exc ;
240
239
if (type == NULL ) {
241
240
/* There was no exception, so nothing to do. */
242
241
return ;
243
242
}
244
243
244
+ value = * val ;
245
245
/* If PyErr_SetNone() was used, the value will have been actually
246
246
set to NULL.
247
247
*/
@@ -250,54 +250,52 @@ PyErr_NormalizeExceptionEx(PyObject **exc, PyObject **val,
250
250
Py_INCREF (value );
251
251
}
252
252
253
- if (PyExceptionInstance_Check (value ))
254
- inclass = PyExceptionInstance_Class (value );
255
-
256
253
/* Normalize the exception so that if the type is a class, the
257
254
value will be an instance.
258
255
*/
259
256
if (PyExceptionClass_Check (type )) {
260
- int is_subclass ;
261
- if (inclass ) {
257
+ PyObject * inclass = NULL ;
258
+ int is_subclass = 0 ;
259
+
260
+ if (PyExceptionInstance_Check (value )) {
261
+ inclass = PyExceptionInstance_Class (value );
262
262
is_subclass = PyObject_IsSubclass (inclass , type );
263
- if (is_subclass < 0 )
264
- goto finally ;
263
+ if (is_subclass < 0 ) {
264
+ goto error ;
265
+ }
265
266
}
266
- else
267
- is_subclass = 0 ;
268
267
269
- /* if the value was not an instance, or is not an instance
268
+ /* If the value was not an instance, or is not an instance
270
269
whose class is (or is derived from) type, then use the
271
270
value as an argument to instantiation of the type
272
271
class.
273
272
*/
274
- if (!inclass || !is_subclass ) {
275
- PyObject * fixed_value ;
276
-
277
- fixed_value = _PyErr_CreateException (type , value );
273
+ if (!is_subclass ) {
274
+ PyObject * fixed_value = _PyErr_CreateException (type , value );
278
275
if (fixed_value == NULL ) {
279
- goto finally ;
276
+ goto error ;
280
277
}
281
-
282
278
Py_DECREF (value );
283
279
value = fixed_value ;
284
280
}
285
- /* if the class of the instance doesn't exactly match the
286
- class of the type, believe the instance
281
+ /* If the class of the instance doesn't exactly match the
282
+ class of the type, believe the instance.
287
283
*/
288
284
else if (inclass != type ) {
285
+ Py_INCREF (inclass );
289
286
Py_DECREF (type );
290
287
type = inclass ;
291
- Py_INCREF (type );
292
288
}
293
289
}
294
290
* exc = type ;
295
291
* val = value ;
296
292
return ;
297
- finally :
293
+
294
+ error :
298
295
Py_DECREF (type );
299
296
Py_DECREF (value );
300
- if (recursion_depth + 1 == Py_NORMALIZE_RECURSION_LIMIT ) {
297
+ recursion_depth ++ ;
298
+ if (recursion_depth == Py_NORMALIZE_RECURSION_LIMIT ) {
301
299
PyErr_SetString (PyExc_RecursionError , "maximum recursion depth "
302
300
"exceeded while normalizing an exception" );
303
301
}
@@ -307,16 +305,18 @@ PyErr_NormalizeExceptionEx(PyObject **exc, PyObject **val,
307
305
*/
308
306
initial_tb = * tb ;
309
307
PyErr_Fetch (exc , val , tb );
308
+ assert (* exc != NULL );
310
309
if (initial_tb != NULL ) {
311
310
if (* tb == NULL )
312
311
* tb = initial_tb ;
313
312
else
314
313
Py_DECREF (initial_tb );
315
314
}
316
- /* Normalize recursively.
317
- * Abort when Py_NORMALIZE_RECURSION_LIMIT has been exceeded and the
318
- * corresponding RecursionError could not be normalized.*/
319
- if (++ recursion_depth > Py_NORMALIZE_RECURSION_LIMIT ) {
315
+ /* Abort when Py_NORMALIZE_RECURSION_LIMIT has been exceeded, and the
316
+ corresponding RecursionError could not be normalized, and the
317
+ MemoryError raised when normalize this RecursionError could not be
318
+ normalized. */
319
+ if (recursion_depth >= Py_NORMALIZE_RECURSION_LIMIT + 2 ) {
320
320
if (PyErr_GivenExceptionMatches (* exc , PyExc_MemoryError )) {
321
321
Py_FatalError ("Cannot recover from MemoryErrors "
322
322
"while normalizing exceptions." );
@@ -326,13 +326,7 @@ PyErr_NormalizeExceptionEx(PyObject **exc, PyObject **val,
326
326
"of an exception." );
327
327
}
328
328
}
329
- PyErr_NormalizeExceptionEx (exc , val , tb , recursion_depth );
330
- }
331
-
332
- void
333
- PyErr_NormalizeException (PyObject * * exc , PyObject * * val , PyObject * * tb )
334
- {
335
- PyErr_NormalizeExceptionEx (exc , val , tb , 0 );
329
+ goto restart ;
336
330
}
337
331
338
332
0 commit comments