Skip to content

Commit 432055b

Browse files
committed
Port PyArrayDTypeMeta to HPy
1 parent 4a42b8a commit 432055b

12 files changed

+56
-38
lines changed

numpy/core/include/numpy/ndarraytypes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1975,7 +1975,7 @@ typedef void (PyDataMem_EventHookFunc)(void *inp, void *outp, size_t size,
19751975
* further modifications.
19761976
*/
19771977
/* TODO: Make this definition public in the API, as soon as its settled */
1978-
NPY_NO_EXPORT extern PyTypeObject PyArrayDTypeMeta_Type;
1978+
NPY_NO_EXPORT extern PyTypeObject *PyArrayDTypeMeta_Type;
19791979

19801980
/*
19811981
* While NumPy DTypes would not need to be heap types the plan is to

numpy/core/src/multiarray/abstractdtypes.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ initialize_and_map_pytypes_to_dtypes(HPyContext *ctx)
113113
{
114114
int result = -1;
115115
HPy h_PyArrayDescr_Type = HPy_FromPyObject(ctx, (PyObject *) &PyArrayDescr_Type);
116-
HPy h_PyArrayDTypeMeta_Type = HPy_FromPyObject(ctx, (PyObject*) &PyArrayDTypeMeta_Type);
116+
HPy h_PyArrayDTypeMeta_Type = HPy_FromPyObject(ctx, (PyObject*) PyArrayDTypeMeta_Type);
117117
HPyType_SpecParam abstract_dtype_params[] = {
118118
{HPyType_SpecParam_Base, h_PyArrayDescr_Type},
119119
{ HPyType_SpecParam_Metaclass, h_PyArrayDTypeMeta_Type },

numpy/core/src/multiarray/array_coercion.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ npy_discover_dtype_from_pytype(PyTypeObject *pytype)
226226
if (DType == Py_None) {
227227
return (PyArray_DTypeMeta *)Py_None;
228228
}
229-
assert(PyObject_TypeCheck(DType, (PyTypeObject *)&PyArrayDTypeMeta_Type));
229+
assert(PyObject_TypeCheck(DType, PyArrayDTypeMeta_Type));
230230
return (PyArray_DTypeMeta *)DType;
231231
}
232232

@@ -1208,7 +1208,7 @@ PyArray_DiscoverDTypeAndShape(
12081208
/* Validate input of requested descriptor and DType */
12091209
if (fixed_DType != NULL) {
12101210
assert(PyObject_TypeCheck(
1211-
(PyObject *)fixed_DType, (PyTypeObject *)&PyArrayDTypeMeta_Type));
1211+
(PyObject *)fixed_DType, PyArrayDTypeMeta_Type));
12121212
}
12131213

