mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 05:05:11 +00:00
Dtype field ordering for NumPy 1.14 (#1837)
* Test dtype field order in numpy dtype tests When running tests with NumPy 1.14 or later this test exposes the "invalid buffer descriptor" error reported in #1274. * Create dtype_ptr with ordered fields
This commit is contained in:
parent
74d335a535
commit
a301c5add8
@ -1066,8 +1066,14 @@ inline PYBIND11_NOINLINE void register_structured_dtype(
|
||||
if (numpy_internals.get_type_info(tinfo, false))
|
||||
pybind11_fail("NumPy: dtype is already registered");
|
||||
|
||||
// Use ordered fields because order matters as of NumPy 1.14:
|
||||
// https://docs.scipy.org/doc/numpy/release.html#multiple-field-indexing-assignment-of-structured-arrays
|
||||
std::vector<field_descriptor> ordered_fields(std::move(fields));
|
||||
std::sort(ordered_fields.begin(), ordered_fields.end(),
|
||||
[](const field_descriptor &a, const field_descriptor &b) { return a.offset < b.offset; });
|
||||
|
||||
list names, formats, offsets;
|
||||
for (auto field : *fields) {
|
||||
for (auto& field : ordered_fields) {
|
||||
if (!field.descr)
|
||||
pybind11_fail(std::string("NumPy: unsupported field dtype: `") +
|
||||
field.name + "` @ " + tinfo.name());
|
||||
@ -1084,9 +1090,6 @@ inline PYBIND11_NOINLINE void register_structured_dtype(
|
||||
// - https://github.com/numpy/numpy/pull/7798
|
||||
// Because of this, we won't use numpy's logic to generate buffer format
|
||||
// strings and will just do it ourselves.
|
||||
std::vector<field_descriptor> ordered_fields(std::move(fields));
|
||||
std::sort(ordered_fields.begin(), ordered_fields.end(),
|
||||
[](const field_descriptor &a, const field_descriptor &b) { return a.offset < b.offset; });
|
||||
ssize_t offset = 0;
|
||||
std::ostringstream oss;
|
||||
// mark the structure as unaligned with '^', because numpy and C++ don't
|
||||
|
@ -29,6 +29,13 @@ std::ostream& operator<<(std::ostream& os, const SimpleStruct& v) {
|
||||
return os << "s:" << v.bool_ << "," << v.uint_ << "," << v.float_ << "," << v.ldbl_;
|
||||
}
|
||||
|
||||
struct SimpleStructReordered {
|
||||
bool bool_;
|
||||
float float_;
|
||||
uint32_t uint_;
|
||||
long double ldbl_;
|
||||
};
|
||||
|
||||
PYBIND11_PACKED(struct PackedStruct {
|
||||
bool bool_;
|
||||
uint32_t uint_;
|
||||
@ -255,6 +262,7 @@ TEST_SUBMODULE(numpy_dtypes, m) {
|
||||
py::class_<SimpleStruct>(m, "SimpleStruct");
|
||||
|
||||
PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_);
|
||||
PYBIND11_NUMPY_DTYPE(SimpleStructReordered, bool_, uint_, float_, ldbl_);
|
||||
PYBIND11_NUMPY_DTYPE(PackedStruct, bool_, uint_, float_, ldbl_);
|
||||
PYBIND11_NUMPY_DTYPE(NestedStruct, a, b);
|
||||
PYBIND11_NUMPY_DTYPE(PartialStruct, bool_, uint_, float_, ldbl_);
|
||||
|
Loading…
Reference in New Issue
Block a user