Skip to content

Commit 4b73d5c

Browse files
committed
Better explanations for PYBIND11_SH_AVL, PYBIND11_SH_DEF.
1 parent 78d6f10 commit 4b73d5c

File tree

1 file changed

+64
-39
lines changed

1 file changed

+64
-39
lines changed

README_smart_holder.rst

Lines changed: 64 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -106,25 +106,43 @@ There are three small differences compared to Classic pybind11:
106106
- ``#include <pybind11/smart_holder.h>`` is used instead of
107107
``#include <pybind11/pybind11.h>``.
108108

109+
- The ``PYBIND11_SMART_HOLDER_TYPE_CASTERS(Foo)`` macro is needed.
110+
109111
- ``py::classh`` is used instead of ``py::class_``.
110112

111-
- The ``PYBIND11_SMART_HOLDER_TYPE_CASTERS(Foo)`` macro is needed.
113+
To the 2nd bullet point, the ``PYBIND11_SMART_HOLDER_TYPE_CASTERS`` macro
114+
needs to appear in all translation units with pybind11 bindings that involve
115+
Python⇄C++ conversions for `Foo`. This is the biggest inconvenience of the
116+
Conservative mode. Practically, at a larger scale it is best to work with a
117+
pair of `.h` and `.cpp` files for the bindings code, with the macros in the
118+
`.h` files.
112119

113-
To the 2nd bullet point, ``py::classh<Foo>`` is simply a shortcut for
120+
To the 3rd bullet point, ``py::classh<Foo>`` is simply a shortcut for
114121
``py::class_<Foo, py::smart_holder>``. The shortcut makes it possible to
115122
switch to using ``py::smart_holder`` without disturbing the indentation of
116123
existing code.
117124

118-
When migrating code that uses ``py::class_<Foo, std::shared_ptr<Foo>>``,
119-
``std::shared_ptr<Foo>`` can be replaced with ``PYBIND11_SH_AVL(Foo)``,
120-
which substitutes ``py::smart_holder`` in Conservative mode, but also allows
121-
fallback to Classic mode by substituting ``std::shared_ptr<Foo>`` instead.
125+
When migrating code that uses ``py::class_<Bar, std::shared_ptr<Bar>>``
126+
there are two alternatives. The first one is to use ``py::classh<Bar>``:
127+
128+
.. code-block:: diff
129+
130+
- py::class_<Bar, std::shared_ptr<Bar>>(m, "Bar");
131+
+ py::classh<Bar>(m, "Bar");
132+
133+
This is clean and simple, but makes it difficult to fall back to Classic
134+
mode if needed. The second alternative is to replace ``std::shared_ptr<Bar>``
135+
with ``PYBIND11_SH_AVL(Bar)``:
136+
137+
.. code-block:: diff
138+
139+
- py::class_<Bar, std::shared_ptr<Bar>>(m, "Bar");
140+
+ py::class_<Bar, PYBIND11_SH_AVL(Bar)>(m, "Bar");
122141
123-
To the 3rd bullet point, the macro also needs to appear in other translation
124-
units with pybind11 bindings that involve Python⇄C++ conversions for
125-
`Foo`. This is the biggest inconvenience of the Conservative mode. Practically,
126-
at a larger scale it is best to work with a pair of `.h` and `.cpp` files
127-
for the bindings code, with the macros in the `.h` files.
142+
The ``PYBIND11_SH_AVL`` macro substitutes ``py::smart_holder``
143+
in Conservative mode, or ``std::shared_ptr<Bar>`` in Classic mode.
144+
See tests/test_classh_mock.cpp for an example. Note that the macro is also
145+
designed to not disturb the indentation of existing code.
128146

129147

130148
Progressive mode
@@ -134,56 +152,63 @@ To work in Progressive mode:
134152

135153
- Add ``-DPYBIND11_USE_SMART_HOLDER_AS_DEFAULT`` to the compilation commands.
136154

137-
- Remove any ``std::shared_ptr<...>`` holders from existing ``py::class_``
138-
instantiations.
155+
- Remove or replace (see below) ``std::shared_ptr<...>`` holders.
139156

140157
- Only if custom smart-pointers are used: the
141-
`PYBIND11_TYPE_CASTER_BASE_HOLDER` macro is needed [`example
142-
<https://github.com/pybind/pybind11/blob/2f624af1ac8571d603df2d70cb54fc7e2e3a356a/tests/test_multiple_inheritance.cpp#L72>`_].
158+
`PYBIND11_TYPE_CASTER_BASE_HOLDER` macro is needed (see
159+
tests/test_smart_ptr.cpp for examples).
143160

