diff options
author | Matti Picus <matti.picus@gmail.com> | 2019-10-03 10:16:51 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-10-03 10:16:51 +0300 |
commit | 454c5b5e9a76809a4ab60bda30aa048ec37ee11e (patch) | |
tree | bdacfe44fc0dcedd12040336458ad37333a0ec57 | |
parent | 18aa81985d36fe6922a813f513190944b03c8677 (diff) | |
download | numpy-454c5b5e9a76809a4ab60bda30aa048ec37ee11e.tar.gz |
BUG: dtype refcount cleanups (#14586)
* BUG: dtype reference count cleanup
-rw-r--r-- | numpy/core/src/multiarray/_multiarray_tests.c.src | 10 | ||||
-rw-r--r-- | numpy/core/src/multiarray/ctors.c | 28 |
2 files changed, 16 insertions, 22 deletions
diff --git a/numpy/core/src/multiarray/_multiarray_tests.c.src b/numpy/core/src/multiarray/_multiarray_tests.c.src index 9e6083e2a..fa2efb428 100644 --- a/numpy/core/src/multiarray/_multiarray_tests.c.src +++ b/numpy/core/src/multiarray/_multiarray_tests.c.src @@ -601,14 +601,14 @@ static PyObject * fromstring_null_term_c_api(PyObject *dummy, PyObject *byte_obj) { char *string; + PyArray_Descr *descr; string = PyBytes_AsString(byte_obj); if (string == NULL) { return NULL; } - - return PyArray_FromString( - string, -1, PyArray_DescrFromType(NPY_FLOAT64), -1, " "); + descr = PyArray_DescrNewFromType(NPY_FLOAT64); + return PyArray_FromString(string, -1, descr, -1, " "); } @@ -913,6 +913,7 @@ static PyObject* get_c_wrapping_array(PyObject* NPY_UNUSED(self), PyObject* arg) { int writeable, flags; + PyArray_Descr *descr; npy_intp zero = 0; writeable = PyObject_IsTrue(arg); @@ -922,7 +923,8 @@ get_c_wrapping_array(PyObject* NPY_UNUSED(self), PyObject* arg) flags = writeable ? NPY_ARRAY_WRITEABLE : 0; /* Create an empty array (which points to a random place) */ - return PyArray_NewFromDescr(&PyArray_Type, PyArray_DescrFromType(NPY_INTP), + descr = PyArray_DescrNewFromType(NPY_INTP); + return PyArray_NewFromDescr(&PyArray_Type, descr, 1, &zero, NULL, &zero, flags, NULL); } diff --git a/numpy/core/src/multiarray/ctors.c b/numpy/core/src/multiarray/ctors.c index c5199c015..e6387e3d3 100644 --- a/numpy/core/src/multiarray/ctors.c +++ b/numpy/core/src/multiarray/ctors.c @@ -3574,6 +3574,7 @@ PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject *step, PyArray_Descr return NULL; } +/* This array creation function steals the reference to dtype. */ static PyArrayObject * array_fromfile_binary(FILE *fp, PyArray_Descr *dtype, npy_intp num, size_t *nread) { @@ -3605,27 +3606,24 @@ array_fromfile_binary(FILE *fp, PyArray_Descr *dtype, npy_intp num, size_t *nrea } num = numbytes / dtype->elsize; } - /* - * When dtype->subarray is true, PyArray_NewFromDescr will decref dtype - * even on success, so make sure it stays around until exit. - */ - Py_INCREF(dtype); r = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &num, NULL, NULL, 0, NULL); if (r == NULL) { - Py_DECREF(dtype); return NULL; } + /* In some cases NewFromDescr can replace the dtype, so fetch new one */ + dtype = PyArray_DESCR(r); + NPY_BEGIN_ALLOW_THREADS; *nread = fread(PyArray_DATA(r), dtype->elsize, num, fp); NPY_END_ALLOW_THREADS; - Py_DECREF(dtype); return r; } /* * Create an array by reading from the given stream, using the passed * next_element and skip_separator functions. + * As typical for array creation functions, it steals the reference to dtype. */ #define FROM_BUFFER_SIZE 4096 static PyArrayObject * @@ -3644,18 +3642,15 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread, size = (num >= 0) ? num : FROM_BUFFER_SIZE; - /* - * When dtype->subarray is true, PyArray_NewFromDescr will decref dtype - * even on success, so make sure it stays around until exit. - */ - Py_INCREF(dtype); r = (PyArrayObject *) PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &size, NULL, NULL, 0, NULL); if (r == NULL) { - Py_DECREF(dtype); return NULL; } + /* In some cases NewFromDescr can replace the dtype, so fetch new one */ + dtype = PyArray_DESCR(r); + clean_sep = swab_separator(sep); if (clean_sep == NULL) { err = 1; @@ -3726,7 +3721,6 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread, free(clean_sep); fail: - Py_DECREF(dtype); if (err == 1) { PyErr_NoMemory(); } @@ -3743,9 +3737,8 @@ fail: * Given a ``FILE *`` pointer ``fp``, and a ``PyArray_Descr``, return an * array corresponding to the data encoded in that file. * - * If the dtype is NULL, the default array type is used (double). - * If non-null, the reference is stolen and if dtype->subarray is true dtype - * will be decrefed even on success. + * The reference to `dtype` is stolen (it is possible that the passed in + * dtype is not held on to). * * The number of elements to read is given as ``num``; if it is < 0, then * then as many as possible are read. @@ -3793,7 +3786,6 @@ PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char *sep) (skip_separator) fromfile_skip_separator, NULL); } if (ret == NULL) { - Py_DECREF(dtype); return NULL; } if (((npy_intp) nread) < num) { |