From 48b4a8430111d7fdd16e0747921a9af9c0069842 Mon Sep 17 00:00:00 2001
From: Pim Schellart
Date: Mon, 17 Jul 2017 18:05:32 -0400
Subject: [PATCH] Use NumPy 1.7 API for pybind11
---
include/ndarray/converter/eigen.h | 11 +++----
include/ndarray/converter/numpy.h | 42 +++++++++++++++------------
include/ndarray/converter/ufunctors.h | 14 ++++-----
tests/pybind11_test_mod.cc | 1 +
4 files changed, 38 insertions(+), 30 deletions(-)
diff --git a/include/ndarray/converter/eigen.h b/include/ndarray/converter/eigen.h
index 401b4362..30895fc6 100644
--- a/include/ndarray/converter/eigen.h
+++ b/include/ndarray/converter/eigen.h
@@ -30,6 +30,7 @@ template
struct PyConverter< EigenView > {
static bool fromPythonStage1(PyPtr & p) {
+ auto array = reinterpret_cast(p.get());
// add or remove dimensions with size one so we have the right number of dimensions
if (PyArray_Check(p.get())) {
if ((Rows_ == 1 || Cols_ == 1) && N == 2) {
@@ -40,11 +41,11 @@ struct PyConverter< EigenView > {
shape[1] = 1;
}
PyArray_Dims dims = { shape, 2 };
- PyPtr r(PyArray_Newshape(reinterpret_cast(p.get()), &dims, NPY_ANYORDER));
+ PyPtr r(PyArray_Newshape(array, &dims, NPY_ANYORDER));
if (!r) return false;
p.swap(r);
} else if (N == 1) {
- PyPtr r(PyArray_Squeeze(reinterpret_cast(p.get())));
+ PyPtr r(PyArray_Squeeze(array));
if (!r) return false;
p.swap(r);
}
@@ -52,17 +53,17 @@ struct PyConverter< EigenView > {
if (!PyConverter< Array >::fromPythonStage1(p)) return false;
// check whether the size is correct if it's static
if (N == 2) {
- if (Rows_ != Eigen::Dynamic && PyArray_DIM(p.get(), 0) != Rows_) {
+ if (Rows_ != Eigen::Dynamic && PyArray_DIM(array, 0) != Rows_) {
PyErr_SetString(PyExc_ValueError, "incorrect number of rows for matrix");
return false;
}
- if (Cols_ != Eigen::Dynamic && PyArray_DIM(p.get(), 1) != Cols_) {
+ if (Cols_ != Eigen::Dynamic && PyArray_DIM(array, 1) != Cols_) {
PyErr_SetString(PyExc_ValueError, "incorrect number of columns for matrix");
return false;
}
} else {
int requiredSize = Rows_ * Cols_;
- if (requiredSize != Eigen::Dynamic && PyArray_SIZE(p.get()) != requiredSize) {
+ if (requiredSize != Eigen::Dynamic && PyArray_SIZE(array) != requiredSize) {
PyErr_SetString(PyExc_ValueError, "incorrect number of elements for vector");
return false;
}
diff --git a/include/ndarray/converter/numpy.h b/include/ndarray/converter/numpy.h
index e71b36f8..9b887819 100644
--- a/include/ndarray/converter/numpy.h
+++ b/include/ndarray/converter/numpy.h
@@ -11,6 +11,10 @@
#ifndef NDARRAY_CONVERTER_numpy_h_INCLUDED
#define NDARRAY_CONVERTER_numpy_h_INCLUDED
+#ifndef NPY_NO_DEPRECATED_API
+#pragma message ( "ndarray is compatible with the NumPy 1.7 API, define NPY_NO_DEPRECATED_API to suppress API version warnings" )
+#endif
+
/**
* @file ndarray/converter/numpy.h
* @brief Python C-API conversions between ndarray and numpy.
@@ -155,25 +159,26 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array(p.get());
+ int actualType = PyArray_TYPE(array);
int requiredType = detail::NumpyTraits::getCode();
if (actualType != requiredType) {
PyErr_SetString(PyExc_ValueError, ("numpy.ndarray argument has incorrect data type"));
return false;
}
- if (PyArray_NDIM(p.get()) != N) {
+ if (PyArray_NDIM(array) != N) {
PyErr_SetString(PyExc_ValueError, "numpy.ndarray argument has incorrect number of dimensions");
return false;
}
bool writeable = !boost::is_const::value;
- if (writeable && !(PyArray_FLAGS(p.get()) & NPY_WRITEABLE)) {
+ if (writeable && !(PyArray_FLAGS(array) & NPY_ARRAY_WRITEABLE)) {
PyErr_SetString(PyExc_TypeError, "numpy.ndarray argument must be writeable");
return false;
}
if (C > 0) {
Offset requiredStride = sizeof(Element);
for (int i = 0; i < C; ++i) {
- Offset actualStride = PyArray_STRIDE(p.get(), N-i-1);
+ Offset actualStride = PyArray_STRIDE(array, N-i-1);
if (actualStride != requiredStride) {
PyErr_SetString(
PyExc_ValueError,
@@ -181,12 +186,12 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array > : public detail::PyConverterBase< Array > : public detail::PyConverterBase< Array & output ///< Reference to existing output C++ object.
) {
- if (!(PyArray_FLAGS(input.get()) & NPY_ALIGNED)) {
+ auto array = reinterpret_cast(input.get());
+ if (!(PyArray_FLAGS(array) & NPY_ARRAY_ALIGNED)) {
PyErr_SetString(PyExc_TypeError, "unaligned arrays cannot be converted to C++");
return false;
}
Offset itemsize = sizeof(Element);
for (int i = 0; i < N; ++i) {
- if ((PyArray_DIM(input.get(), i) > 1) && (PyArray_STRIDE(input.get(), i) % itemsize != 0)) {
+ if ((PyArray_DIM(array, i) > 1) && (PyArray_STRIDE(array, i) % itemsize != 0)) {
PyErr_SetString(
PyExc_TypeError,
"Cannot convert array to C++: strides must be an integer multiple of the element size"
@@ -232,11 +238,11 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array shape;
Vector strides;
- std::copy(PyArray_DIMS(input.get()), PyArray_DIMS(input.get()) + N, shape.begin());
- std::copy(PyArray_STRIDES(input.get()), PyArray_STRIDES(input.get()) + N , strides.begin());
+ std::copy(PyArray_DIMS(array), PyArray_DIMS(array) + N, shape.begin());
+ std::copy(PyArray_STRIDES(array), PyArray_STRIDES(array) + N , strides.begin());
for (int i = 0; i < N; ++i) strides[i] /= sizeof(Element);
output = external(
- reinterpret_cast(PyArray_DATA(input.get())),
+ reinterpret_cast(PyArray_DATA(array)),
shape, strides, input
);
return true;
@@ -257,10 +263,10 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array::value;
- if (writeable) flags |= NPY_WRITEABLE;
+ if (writeable) flags |= NPY_ARRAY_WRITEABLE;
npy_intp outShape[N];
npy_intp outStrides[N];
Vector inShape = m.getShape();
@@ -276,8 +282,8 @@ struct PyConverter< Array > : public detail::PyConverterBase< Array > : public detail::PyConverterBase< Array(array.get())->base = owner;
+ PyArray_SetBaseObject(reinterpret_cast(array.get()), owner);
}
Py_INCREF(array.get());
return PyArray_Return(reinterpret_cast(array.get()));
diff --git a/include/ndarray/converter/ufunctors.h b/include/ndarray/converter/ufunctors.h
index 9d8f1e19..c65b0e53 100644
--- a/include/ndarray/converter/ufunctors.h
+++ b/include/ndarray/converter/ufunctors.h
@@ -26,17 +26,17 @@ template ::getCode(),
- NPY_ALIGNED);
+ PyArrayObject* input_array = PyArray_FROM_OTF(input,detail::NumpyTraits::getCode(),
+ NPY_ARRAY_ALIGNED);
if (input_array == NULL) return NULL;
- PyObject* output_array;
+ PyArrayObject* output_array;
if (output == NULL || output == Py_None) {
output_array = PyArray_SimpleNew(PyArray_NDIM(input_array),
PyArray_DIMS(input_array),
detail::NumpyTraits::getCode());
} else {
output_array = PyArray_FROM_OTF(output,detail::NumpyTraits::getCode(),
- NPY_ALIGNED | NPY_WRITEABLE | NPY_UPDATEIFCOPY);
+ NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEABLE | NPY_ARRAY_UPDATEIFCOPY);
}
if (output_array == NULL) {
Py_DECREF(input_array);
@@ -72,9 +72,9 @@ struct PyBinaryUFunctor {
static PyObject* _call_(TBinaryFunctor const& self, PyObject* input1, PyObject* input2,
PyObject* output) {
PyObject* input1_array = PyArray_FROM_OTF(input1,detail::NumpyTraits::getCode(),
- NPY_ALIGNED);
+ NPY_ARRAY_ALIGNED);
PyObject* input2_array = PyArray_FROM_OTF(input2,detail::NumpyTraits::getCode(),
- NPY_ALIGNED);
+ NPY_ARRAY_ALIGNED);
if (input1_array == NULL || input2_array == NULL) {
Py_XDECREF(input1_array);
Py_XDECREF(input2_array);
@@ -94,7 +94,7 @@ struct PyBinaryUFunctor {
Py_DECREF(tmp);
} else {
output_array = PyArray_FROM_OTF(output,detail::NumpyTraits::getCode(),
- NPY_ALIGNED | NPY_WRITEABLE | NPY_UPDATEIFCOPY);
+ NPY_ARRAY_ALIGNED | NPY_ARRAY_WRITEABLE | NPY_ARRAY_UPDATEIFCOPY);
}
if (output_array == NULL) {
Py_DECREF(input1_array);
diff --git a/tests/pybind11_test_mod.cc b/tests/pybind11_test_mod.cc
index 22118c2e..5e75def6 100644
--- a/tests/pybind11_test_mod.cc
+++ b/tests/pybind11_test_mod.cc
@@ -1,3 +1,4 @@
+#define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION
#include "pybind11/pybind11.h"
#include "numpy/arrayobject.h"