12141214
if (requested_descr != NULL) {
@@ -1469,13 +1469,13 @@ PyArray_ExtractDTypeAndDescriptor(PyObject *dtype,
14691469
*out_descr = NULL;
14701470

14711471
if (dtype != NULL) {
1472-
if (PyObject_TypeCheck(dtype, (PyTypeObject *)&PyArrayDTypeMeta_Type)) {
1472+
if (PyObject_TypeCheck(dtype, PyArrayDTypeMeta_Type)) {
14731473
assert(dtype != (PyObject * )&PyArrayDescr_Type); /* not np.dtype */
14741474
*out_DType = (PyArray_DTypeMeta *)dtype;
14751475
Py_INCREF(*out_DType);
14761476
}
14771477
else if (PyObject_TypeCheck((PyObject *)Py_TYPE(dtype),
1478-
(PyTypeObject *)&PyArrayDTypeMeta_Type)) {
1478+
PyArrayDTypeMeta_Type)) {
14791479
*out_DType = NPY_DTYPE(dtype);
14801480
Py_INCREF(*out_DType);
14811481
if (!descr_is_legacy_parametric_instance((PyArray_Descr *)dtype)) {

numpy/core/src/multiarray/array_method.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ validate_spec(PyArrayMethod_Spec *spec)
212212
"(method: %s)", spec->name);
213213
return -1;
214214
}
215-
if (!PyObject_TypeCheck(spec->dtypes[i], &PyArrayDTypeMeta_Type)) {
215+
if (!PyObject_TypeCheck(spec->dtypes[i], PyArrayDTypeMeta_Type)) {
216216
PyErr_Format(PyExc_TypeError,
217217
"ArrayMethod provided object %R is not a DType."
218218
"(method: %s)", spec->dtypes[i], spec->name);
@@ -372,7 +372,7 @@ NPY_NO_EXPORT PyObject *
372372
PyArrayMethod_FromSpec(PyArrayMethod_Spec *spec)
373373
{
374374
for (int i = 0; i < spec->nin + spec->nout; i++) {
375-
if (!PyObject_TypeCheck(spec->dtypes[i], &PyArrayDTypeMeta_Type)) {
375+
if (!PyObject_TypeCheck(spec->dtypes[i], PyArrayDTypeMeta_Type)) {
376376
PyErr_SetString(PyExc_RuntimeError,
377377
"ArrayMethod spec contained a non DType.");
378378
return NULL;

numpy/core/src/multiarray/convert_datatype.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,7 @@ _get_castingimpl(PyObject *NPY_UNUSED(module), PyObject *args)
200200
{
201201
PyArray_DTypeMeta *from, *to;
202202
if (!PyArg_ParseTuple(args, "O!O!:_get_castingimpl",
203-
&PyArrayDTypeMeta_Type, &from, &PyArrayDTypeMeta_Type, &to)) {
203+
PyArrayDTypeMeta_Type, &from, PyArrayDTypeMeta_Type, &to)) {
204204
return NULL;
205205
}
206206
return PyArray_GetBoundCastingImpl(from, to);

numpy/core/src/multiarray/descriptor.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2447,7 +2447,7 @@ arraydescr_new(PyTypeObject *subtype,
24472447
PyObject *args, PyObject *kwds)
24482448
{
24492449
if (subtype != &PyArrayDescr_Type) {
2450-
if (Py_TYPE(subtype) == &PyArrayDTypeMeta_Type &&
2450+
if (Py_TYPE(subtype) == PyArrayDTypeMeta_Type &&
24512451
(NPY_DT_SLOTS((PyArray_DTypeMeta *)subtype)) != NULL &&
24522452
!NPY_DT_is_legacy((PyArray_DTypeMeta *)subtype) &&
24532453
subtype->tp_new != PyArrayDescr_Type.tp_new) {

numpy/core/src/multiarray/dtypemeta.c

Lines changed: 30 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,9 @@ dtypemeta_is_gc(PyObject *dtype_class)
7070
return PyType_Type.tp_is_gc(dtype_class);
7171
}
7272

73-
74-
static int
75-
dtypemeta_traverse(PyArray_DTypeMeta *type, visitproc visit, void *arg)
76-
{
73+
HPyDef_SLOT(DTypeMeta_traverse, DTypeMeta_traverse_impl, HPy_tp_traverse)
74+
static int DTypeMeta_traverse_impl(void *self, HPyFunc_visitproc visit, void *arg) {
75+
// HPY TODO: implement
7776
/*
7877
* We have to traverse the base class (if it is a HeapType).
7978
* PyType_Type will handle this logic for us.
@@ -571,7 +570,7 @@ dtypemeta_wrap_legacy_descriptor(HPyContext *ctx, PyArray_Descr *descr)
571570
New_PyArrayDescr_spec.name = tp_name;
572571

573572
HPy h_PyArrayDescr_Type = HPy_FromPyObject(ctx, (PyObject *) &PyArrayDescr_Type);
574-
HPy h_PyArrayDTypeMeta_Type = HPy_FromPyObject(ctx, (PyObject*) &PyArrayDTypeMeta_Type);
573+
HPy h_PyArrayDTypeMeta_Type = HPy_FromPyObject(ctx, (PyObject*) PyArrayDTypeMeta_Type);
575574
HPy h_new_dtype_type = HPy_NULL;
576575
PyObject *dtype_class = NULL; // to pass to legacy helpers
577576
int result = -1;
@@ -700,19 +699,30 @@ static PyMemberDef dtypemeta_members[] = {
700699
{NULL, 0, 0, 0, NULL},
701700
};
702701

703-
NPY_NO_EXPORT PyTypeObject PyArrayDTypeMeta_Type = {
704-
PyVarObject_HEAD_INIT(NULL, 0)
705-
.tp_name = "numpy._DTypeMeta",
706-
.tp_basicsize = sizeof(PyArray_DTypeMeta),
707-
.tp_dealloc = (destructor)dtypemeta_dealloc,
708-
/* Types are garbage collected (see dtypemeta_is_gc documentation) */
709-
.tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC,
710-
.tp_doc = "Preliminary NumPy API: The Type of NumPy DTypes (metaclass)",
711-
.tp_getset = dtypemeta_getset,
712-
.tp_members = dtypemeta_members,
713-
.tp_base = NULL, /* set to PyType_Type at import time */
714-
.tp_init = (initproc)dtypemeta_init,
715-
.tp_new = dtypemeta_new,
716-
.tp_is_gc = dtypemeta_is_gc,
717-
.tp_traverse = (traverseproc)dtypemeta_traverse,
702+
// HPY TODO: global set in module init:
703+
NPY_NO_EXPORT PyTypeObject *PyArrayDTypeMeta_Type;
704+
705+
NPY_NO_EXPORT PyType_Slot PyArrayDTypeMeta_Type_legacy_slots[] = {
706+
{Py_tp_getset, dtypemeta_getset},
707+
{Py_tp_members, dtypemeta_members},
708+
{Py_tp_init, dtypemeta_init},
709+
{Py_tp_new, dtypemeta_new},
710+
{0, 0},
718711
};
712+
713+
NPY_NO_EXPORT HPyDef *PyArrayDTypeMeta_Type_slots[] = {
714+
&DTypeMeta_traverse,
715+
0,
716+
};
717+
718+
NPY_NO_EXPORT HPyType_Spec PyArrayDTypeMeta_Type_spec = {
719+
.name = "numpy._DTypeMeta",
720+
.basicsize = sizeof(PyArray_DTypeMeta),
721+
/* Types are garbage collected (see dtypemeta_is_gc documentation) */
722+
.flags = HPy_TPFLAGS_DEFAULT | HPy_TPFLAGS_HAVE_GC,
723+
.doc = "Preliminary NumPy API: The Type of NumPy DTypes (metaclass)",
724+
.legacy = true,
725+
.defines = PyArrayDTypeMeta_Type_slots,
726+
.legacy_slots = &PyArrayDTypeMeta_Type_legacy_slots,
727+
// HPY TODO: .tp_traverse = (traverseproc)dtypemeta_traverse,
728+
};

numpy/core/src/multiarray/dtypemeta.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,4 +122,6 @@ python_builtins_are_known_scalar_types(
122122
NPY_NO_EXPORT int
123123
dtypemeta_wrap_legacy_descriptor(HPyContext *ctx, PyArray_Descr *dtypem);
124124

125+
NPY_NO_EXPORT HPyType_Spec PyArrayDTypeMeta_Type_spec;
126+
125127
#endif /* NUMPY_CORE_SRC_MULTIARRAY_DTYPEMETA_H_ */

numpy/core/src/multiarray/experimental_public_dtype_api.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ int
124124
PyArrayInitDTypeMeta_FromSpec(
125125
PyArray_DTypeMeta *DType, PyArrayDTypeMeta_Spec *spec)
126126
{
127-
if (!PyObject_TypeCheck(DType, &PyArrayDTypeMeta_Type)) {
127+
if (!PyObject_TypeCheck(DType, PyArrayDTypeMeta_Type)) {
128128
PyErr_SetString(PyExc_RuntimeError,
129129
"Passed in DType must be a valid (initialized) DTypeMeta "
130130
"instance!");
@@ -387,7 +387,7 @@ _get_experimental_dtype_api(PyObject *NPY_UNUSED(mod), PyObject *arg)
387387
static void *experimental_api_table[42] = {
388388
&PyUFunc_AddLoopFromSpec,
389389
&PyUFunc_AddPromoter,
390-
&PyArrayDTypeMeta_Type,
390+
NULL,
391391
&PyArrayInitDTypeMeta_FromSpec,
392392
&PyArray_CommonDType,
393393
&PyArray_PromoteDTypeSequence,
@@ -398,6 +398,7 @@ _get_experimental_dtype_api(PyObject *NPY_UNUSED(mod), PyObject *arg)
398398
/* NumPy's builtin DTypes (starting at offset 10 going to 41) */
399399
};
400400
if (experimental_api_table[10] == NULL) {
401+
experimental_api_table[2] = PyArrayDTypeMeta_Type;
401402
experimental_api_table[10] = PyArray_DTypeFromTypeNum(NPY_BOOL);
402403
/* Integers */
403404
experimental_api_table[11] = PyArray_DTypeFromTypeNum(NPY_BYTE);

numpy/core/src/multiarray/multiarraymodule.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4762,12 +4762,15 @@ static HPy init__multiarray_umath_impl(HPyContext *ctx) {
47624762
goto err;
47634763
}
47644764

4765-
PyArrayDTypeMeta_Type.tp_base = &PyType_Type;
4766-
if (PyType_Ready(&PyArrayDTypeMeta_Type) < 0) {
4765+
HPyType_SpecParam dtypemeta_params[] = {
4766+
{ HPyType_SpecParam_Base, ctx->h_TypeType },
4767+
{ 0 }
4768+
};
4769+
HPy h_PyArrayDTypeMeta_Type = HPyType_FromSpec(ctx, &PyArrayDTypeMeta_Type_spec, dtypemeta_params);
4770+
if (HPy_IsNull(h_PyArrayDTypeMeta_Type)) {
47674771
goto err;
47684772
}
47694773

4770-
HPy h_PyArrayDTypeMeta_Type = HPy_FromPyObject(ctx, (PyObject*) &PyArrayDTypeMeta_Type);
47714774
HPyType_SpecParam dtype_params[] = {
47724775
{ HPyType_SpecParam_Metaclass, h_PyArrayDTypeMeta_Type },
47734776
{ 0 }
@@ -4783,12 +4786,14 @@ static HPy init__multiarray_umath_impl(HPyContext *ctx) {
47834786
pyarry_descr_data->singleton = NULL;
47844787
pyarry_descr_data->scalar_type = NULL;
47854788

4786-
// HPY TODO: storing the dtype to globals to support legacy code, and HPy code w/o module state
4789+
// HPY TODO: storing the types to globals to support legacy code, and HPy code w/o module state
47874790
_PyArrayDescr_Type_p = (PyTypeObject*) HPy_AsPyObject(ctx, h_PyArrayDescr_Type);
4791+
PyArrayDTypeMeta_Type = (PyTypeObject*) HPy_AsPyObject(ctx, h_PyArrayDTypeMeta_Type);
47884792
HPyArrayDescr_Type = HPy_Dup(ctx, h_PyArrayDescr_Type);
47894793

47904794
HPy_Close(ctx, h_PyArrayDTypeMeta_Type);
47914795
HPy_Close(ctx, h_PyArrayDescr_Type);
4796+
HPy_Close(ctx, h_PyArrayDTypeMeta_Type);
47924797

47934798
initialize_casting_tables();
47944799
initialize_numeric_types();

numpy/core/src/umath/dispatching.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ PyUFunc_AddLoop(PyUFuncObject *ufunc, PyObject *info, int ignore_duplicate)
9696
for (Py_ssize_t i = 0; i < PyTuple_GET_SIZE(DType_tuple); i++) {
9797
PyObject *item = PyTuple_GET_ITEM(DType_tuple, i);
9898
if (item != Py_None
99-
&& !PyObject_TypeCheck(item, &PyArrayDTypeMeta_Type)) {
99+
&& !PyObject_TypeCheck(item, PyArrayDTypeMeta_Type)) {
100100
PyErr_SetString(PyExc_TypeError,
101101
"DType tuple may only contain None and DType classes");
102102
return -1;

numpy/core/src/umath/ufunc_object.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4291,7 +4291,7 @@ _check_and_copy_sig_to_signature(
42914291
*/
42924292
static PyArray_DTypeMeta *
42934293
_get_dtype(PyObject *dtype_obj) {
4294-
if (PyObject_TypeCheck(dtype_obj, &PyArrayDTypeMeta_Type)) {
4294+
if (PyObject_TypeCheck(dtype_obj, PyArrayDTypeMeta_Type)) {
42954295
Py_INCREF(dtype_obj);
42964296
return (PyArray_DTypeMeta *)dtype_obj;
42974297
}

0 commit comments

Comments
 (0)