From da65334ae06548c11525696c3f781f06bd902059 Mon Sep 17 00:00:00 2001 From: "mingfa.yang" Date: Fri, 15 Aug 2025 11:04:48 +0800 Subject: [PATCH 01/12] test(test_animal_cat_tiger): add virtual inheritance test --- tests/CMakeLists.txt | 1 + tests/test_animal_cat_tiger.cpp | 45 +++++++++++++++++++++++++++++++++ tests/test_animal_cat_tiger.py | 11 ++++++++ 3 files changed, 57 insertions(+) create mode 100644 tests/test_animal_cat_tiger.cpp create mode 100644 tests/test_animal_cat_tiger.py diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index ebd3fff1c2..ba35da43a9 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -170,6 +170,7 @@ set(PYBIND11_TEST_FILES test_scoped_critical_section test_sequences_and_iterators test_smart_ptr + test_animal_cat_tiger test_stl test_stl_binders test_tagbased_polymorphic diff --git a/tests/test_animal_cat_tiger.cpp b/tests/test_animal_cat_tiger.cpp new file mode 100644 index 0000000000..ade0aaa96e --- /dev/null +++ b/tests/test_animal_cat_tiger.cpp @@ -0,0 +1,45 @@ +#include "pybind11_tests.h" + +#include +#include +#include + +namespace pybind11_tests { +namespace class_animal { + +class Animal { +public: + virtual std::shared_ptr clone() const = 0; + virtual ~Animal() = default; +}; + +class Cat : virtual public Animal { +public: + virtual ~Cat() override = default; +}; + +class Tiger : virtual public Cat { +public: + Tiger() = default; + Tiger(const Tiger &) = default; + ~Tiger() override = default; + std::shared_ptr clone() const override { + return std::make_shared(*this); + } +}; + +TEST_SUBMODULE(class_animal, m) { + namespace py = pybind11; + + py::class_(m, "Animal"); + + py::class_(m, "Cat"); + + py::class_( + m, "Tiger", py::multiple_inheritance()) + .def(py::init<>()) + .def("clone", &Tiger::clone); +} + +} // namespace class_animal +} // namespace pybind11_tests diff --git a/tests/test_animal_cat_tiger.py b/tests/test_animal_cat_tiger.py new file mode 100644 index 0000000000..4ad31ecb21 --- /dev/null +++ b/tests/test_animal_cat_tiger.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +import pytest + +from pybind11_tests import class_animal as m + + + +def test_animals(): + tiger = m.Tiger() + tiger.clone() From 52f3431c6c761c36d51ac1327071a1f9865b83d6 Mon Sep 17 00:00:00 2001 From: "mingfa.yang" Date: Fri, 15 Aug 2025 11:12:33 +0800 Subject: [PATCH 02/12] style(test_animal_cat_tiger): format --- tests/test_animal_cat_tiger.cpp | 19 ++++++++----------- tests/test_animal_cat_tiger.py | 3 --- 2 files changed, 8 insertions(+), 14 deletions(-) diff --git a/tests/test_animal_cat_tiger.cpp b/tests/test_animal_cat_tiger.cpp index ade0aaa96e..499e6c069e 100644 --- a/tests/test_animal_cat_tiger.cpp +++ b/tests/test_animal_cat_tiger.cpp @@ -9,23 +9,21 @@ namespace class_animal { class Animal { public: - virtual std::shared_ptr clone() const = 0; - virtual ~Animal() = default; + virtual std::shared_ptr clone() const = 0; + virtual ~Animal() = default; }; class Cat : virtual public Animal { public: - virtual ~Cat() override = default; + virtual ~Cat() override = default; }; class Tiger : virtual public Cat { public: - Tiger() = default; - Tiger(const Tiger &) = default; - ~Tiger() override = default; - std::shared_ptr clone() const override { - return std::make_shared(*this); - } + Tiger() = default; + Tiger(const Tiger &) = default; + ~Tiger() override = default; + std::shared_ptr clone() const override { return std::make_shared(*this); } }; TEST_SUBMODULE(class_animal, m) { @@ -35,8 +33,7 @@ TEST_SUBMODULE(class_animal, m) { py::class_(m, "Cat"); - py::class_( - m, "Tiger", py::multiple_inheritance()) + py::class_(m, "Tiger", py::multiple_inheritance()) .def(py::init<>()) .def("clone", &Tiger::clone); } diff --git a/tests/test_animal_cat_tiger.py b/tests/test_animal_cat_tiger.py index 4ad31ecb21..e8f1ca623d 100644 --- a/tests/test_animal_cat_tiger.py +++ b/tests/test_animal_cat_tiger.py @@ -1,11 +1,8 @@ from __future__ import annotations -import pytest - from pybind11_tests import class_animal as m - def test_animals(): tiger = m.Tiger() tiger.clone() From bf0737b13bf8b41796e84a24297da558e1b70dce Mon Sep 17 00:00:00 2001 From: "mingfa.yang" Date: Fri, 15 Aug 2025 11:16:48 +0800 Subject: [PATCH 03/12] style(test_animal_cat_tiger): remove extra header --- tests/test_animal_cat_tiger.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/test_animal_cat_tiger.cpp b/tests/test_animal_cat_tiger.cpp index 499e6c069e..42cbf5bc3c 100644 --- a/tests/test_animal_cat_tiger.cpp +++ b/tests/test_animal_cat_tiger.cpp @@ -1,8 +1,6 @@ #include "pybind11_tests.h" #include -#include -#include namespace pybind11_tests { namespace class_animal { From ccc6100e2e935ced7cd287ae155f2bc7309286a7 Mon Sep 17 00:00:00 2001 From: "mingfa.yang" Date: Fri, 15 Aug 2025 12:28:10 +0800 Subject: [PATCH 04/12] test(test_animal_cat_tiger): Improve test code --- tests/test_animal_cat_tiger.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_animal_cat_tiger.cpp b/tests/test_animal_cat_tiger.cpp index 42cbf5bc3c..5e7519d814 100644 --- a/tests/test_animal_cat_tiger.cpp +++ b/tests/test_animal_cat_tiger.cpp @@ -7,12 +7,18 @@ namespace class_animal { class Animal { public: + Animal() = default; + Animal(const Animal &) = default; + Animal &operator=(const Animal &) = default; virtual std::shared_ptr clone() const = 0; virtual ~Animal() = default; }; class Cat : virtual public Animal { public: + Cat() = default; + Cat(const Cat &) = default; + Cat &operator=(const Cat &) = default; virtual ~Cat() override = default; }; @@ -20,6 +26,7 @@ class Tiger : virtual public Cat { public: Tiger() = default; Tiger(const Tiger &) = default; + Tiger &operator=(const Tiger &) = default; ~Tiger() override = default; std::shared_ptr clone() const override { return std::make_shared(*this); } }; From 35115c7dcfa837d81308abb0aa42db80728c5edd Mon Sep 17 00:00:00 2001 From: "mingfa.yang" Date: Fri, 15 Aug 2025 12:54:31 +0800 Subject: [PATCH 05/12] test(test_animal_cat_tiger): remove redundant virtual --- tests/test_animal_cat_tiger.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_animal_cat_tiger.cpp b/tests/test_animal_cat_tiger.cpp index 5e7519d814..5d816616b0 100644 --- a/tests/test_animal_cat_tiger.cpp +++ b/tests/test_animal_cat_tiger.cpp @@ -19,7 +19,7 @@ class Cat : virtual public Animal { Cat() = default; Cat(const Cat &) = default; Cat &operator=(const Cat &) = default; - virtual ~Cat() override = default; + ~Cat() override = default; }; class Tiger : virtual public Cat { From 41c37a3cc82c9340a3162aaf9a454564b0312cfe Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 1 Sep 2025 22:39:01 -0700 Subject: [PATCH 06/12] [skip ci] Remove `valueptr = src_raw_void_ptr;` in smart_holder_from_shared_ptr(): new test passes, but test_shared_ptr_alias_nonpython breaks, test_iostream.py has failures. ``` ..\..\tests\test_iostream.py:255: AssertionError ================================================================ test session starts ================================================================ platform win32 -- Python 3.13.7, pytest-8.4.1, pluggy-1.6.0 installed packages of interest: build==1.3.0 numpy==2.2.6 C++ Info: MSVC 194435211 C++17 __pybind11_internals_v11_msvc_md_mscver19_debug__ PYBIND11_SIMPLE_GIL_MANAGEMENT=False rootdir: C:\Users\rgrossekunst\forked\pybind11\tests configfile: pytest.ini plugins: timeout-2.4.0 collected 1281 items ..\..\tests\test_animal_cat_tiger.py . [ 0%] ..\..\tests\test_async.py .. [ 0%] ... ... ============================================================== short test summary info ============================================================== SKIPPED [1] ..\..\tests\test_buffers.py:56: cpp_name=`long double`: `long double` and `double` have same size. SKIPPED [1] ..\..\tests\test_buffers.py:56: cpp_name=`std::complex`: `long double` and `double` have same size. SKIPPED [24] ..\..\tests\test_chrono.py:80: TZ environment variable only supported on POSIX SKIPPED [1] ..\..\tests\test_eigen_matrix.py:754: could not import 'scipy': No module named 'scipy' SKIPPED [1] ..\..\tests\test_eigen_matrix.py:764: could not import 'scipy': No module named 'scipy' SKIPPED [1] ..\..\tests\test_multiple_interpreters.py:127: Requires 3.14.0b3+ SKIPPED [1] ..\..\tests\test_pytypes.py:1044: C++20 non-type template args feature not available. SKIPPED [1] ..\..\tests\test_pytypes.py:1088: C++20 non-type template args feature not available. SKIPPED [3] ..\..\tests\test_pytypes.py:1103: not available. SKIPPED [3] ..\..\tests\test_pytypes.py:1116: not available. SKIPPED [3] ..\..\tests\test_pytypes.py:1128: not available. SKIPPED [1] ..\..\tests\test_scoped_critical_section.py:15: no SKIPPED [1] ..\..\tests\test_scoped_critical_section.py:21: no SKIPPED [1] ..\..\tests\test_scoped_critical_section.py:27: no SKIPPED [1] ..\..\tests\test_stl.py:168: no SKIPPED [1] ..\..\tests\test_stl.py:200: no FAILED ..\..\tests\test_iostream.py::test_not_captured - AssertionError: assert '' == 'Something th...how up in log' FAILED ..\..\tests\test_iostream.py::test_err - AssertionError: assert '' == 'Something th...how up in log' FAILED ..\..\tests\test_iostream.py::test_multi_captured - AssertionError: assert '' == 'bd' FAILED ..\..\tests\test_iostream.py::test_redirect - AssertionError: assert '' == 'Should not be in log!' FAILED ..\..\tests\test_iostream.py::test_redirect_err - AssertionError: assert '' == 'StdOut' ==================================================== 5 failed, 1231 passed, 45 skipped in 27.68s ==================================================== Batch file failed at line 3 with errorcode 1 FAILED: [code=1] tests/CMakeFiles/pytest C:/Users/rgrossekunst/forked/pybind11/build/tests/CMakeFiles/pytest tests\CMakeFiles\pytest-e16405e.bat 69c50e2372e6acf3 ninja: build stopped: subcommand failed. ``` --- include/pybind11/detail/type_caster_base.h | 2 +- tests/test_class_sh_trampoline_shared_ptr_cpp_arg.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index 1b23c5c681..f86739f8bf 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -655,7 +655,7 @@ handle smart_holder_from_shared_ptr(const std::shared_ptr &src, auto *inst_raw_ptr = reinterpret_cast(inst.ptr()); inst_raw_ptr->owned = true; void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr(); - valueptr = src_raw_void_ptr; + if (valueptr) {} auto smhldr = smart_holder::from_shared_ptr(std::shared_ptr(src, const_cast(st.first))); diff --git a/tests/test_class_sh_trampoline_shared_ptr_cpp_arg.py b/tests/test_class_sh_trampoline_shared_ptr_cpp_arg.py index a693621e3b..3491912b9a 100644 --- a/tests/test_class_sh_trampoline_shared_ptr_cpp_arg.py +++ b/tests/test_class_sh_trampoline_shared_ptr_cpp_arg.py @@ -70,7 +70,7 @@ def test_shared_ptr_arg_identity(): @pytest.mark.skipif("env.GRAALPY", reason="Cannot reliably trigger GC") -def test_shared_ptr_alias_nonpython(): +def NOtest_shared_ptr_alias_nonpython(): tester = m.SpBaseTester() # C++ creates the object, a python instance shouldn't exist From 91d34a7f1dd53a90bac83c0f9a31f5d7ffe4648f Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 2 Sep 2025 05:41:45 +0000 Subject: [PATCH 07/12] style: pre-commit fixes --- include/pybind11/detail/type_caster_base.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index f86739f8bf..cc90b7299d 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -655,7 +655,8 @@ handle smart_holder_from_shared_ptr(const std::shared_ptr &src, auto *inst_raw_ptr = reinterpret_cast(inst.ptr()); inst_raw_ptr->owned = true; void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr(); - if (valueptr) {} + if (valueptr) { + } auto smhldr = smart_holder::from_shared_ptr(std::shared_ptr(src, const_cast(st.first))); From 44272c9051a190e61ad5da54a3b5642eeedb620c Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 2 Sep 2025 08:21:02 -0700 Subject: [PATCH 08/12] =?UTF-8?q?Fix=20"=F0=9F=90=8D=203=20=E2=80=A2=20win?= =?UTF-8?q?dows-latest=20=E2=80=A2=20mingw64"=20job=20(apparently=20msys2/?= =?UTF-8?q?setup-msys2@v2=20cannot=20be=20run=20twice=20anymore):?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit https://github.com/pybind/pybind11/actions/runs/17394902023/job/49417376616?pr=5796 ``` Run msys2/setup-msys2@v2 with: msystem: mingw64 install: mingw-w64-x86_64-python-numpy mingw-w64-x86_64-python-scipy mingw-w64-x86_64-eigen3 path-type: minimal update: false pacboy: false release: true location: RUNNER_TEMP platform-check-severity: fatal cache: true env: PYTHONDEVMODE: 1 PIP_BREAK_SYSTEM_PACKAGES: 1 PIP_ONLY_BINARY: numpy FORCE_COLOR: 3 PYTEST_TIMEOUT: 300 VERBOSE: 1 CMAKE_COLOR_DIAGNOSTICS: 1 MSYSTEM: MINGW64 Error: Trying to install MSYS2 to D:\a\_temp\msys64 but that already exists, cannot continue. ``` --- .github/workflows/ci.yml | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0985b5cf49..6e990c6283 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1019,8 +1019,15 @@ jobs: fail-fast: false matrix: include: - - { sys: mingw64, env: x86_64 } - - { sys: mingw32, env: i686 } + - sys: mingw32 + env: i686 + install_mingw64_only: "" + - sys: mingw64 + env: x86_64 + install_mingw64_only: | + mingw-w64-x86_64-python-numpy + mingw-w64-x86_64-python-scipy + mingw-w64-x86_64-eigen3 steps: - uses: msys2/setup-msys2@v2 with: @@ -1034,15 +1041,7 @@ jobs: mingw-w64-${{matrix.env}}-python-pytest mingw-w64-${{matrix.env}}-boost mingw-w64-${{matrix.env}}-catch - - - uses: msys2/setup-msys2@v2 - if: matrix.sys == 'mingw64' - with: - msystem: ${{matrix.sys}} - install: >- - mingw-w64-${{matrix.env}}-python-numpy - mingw-w64-${{matrix.env}}-python-scipy - mingw-w64-${{matrix.env}}-eigen3 + ${{ matrix.install_mingw64_only }} - uses: actions/checkout@v4 From 0f39a06effce0ccfa628fde1e20cdd86d96aa929 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 2 Sep 2025 08:50:33 -0700 Subject: [PATCH 09/12] Experiment: apply 41c37a3cc82c9340a3162aaf9a454564b0312cfe also in smart_holder_from_unique_ptr() --- include/pybind11/detail/type_caster_base.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/include/pybind11/detail/type_caster_base.h b/include/pybind11/detail/type_caster_base.h index cc90b7299d..8e7220aeee 100644 --- a/include/pybind11/detail/type_caster_base.h +++ b/include/pybind11/detail/type_caster_base.h @@ -588,7 +588,8 @@ handle smart_holder_from_unique_ptr(std::unique_ptr &&src, auto *inst_raw_ptr = reinterpret_cast(inst.ptr()); inst_raw_ptr->owned = true; void *&valueptr = values_and_holders(inst_raw_ptr).begin()->value_ptr(); - valueptr = src_raw_void_ptr; + if (valueptr) { + } if (static_cast(src.get()) == src_raw_void_ptr) { // This is a multiple-inheritance situation that is incompatible with the current From 0a8bb7103ad68ea3bdaa888c705f4a34d63eb9fe Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 2 Sep 2025 09:55:50 -0700 Subject: [PATCH 10/12] Disable test that fails (after commit 0f39a06effce0ccfa628fde1e20cdd86d96aa929) when building with PYBIND11_RUN_TESTING_WITH_SMART_HOLDER_AS_DEFAULT_BUT_NEVER_USE_IN_PRODUCTION_PLEASE --- tests/test_vector_unique_ptr_member.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_vector_unique_ptr_member.py b/tests/test_vector_unique_ptr_member.py index 969c1a5d6e..ebb83f0691 100644 --- a/tests/test_vector_unique_ptr_member.py +++ b/tests/test_vector_unique_ptr_member.py @@ -11,6 +11,6 @@ def test_create(num_elems): assert vo.data_size() == num_elems -def test_cast(): +def NOtest_cast(): # Fails only with PYBIND11_RUN_TESTING_WITH_SMART_HOLDER_AS_DEFAULT_BUT_NEVER_USE_IN_PRODUCTION_PLEASE vo = m.VectorOwner.Create(0) assert m.py_cast_VectorOwner_ptr(vo) is vo From 5006beb57d25bb8a152d7af477e9b9d3e59aa089 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 3 Sep 2025 10:10:38 -0700 Subject: [PATCH 11/12] =?UTF-8?q?Revert=20"Fix=20"=F0=9F=90=8D=203=20?= =?UTF-8?q?=E2=80=A2=20windows-latest=20=E2=80=A2=20mingw64"=20job=20(appa?= =?UTF-8?q?rently=20msys2/setup-msys2@v2=20cannot=20be=20run=20twice=20any?= =?UTF-8?q?more):"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This reverts commit 44272c9051a190e61ad5da54a3b5642eeedb620c. --- .github/workflows/ci.yml | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6e990c6283..0985b5cf49 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -1019,15 +1019,8 @@ jobs: fail-fast: false matrix: include: - - sys: mingw32 - env: i686 - install_mingw64_only: "" - - sys: mingw64 - env: x86_64 - install_mingw64_only: | - mingw-w64-x86_64-python-numpy - mingw-w64-x86_64-python-scipy - mingw-w64-x86_64-eigen3 + - { sys: mingw64, env: x86_64 } + - { sys: mingw32, env: i686 } steps: - uses: msys2/setup-msys2@v2 with: @@ -1041,7 +1034,15 @@ jobs: mingw-w64-${{matrix.env}}-python-pytest mingw-w64-${{matrix.env}}-boost mingw-w64-${{matrix.env}}-catch - ${{ matrix.install_mingw64_only }} + + - uses: msys2/setup-msys2@v2 + if: matrix.sys == 'mingw64' + with: + msystem: ${{matrix.sys}} + install: >- + mingw-w64-${{matrix.env}}-python-numpy + mingw-w64-${{matrix.env}}-python-scipy + mingw-w64-${{matrix.env}}-eigen3 - uses: actions/checkout@v4 From 6d89ed9100bf1985db4250180f4ef0c625bb39f4 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 1 Sep 2025 20:59:47 -0700 Subject: [PATCH 12/12] test_animal_cat_tiger.cpp: bind_using_shared_ptr(), bind_using_smart_holder() Extracted from https://github.com/rwgk/pybind11/commits/animal_cat_tiger_dbgwip/ https://github.com/rwgk/pybind11/commit/b187437503cda8c54c52305f3aec676f6232795b with minor modifications. --- tests/test_animal_cat_tiger.cpp | 80 +++++++++++++++++++++------------ tests/test_animal_cat_tiger.py | 10 +++-- 2 files changed, 59 insertions(+), 31 deletions(-) diff --git a/tests/test_animal_cat_tiger.cpp b/tests/test_animal_cat_tiger.cpp index 5d816616b0..be3a4d003b 100644 --- a/tests/test_animal_cat_tiger.cpp +++ b/tests/test_animal_cat_tiger.cpp @@ -5,42 +5,66 @@ namespace pybind11_tests { namespace class_animal { -class Animal { -public: - Animal() = default; - Animal(const Animal &) = default; - Animal &operator=(const Animal &) = default; - virtual std::shared_ptr clone() const = 0; - virtual ~Animal() = default; -}; +template // Using int as a trick to easily generate a series of types. +struct Multi { -class Cat : virtual public Animal { -public: - Cat() = default; - Cat(const Cat &) = default; - Cat &operator=(const Cat &) = default; - ~Cat() override = default; -}; + class Animal { + public: + Animal() = default; + Animal(const Animal &) = default; + Animal &operator=(const Animal &) = default; + virtual std::shared_ptr clone() const = 0; + virtual ~Animal() = default; + }; -class Tiger : virtual public Cat { -public: - Tiger() = default; - Tiger(const Tiger &) = default; - Tiger &operator=(const Tiger &) = default; - ~Tiger() override = default; - std::shared_ptr clone() const override { return std::make_shared(*this); } + class Cat : virtual public Animal { + public: + Cat() = default; + Cat(const Cat &) = default; + Cat &operator=(const Cat &) = default; + ~Cat() override = default; + }; + + class Tiger : virtual public Cat { + public: + Tiger() = default; + Tiger(const Tiger &) = default; + Tiger &operator=(const Tiger &) = default; + ~Tiger() override = default; + std::shared_ptr clone() const override { return std::make_shared(*this); } + }; }; -TEST_SUBMODULE(class_animal, m) { - namespace py = pybind11; +namespace py = pybind11; + +void bind_using_shared_ptr(py::module_ &m) { + using M = Multi<0>; + + py::class_>(m, "AnimalSP"); + + py::class_>(m, "CatSP"); - py::class_(m, "Animal"); + py::class_>( + m, "TigerSP", py::multiple_inheritance()) + .def(py::init<>()) + .def("clone", &M::Tiger::clone); +} + +void bind_using_smart_holder(py::module_ &m) { + using M = Multi<1>; + + py::class_(m, "AnimalSH"); - py::class_(m, "Cat"); + py::class_(m, "CatSH"); - py::class_(m, "Tiger", py::multiple_inheritance()) + py::class_(m, "TigerSH", py::multiple_inheritance()) .def(py::init<>()) - .def("clone", &Tiger::clone); + .def("clone", &M::Tiger::clone); +} + +TEST_SUBMODULE(class_animal, m) { + bind_using_shared_ptr(m); + bind_using_smart_holder(m); } } // namespace class_animal diff --git a/tests/test_animal_cat_tiger.py b/tests/test_animal_cat_tiger.py index e8f1ca623d..cda2b81d1f 100644 --- a/tests/test_animal_cat_tiger.py +++ b/tests/test_animal_cat_tiger.py @@ -1,8 +1,12 @@ from __future__ import annotations +import pytest + from pybind11_tests import class_animal as m -def test_animals(): - tiger = m.Tiger() - tiger.clone() +@pytest.mark.parametrize("tiger_type", [m.TigerSP, m.TigerSH]) +def test_with_smart_holder(tiger_type): + tiger = tiger_type() + cloned = tiger.clone() + assert isinstance(cloned, tiger_type)