mirror of
https://github.com/pybind/pybind11.git
synced 2026-04-20 06:49:25 +00:00
Add regression test for issue #5988: PYBIND11_MAKE_OPAQUE with std::array and nested containers
Co-authored-by: henryiii <4616906+henryiii@users.noreply.github.com>
This commit is contained in:
@@ -11,6 +11,7 @@
|
||||
|
||||
#include "pybind11_tests.h"
|
||||
|
||||
#include <array>
|
||||
#include <vector>
|
||||
|
||||
// IMPORTANT: Disable internal pybind11 translation mechanisms for STL data structures
|
||||
@@ -20,8 +21,18 @@
|
||||
// bit is just the default `std::vector` allocator).
|
||||
PYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>)
|
||||
|
||||
// Test for GitHub issue #5988: PYBIND11_MAKE_OPAQUE with std::array types.
|
||||
// These types are not used as converted types in other test files, so they
|
||||
// can safely be made opaque here without ODR violations.
|
||||
PYBIND11_MAKE_OPAQUE(std::array<double, 3>)
|
||||
PYBIND11_MAKE_OPAQUE(std::vector<std::array<double, 3>>)
|
||||
|
||||
using StringList = std::vector<std::string, std::allocator<std::string>>;
|
||||
|
||||
// Type aliases for issue #5988 test
|
||||
using Array3d = std::array<double, 3>;
|
||||
using VecArray3d = std::vector<Array3d>;
|
||||
|
||||
TEST_SUBMODULE(opaque_types, m) {
|
||||
// test_string_list
|
||||
py::class_<StringList>(m, "StringList")
|
||||
@@ -74,4 +85,37 @@ TEST_SUBMODULE(opaque_types, m) {
|
||||
.def(py::init<>())
|
||||
.def_readwrite("i", &IntFloat::i)
|
||||
.def_readwrite("f", &IntFloat::f);
|
||||
|
||||
// test_issue_5988: PYBIND11_MAKE_OPAQUE with std::array and nested containers
|
||||
// (Regression test for crash when importing modules with opaque std::array types)
|
||||
py::class_<Array3d>(m, "Array3d")
|
||||
.def(py::init<>())
|
||||
.def("__getitem__",
|
||||
[](const Array3d &a, std::size_t i) -> double {
|
||||
if (i >= a.size()) {
|
||||
throw py::index_error();
|
||||
}
|
||||
return a[i];
|
||||
})
|
||||
.def("__setitem__",
|
||||
[](Array3d &a, std::size_t i, double v) {
|
||||
if (i >= a.size()) {
|
||||
throw py::index_error();
|
||||
}
|
||||
a[i] = v;
|
||||
})
|
||||
.def("__len__", [](const Array3d &a) { return a.size(); });
|
||||
|
||||
py::class_<VecArray3d>(m, "VecArray3d")
|
||||
.def(py::init<>())
|
||||
.def("push_back", [](VecArray3d &v, const Array3d &a) { v.push_back(a); })
|
||||
.def("__getitem__",
|
||||
[](const VecArray3d &v, std::size_t i) -> const Array3d & {
|
||||
if (i >= v.size()) {
|
||||
throw py::index_error();
|
||||
}
|
||||
return v[i];
|
||||
},
|
||||
py::return_value_policy::reference_internal)
|
||||
.def("__len__", [](const VecArray3d &v) { return v.size(); });
|
||||
}
|
||||
|
||||
@@ -62,3 +62,31 @@ def test_unions():
|
||||
assert int_float_union.i == 42
|
||||
int_float_union.f = 3.0
|
||||
assert int_float_union.f == 3.0
|
||||
|
||||
|
||||
def test_issue_5988_opaque_std_array():
|
||||
"""Regression test for GitHub issue #5988: crash when binding with opaque std::array types."""
|
||||
# Test basic Array3d (opaque std::array<double, 3>) functionality
|
||||
a = m.Array3d()
|
||||
a[0] = 1.0
|
||||
a[1] = 2.5
|
||||
a[2] = 3.0
|
||||
assert a[0] == 1.0
|
||||
assert a[1] == 2.5
|
||||
assert a[2] == 3.0
|
||||
assert len(a) == 3
|
||||
|
||||
with pytest.raises(IndexError):
|
||||
_ = a[3]
|
||||
|
||||
# Test VecArray3d (opaque std::vector<std::array<double, 3>>) functionality
|
||||
v = m.VecArray3d()
|
||||
assert len(v) == 0
|
||||
v.push_back(a)
|
||||
assert len(v) == 1
|
||||
assert v[0][0] == 1.0
|
||||
assert v[0][1] == 2.5
|
||||
assert v[0][2] == 3.0
|
||||
|
||||
with pytest.raises(IndexError):
|
||||
_ = v[1]
|
||||
|
||||
Reference in New Issue
Block a user