Skip to content

Commit e0f9468

Browse files
committed
Merge remote-tracking branch 'upstream/master' into relax-class-arguments
2 parents 86d5f83 + 146397e commit e0f9468

14 files changed

+374
-146
lines changed

docs/advanced.rst

Lines changed: 136 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -552,15 +552,150 @@ and the Python ``list``, ``set`` and ``dict`` data structures are automatically
552552
enabled. The types ``std::pair<>`` and ``std::tuple<>`` are already supported
553553
out of the box with just the core :file:`pybind11/pybind11.h` header.
554554

555+
The major downside of these implicit conversions is that containers must be
556+
converted (i.e. copied) on every Python->C++ and C++->Python transition, which
557+
can have implications on the program semantics and performance. Please read the
558+
next sections for more details and alternative approaches that avoid this.
559+
555560
.. note::
556561

557-
Arbitrary nesting of any of these types is supported.
562+
Arbitrary nesting of any of these types is possible.
558563

559564
.. seealso::
560565

561566
The file :file:`tests/test_python_types.cpp` contains a complete
562567
example that demonstrates how to pass STL data types in more detail.
563568

569+
.. _opaque:
570+
571+
Treating STL data structures as opaque objects
572+
==============================================
573+
574+
pybind11 heavily relies on a template matching mechanism to convert parameters
575+
and return values that are constructed from STL data types such as vectors,
576+
linked lists, hash tables, etc. This even works in a recursive manner, for
577+
instance to deal with lists of hash maps of pairs of elementary and custom
578+
types, etc.
579+
580+
However, a fundamental limitation of this approach is that internal conversions
581+
between Python and C++ types involve a copy operation that prevents
582+
pass-by-reference semantics. What does this mean?
583+
584+
Suppose we bind the following function
585+
586+
.. code-block:: cpp
587+
588+
void append_1(std::vector<int> &v) {
589+
v.push_back(1);
590+
}
591+
592+
and call it from Python, the following happens:
593+
594+
.. code-block:: pycon
595+
596+
>>> v = [5, 6]
597+
>>> append_1(v)
598+
>>> print(v)
599+
[5, 6]
600+
601+
As you can see, when passing STL data structures by reference, modifications
602+
are not propagated back the Python side. A similar situation arises when
603+
exposing STL data structures using the ``def_readwrite`` or ``def_readonly``
604+
functions:
605+
606+
.. code-block:: cpp
607+
608+
/* ... definition ... */
609+
610+
class MyClass {
611+
std::vector<int> contents;
612+
};
613+
614+
/* ... binding code ... */
615+
616+
py::class_<MyClass>(m, "MyClass")
617+
.def(py::init<>)
618+
.def_readwrite("contents", &MyClass::contents);
619+
620+
In this case, properties can be read and written in their entirety. However, an
621+
``append`` operaton involving such a list type has no effect:
622+
623+
.. code-block:: pycon
624+
625+
>>> m = MyClass()
626+
>>> m.contents = [5, 6]
627+
>>> print(m.contents)
628+
[5, 6]
629+
>>> m.contents.append(7)
630+
>>> print(m.contents)
631+
[5, 6]
632+
633+
Finally, the involved copy operations can be costly when dealing with very
634+
large lists. To deal with all of the above situations, pybind11 provides a
635+
macro named ``PYBIND11_MAKE_OPAQUE(T)`` that disables the template-based
636+
conversion machinery of types, thus rendering them *opaque*. The contents of
637+
opaque objects are never inspected or extracted, hence they *can* be passed by
638+
reference. For instance, to turn ``std::vector<int>`` into an opaque type, add
639+
the declaration
640+
641+
.. code-block:: cpp
642+
643+
PYBIND11_MAKE_OPAQUE(std::vector<int>);
644+
645+
before any binding code (e.g. invocations to ``class_::def()``, etc.). This
646+
macro must be specified at the top level (and outside of any namespaces), since
647+
it instantiates a partial template overload. If your binding code consists of
648+
multiple compilation units, it must be present in every file preceding any
649+
usage of ``std::vector<int>``. Opaque types must also have a corresponding
650+
``class_`` declaration to associate them with a name in Python, and to define a
651+
set of available operations, e.g.:
652+
653+
.. code-block:: cpp
654+
655+
py::class_<std::vector<int>>(m, "IntVector")
656+
.def(py::init<>())
657+
.def("clear", &std::vector<int>::clear)
658+
.def("pop_back", &std::vector<int>::pop_back)
659+
.def("__len__", [](const std::vector<int> &v) { return v.size(); })
660+
.def("__iter__", [](std::vector<int> &v) {
661+
return py::make_iterator(v.begin(), v.end());
662+
}, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */
663+
// ....
664+
665+
The ability to expose STL containers as native Python objects is a fairly
666+
common request, hence pybind11 also provides an optional header file named
667+
:file:`pybind11/stl_bind.h` that does exactly this. The mapped containers try
668+
to match the behavior of their native Python counterparts as much as possible.
669+
670+
The following example showcases usage of :file:`pybind11/stl_bind.h`:
671+
672+
.. code-block:: cpp
673+
674+
// Don't forget this
675+
#include <pybind11/stl_bind.h>
676+
677+
PYBIND11_MAKE_OPAQUE(std::vector<int>);
678+
PYBIND11_MAKE_OPAQUE(std::map<std::string, double>);
679+
680+
// ...
681+
682+
// later in binding code:
683+
py::bind_vector<std::vector<int>>(m, "VectorInt");
684+
py::bind_map<std::map<std::string, double>>(m, "MapStringDouble");
685+
686+
Please take a look at the :ref:`macro_notes` before using the
687+
``PYBIND11_MAKE_OPAQUE`` macro.
688+
689+
.. seealso::
690+
691+
The file :file:`tests/test_opaque_types.cpp` contains a complete
692+
example that demonstrates how to create and expose opaque types using
693+
pybind11 in more detail.
694+
695+
The file :file:`tests/test_stl_binders.cpp` shows how to use the
696+
convenience STL container wrappers.
697+
698+
564699
Binding sequence data types, iterators, the slicing protocol, etc.
565700
==================================================================
566701

@@ -1094,108 +1229,6 @@ section.
10941229
The ``py::exception`` wrapper for creating custom exceptions cannot (yet)
10951230
be used as a base type.
10961231

1097-
.. _opaque:
1098-
1099-
Treating STL data structures as opaque objects
1100-
==============================================
1101-
1102-
pybind11 heavily relies on a template matching mechanism to convert parameters
1103-
and return values that are constructed from STL data types such as vectors,
1104-
linked lists, hash tables, etc. This even works in a recursive manner, for
1105-
instance to deal with lists of hash maps of pairs of elementary and custom
1106-
types, etc.
1107-
1108-
However, a fundamental limitation of this approach is that internal conversions
1109-
between Python and C++ types involve a copy operation that prevents
1110-
pass-by-reference semantics. What does this mean?
1111-
1112-
Suppose we bind the following function
1113-
1114-
.. code-block:: cpp
1115-
1116-
void append_1(std::vector<int> &v) {
1117-
v.push_back(1);
1118-
}
1119-
1120-
and call it from Python, the following happens:
1121-
1122-
.. code-block:: pycon
1123-
1124-
>>> v = [5, 6]
1125-
>>> append_1(v)
1126-
>>> print(v)
1127-
[5, 6]
1128-
1129-
As you can see, when passing STL data structures by reference, modifications
1130-
are not propagated back the Python side. A similar situation arises when
1131-
exposing STL data structures using the ``def_readwrite`` or ``def_readonly``
1132-
functions:
1133-
1134-
.. code-block:: cpp
1135-
1136-
/* ... definition ... */
1137-
1138-
class MyClass {
1139-
std::vector<int> contents;
1140-
};
1141-
1142-
/* ... binding code ... */
1143-
1144-
py::class_<MyClass>(m, "MyClass")
1145-
.def(py::init<>)
1146-
.def_readwrite("contents", &MyClass::contents);
1147-
1148-
In this case, properties can be read and written in their entirety. However, an
1149-
``append`` operaton involving such a list type has no effect:
1150-
1151-
.. code-block:: pycon
1152-
1153-
>>> m = MyClass()
1154-
>>> m.contents = [5, 6]
1155-
>>> print(m.contents)
1156-
[5, 6]
1157-
>>> m.contents.append(7)
1158-
>>> print(m.contents)
1159-
[5, 6]
1160-
1161-
To deal with both of the above situations, pybind11 provides a macro named
1162-
``PYBIND11_MAKE_OPAQUE(T)`` that disables the template-based conversion
1163-
machinery of types, thus rendering them *opaque*. The contents of opaque
1164-
objects are never inspected or extracted, hence they can be passed by
1165-
reference. For instance, to turn ``std::vector<int>`` into an opaque type, add
1166-
the declaration
1167-
1168-
.. code-block:: cpp
1169-
1170-
PYBIND11_MAKE_OPAQUE(std::vector<int>);
1171-
1172-
before any binding code (e.g. invocations to ``class_::def()``, etc.). This
1173-
macro must be specified at the top level, since instantiates a partial template
1174-
overload. If your binding code consists of multiple compilation units, it must
1175-
be present in every file preceding any usage of ``std::vector<int>``. Opaque
1176-
types must also have a corresponding ``class_`` declaration to associate them
1177-
with a name in Python, and to define a set of available operations:
1178-
1179-
.. code-block:: cpp
1180-
1181-
py::class_<std::vector<int>>(m, "IntVector")
1182-
.def(py::init<>())
1183-
.def("clear", &std::vector<int>::clear)
1184-
.def("pop_back", &std::vector<int>::pop_back)
1185-
.def("__len__", [](const std::vector<int> &v) { return v.size(); })
1186-
.def("__iter__", [](std::vector<int> &v) {
1187-
return py::make_iterator(v.begin(), v.end());
1188-
}, py::keep_alive<0, 1>()) /* Keep vector alive while iterator is used */
1189-
// ....
1190-
1191-
Please take a look at the :ref:`macro_notes` before using this feature.
1192-
1193-
.. seealso::
1194-
1195-
The file :file:`tests/test_opaque_types.cpp` contains a complete
1196-
example that demonstrates how to create and expose opaque types using
1197-
pybind11 in more detail.
1198-
11991232
.. _eigen:
12001233

12011234
Transparent conversion of dense and sparse Eigen data types

docs/basics.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -178,16 +178,16 @@ The keyword names also appear in the function signatures within the documentatio
178178
A shorter notation for named arguments is also available:
179179

180180
.. code-block:: cpp
181-
181+
182182
// regular notation
183183
m.def("add1", &add, py::arg("i"), py::arg("j"));
184184
// shorthand
185185
using namespace pybind11::literals;
186186
m.def("add2", &add, "i"_a, "j"_a);
187187
188-
The :var:`_a` suffix forms a C++11 literal which is equivalent to :class:`arg`.
189-
Note that the literal operator must first be made visible with the directive
190-
``using namespace pybind11::literals``. This does not bring in anything else
188+
The :var:`_a` suffix forms a C++11 literal which is equivalent to :class:`arg`.
189+
Note that the literal operator must first be made visible with the directive
190+
``using namespace pybind11::literals``. This does not bring in anything else
191191
from the ``pybind11`` namespace except for literals.
192192

193193
.. _default_args:
@@ -229,7 +229,7 @@ The default values also appear within the documentation.
229229
The shorthand notation is also available for default arguments:
230230

231231
.. code-block:: cpp
232-
232+
233233
// regular notation
234234
m.def("add1", &add, py::arg("i") = 1, py::arg("j") = 2);
235235
// shorthand

docs/compiling.rst

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Building with cppimport
2626
Building with CMake
2727
===================
2828

29-
For C++ codebases that have an existing CMake-based build system, a Python
29+
For C++ codebases that have an existing CMake-based build system, a Python
3030
extension module can be created with just a few lines of code:
3131

3232
.. code-block:: cmake
@@ -37,14 +37,14 @@ extension module can be created with just a few lines of code:
3737
add_subdirectory(pybind11)
3838
pybind11_add_module(example example.cpp)
3939
40-
This assumes that the pybind11 repository is located in a subdirectory named
40+
This assumes that the pybind11 repository is located in a subdirectory named
4141
:file:`pybind11` and that the code is located in a file named :file:`example.cpp`.
4242
The CMake command ``add_subdirectory`` will import a function with the signature
4343
``pybind11_add_module(<name> source1 [source2 ...])``. It will take care of all
4444
the details needed to build a Python extension module on any platform.
4545

46-
The target Python version can be selected by setting the ``PYBIND11_PYTHON_VERSION``
47-
variable before adding the pybind11 subdirectory. Alternatively, an exact Python
46+
The target Python version can be selected by setting the ``PYBIND11_PYTHON_VERSION``
47+
variable before adding the pybind11 subdirectory. Alternatively, an exact Python
4848
installation can be specified by setting ``PYTHON_EXECUTABLE``.
4949

5050
A working sample project, including a way to invoke CMake from :file:`setup.py` for

docs/faq.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ the included test suite contains the following symbol:
140140

141141
.. code-block:: none
142142
143-
_​_​Z​N​8​p​y​b​i​n​d​1​1​1​2​c​p​p​_​f​u​n​c​t​i​o​n​C​1​I​v​8​E​x​a​m​p​l​e​2​J​R​N​S​t​3​_​_​1​6​v​e​c​t​o​r​I​N​S​3​_​1​2​b​a​s​i​c​_​s​t​r​i​n​g​I​w​N​S​3​_​1​1​c​h​a​r​_​t​r​a​i​t​s​I​w​E​E​N​S​3​_​9​a​l​l​o​c​a​t​o​r​I​w​E​E​E​E​N​S​8​_​I​S​A​_​E​E​E​E​E​J​N​S​_​4​n​a​m​e​E​N​S​_​7​s​i​b​l​i​n​g​E​N​S​_​9​i​s​_​m​e​t​h​o​d​E​A​2​8​_​c​E​E​E​M​T​0​_​F​T​_​D​p​T​1​_​E​D​p​R​K​T​2​_
143+
_​_​Z​N​8​p​y​b​i​n​d​1​1​1​2​c​p​p​_​f​u​n​c​t​i​o​n​C​1​I​v​8​E​x​a​m​p​l​e​2​J​R​N​S​t​3​_​_​1​6​v​e​c​t​o​r​I​N​S​3​_​1​2​b​a​s​i​c​_​s​t​r​i​n​g​I​w​N​S​3​_​1​1​c​h​a​r​_​t​r​a​i​t​s​I​w​E​E​N​S​3​_​9​a​l​l​o​c​a​t​o​r​I​w​E​E​E​E​N​S​8​_​I​S​A​_​E​E​E​E​E​J​N​S​_​4​n​a​m​e​E​N​S​_​7​s​i​b​l​i​n​g​E​N​S​_​9​i​s​_​m​e​t​h​o​d​E​A​2​8​_​c​E​E​E​M​T​0​_​F​T​_​D​p​T​1​_​E​D​p​R​K​T​2​_
144144
145145
.. only:: not html
146146

include/pybind11/cast.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -683,7 +683,7 @@ template <typename... Tuple> class type_caster<std::tuple<Tuple...>> {
683683
static PYBIND11_DESCR element_names() {
684684
return detail::concat(type_caster<typename intrinsic_type<Tuple>::type>::name()...);
685685
}
686-
686+
687687
static PYBIND11_DESCR name() {
688688
return type_descr(_("Tuple[") + element_names() + _("]"));
689689
}

include/pybind11/pybind11.h

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1085,7 +1085,7 @@ template <typename Type> class enum_ : public class_<Type> {
10851085
def("__ne__", [](const Type &value, UnderlyingType value2) { return (UnderlyingType) value != value2; });
10861086
}
10871087
def("__hash__", [](const Type &value) { return (UnderlyingType) value; });
1088-
// Pickling and unpickling -- needed for use with the 'multiprocessing' module
1088+
// Pickling and unpickling -- needed for use with the 'multiprocessing' module
10891089
def("__getstate__", [](const Type &value) { return pybind11::make_tuple((UnderlyingType) value); });
10901090
def("__setstate__", [](Type &p, tuple t) { new (&p) Type((Type) t[0].cast<UnderlyingType>()); });
10911091
m_entries = entries;
@@ -1169,7 +1169,7 @@ PYBIND11_NOINLINE inline void keep_alive_impl(int Nurse, int Patient, handle arg
11691169
keep_alive_impl(nurse, patient);
11701170
}
11711171

1172-
template <typename Iterator, typename Sentinel, bool KeyIterator = false>
1172+
template <typename Iterator, typename Sentinel, bool KeyIterator, typename... Extra>
11731173
struct iterator_state {
11741174
Iterator it;
11751175
Sentinel end;
@@ -1185,10 +1185,10 @@ template <typename Iterator,
11851185
typename ValueType = decltype(*std::declval<Iterator>()),
11861186
typename... Extra>
11871187
iterator make_iterator(Iterator first, Sentinel last, Extra &&... extra) {
1188-
typedef detail::iterator_state<Iterator, Sentinel> state;
1188+
typedef detail::iterator_state<Iterator, Sentinel, false, Extra...> state;
11891189

11901190
if (!detail::get_type_info(typeid(state))) {
1191-
class_<state>(handle(), "")
1191+
class_<state>(handle(), "iterator")
11921192
.def("__iter__", [](state &s) -> state& { return s; })
11931193
.def("__next__", [](state &s) -> ValueType {
11941194
if (!s.first)
@@ -1203,15 +1203,16 @@ iterator make_iterator(Iterator first, Sentinel last, Extra &&... extra) {
12031203

12041204
return (iterator) cast(state { first, last, true });
12051205
}
1206+
12061207
template <typename Iterator,
12071208
typename Sentinel,
12081209
typename KeyType = decltype((*std::declval<Iterator>()).first),
12091210
typename... Extra>
12101211
iterator make_key_iterator(Iterator first, Sentinel last, Extra &&... extra) {
1211-
typedef detail::iterator_state<Iterator, Sentinel, true> state;
1212+
typedef detail::iterator_state<Iterator, Sentinel, true, Extra...> state;
12121213

12131214
if (!detail::get_type_info(typeid(state))) {
1214-
class_<state>(handle(), "")
1215+
class_<state>(handle(), "iterator")
12151216
.def("__iter__", [](state &s) -> state& { return s; })
12161217
.def("__next__", [](state &s) -> KeyType {
12171218
if (!s.first)

0 commit comments

Comments
 (0)