144161
Overall this is probably easier to work with than the Conservative mode, but
145162

146163
- the macro inconvenience is shifted from ``py::smart_holder`` to custom
147-
smart-pointers (but probably much more rarely needed).
164+
smart-pointer holders (which are probably much more rare).
148165

149166
- it will not interoperate with other extensions built against master or
150167
stable, or extensions built in Conservative mode (see the cross-module
151168
compatibility section below).
152169

170+
When migrating code that uses ``py::class_<Bar, std::shared_ptr<Bar>>`` there
171+
are the same alternatives as for the Conservative mode (see previous section).
172+
An additional alternative is to use the ``PYBIND11_SH_DEF(...)`` macro:
153173

154-
Transition from Conservative to Progressive mode
155-
------------------------------------------------
174+
.. code-block:: diff
175+
176+
- py::class_<Bar, std::shared_ptr<Bar>>(m, "Bar");
177+
+ py::class_<Bar, PYBIND11_SH_DEF(Bar)>(m, "Bar");
178+
179+
The ``PYBIND11_SH_DEF`` macro substitutes ``py::smart_holder`` only in
180+
Progressive mode, or ``std::shared_ptr<Bar>`` in Classic or Conservative
181+
mode. See tests/test_classh_mock.cpp for an example. Note that the
182+
``PYBIND11_SMART_HOLDER_TYPE_CASTERS`` macro is never needed in combination
183+
with the ``PYBIND11_SH_DEF`` macro, which is an advantage compared to the
184+
``PYBIND11_SH_AVL`` macro. Please review tests/test_classh_mock.cpp for a
185+
concise overview of all available options.
186+
187+
188+
Transition from Classic to Progressive mode
189+
-------------------------------------------
156190

157191
This still has to be tried out more in practice, but in small-scale situations
158192
it may be feasible to switch directly to Progressive mode in a break-fix
159193
fashion. In large-scale situations it seems more likely that an incremental
160194
approach is needed, which could mean incrementally converting ``py::class_``
161-
to ``py::classh`` including addition of the macros, then flip the switch,
162-
and convert ``py::classh`` back to ``py:class_`` combined with removal of the
163-
macros if desired (at that point it will work equivalently either way). It
164-
may be smart to delay the final cleanup step until all third-party projects
165-
of interest have made the switch, because then the code will continue to
166-
work in either mode.
195+
to ``py::classh`` and using the family of related macros, then flip the switch
196+
to Progressive mode, and convert ``py::classh`` back to ``py:class_`` combined
197+
with removal of the macros if desired (at that point it will work equivalently
198+
either way). It may be smart to delay the final cleanup step until all
199+
third-party projects of interest have made the switch, because then the code
200+
will continue to work in all modes.
167201

168202

169203
Using py::smart_holder but with fallback to Classic pybind11
170204
------------------------------------------------------------
171205

172-
For situations in which compatibility with Classic pybind11 (without
173-
smart_holder) is needed for some period of time, fallback to Classic
174-
mode can be enabled by copying the ``BOILERPLATE`` code block from
175-
tests/test_classh_mock.cpp.
176-
177-
Fallback from Conservative to Classic mode could be viewed as
178-
super-conservative mode. The main idea is to enable use of ``py::classh``
179-
and the associated ``PYBIND11_SMART_HOLDER_TYPE_CASTERS`` macro while still
180-
being able to build the same code with Classic pybind11.
181-
182-
Fallback from Progressive to Classic mode is supported by the
183-
``PYBIND11_SH_DEF(...)`` macro in the BOILERPLATE code block. "SH_DEF" is
184-
short for "Smart_Holder if DEFault". The length of the macro is identical
185-
by design to ``std::shared_ptr<...>``, to not disturb the indentation of
186-
existing code.
206+
For situations in which compatibility with Classic pybind11
207+
(without smart_holder) is needed for some period of time, fallback
208+
to Classic mode can be enabled by copying the ``BOILERPLATE`` code
209+
block from tests/test_classh_mock.cpp. This code block provides mock
210+
implementations of ``py::classh`` and the family of related macros
211+
(e.g. ``PYBIND11_SMART_HOLDER_TYPE_CASTERS``).
187212

188213

189214
Classic / Conservative / Progressive cross-module compatibility

0 commit comments

Comments
 (0)