bpo-25750: fix refcounts in type_getattro() (GH-6118) (GH-9091) · python/cpython@bf2bd8f (original) (raw)

`@@ -2611,6 +2611,7 @@ type_getattro(PyTypeObject *type, PyObject *name)

`

2611

2611

`PyTypeObject *metatype = Py_TYPE(type);

`

2612

2612

`PyObject *meta_attribute, *attribute;

`

2613

2613

`descrgetfunc meta_get;

`

``

2614

`+

PyObject* res;

`

2614

2615

``

2615

2616

`if (!PyString_Check(name)) {

`

2616

2617

`PyErr_Format(PyExc_TypeError,

`

`@@ -2632,36 +2633,41 @@ type_getattro(PyTypeObject *type, PyObject *name)

`

2632

2633

`meta_attribute = _PyType_Lookup(metatype, name);

`

2633

2634

``

2634

2635

`if (meta_attribute != NULL) {

`

``

2636

`+

Py_INCREF(meta_attribute);

`

2635

2637

`meta_get = Py_TYPE(meta_attribute)->tp_descr_get;

`

2636

2638

``

2637

2639

`if (meta_get != NULL && PyDescr_IsData(meta_attribute)) {

`

2638

2640

`/* Data descriptors implement tp_descr_set to intercept

`

2639

2641

` * writes. Assume the attribute is not overridden in

`

2640

2642

` * type's tp_dict (and bases): call the descriptor now.

`

2641

2643

` */

`

2642

``

`-

return meta_get(meta_attribute, (PyObject *)type,

`

2643

``

`-

(PyObject *)metatype);

`

``

2644

`+

res = meta_get(meta_attribute, (PyObject *)type,

`

``

2645

`+

(PyObject *)metatype);

`

``

2646

`+

Py_DECREF(meta_attribute);

`

``

2647

`+

return res;

`

2644

2648

` }

`

2645

``

`-

Py_INCREF(meta_attribute);

`

2646

2649

` }

`

2647

2650

``

2648

2651

`/* No data descriptor found on metatype. Look in tp_dict of this

`

2649

2652

` * type and its bases */

`

2650

2653

`attribute = _PyType_Lookup(type, name);

`

2651

2654

`if (attribute != NULL) {

`

2652

2655

`/* Implement descriptor functionality, if any */

`

2653

``

`-

descrgetfunc local_get = Py_TYPE(attribute)->tp_descr_get;

`

``

2656

`+

descrgetfunc local_get;

`

``

2657

`+

Py_INCREF(attribute);

`

``

2658

`+

local_get = Py_TYPE(attribute)->tp_descr_get;

`

2654

2659

``

2655

2660

`Py_XDECREF(meta_attribute);

`

2656

2661

``

2657

2662

`if (local_get != NULL) {

`

2658

2663

`/* NULL 2nd argument indicates the descriptor was

`

2659

2664

` * found on the target object itself (or a base) */

`

2660

``

`-

return local_get(attribute, (PyObject *)NULL,

`

2661

``

`-

(PyObject *)type);

`

``

2665

`+

res = local_get(attribute, (PyObject *)NULL,

`

``

2666

`+

(PyObject *)type);

`

``

2667

`+

Py_DECREF(attribute);

`

``

2668

`+

return res;

`

2662

2669

` }

`

2663

2670

``

2664

``

`-

Py_INCREF(attribute);

`

2665

2671

`return attribute;

`

2666

2672

` }

`

2667

2673

``