mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +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))
|
if (numpy_internals.get_type_info(tinfo, false))
|
||||||
pybind11_fail("NumPy: dtype is already registered");
|
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;
|
list names, formats, offsets;
|
||||||
for (auto field : *fields) {
|
for (auto& field : ordered_fields) {
|
||||||
if (!field.descr)
|
if (!field.descr)
|
||||||
pybind11_fail(std::string("NumPy: unsupported field dtype: `") +
|
pybind11_fail(std::string("NumPy: unsupported field dtype: `") +
|
||||||
field.name + "` @ " + tinfo.name());
|
field.name + "` @ " + tinfo.name());
|
||||||
@ -1084,9 +1090,6 @@ inline PYBIND11_NOINLINE void register_structured_dtype(
|
|||||||
// - https://github.com/numpy/numpy/pull/7798
|
// - https://github.com/numpy/numpy/pull/7798
|
||||||
// Because of this, we won't use numpy's logic to generate buffer format
|
// Because of this, we won't use numpy's logic to generate buffer format
|
||||||
// strings and will just do it ourselves.
|
// 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;
|
ssize_t offset = 0;
|
||||||
std::ostringstream oss;
|
std::ostringstream oss;
|
||||||
// mark the structure as unaligned with '^', because numpy and C++ don't
|
// 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_;
|
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 {
|
PYBIND11_PACKED(struct PackedStruct {
|
||||||
bool bool_;
|
bool bool_;
|
||||||
uint32_t uint_;
|
uint32_t uint_;
|
||||||
@ -255,6 +262,7 @@ TEST_SUBMODULE(numpy_dtypes, m) {
|
|||||||
py::class_<SimpleStruct>(m, "SimpleStruct");
|
py::class_<SimpleStruct>(m, "SimpleStruct");
|
||||||
|
|
||||||
PYBIND11_NUMPY_DTYPE(SimpleStruct, bool_, uint_, float_, ldbl_);
|
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(PackedStruct, bool_, uint_, float_, ldbl_);
|
||||||
PYBIND11_NUMPY_DTYPE(NestedStruct, a, b);
|
PYBIND11_NUMPY_DTYPE(NestedStruct, a, b);
|
||||||
PYBIND11_NUMPY_DTYPE(PartialStruct, bool_, uint_, float_, ldbl_);
|
PYBIND11_NUMPY_DTYPE(PartialStruct, bool_, uint_, float_, ldbl_);
|
||||||
|
Loading…
Reference in New Issue
Block a user