Skip to content

doc + test: Using py::classh but with fallback to classic pybind11 #2952

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 14, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -174,8 +174,9 @@ jobs:
- python-version: 3.9
python-debug: true
valgrind: true
- python-version: 3.10-dev
python-debug: false
# Broken b/o https://github.com/pytest-dev/pytest/issues/8539
# - python-version: 3.10-dev
# python-debug: false

name: "🐍 ${{ matrix.python-version }}${{ matrix.python-debug && '-dbg' || '' }} (deadsnakes)${{ matrix.valgrind && ' • Valgrind' || '' }} • x64"
runs-on: ubuntu-latest
Expand Down
11 changes: 11 additions & 0 deletions README_smart_holder.rst
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,17 @@ of interest have made the switch, because then the code will continue to
work in either mode.


Using py::classh but with fallback to classic pybind11
------------------------------------------------------

This could be viewed as super-conservative mode, for situations in which
compatibility with classic pybind11 (without smart_holder) is needed for
some period of time. The main idea is to enable use of ``py::classh``
and the associated ``PYBIND11_SMART_HOLDER_TYPE_CASTERS`` macro while
still being able to build the same code with classic pybind11. Please see
tests/test_classh_mock.cpp for an example.


Trampolines and std::unique_ptr
-------------------------------

Expand Down
1 change: 1 addition & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ set(PYBIND11_TEST_FILES
test_class_sh_trampoline_unique_ptr.cpp
test_class_sh_unique_ptr_member.cpp
test_class_sh_virtual_py_cpp_mix.cpp
test_classh_mock.cpp
test_constants_and_functions.cpp
test_copy_move.cpp
test_custom_type_casters.cpp
Expand Down
46 changes: 46 additions & 0 deletions tests/test_classh_mock.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#include "pybind11_tests.h"

// The main purpose of this test is to ensure the suggested BOILERPLATE code block below is
// correct.

// Copy this block of code into your project.
// Replace FOOEXT with the name of your project.
// BOILERPLATE BEGIN
#ifdef FOOEXT_USING_PYBIND11_SMART_HOLDER
# include <pybind11/smart_holder.h>
#else
# include <pybind11/pybind11.h>
PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)
template <typename type_, typename... options>
using classh = class_<type_, options...>;
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
# ifndef PYBIND11_SMART_HOLDER_TYPE_CASTERS
# define PYBIND11_SMART_HOLDER_TYPE_CASTERS(...)
# endif
# ifndef PYBIND11_TYPE_CASTER_BASE_HOLDER
# define PYBIND11_TYPE_CASTER_BASE_HOLDER(...)
# endif
#endif
// BOILERPLATE END

namespace {
struct Foo0 {};
struct Foo1 {};
struct Foo2 {};
} // namespace

PYBIND11_TYPE_CASTER_BASE_HOLDER(Foo1, std::shared_ptr<Foo1>)
PYBIND11_SMART_HOLDER_TYPE_CASTERS(Foo2)

TEST_SUBMODULE(classh_mock, m) {
// Uses std::unique_ptr<Foo0> as holder in conservative mode, py::smart_holder in progressive
// mode (if available).
py::class_<Foo0>(m, "Foo0").def(py::init<>());

// Always uses std::shared_ptr<Foo1> as holder.
py::class_<Foo1, std::shared_ptr<Foo1>>(m, "Foo1").def(py::init<>());

// Uses py::smart_holder if available, or std::unique_ptr<Foo2> if only pybind11 classic is
// available.
py::classh<Foo2>(m, "Foo2").def(py::init<>());
}
11 changes: 11 additions & 0 deletions tests/test_classh_mock.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# -*- coding: utf-8 -*-

from pybind11_tests import classh_mock as m


def test_foobar():
# Not really testing anything in particular. The main purpose of this test is to ensure the
# suggested BOILERPLATE code block in test_classh_mock.cpp is correct.
assert m.Foo0()
assert m.Foo1()
assert m.Foo2()