Skip to content

Numpy 2.0.0b1 is not supported #447

@duburcqa

Description

@duburcqa

Numpy 2.0.0 has been released on beta a few days ago and I waited to check how bad the migration would be. It turns out it is not working out of the box but supporting both 1.x and 2.x should be quite manageable. For instance, a one-liner is enough to fix Boost::Python (boostorg/python#431) on 1.84 release, but I think it should be the same on 1.76.

For eigenpy, it is more tricky. I tried to do it myself, and for now I'm stuck here:

/Users/alexis.duburcq/workspace/src/jiminy/eigenpy/src/numpy.cpp:17:10: error: use of undeclared identifier 'PyArray_TypeNumFromName'
  return PyArray_TypeNumFromName(const_cast<char*>(type->tp_name));

Unfortunately, PyArray_TypeNumFromName has been removed with no alternative apparently. See commit. I tried to backport the old implementation but it relies on some hidden global registry. I'm not sure it is possible to get access to it.

My patch so far:

diff --git a/include/eigenpy/numpy-allocator.hpp b/include/eigenpy/numpy-allocator.hpp
index 6165394..58f6415 100644
--- a/include/eigenpy/numpy-allocator.hpp
+++ b/include/eigenpy/numpy-allocator.hpp
@@ -138,7 +138,7 @@ struct numpy_allocator_impl_matrix<Eigen::Ref<MatType, Options, Stride> > {
                         outer_stride = reverse_strides ? mat.innerStride()
                                                        : mat.outerStride();
 
-      const int elsize = call_PyArray_DescrFromType(Scalar_type_code)->elsize;
+      const int elsize = PyDataType_ELSIZE(call_PyArray_DescrFromType(Scalar_type_code));
       npy_intp strides[2] = {elsize * inner_stride, elsize * outer_stride};
 
       PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New(
@@ -204,7 +204,7 @@ struct numpy_allocator_impl_matrix<
                         outer_stride = reverse_strides ? mat.innerStride()
                                                        : mat.outerStride();
 
-      const int elsize = call_PyArray_DescrFromType(Scalar_type_code)->elsize;
+      const int elsize = PyDataType_ELSIZE(call_PyArray_DescrFromType(Scalar_type_code));
       npy_intp strides[2] = {elsize * inner_stride, elsize * outer_stride};
 
       PyArrayObject *pyArray = (PyArrayObject *)call_PyArray_New(
diff --git a/include/eigenpy/numpy.hpp b/include/eigenpy/numpy.hpp
index 6ab627d..1cbbcf1 100644
--- a/include/eigenpy/numpy.hpp
+++ b/include/eigenpy/numpy.hpp
@@ -16,6 +16,11 @@
 #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
 #endif
 
+/* Allow compiling against NumPy 1.x and 2.x
+   see: https://github.com/numpy/numpy/blob/afea8fd66f6bdbde855f5aff0b4e73eb0213c646/doc/source/reference/c-api/array.rst#L1224
+*/
+#if NPY_ABI_VERSION < 0x02000000
+#define PyArray_DescrProto PyArray_Descr
+#endif
+
 #include <numpy/ndarrayobject.h>
 #include <numpy/ufuncobject.h>
 
@@ -170,7 +175,7 @@ inline void call_PyArray_InitArrFuncs(PyArray_ArrFuncs* funcs) {
   PyArray_InitArrFuncs(funcs);
 }
 
-inline int call_PyArray_RegisterDataType(PyArray_Descr* dtype) {
+inline int call_PyArray_RegisterDataType(PyArray_DescrProto* dtype) {
   return PyArray_RegisterDataType(dtype);
 }

Nota Bene: C-modules compiled against Numpy 2.x is backward compatible with Numpy 1.23.5 and onward by default, which means that the minimal requirement for Numpy should be bumped up. Python 3.8 would still be supported but no Python 3.6 nor Python 3.7. Both are already EOL so I don't think it is a big issue.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions