bpo-25750: fix refcounts in type_getattro() (GH-6118) (GH-9088) · python/cpython@3ee0743 (original) (raw)

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

`

3004

3004

`PyTypeObject *metatype = Py_TYPE(type);

`

3005

3005

`PyObject *meta_attribute, *attribute;

`

3006

3006

`descrgetfunc meta_get;

`

``

3007

`+

PyObject* res;

`

3007

3008

``

3008

3009

`if (!PyUnicode_Check(name)) {

`

3009

3010

`PyErr_Format(PyExc_TypeError,

`

`@@ -3025,36 +3026,40 @@ type_getattro(PyTypeObject *type, PyObject *name)

`

3025

3026

`meta_attribute = _PyType_Lookup(metatype, name);

`

3026

3027

``

3027

3028

`if (meta_attribute != NULL) {

`

``

3029

`+

Py_INCREF(meta_attribute);

`

3028

3030

`meta_get = Py_TYPE(meta_attribute)->tp_descr_get;

`

3029

3031

``

3030

3032

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

`

3031

3033

`/* Data descriptors implement tp_descr_set to intercept

`

3032

3034

` * writes. Assume the attribute is not overridden in

`

3033

3035

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

`

3034

3036

` */

`

3035

``

`-

return meta_get(meta_attribute, (PyObject *)type,

`

3036

``

`-

(PyObject *)metatype);

`

``

3037

`+

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

`

``

3038

`+

(PyObject *)metatype);

`

``

3039

`+

Py_DECREF(meta_attribute);

`

``

3040

`+

return res;

`

3037

3041

` }

`

3038

``

`-

Py_INCREF(meta_attribute);

`

3039

3042

` }

`

3040

3043

``

3041

3044

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

`

3042

3045

` * type and its bases */

`

3043

3046

`attribute = _PyType_Lookup(type, name);

`

3044

3047

`if (attribute != NULL) {

`

3045

3048

`/* Implement descriptor functionality, if any */

`

``

3049

`+

Py_INCREF(attribute);

`

3046

3050

`descrgetfunc local_get = Py_TYPE(attribute)->tp_descr_get;

`

3047

3051

``

3048

3052

`Py_XDECREF(meta_attribute);

`

3049

3053

``

3050

3054

`if (local_get != NULL) {

`

3051

3055

`/* NULL 2nd argument indicates the descriptor was

`

3052

3056

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

`

3053

``

`-

return local_get(attribute, (PyObject *)NULL,

`

3054

``

`-

(PyObject *)type);

`

``

3057

`+

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

`

``

3058

`+

(PyObject *)type);

`

``

3059

`+

Py_DECREF(attribute);

`

``

3060

`+

return res;

`

3055

3061

` }

`

3056

3062

``

3057

``

`-

Py_INCREF(attribute);

`

3058

3063

`return attribute;

`

3059

3064

` }

`

3060

3065

``