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:
copilot-swe-agent[bot]
2026-03-07 03:06:50 +00:00
parent 08b5f3c2d3
commit 6159c222c9
2 changed files with 72 additions and 0 deletions

View File

@@ -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(); });
}

View File

@@ -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]