From 08b5f3c2d306f2d2516151504d11c5ea49c40590 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 7 Mar 2026 02:45:20 +0000 Subject: [PATCH 1/3] Initial plan From 6159c222c9d26b0ecc8c3bdd0377d9383d1f3219 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 7 Mar 2026 03:06:50 +0000 Subject: [PATCH 2/3] 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> --- tests/test_opaque_types.cpp | 44 +++++++++++++++++++++++++++++++++++++ tests/test_opaque_types.py | 28 +++++++++++++++++++++++ 2 files changed, 72 insertions(+) diff --git a/tests/test_opaque_types.cpp b/tests/test_opaque_types.cpp index 2e972d0b88..29979735a8 100644 --- a/tests/test_opaque_types.cpp +++ b/tests/test_opaque_types.cpp @@ -11,6 +11,7 @@ #include "pybind11_tests.h" +#include #include // 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>) +// 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) +PYBIND11_MAKE_OPAQUE(std::vector>) + using StringList = std::vector>; +// Type aliases for issue #5988 test +using Array3d = std::array; +using VecArray3d = std::vector; + TEST_SUBMODULE(opaque_types, m) { // test_string_list py::class_(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_(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_(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(); }); } diff --git a/tests/test_opaque_types.py b/tests/test_opaque_types.py index 7a4d7a43da..444b62dd75 100644 --- a/tests/test_opaque_types.py +++ b/tests/test_opaque_types.py @@ -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) 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>) 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] From 6bb404d320c2d3976795e5a97d2311b32232318c Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Sat, 7 Mar 2026 05:35:17 +0000 Subject: [PATCH 3/3] style: pre-commit fixes --- tests/test_opaque_types.cpp | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/tests/test_opaque_types.cpp b/tests/test_opaque_types.cpp index 29979735a8..228e12ff06 100644 --- a/tests/test_opaque_types.cpp +++ b/tests/test_opaque_types.cpp @@ -109,13 +109,14 @@ TEST_SUBMODULE(opaque_types, m) { py::class_(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( + "__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(); }); }