diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/include/numpy/ndarraytypes.h | 23 | ||||
-rw-r--r-- | numpy/core/src/multiarray/descriptor.c | 6 | ||||
-rw-r--r-- | numpy/core/src/multiarray/dtypemeta.c | 79 |
3 files changed, 52 insertions, 56 deletions
diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h index 63c896302..5662ca7a3 100644 --- a/numpy/core/include/numpy/ndarraytypes.h +++ b/numpy/core/include/numpy/ndarraytypes.h @@ -1839,18 +1839,20 @@ typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size, PyHeapTypeObject super; /* - * TODO: Update above comment as necessary. * Most DTypes will have a singleton default instance, for the * parametric legacy DTypes (bytes, string, void, datetime) this * may be a pointer to the *prototype* instance? */ PyArray_Descr *singleton; /* - * Is this DType created using the old API? - * TODO: For now this mostly exists for possible assertions, - * we may not need it. + * Is this DType created using the old API? This exists mainly to + * allow for assertions in paths specific to wrapping legacy types. */ - npy_bool is_legacy; + npy_bool legacy; + /* The values stored by a parametric datatype depend on its instance */ + npy_bool parametric; + /* whether the DType can be instantiated (i.e. np.dtype cannot) */ + npy_bool abstract; /* * The following fields replicate the most important dtype information. @@ -1865,20 +1867,11 @@ typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size, char type; /* flags describing data type */ char flags; - npy_bool is_parametric; - /* whether the DType can be instantiated (i.e. np.dtype cannot) */ - npy_bool is_abstract; /* number representing this type */ int type_num; /* - * itemsize of this type, -1 if variable. Use npy_intp, even though it - * is effectively limited to int due to other public API. - */ - npy_intp itemsize; - /* * Point to the original ArrFuncs. - * TODO: If we wanted to do, we could make a copy to detect changes. - * However, I doubt that is necessary. + * NOTE: We could make a copy to detect changes to `f`. */ PyArray_ArrFuncs *f; } PyArray_DTypeMeta; diff --git a/numpy/core/src/multiarray/descriptor.c b/numpy/core/src/multiarray/descriptor.c index 37373451e..b4107f8f3 100644 --- a/numpy/core/src/multiarray/descriptor.c +++ b/numpy/core/src/multiarray/descriptor.c @@ -3490,6 +3490,8 @@ NPY_NO_EXPORT PyArray_DTypeMeta PyArrayDescr_TypeFull = { },}, .type_num = -1, .kind = '\0', - .is_abstract = 1, - .is_parametric = 0, + .abstract = 1, + .parametric = 0, + .singleton = 0, + .scalar_type = NULL, }; diff --git a/numpy/core/src/multiarray/dtypemeta.c b/numpy/core/src/multiarray/dtypemeta.c index daaf58aa6..76f7b599a 100644 --- a/numpy/core/src/multiarray/dtypemeta.c +++ b/numpy/core/src/multiarray/dtypemeta.c @@ -15,17 +15,17 @@ static void dtypemeta_dealloc(PyArray_DTypeMeta *self) { - /* - * PyType_Type asserts Py_TPFLAGS_HEAPTYPE as well. Do not rely on - * a python debug build though. - */ + /* Do not accidentally delete a statically defined DType: */ assert(((PyTypeObject *)self)->tp_flags & Py_TPFLAGS_HEAPTYPE); + Py_XDECREF(self->scalar_type); + Py_XDECREF(self->singleton); PyType_Type.tp_dealloc((PyObject *) self); } static PyObject * -dtypemeta_new(PyTypeObject *type, PyObject *args, PyObject *kwds) +dtypemeta_new(PyTypeObject *NPY_UNUSED(type), + PyObject *NPY_UNUSED(args), PyObject *NPY_UNUSED(kwds)) { PyErr_SetString(PyExc_TypeError, "Preliminary-API: Cannot subclass DType."); @@ -33,10 +33,11 @@ dtypemeta_new(PyTypeObject *type, PyObject *args, PyObject *kwds) } static int -dtypemeta_init(PyTypeObject *type, PyObject *args, PyObject *kwds) +dtypemeta_init(PyTypeObject *NPY_UNUSED(type), + PyObject *NPY_UNUSED(args), PyObject *NPY_UNUSED(kwds)) { PyErr_SetString(PyExc_TypeError, - "Preliminary-API: Cannot initialize DType class."); + "Preliminary-API: Cannot __init__ DType class."); return -1; } @@ -46,8 +47,8 @@ dtypemeta_init(PyTypeObject *type, PyObject *args, PyObject *kwds) * * Python Type objects are either statically created (typical C-Extension type) * or HeapTypes (typically created in Python). - * HeapTypes have the Py_TPFLAGS_HEAPTYPE flag, and are garbage collected, our - * DTypeMeta instances (`np.dtype` and its subclasses) *may* be HeapTypes + * HeapTypes have the Py_TPFLAGS_HEAPTYPE flag and are garbage collected. + * Our DTypeMeta instances (`np.dtype` and its subclasses) *may* be HeapTypes * if the Py_TPFLAGS_HEAPTYPE flag is set (they are created from Python). * They are not for legacy DTypes or np.dtype itself. * @@ -67,10 +68,12 @@ dtypemeta_traverse(PyArray_DTypeMeta *type, visitproc visit, void *arg) /* * We have to traverse the base class (if it is a HeapType). * PyType_Type will handle this logic for us. - * This function is currently not used, but may be necessary in the future - * when we implement HeapTypes (python/dynamically defined types). + * This function is currently not used, but will probably be necessary + * in the future when we implement HeapTypes (python/dynamically + * defined types). It should be revised at that time. */ - assert(!type->is_legacy && (PyTypeObject *)type != &PyArrayDescr_Type); + assert(0); + assert(!type->legacy && (PyTypeObject *)type != &PyArrayDescr_Type); Py_VISIT(type->singleton); Py_VISIT(type->scalar_type); return PyType_Type.tp_traverse((PyObject *)type, visit, arg); @@ -82,7 +85,7 @@ legacy_dtype_default_new(PyArray_DTypeMeta *self, PyObject *args, PyObject *kwargs) { /* TODO: This should allow endianess and possibly metadata */ - if (self->is_parametric) { + if (self->parametric) { /* reject parametric ones since we would need to get unit, etc. info */ PyErr_Format(PyExc_TypeError, "Preliminary-API: Flexible/Parametric legacy DType '%S' can " @@ -193,8 +196,8 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr) .tp_base = &PyArrayDescr_Type, .tp_new = (newfunc)legacy_dtype_default_new, },}, - .is_legacy = 1, - .is_abstract = 0, /* this is a concrete DType */ + .legacy = 1, + .abstract = 0, /* this is a concrete DType */ /* Further fields are not common between DTypes */ }; memcpy(dtype_class, &prototype, sizeof(PyArray_DTypeMeta)); @@ -217,15 +220,13 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr) dtype_class->type = descr->type; dtype_class->f = descr->f; dtype_class->kind = descr->kind; - dtype_class->itemsize = descr->elsize; if (PyTypeNum_ISDATETIME(descr->type_num)) { /* Datetimes are flexible, but were not considered previously */ - dtype_class->is_parametric = NPY_TRUE; + dtype_class->parametric = NPY_TRUE; } else if (PyTypeNum_ISFLEXIBLE(descr->type_num)) { - dtype_class->is_parametric = NPY_TRUE; - dtype_class->itemsize = -1; /* itemsize is not fixed */ + dtype_class->parametric = NPY_TRUE; } /* Finally, replace the current class of the descr */ @@ -240,29 +241,29 @@ dtypemeta_wrap_legacy_descriptor(PyArray_Descr *descr) * preliminary (the flags should also return bools). */ static PyMemberDef dtypemeta_members[] = { - {"_abstract", - T_BYTE, offsetof(PyArray_DTypeMeta, is_abstract), READONLY, NULL}, - {"type", - T_OBJECT, offsetof(PyArray_DTypeMeta, scalar_type), READONLY, NULL}, - {"_parametric", - T_BYTE, offsetof(PyArray_DTypeMeta, is_parametric), READONLY, NULL}, - {NULL, 0, 0, 0, NULL}, + {"_abstract", + T_BYTE, offsetof(PyArray_DTypeMeta, abstract), READONLY, NULL}, + {"type", + T_OBJECT, offsetof(PyArray_DTypeMeta, scalar_type), READONLY, NULL}, + {"_parametric", + T_BYTE, offsetof(PyArray_DTypeMeta, parametric), READONLY, NULL}, + {NULL, 0, 0, 0, NULL}, }; NPY_NO_EXPORT PyTypeObject PyArrayDTypeMeta_Type = { - PyVarObject_HEAD_INIT(NULL, 0) - .tp_name = "numpy._DTypeMeta", - .tp_basicsize = sizeof(PyArray_DTypeMeta), - .tp_dealloc = (destructor)dtypemeta_dealloc, - /* Types are garbage collected (see dtypemeta_is_gc documentation) */ - .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, - .tp_doc = "Preliminary NumPy API: The Type of NumPy DTypes (metaclass)", - .tp_members = dtypemeta_members, - .tp_base = NULL, /* set to PyType_Type at import time */ - .tp_init = (initproc)dtypemeta_init, - .tp_new = dtypemeta_new, - .tp_is_gc = dtypemeta_is_gc, - .tp_traverse = (traverseproc)dtypemeta_traverse, + PyVarObject_HEAD_INIT(NULL, 0) + .tp_name = "numpy._DTypeMeta", + .tp_basicsize = sizeof(PyArray_DTypeMeta), + .tp_dealloc = (destructor)dtypemeta_dealloc, + /* Types are garbage collected (see dtypemeta_is_gc documentation) */ + .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, + .tp_doc = "Preliminary NumPy API: The Type of NumPy DTypes (metaclass)", + .tp_members = dtypemeta_members, + .tp_base = NULL, /* set to PyType_Type at import time */ + .tp_init = (initproc)dtypemeta_init, + .tp_new = dtypemeta_new, + .tp_is_gc = dtypemeta_is_gc, + .tp_traverse = (traverseproc)dtypemeta_traverse, }; |