Skip to content

Commit 9f0a880

Browse files
committed
Extend integer / double converters to properly treat NPY integer / float types
1 parent 9e6bafb commit 9f0a880

File tree

1 file changed

+25
-4
lines changed

1 file changed

+25
-4
lines changed

c++/cpp2py/converters/basic_types.hpp

+25-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
#pragma once
2+
#include "./../pyref.hpp"
23
#include "./complex.hpp"
34

5+
#include <numpy/arrayobject.h>
6+
47
namespace cpp2py {
58

69
// PyObject *
@@ -28,17 +31,26 @@ namespace cpp2py {
2831

2932
// --- long
3033

31-
namespace details{
34+
namespace details {
3235
template <typename I> struct py_converter_impl {
3336
static PyObject *c2py(I i) { return PyLong_FromLong(long(i)); }
34-
static I py2c(PyObject *ob) { return I(PyLong_AsLong(ob)); }
37+
static I py2c(PyObject *ob) {
38+
if (PyLong_Check(ob)) { return I(PyLong_AsLong(ob)); }
39+
// Convert NPY Scalar Type to Builtin Type
40+
pyref py_builtin = PyObject_CallMethod(ob, "item", NULL);
41+
return I(PyLong_AsLong(py_builtin));
42+
}
3543
static bool is_convertible(PyObject *ob, bool raise_exception) {
3644
if (PyLong_Check(ob)) return true;
45+
if (PyArray_CheckScalar(ob)) {
46+
pyref py_arr = PyArray_FromScalar(ob, NULL);
47+
if (PyArray_ISINTEGER((PyObject *)py_arr)) return true;
48+
}
3749
if (raise_exception) { PyErr_SetString(PyExc_TypeError, "Cannot convert to integer type"); }
3850
return false;
3951
}
4052
};
41-
}
53+
} // namespace details
4254

4355
template <> struct py_converter<long> : details::py_converter_impl<long> {};
4456
template <> struct py_converter<int> : details::py_converter_impl<int> {};
@@ -50,9 +62,18 @@ namespace cpp2py {
5062

5163
template <> struct py_converter<double> {
5264
static PyObject *c2py(double x) { return PyFloat_FromDouble(x); }
53-
static double py2c(PyObject *ob) { return PyFloat_AsDouble(ob); }
65+
static double py2c(PyObject *ob) {
66+
if (PyFloat_Check(ob) || PyLong_Check(ob)) { return PyFloat_AsDouble(ob); }
67+
// Convert NPY Scalar Type to Builtin Type
68+
pyref py_builtin = PyObject_CallMethod(ob, "item", NULL);
69+
return PyFloat_AsDouble(py_builtin);
70+
}
5471
static bool is_convertible(PyObject *ob, bool raise_exception) {
5572
if (PyFloat_Check(ob) || PyLong_Check(ob)) return true;
73+
if (PyArray_CheckScalar(ob)) {
74+
pyref py_arr = PyArray_FromScalar(ob, NULL);
75+
if (PyArray_ISINTEGER((PyObject*)py_arr) or PyArray_ISFLOAT((PyObject*)py_arr)) return true;
76+
}
5677
if (raise_exception) { PyErr_SetString(PyExc_TypeError, "Cannot convert to double"); }
5778
return false;
5879
}

0 commit comments

Comments
 (0)