Skip to content

PYBIND11_NUMPY_DTYPE does not work on structure containing array #800

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
bmerry opened this issue Apr 16, 2017 · 3 comments
Closed

PYBIND11_NUMPY_DTYPE does not work on structure containing array #800

bmerry opened this issue Apr 16, 2017 · 3 comments

Comments

@bmerry
Copy link
Contributor

bmerry commented Apr 16, 2017

Issue description

Using PYBIND11_NUMPY_DTYPE on a structure member which is an array (either a language array or std::array) leads to a compilation error:

pybind11/numpy.h:1027:9: error: ‘format’ is not a member of ‘pybind11::format_descriptor<int [2]>’
         ::pybind11::format_descriptor<decltype(std::declval<T>().Field)>::format(),           \
         ^

Reproducible example code

#include <pybind11/pybind11.h>
#include <pybind11/numpy.h>
#include <array>
#include <cstdint>

namespace py = pybind11;

struct foo
{
    std::int32_t array[2];
};

PYBIND11_PLUGIN(arraytest)
{
    PYBIND11_NUMPY_DTYPE(foo, array);

    py::module m("arraytest", "doc");
    return m.ptr();
}

Compiled with GCC 5.4 with g++ -std=c++14 -c pybind11-array.cpp plus -I options for Python and pybind11, and pybind11 version 2.1.1

@jagerman
Copy link
Member

It's an intentional, explicit omission: not because it's impossible, but just because no one has done it yet.

@aldanor
Copy link
Member

aldanor commented Apr 17, 2017

Well, almost... we wouldn't mark arrays as is_pod_struct, but rather specialise npy_format_descriptor and format_descriptor. In fact, we do specialise those for char[N] and std::array<char, N>, mapping them to S dtype which is admittedly slightly hacky (since it overlaps with int8_t[N], if we were to map arbitrary fixed-size arrays).

@bmerry
Copy link
Contributor Author

bmerry commented Apr 17, 2017

I don't think it's likely to conflict with int8_t[N], because int8_t will be signed char and char is a distinct type from both signed char and unsigned char.

I might have a go at it if I get time, although it won't be this week.

bmerry added a commit to bmerry/pybind11 that referenced this issue May 4, 2017
This implements pybind#800.

Both C++ arrays and std::array are supported, including mixtures like
std::array<int, 2>[4]. In a multi-dimensional array of char, the last
dimension is used to construct a numpy string type.

There are some things I'm not sure about:
- Is there a better name for array_info? The "array" could easily be
  misinterpreted as referring to py::array rather than std::array.
- Should array_info be split into separate classes for the different
  traits, or is it okay to have this uber traits class?
- When constructing the dtype, the shape should really be a tuple rather
  than a list, but I'm not sure how to dynamically construct a tuple (or
  how to convert the list to a tuple). numpy seems to accept a list.
- Should the array dtypes be registered in some way? At present two
  structures embedding the same array type will each construct a
  separate dtype object to represent that array type. That's already the
  case for char[N] though.
- Should I add tests to use an array type directly e.g.
  py::array_t<int[2]>?
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants