summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCharles Harris <charlesr.harris@gmail.com>2023-02-25 12:15:16 -0500
committerGitHub <noreply@github.com>2023-02-25 12:15:16 -0500
commita6d8b305aadf6c0a76fbaa91d301274985e9322e (patch)
tree24303871ecdc53ba02a687feea15d4e9a2fe5948
parentaae341afa9125070c8ede2470ee0997b26ef2389 (diff)
parent770fe81cc2969d36af4bd1576ce5b69fcb03ffbf (diff)
downloadnumpy-a6d8b305aadf6c0a76fbaa91d301274985e9322e.tar.gz
Merge pull request #23279 from seberg/issue-23277
BUG: Allow no-op clearing of void dtypes
-rw-r--r--numpy/core/src/multiarray/arrayobject.c4
-rw-r--r--numpy/core/src/multiarray/dtype_traversal.c13
-rw-r--r--numpy/core/tests/test_dtype.py8
3 files changed, 23 insertions, 2 deletions
diff --git a/numpy/core/src/multiarray/arrayobject.c b/numpy/core/src/multiarray/arrayobject.c
index 4c8cfab06..0434e8676 100644
--- a/numpy/core/src/multiarray/arrayobject.c
+++ b/numpy/core/src/multiarray/arrayobject.c
@@ -455,7 +455,9 @@ array_dealloc(PyArrayObject *self)
if ((fa->flags & NPY_ARRAY_OWNDATA) && fa->data) {
/* Free any internal references */
if (PyDataType_REFCHK(fa->descr)) {
- PyArray_ClearArray(self);
+ if (PyArray_ClearArray(self) < 0) {
+ PyErr_WriteUnraisable(NULL);
+ }
}
if (fa->mem_handler == NULL) {
char *env = getenv("NUMPY_WARN_IF_NO_MEM_POLICY");
diff --git a/numpy/core/src/multiarray/dtype_traversal.c b/numpy/core/src/multiarray/dtype_traversal.c
index e2197da0c..cefa7d6e1 100644
--- a/numpy/core/src/multiarray/dtype_traversal.c
+++ b/numpy/core/src/multiarray/dtype_traversal.c
@@ -454,10 +454,21 @@ npy_get_clear_void_and_legacy_user_dtype_loop(
}
return 0;
}
+ else if (dtype->type_num == NPY_VOID) {
+ /*
+ * Void dtypes can have "ghosts" of objects marking the dtype because
+ * holes (or the raw bytes if fields are gone) may include objects.
+ * Paths that need those flags should probably be considered incorrect.
+ * But as long as this can happen (a V8 that indicates references)
+ * we need to make it a no-op here.
+ */
+ *out_func = &clear_no_op;
+ return 0;
+ }
PyErr_Format(PyExc_RuntimeError,
"Internal error, tried to fetch clear function for the "
- "user dtype '%s' without fields or subarray (legacy support).",
+ "user dtype '%S' without fields or subarray (legacy support).",
dtype);
return -1;
}
diff --git a/numpy/core/tests/test_dtype.py b/numpy/core/tests/test_dtype.py
index 030efb716..9b44367e6 100644
--- a/numpy/core/tests/test_dtype.py
+++ b/numpy/core/tests/test_dtype.py
@@ -551,6 +551,14 @@ class TestRecord:
assert_equal(np.zeros((1, 2), dtype=[]) == a,
np.ones((1, 2), dtype=bool))
+ def test_nonstructured_with_object(self):
+ # See gh-23277, the dtype here thinks it contain objects, if the
+ # assert about that fails, the test becomes meaningless (which is OK)
+ arr = np.recarray((0,), dtype="O")
+ assert arr.dtype.names is None # no fields
+ assert arr.dtype.hasobject # but claims to contain objects
+ del arr # the deletion failed previously.
+
class TestSubarray:
def test_single_subarray(self):