@@ -139,6 +139,15 @@ PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject **ret, int getm
139
139
* ret = (PyArrayObject * )new ;
140
140
}
141
141
142
+ NPY_NO_EXPORT NPY_INLINE void
143
+ multi_DECREF (PyObject * * objects , npy_intp n )
144
+ {
145
+ npy_intp i ;
146
+ for (i = 0 ; i < n ; i ++ ) {
147
+ Py_DECREF (objects [i ]);
148
+ }
149
+ }
150
+
142
151
/**
143
152
* Turn an index argument into a c-array of `PyObject *`s, one for each index.
144
153
*
@@ -158,7 +167,7 @@ PyArray_MapIterSwapAxes(PyArrayMapIterObject *mit, PyArrayObject **ret, int getm
158
167
* @param index The index object, which may or may not be a tuple. This is a
159
168
* borrowed reference.
160
169
* @param result An empty buffer of 2*NPY_MAXDIMS PyObject* to write each
161
- * index component to. The references written are borrowed .
170
+ * index component to. The references written are new. .
162
171
* This function will in some cases clobber the array beyond
163
172
* the last item unpacked.
164
173
*
@@ -180,6 +189,7 @@ unpack_indices(PyObject *index, PyObject *result[2*NPY_MAXDIMS])
180
189
}
181
190
for (i = 0 ; i < n ; i ++ ) {
182
191
result [i ] = PyTuple_GET_ITEM (index , i );
192
+ Py_INCREF (result [i ]);
183
193
}
184
194
return n ;
185
195
}
@@ -196,6 +206,7 @@ unpack_indices(PyObject *index, PyObject *result[2*NPY_MAXDIMS])
196
206
|| PyArray_Check (index )
197
207
|| !PySequence_Check (index )) {
198
208
209
+ Py_INCREF (index );
199
210
result [0 ] = index ;
200
211
return 1 ;
201
212
}
@@ -214,8 +225,10 @@ unpack_indices(PyObject *index, PyObject *result[2*NPY_MAXDIMS])
214
225
for (i = 0 ; i < n ; i ++ ) {
215
226
result [i ] = PySequence_GetItem (index , i );
216
227
if (result [i ] == NULL ) {
228
+ multi_DECREF (result , i );
217
229
return -1 ;
218
230
}
231
+ Py_INCREF (result [i ]);
219
232
}
220
233
return n ;
221
234
}
@@ -233,13 +246,15 @@ unpack_indices(PyObject *index, PyObject *result[2*NPY_MAXDIMS])
233
246
n = PySequence_Size (index );
234
247
if (n < 0 ) {
235
248
PyErr_Clear ();
249
+ Py_INCREF (index );
236
250
result [0 ] = index ;
237
251
return 1 ;
238
252
}
239
253
240
254
/* for some reason, anything that's long but not too long is turned into
241
255
* a single index. The *2 is missing here for backward-compatibility. */
242
256
if (n >= NPY_MAXDIMS ) {
257
+ Py_INCREF (index );
243
258
result [0 ] = index ;
244
259
return 1 ;
245
260
}
@@ -253,13 +268,15 @@ unpack_indices(PyObject *index, PyObject *result[2*NPY_MAXDIMS])
253
268
if (commit_to_unpack ) {
254
269
/* propagate errors */
255
270
if (tmp_obj == NULL ) {
271
+ multi_DECREF (result , i );
256
272
return -1 ;
257
273
}
258
274
}
259
275
else {
260
276
/* if getitem fails (unusual) before we've committed, then
261
277
* commit to not unpacking */
262
278
if (tmp_obj == NULL ) {
279
+ multi_DECREF (result , i );
263
280
PyErr_Clear ();
264
281
break ;
265
282
}
@@ -273,18 +290,18 @@ unpack_indices(PyObject *index, PyObject *result[2*NPY_MAXDIMS])
273
290
commit_to_unpack = 1 ;
274
291
}
275
292
}
276
-
277
- Py_DECREF (tmp_obj );
278
293
}
279
294
280
295
/* unpacking was the right thing to do, and we already did it */
281
296
if (commit_to_unpack ) {
282
297
return n ;
283
298
}
284
-
285
299
/* got to the end, never found an indication that we should have unpacked */
286
300
else {
287
- /* we already filled result, but it doesn't matter */
301
+ /* we already filled result, so empty it first */
302
+ multi_DECREF (result , n );
303
+
304
+ Py_INCREF (index );
288
305
result [0 ] = index ;
289
306
return 1 ;
290
307
}
@@ -757,13 +774,15 @@ prepare_index(PyArrayObject *self, PyObject *index,
757
774
* ndim = new_ndim + fancy_ndim ;
758
775
* out_fancy_ndim = fancy_ndim ;
759
776
777
+ multi_DECREF (raw_indices , index_ndim );
760
778
761
779
return index_type ;
762
780
763
781
failed_building_indices :
764
782
for (i = 0 ; i < curr_idx ; i ++ ) {
765
783
Py_XDECREF (indices [i ].object );
766
784
}
785
+ multi_DECREF (raw_indices , index_ndim );
767
786
return -1 ;
768
787
}
769
788
0 commit comments