Skip to content

Commit e41e97d

Browse files
committed
BUG: fix refcount issue caused by numpy#12524
1 parent 2f231b3 commit e41e97d

File tree

4 files changed

+15
-3
lines changed

4 files changed

+15
-3
lines changed

numpy/core/src/common/ufunc_override.c

+8-2
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,22 @@ PyUFunc_HasOverride(PyObject * obj)
7171
* Get possible out argument from kwds, and returns the number of outputs
7272
* contained within it: if a tuple, the number of elements in it, 1 otherwise.
7373
* The out argument itself is returned in out_kwd_obj, and the outputs
74-
* in the out_obj array (all as borrowed references).
74+
* in the out_obj array (as borrowed references).
7575
*
7676
* Returns 0 if no outputs found, -1 if kwds is not a dict (with an error set).
7777
*/
7878
NPY_NO_EXPORT int
7979
PyUFuncOverride_GetOutObjects(PyObject *kwds, PyObject **out_kwd_obj, PyObject ***out_objs)
8080
{
8181
if (kwds == NULL) {
82+
*out_kwd_obj = NULL;
8283
return 0;
8384
}
8485
if (!PyDict_CheckExact(kwds)) {
8586
PyErr_SetString(PyExc_TypeError,
8687
"Internal Numpy error: call to PyUFuncOverride_GetOutObjects "
8788
"with non-dict kwds");
89+
*out_kwd_obj = NULL;
8890
return -1;
8991
}
9092
/* borrowed reference */
@@ -97,8 +99,11 @@ PyUFuncOverride_GetOutObjects(PyObject *kwds, PyObject **out_kwd_obj, PyObject *
9799
* The C-API recommends calling PySequence_Fast before any of the other
98100
* PySequence_Fast* functions. This is required for PyPy
99101
*/
100-
PyObject *seq = PySequence_Fast(*out_kwd_obj, "Could not convert object to sequence");
102+
PyObject *seq;
101103
int ret;
104+
Py_INCREF(*out_kwd_obj);
105+
seq = PySequence_Fast(*out_kwd_obj,
106+
"Could not convert object to sequence");
102107
if (seq == NULL) {
103108
return -1;
104109
}
@@ -108,6 +113,7 @@ PyUFuncOverride_GetOutObjects(PyObject *kwds, PyObject **out_kwd_obj, PyObject *
108113
return ret;
109114
}
110115
else {
116+
Py_INCREF(*out_kwd_obj);
111117
*out_objs = out_kwd_obj;
112118
return 1;
113119
}

numpy/core/src/common/ufunc_override.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ PyUFunc_HasOverride(PyObject *obj);
2828
* Get possible out argument from kwds, and returns the number of outputs
2929
* contained within it: if a tuple, the number of elements in it, 1 otherwise.
3030
* The out argument itself is returned in out_kwd_obj, and the outputs
31-
* in the out_obj array (all as borrowed references).
31+
* in the out_obj array (as borrowed references).
3232
*
3333
* Returns 0 if no outputs found, -1 if kwds is not a dict (with an error set).
3434
*/

numpy/core/src/multiarray/methods.c

+3
Original file line numberDiff line numberDiff line change
@@ -1026,13 +1026,16 @@ any_array_ufunc_overrides(PyObject *args, PyObject *kwds)
10261026
/* check outputs, if any */
10271027
nout = PyUFuncOverride_GetOutObjects(kwds, &out_kwd_obj, &out_objs);
10281028
if (nout < 0) {
1029+
Py_XDECREF(out_kwd_obj);
10291030
return -1;
10301031
}
10311032
for (i = 0; i < nout; i++) {
10321033
if (PyUFunc_HasOverride(out_objs[i])) {
1034+
Py_XDECREF(out_kwd_obj);
10331035
return 1;
10341036
}
10351037
}
1038+
Py_XDECREF(out_kwd_obj);
10361039
return 0;
10371040
}
10381041

numpy/core/src/umath/override.c

+3
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ get_array_ufunc_overrides(PyObject *args, PyObject *kwds,
3939

4040
nout = PyUFuncOverride_GetOutObjects(kwds, &out_kwd_obj, &out_objs);
4141
if (nout < 0) {
42+
Py_XDECREF(out_kwd_obj);
4243
return -1;
4344
}
4445

@@ -86,13 +87,15 @@ get_array_ufunc_overrides(PyObject *args, PyObject *kwds,
8687
++num_override_args;
8788
}
8889
}
90+
Py_XDECREF(out_kwd_obj);
8991
return num_override_args;
9092

9193
fail:
9294
for (i = 0; i < num_override_args; i++) {
9395
Py_DECREF(with_override[i]);
9496
Py_DECREF(methods[i]);
9597
}
98+
Py_XDECREF(out_kwd_obj);
9699
return -1;
97100
}
98101

0 commit comments

Comments
 (0)