8000 BUG: dtype refcount cleanups (#14586) · numpy/numpy@454c5b5 · GitHub
[go: up one dir, main page]

Skip to content

Commit 454c5b5

Browse files
authored
BUG: dtype refcount cleanups (#14586)
* BUG: dtype reference count cleanup
1 parent 18aa819 commit 454c5b5

File tree

2 files changed

+16
-22
lines changed

2 files changed

+16
-22
lines changed

numpy/core/src/multiarray/_multiarray_tests.c.src

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -601,14 +601,14 @@ static PyObject *
601601
fromstring_null_term_c_api(PyObject *dummy, PyObject *byte_obj)
602602
{
603603
char *string;
604+
PyArray_Descr *descr;
604605

605606
string = PyBytes_AsString(byte_obj);
606607
if (string == NULL) {
607608
return NULL;
608609
}
609-
610-
return PyArray_FromString(
611-
string, -1, PyArray_DescrFromType(NPY_FLOAT64), -1, " ");
610+
descr = PyArray_DescrNewFromType(NPY_FLOAT64);
611+
return PyArray_FromString(string, -1, descr, -1, " ");
612612
}
613613

614614

@@ -913,6 +913,7 @@ static PyObject*
913913
get_c_wrapping_array(PyObject* NPY_UNUSED(self), PyObject* arg)
914914
{
915915
int writeable, flags;
916+
PyArray_Descr *descr;
916917
npy_intp zero = 0;
917918

918919
writeable = PyObject_IsTrue(arg);
@@ -922,7 +923,8 @@ get_c_wrapping_array(PyObject* NPY_UNUSED(self), PyObject* arg)
922923

923924
flags = writeable ? NPY_ARRAY_WRITEABLE : 0;
924925
/* Create an empty array (which points to a random place) */
925-
return PyArray_NewFromDescr(&PyArray_Type, PyArray_DescrFromType(NPY_INTP),
926+
descr = PyArray_DescrNewFromType(NPY_INTP);
927+
return PyArray_NewFromDescr(&PyArray_Type, descr,
926928
1, &zero, NULL, &zero, flags, NULL);
927929
}
928930

numpy/core/src/multiarray/ctors.c

Lines changed: 10 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3574,6 +3574,7 @@ PyArray_ArangeObj(PyObject *start, PyObject *stop, PyObject *step, PyArray_Descr
35743574
return NULL;
35753575
}
35763576

3577+
/* This array creation function steals the reference to dtype. */
35773578
static PyArrayObject *
35783579
array_fromfile_binary(FILE *fp, PyArray_Descr *dtype, npy_intp num, size_t *nread)
35793580
{
@@ -3605,27 +3606,24 @@ array_fromfile_binary(FILE *fp, PyArray_Descr *dtype, npy_intp num, size_t *nrea
36053606
}
36063607
num = numbytes / dtype->elsize;
36073608
}
3608-
/*
3609-
* When dtype->subarray is true, PyArray_NewFromDescr will decref dtype
3610-
* even on success, so make sure it stays around until exit.
3611-
*/
3612-
Py_INCREF(dtype);
36133609
r = (PyArrayObject *)PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &num,
36143610
NULL, NULL, 0, NULL);
36153611
if (r == NULL) {
3616-
Py_DECREF(dtype);
36173612
return NULL;
36183613
}
3614+
/* In some cases NewFromDescr can replace the dtype, so fetch new one */
3615+
dtype = PyArray_DESCR(r);
3616+
36193617
NPY_BEGIN_ALLOW_THREADS;
36203618
*nread = fread(PyArray_DATA(r), dtype->elsize, num, fp);
36213619
NPY_END_ALLOW_THREADS;
3622-
Py_DECREF(dtype);
36233620
return r;
36243621
}
36253622

36263623
/*
36273624
* Create an array by reading from the given stream, using the passed
36283625
* next_element and skip_separator functions.
3626+
* As typical for array creation functions, it steals the reference to dtype.
36293627
*/
36303628
#define FROM_BUFFER_SIZE 4096
36313629
static PyArrayObject *
@@ -3644,18 +3642,15 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread,
36443642

36453643
size = (num >= 0) ? num : FROM_BUFFER_SIZE;
36463644

3647-
/*
3648-
* When dtype->subarray is true, PyArray_NewFromDescr will decref dtype
3649-
* even on success, so make sure it stays around until exit.
3650-
*/
3651-
Py_INCREF(dtype);
36523645
r = (PyArrayObject *)
36533646
PyArray_NewFromDescr(&PyArray_Type, dtype, 1, &size,
36543647
NULL, NULL, 0, NULL);
36553648
if (r == NULL) {
3656-
Py_DECREF(dtype);
36573649
return NULL;
36583650
}
3651+
/* In some cases NewFromDescr can replace the dtype, so fetch new one */
3652+
dtype = PyArray_DESCR(r);
3653+
36593654
clean_sep = swab_separator(sep);
36603655
if (clean_sep == NULL) {
36613656
err = 1;
@@ -3726,7 +3721,6 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread,
37263721
free(clean_sep);
37273722

37283723
fail:
3729-
Py_DECREF(dtype);
37303724
if (err == 1) {
37313725
PyErr_NoMemory();
37323726
}
@@ -3743,9 +3737,8 @@ array_from_text(PyArray_Descr *dtype, npy_intp num, char *sep, size_t *nread,
37433737
* Given a ``FILE *`` pointer ``fp``, and a ``PyArray_Descr``, return an
37443738
* array corresponding to the data encoded in that file.
37453739
*
3746-
* If the dtype is NULL, the default array type is used (double).
3747-
* If non-null, the reference is stolen and if dtype->subarray is true dtype
3748-
* will be decrefed even on success.
3740+
* The reference to `dtype` is stolen (it is possible that the passed in
3741+
* dtype is not held on to).
37493742
*
37503743
* The number of elements to read is given as ``num``; if it is < 0, then
37513744
* then as many as possible are read.
@@ -3793,7 +3786,6 @@ PyArray_FromFile(FILE *fp, PyArray_Descr *dtype, npy_intp num, char *sep)
37933786
(skip_separator) fromfile_skip_separator, NULL);
37943787
}
37953788
if (ret == NULL) {
3796-
Py_DECREF(dtype);
37973789
return NULL;
37983790
}
37993791
if (((npy_intp) nread) < num) {

0 commit comments

Comments
 (0)
0