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

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

`

3145

3145

`PyTypeObject *metatype = Py_TYPE(type);

`

3146

3146

`PyObject *meta_attribute, *attribute;

`

3147

3147

`descrgetfunc meta_get;

`

``

3148

`+

PyObject* res;

`

3148

3149

``

3149

3150

`if (!PyUnicode_Check(name)) {

`

3150

3151

`PyErr_Format(PyExc_TypeError,

`

`@@ -3166,36 +3167,40 @@ type_getattro(PyTypeObject *type, PyObject *name)

`

3166

3167

`meta_attribute = _PyType_Lookup(metatype, name);

`

3167

3168

``

3168

3169

`if (meta_attribute != NULL) {

`

``

3170

`+

Py_INCREF(meta_attribute);

`

3169

3171

`meta_get = Py_TYPE(meta_attribute)->tp_descr_get;

`

3170

3172

``

3171

3173

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

`

3172

3174

`/* Data descriptors implement tp_descr_set to intercept

`

3173

3175

` * writes. Assume the attribute is not overridden in

`

3174

3176

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

`

3175

3177

` */

`

3176

``

`-

return meta_get(meta_attribute, (PyObject *)type,

`

3177

``

`-

(PyObject *)metatype);

`

``

3178

`+

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

`

``

3179

`+

(PyObject *)metatype);

`

``

3180

`+

Py_DECREF(meta_attribute);

`

``

3181

`+

return res;

`

3178

3182

` }

`

3179

``

`-

Py_INCREF(meta_attribute);

`

3180

3183

` }

`

3181

3184

``

3182

3185

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

`

3183

3186

` * type and its bases */

`

3184

3187

`attribute = _PyType_Lookup(type, name);

`

3185

3188

`if (attribute != NULL) {

`

3186

3189

`/* Implement descriptor functionality, if any */

`

``

3190

`+

Py_INCREF(attribute);

`

3187

3191

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

`

3188

3192

``

3189

3193

`Py_XDECREF(meta_attribute);

`

3190

3194

``

3191

3195

`if (local_get != NULL) {

`

3192

3196

`/* NULL 2nd argument indicates the descriptor was

`

3193

3197

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

`

3194

``

`-

return local_get(attribute, (PyObject *)NULL,

`

3195

``

`-

(PyObject *)type);

`

``

3198

`+

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

`

``

3199

`+

(PyObject *)type);

`

``

3200

`+

Py_DECREF(attribute);

`

``

3201

`+

return res;

`

3196

3202

` }

`

3197

3203

``

3198

``

`-

Py_INCREF(attribute);

`

3199

3204

`return attribute;

`

3200

3205

` }

`

3201

3206

``