@@ -27,6 +27,15 @@ static void OneDimensionalArray_dealloc(OneDimensionalArray *self) {
27
27
Py_TYPE (self)->tp_free (reinterpret_cast <PyObject*>(self));
28
28
}
29
29
30
+ static void cleanup_partial_data (PyObject** data, size_t count) {
31
+ if (data) {
32
+ for (size_t i = 0 ; i < count; i++) {
33
+ Py_XDECREF (data[i]);
34
+ }
35
+ std::free (data);
36
+ }
37
+ }
38
+
30
39
static PyObject* OneDimensionalArray___new__ (PyTypeObject* type, PyObject *args,
31
40
PyObject *kwds) {
32
41
OneDimensionalArray *self;
@@ -49,7 +58,6 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
49
58
return NULL ;
50
59
}
51
60
52
- Py_INCREF (dtype);
53
61
self->_dtype = dtype;
54
62
55
63
if (len_args != 2 && len_args != 3 ) {
@@ -63,8 +71,11 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
63
71
if (len_args == 3 ) {
64
72
PyObject *args0 = PyObject_GetItem (args, PyOne);
65
73
PyObject *args1 = PyObject_GetItem (args, PyTwo);
66
- if (!args0 || !args1) return NULL ;
67
-
74
+ if (!args0 || !args1) {
75
+ Py_XDECREF (args0);
76
+ Py_XDECREF (args1);
77
+ return NULL ;
78
+ }
68
79
size_t size;
69
80
PyObject *data = NULL ;
70
81
if ((PyList_Check (args0) || PyTuple_Check (args0)) && PyLong_Check (args1)) {
@@ -81,7 +92,6 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
81
92
" expected type of data is list/tuple." );
82
93
return NULL ;
83
94
}
84
-
85
95
if (PyErr_Occurred ()) {
86
96
Py_DECREF (args0);
87
97
Py_DECREF (args1);
@@ -112,6 +122,8 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
112
122
for (size_t i = 0 ; i < size; i++) {
113
123
PyObject* idx = PyLong_FromSize_t (i);
114
124
if (!idx) {
125
+ cleanup_partial_data (self->_data , i);
126
+ self->_data = nullptr ;
115
127
Py_DECREF (args0);
116
128
Py_DECREF (args1);
117
129
return NULL ;
@@ -121,20 +133,22 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
121
133
Py_DECREF (idx);
122
134
123
135
if (!value) {
136
+ cleanup_partial_data (self->_data , i);
137
+ self->_data = nullptr ;
124
138
Py_DECREF (args0);
125
139
Py_DECREF (args1);
126
140
return NULL ;
127
141
}
128
142
129
143
if (raise_exception_if_dtype_mismatch (value, self->_dtype )) {
130
144
Py_DECREF (value);
145
+ cleanup_partial_data (self->_data , i);
146
+ self->_data = nullptr ;
131
147
Py_DECREF (args0);
132
148
Py_DECREF (args1);
133
149
return NULL ;
134
150
}
135
- Py_INCREF (value);
136
151
self->_data [i] = value;
137
- Py_DECREF (value);
138
152
}
139
153
Py_DECREF (args0);
140
154
Py_DECREF (args1);
@@ -157,33 +171,33 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
157
171
if (!init) {
158
172
PyErr_Clear ();
159
173
init = Py_None;
174
+ Py_INCREF (init);
160
175
}
161
176
}
162
177
}
163
178
if (!init) {
164
179
init = Py_None;
180
+ Py_INCREF (init);
165
181
}
166
182
if (init != Py_None && raise_exception_if_dtype_mismatch (init, self->_dtype )) {
167
- if (init != Py_None) Py_DECREF (init);
183
+ Py_DECREF (init);
168
184
Py_DECREF (args0);
169
185
return NULL ;
170
186
}
171
187
self->_data = reinterpret_cast <PyObject**>(std::calloc (self->_size , sizeof (PyObject*)));
172
188
if (!self->_data ) {
173
- if (init != Py_None) Py_DECREF (init);
189
+ Py_DECREF (init);
174
190
Py_DECREF (args0);
175
191
PyErr_NoMemory ();
176
192
return NULL ;
177
193
}
178
194
179
- Py_INCREF (init);
180
195
for (size_t i = 0 ; i < self->_size ; i++) {
181
196
Py_INCREF (init);
182
197
self->_data [i] = init;
183
198
}
184
199
Py_DECREF (init);
185
- if (init != Py_None)
186
- Py_DECREF (init);
200
+
187
201
} else if (PyList_Check (args0) || PyTuple_Check (args0)) {
188
202
Py_ssize_t size_ssize = PyObject_Length (args0);
189
203
if (size_ssize < 0 ) {
@@ -201,6 +215,8 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
201
215
for (size_t i = 0 ; i < self->_size ; i++) {
202
216
PyObject* idx = PyLong_FromSize_t (i);
203
217
if (!idx) {
218
+ cleanup_partial_data (self->_data , i);
219
+ self->_data = nullptr ;
204
220
Py_DECREF (args0);
205
221
return NULL ;
206
222
}
@@ -209,18 +225,21 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
209
225
Py_DECREF (idx);
210
226
211
227
if (!value) {
228
+ cleanup_partial_data (self->_data , i);
229
+ self->_data = nullptr ;
212
230
Py_DECREF (args0);
213
231
return NULL ;
214
232
}
215
233
216
234
if (raise_exception_if_dtype_mismatch (value, self->_dtype )) {
217
235
Py_DECREF (value);
236
+ cleanup_partial_data (self->_data , i);
237
+ self->_data = nullptr ;
218
238
Py_DECREF (args0);
219
239
return NULL ;
220
240
}
221
- Py_INCREF (value);
241
+
222
242
self->_data [i] = value;
223
- Py_DECREF (value);
224
243
}
225
244
} else {
226
245
Py_DECREF (args0);
@@ -301,21 +320,19 @@ static PyObject* OneDimensionalArray_fill(OneDimensionalArray *self, PyObject *a
301
320
return NULL ;
302
321
}
303
322
304
- PyObject* value = PyTuple_GetItem (args, 0 );
323
+ PyObject* value = PyTuple_GetItem (args, 0 ); // Borrowed reference
305
324
if (!value) return NULL ;
306
325
307
326
if (value != Py_None && raise_exception_if_dtype_mismatch (value, self->_dtype )) {
308
327
return NULL ;
309
328
}
310
329
311
- Py_INCREF (value);
312
330
for (size_t i = 0 ; i < self->_size ; i++) {
313
331
PyObject* old_value = self->_data [i];
314
332
Py_INCREF (value);
315
333
self->_data [i] = value;
316
334
Py_XDECREF (old_value);
317
335
}
318
- Py_DECREF (value);
319
336
320
337
Py_RETURN_NONE;
321
338
}
0 commit comments