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

``