Skip to content

Commit 5af5b44

Browse files
authored
Merge pull request numpy#20303 from seberg/relax-experimental-dtype-new
BUG: Fix requirement that user DTypes had to be heaptypes
2 parents 112e63e + 6f6802b commit 5af5b44

File tree

2 files changed

+14
-3
lines changed

2 files changed

+14
-3
lines changed

numpy/core/src/multiarray/descriptor.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2305,8 +2305,9 @@ arraydescr_new(PyTypeObject *subtype,
23052305
{
23062306
if (subtype != &PyArrayDescr_Type) {
23072307
if (Py_TYPE(subtype) == &PyArrayDTypeMeta_Type &&
2308-
!(PyType_GetFlags(Py_TYPE(subtype)) & Py_TPFLAGS_HEAPTYPE) &&
2309-
(NPY_DT_SLOTS((PyArray_DTypeMeta *)subtype)) != NULL) {
2308+
(NPY_DT_SLOTS((PyArray_DTypeMeta *)subtype)) != NULL &&
2309+
!NPY_DT_is_legacy((PyArray_DTypeMeta *)subtype) &&
2310+
subtype->tp_new != PyArrayDescr_Type.tp_new) {
23102311
/*
23112312
* Appears to be a properly initialized user DType. Allocate
23122313
* it and initialize the main part as best we can.
@@ -2333,7 +2334,9 @@ arraydescr_new(PyTypeObject *subtype,
23332334
}
23342335
/* The DTypeMeta class should prevent this from happening. */
23352336
PyErr_Format(PyExc_SystemError,
2336-
"'%S' must not inherit np.dtype.__new__().", subtype);
2337+
"'%S' must not inherit np.dtype.__new__(). User DTypes should "
2338+
"currently call `PyArrayDescr_Type.tp_new` from their new.",
2339+
subtype);
23372340
return NULL;
23382341
}
23392342

numpy/core/src/multiarray/experimental_public_dtype_api.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,14 @@ PyArrayInitDTypeMeta_FromSpec(
131131
return -1;
132132
}
133133

134+
if (((PyTypeObject *)DType)->tp_repr == PyArrayDescr_Type.tp_repr
135+
|| ((PyTypeObject *)DType)->tp_str == PyArrayDescr_Type.tp_str) {
136+
PyErr_SetString(PyExc_TypeError,
137+
"A custom DType must implement `__repr__` and `__str__` since "
138+
"the default inherited version (currently) fails.");
139+
return -1;
140+
}
141+
134142
if (spec->typeobj == NULL || !PyType_Check(spec->typeobj)) {
135143
PyErr_SetString(PyExc_TypeError,
136144
"Not giving a type object is currently not supported, but "

0 commit comments

Comments
 (0)