@@ -27,6 +27,15 @@ static void OneDimensionalArray_dealloc(OneDimensionalArray *self) {
2727 Py_TYPE (self)->tp_free (reinterpret_cast <PyObject*>(self));
2828}
2929
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+
3039static PyObject* OneDimensionalArray___new__ (PyTypeObject* type, PyObject *args,
3140 PyObject *kwds) {
3241 OneDimensionalArray *self;
@@ -49,7 +58,6 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
4958 return NULL ;
5059 }
5160
52- Py_INCREF (dtype);
5361 self->_dtype = dtype;
5462
5563 if (len_args != 2 && len_args != 3 ) {
@@ -63,8 +71,11 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
6371 if (len_args == 3 ) {
6472 PyObject *args0 = PyObject_GetItem (args, PyOne);
6573 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+ }
6879 size_t size;
6980 PyObject *data = NULL ;
7081 if ((PyList_Check (args0) || PyTuple_Check (args0)) && PyLong_Check (args1)) {
@@ -81,7 +92,6 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
8192 " expected type of data is list/tuple." );
8293 return NULL ;
8394 }
84-
8595 if (PyErr_Occurred ()) {
8696 Py_DECREF (args0);
8797 Py_DECREF (args1);
@@ -112,6 +122,8 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
112122 for (size_t i = 0 ; i < size; i++) {
113123 PyObject* idx = PyLong_FromSize_t (i);
114124 if (!idx) {
125+ cleanup_partial_data (self->_data , i);
126+ self->_data = nullptr ;
115127 Py_DECREF (args0);
116128 Py_DECREF (args1);
117129 return NULL ;
@@ -121,20 +133,22 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
121133 Py_DECREF (idx);
122134
123135 if (!value) {
136+ cleanup_partial_data (self->_data , i);
137+ self->_data = nullptr ;
124138 Py_DECREF (args0);
125139 Py_DECREF (args1);
126140 return NULL ;
127141 }
128142
129143 if (raise_exception_if_dtype_mismatch (value, self->_dtype )) {
130144 Py_DECREF (value);
145+ cleanup_partial_data (self->_data , i);
146+ self->_data = nullptr ;
131147 Py_DECREF (args0);
132148 Py_DECREF (args1);
133149 return NULL ;
134150 }
135- Py_INCREF (value);
136151 self->_data [i] = value;
137- Py_DECREF (value);
138152 }
139153 Py_DECREF (args0);
140154 Py_DECREF (args1);
@@ -157,33 +171,33 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
157171 if (!init) {
158172 PyErr_Clear ();
159173 init = Py_None;
174+ Py_INCREF (init);
160175 }
161176 }
162177 }
163178 if (!init) {
164179 init = Py_None;
180+ Py_INCREF (init);
165181 }
166182 if (init != Py_None && raise_exception_if_dtype_mismatch (init, self->_dtype )) {
167- if (init != Py_None) Py_DECREF (init);
183+ Py_DECREF (init);
168184 Py_DECREF (args0);
169185 return NULL ;
170186 }
171187 self->_data = reinterpret_cast <PyObject**>(std::calloc (self->_size , sizeof (PyObject*)));
172188 if (!self->_data ) {
173- if (init != Py_None) Py_DECREF (init);
189+ Py_DECREF (init);
174190 Py_DECREF (args0);
175191 PyErr_NoMemory ();
176192 return NULL ;
177193 }
178194
179- Py_INCREF (init);
180195 for (size_t i = 0 ; i < self->_size ; i++) {
181196 Py_INCREF (init);
182197 self->_data [i] = init;
183198 }
184199 Py_DECREF (init);
185- if (init != Py_None)
186- Py_DECREF (init);
200+
187201 } else if (PyList_Check (args0) || PyTuple_Check (args0)) {
188202 Py_ssize_t size_ssize = PyObject_Length (args0);
189203 if (size_ssize < 0 ) {
@@ -201,6 +215,8 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
201215 for (size_t i = 0 ; i < self->_size ; i++) {
202216 PyObject* idx = PyLong_FromSize_t (i);
203217 if (!idx) {
218+ cleanup_partial_data (self->_data , i);
219+ self->_data = nullptr ;
204220 Py_DECREF (args0);
205221 return NULL ;
206222 }
@@ -209,18 +225,21 @@ static PyObject* OneDimensionalArray___new__(PyTypeObject* type, PyObject *args,
209225 Py_DECREF (idx);
210226
211227 if (!value) {
228+ cleanup_partial_data (self->_data , i);
229+ self->_data = nullptr ;
212230 Py_DECREF (args0);
213231 return NULL ;
214232 }
215233
216234 if (raise_exception_if_dtype_mismatch (value, self->_dtype )) {
217235 Py_DECREF (value);
236+ cleanup_partial_data (self->_data , i);
237+ self->_data = nullptr ;
218238 Py_DECREF (args0);
219239 return NULL ;
220240 }
221- Py_INCREF (value);
241+
222242 self->_data [i] = value;
223- Py_DECREF (value);
224243 }
225244 } else {
226245 Py_DECREF (args0);
@@ -301,21 +320,19 @@ static PyObject* OneDimensionalArray_fill(OneDimensionalArray *self, PyObject *a
301320 return NULL ;
302321 }
303322
304- PyObject* value = PyTuple_GetItem (args, 0 );
323+ PyObject* value = PyTuple_GetItem (args, 0 ); // Borrowed reference
305324 if (!value) return NULL ;
306325
307326 if (value != Py_None && raise_exception_if_dtype_mismatch (value, self->_dtype )) {
308327 return NULL ;
309328 }
310329
311- Py_INCREF (value);
312330 for (size_t i = 0 ; i < self->_size ; i++) {
313331 PyObject* old_value = self->_data [i];
314332 Py_INCREF (value);
315333 self->_data [i] = value;
316334 Py_XDECREF (old_value);
317335 }
318- Py_DECREF (value);
319336
320337 Py_RETURN_NONE;
321338}
0 commit comments