bpo-45711: Change exc_info related APIs to derive type and traceback … · python/cpython@8a45ca5 (original) (raw)
`@@ -470,25 +470,43 @@ PyErr_Clear(void)
`
470
470
`_PyErr_Clear(tstate);
`
471
471
`}
`
472
472
``
``
473
`+
static PyObject*
`
``
474
`+
get_exc_type(PyObject exc_value) / returns a borrowed ref */
`
``
475
`+
{
`
``
476
`+
if (exc_value == NULL || exc_value == Py_None) {
`
``
477
`+
return Py_None;
`
``
478
`+
}
`
``
479
`+
else {
`
``
480
`+
assert(PyExceptionInstance_Check(exc_value));
`
``
481
`+
PyObject *type = PyExceptionInstance_Class(exc_value);
`
``
482
`+
assert(type != NULL);
`
``
483
`+
return type;
`
``
484
`+
}
`
``
485
`+
}
`
``
486
+
``
487
`+
static PyObject*
`
``
488
`+
get_exc_traceback(PyObject exc_value) / returns a borrowed ref */
`
``
489
`+
{
`
``
490
`+
if (exc_value == NULL || exc_value == Py_None) {
`
``
491
`+
return Py_None;
`
``
492
`+
}
`
``
493
`+
else {
`
``
494
`+
assert(PyExceptionInstance_Check(exc_value));
`
``
495
`+
PyObject *tb = PyException_GetTraceback(exc_value);
`
``
496
`+
Py_XDECREF(tb);
`
``
497
`+
return tb ? tb : Py_None;
`
``
498
`+
}
`
``
499
`+
}
`
473
500
``
474
501
`void
`
475
502
`_PyErr_GetExcInfo(PyThreadState *tstate,
`
476
503
`PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
`
477
504
`{
`
478
505
`_PyErr_StackItem *exc_info = _PyErr_GetTopmostException(tstate);
`
479
506
``
``
507
`+
*p_type = get_exc_type(exc_info->exc_value);
`
480
508
`*p_value = exc_info->exc_value;
`
481
``
`-
*p_traceback = exc_info->exc_traceback;
`
482
``
-
483
``
`-
if (*p_value == NULL || *p_value == Py_None) {
`
484
``
`-
assert(exc_info->exc_type == NULL || exc_info->exc_type == Py_None);
`
485
``
`-
*p_type = Py_None;
`
486
``
`-
}
`
487
``
`-
else {
`
488
``
`-
assert(PyExceptionInstance_Check(*p_value));
`
489
``
`-
assert(exc_info->exc_type == PyExceptionInstance_Class(*p_value));
`
490
``
`-
*p_type = PyExceptionInstance_Class(*p_value);
`
491
``
`-
}
`
``
509
`+
*p_traceback = get_exc_traceback(exc_info->exc_value);
`
492
510
``
493
511
`Py_XINCREF(*p_type);
`
494
512
`Py_XINCREF(*p_value);
`
`@@ -504,7 +522,7 @@ PyErr_GetExcInfo(PyObject **p_type, PyObject **p_value, PyObject **p_traceback)
`
504
522
`}
`
505
523
``
506
524
`void
`
507
``
`-
PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
`
``
525
`+
PyErr_SetExcInfo(PyObject *type, PyObject *value, PyObject *traceback)
`
508
526
`{
`
509
527
`PyObject *oldtype, *oldvalue, *oldtraceback;
`
510
528
`PyThreadState *tstate = _PyThreadState_GET();
`
`@@ -513,9 +531,16 @@ PyErr_SetExcInfo(PyObject *p_type, PyObject *p_value, PyObject *p_traceback)
`
513
531
`oldvalue = tstate->exc_info->exc_value;
`
514
532
`oldtraceback = tstate->exc_info->exc_traceback;
`
515
533
``
516
``
`-
tstate->exc_info->exc_type = p_type;
`
517
``
`-
tstate->exc_info->exc_value = p_value;
`
518
``
`-
tstate->exc_info->exc_traceback = p_traceback;
`
``
534
+
``
535
`+
tstate->exc_info->exc_type = get_exc_type(value);
`
``
536
`+
Py_XINCREF(tstate->exc_info->exc_type);
`
``
537
`+
tstate->exc_info->exc_value = value;
`
``
538
`+
tstate->exc_info->exc_traceback = get_exc_traceback(value);
`
``
539
`+
Py_XINCREF(tstate->exc_info->exc_traceback);
`
``
540
+
``
541
`+
/* These args are no longer used, but we still need to steal a ref */
`
``
542
`+
Py_XDECREF(type);
`
``
543
`+
Py_XDECREF(traceback);
`
519
544
``
520
545
`Py_XDECREF(oldtype);
`
521
546
`Py_XDECREF(oldvalue);
`
`@@ -527,22 +552,19 @@ PyObject*
`
527
552
`_PyErr_StackItemToExcInfoTuple(_PyErr_StackItem *err_info)
`
528
553
`{
`
529
554
`PyObject *exc_value = err_info->exc_value;
`
530
``
`-
if (exc_value == NULL) {
`
531
``
`-
exc_value = Py_None;
`
532
``
`-
}
`
533
555
``
534
``
`-
assert(exc_value == Py_None || PyExceptionInstance_Check(exc_value));
`
``
556
`+
assert(exc_value == NULL ||
`
``
557
`+
exc_value == Py_None ||
`
``
558
`+
PyExceptionInstance_Check(exc_value));
`
535
559
``
536
``
`-
PyObject *exc_type = PyExceptionInstance_Check(exc_value) ?
`
537
``
`-
PyExceptionInstance_Class(exc_value) :
`
538
``
`-
Py_None;
`
``
560
`+
PyObject *exc_type = get_exc_type(exc_value);
`
``
561
`+
PyObject *exc_traceback = get_exc_traceback(exc_value);
`
539
562
``
540
563
`return Py_BuildValue(
`
541
564
`"(OOO)",
`
542
``
`-
exc_type,
`
543
``
`-
exc_value,
`
544
``
`-
err_info->exc_traceback != NULL ?
`
545
``
`-
err_info->exc_traceback : Py_None);
`
``
565
`+
exc_type ? exc_type : Py_None,
`
``
566
`+
exc_value ? exc_value : Py_None,
`
``
567
`+
exc_traceback ? exc_traceback : Py_None);
`
546
568
`}
`
547
569
``
548
570
``