summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2019-10-03 10:16:51 +0300
committerGitHub <noreply@github.com>2019-10-03 10:16:51 +0300
commit454c5b5e9a76809a4ab60bda30aa048ec37ee11e (patch)
treebdacfe44fc0dcedd12040336458ad37333a0ec57
parent18aa81985d36fe6922a813f513190944b03c8677 (diff)
downloadnumpy-454c5b5e9a76809a4ab60bda30aa048ec37ee11e.tar.gz
BUG: dtype refcount cleanups (#14586)
* BUG: dtype reference count cleanup
-rw-r--r--numpy/core/src/multiarray/_multiarray_tests.c.src10
-rw-r--r--numpy/core/src/multiarray/ctors.c28
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) {