Skip to content

Commit ed3d23a

Browse files
author
Wenzel Jakob
committed
major cleanup of the whole codebase
- new pybind11::base<> attribute to indicate a subclass relationship - unified infrastructure for parsing variadic arguments in class_ and cpp_function - use 'handle' and 'object' more consistently everywhere
1 parent 140546b commit ed3d23a

20 files changed

+997
-851
lines changed

CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ include_directories(${PYTHON_INCLUDE_DIR})
8080
include_directories(include)
8181

8282
set(PYBIND11_HEADERS
83+
include/pybind11/attr.h
8384
include/pybind11/cast.h
8485
include/pybind11/common.h
8586
include/pybind11/complex.h
@@ -167,7 +168,7 @@ elseif (UNIX)
167168
# Strip unnecessary sections of the binary on Linux/Mac OS
168169
if(APPLE)
169170
set_target_properties(example PROPERTIES MACOSX_RPATH ".")
170-
set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup -dead_strip")
171+
set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
171172
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
172173
add_custom_command(TARGET example POST_BUILD COMMAND strip -u -r ${PROJECT_SOURCE_DIR}/example/example.so)
173174
endif()

docs/advanced.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -925,7 +925,7 @@ If not available, the signature may not be very helpful, e.g.:
925925
FUNCTIONS
926926
...
927927
| myFunction(...)
928-
| Signature : (MyClass, arg : SomeType = <SomeType object at 0x101b7b080>) -> None
928+
| Signature : (MyClass, arg : SomeType = <SomeType object at 0x101b7b080>) -> NoneType
929929
...
930930
931931
The first way of addressing this is by defining ``SomeType.__repr__``.

docs/changelog.rst

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,29 @@ Changelog
55

66
1.2 (not yet released)
77
--------------------------
8+
89
* Optional: efficient generation of function signatures at compile time using C++14
9-
* Switched to a simpler and more general way of dealing with function default arguments
10-
Unused keyword arguments in function calls are now detected and cause errors as expected
10+
* Switched to a simpler and more general way of dealing with function default
11+
arguments. Unused keyword arguments in function calls are now detected and
12+
cause errors as expected
1113
* New ``keep_alive`` call policy analogous to Boost.Python's ``with_custodian_and_ward``
14+
* New ``pybind11::base<>`` attribute to indicate a subclass relationship
1215
* Improved interface for RAII type wrappers in ``pytypes.h``
1316
* Use RAII type wrappers consistently within pybind11 itself. This
1417
fixes various potential refcount leaks when exceptions occur
1518
* Added new ``bytes`` RAII type wrapper (maps to ``string`` in Python 2.7).
16-
* Made handle and related RAII classes const correct
19+
* Made handle and related RAII classes const correct, using them more
20+
consistently everywhere now
1721
* Got rid of the ugly ``__pybind11__`` attributes on the Python side---they are
1822
now stored in a C++ hash table that is not visible in Python
1923
* Fixed refcount leaks involving NumPy arrays and bound functions
2024
* Vastly improved handling of shared/smart pointers
2125
* Removed an unnecessary copy operation in ``pybind11::vectorize``
2226
* Fixed naming clashes when both pybind11 and NumPy headers are included
2327
* Added conversions for additional exception types
24-
* Documentation improvements (using multiple extension modules, smart pointers, other minor clarifications)
28+
* Documentation improvements (using multiple extension modules, smart pointers,
29+
other minor clarifications)
30+
* unified infrastructure for parsing variadic arguments in class_ and cpp_function
2531
* Fixed license text (was: ZLIB, should have been: 3-clause BSD)
2632
* Python 3.2 compatibility
2733

docs/classes.rst

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -177,21 +177,35 @@ inheritance relationship:
177177
std::string bark() const { return "woof!"; }
178178
};
179179
180-
To capture the hierarchical relationship in pybind11, we must assign a name to
181-
the ``Pet`` :class:`class_` instance and reference it when binding the ``Dog``
182-
class.
180+
There are two different ways of indicating a hierarchical relationship to
181+
pybind11: the first is by specifying the C++ base class explicitly during
182+
construction using the ``base`` attribute:
183+
184+
.. code-block:: cpp
185+
186+
py::class_<Pet>(m, "Pet")
187+
.def(py::init<const std::string &>())
188+
.def_readwrite("name", &Pet::name);
189+
190+
py::class_<Dog>(m, "Dog", py::base<Pet>() /* <- specify C++ parent type */)
191+
.def(py::init<const std::string &>())
192+
.def("bark", &Dog::bark);
193+
194+
Alternatively, we can also assign a name to the previously bound ``Pet``
195+
:class:`class_` object and reference it when binding the ``Dog`` class:
183196

184197
.. code-block:: cpp
185198
186199
py::class_<Pet> pet(m, "Pet");
187200
pet.def(py::init<const std::string &>())
188201
.def_readwrite("name", &Pet::name);
189202
190-
py::class_<Dog>(m, "Dog", pet /* <- specify parent */)
203+
py::class_<Dog>(m, "Dog", pet /* <- specify Python parent type */)
191204
.def(py::init<const std::string &>())
192205
.def("bark", &Dog::bark);
193206
194-
Instances then expose fields and methods of both types:
207+
Functionality-wise, both approaches are completely equivalent. Afterwards,
208+
instances will expose fields and methods of both types:
195209

196210
.. code-block:: python
197211
@@ -242,14 +256,14 @@ The overload signatures are also visible in the method's docstring:
242256
| Methods defined here:
243257
|
244258
| __init__(...)
245-
| Signature : (Pet, str, int) -> None
259+
| Signature : (Pet, str, int) -> NoneType
246260
|
247261
| set(...)
248-
| 1. Signature : (Pet, int) -> None
262+
| 1. Signature : (Pet, int) -> NoneType
249263
|
250264
| Set the pet's age
251265
|
252-
| 2. Signature : (Pet, str) -> None
266+
| 2. Signature : (Pet, str) -> NoneType
253267
|
254268
| Set the pet's name
255269

docs/cmake.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ and that the pybind11 repository is located in a subdirectory named :file:`pybin
115115
# Strip unnecessary sections of the binary on Linux/Mac OS
116116
if(APPLE)
117117
set_target_properties(example PROPERTIES MACOSX_RPATH ".")
118-
set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup -dead_strip")
118+
set_target_properties(example PROPERTIES LINK_FLAGS "-undefined dynamic_lookup ")
119119
if (NOT ${U_CMAKE_BUILD_TYPE} MATCHES DEBUG)
120120
add_custom_command(TARGET example POST_BUILD COMMAND strip -u -r ${PROJECT_BINARY_DIR}/example.so)
121121
endif()

docs/reference.rst

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -63,17 +63,19 @@ Without reference counting
6363

6464
Return the ``PyObject *`` underlying a :class:`handle`.
6565

66-
.. function:: void handle::inc_ref() const
66+
.. function:: const handle& handle::inc_ref() const
6767

6868
Manually increase the reference count of the Python object. Usually, it is
6969
preferable to use the :class:`object` class which derives from
70-
:class:`handle` and calls this function automatically.
70+
:class:`handle` and calls this function automatically. Returns a reference
71+
to itself.
7172

72-
.. function:: void handle::dec_ref() const
73+
.. function:: const handle& handle::dec_ref() const
7374

7475
Manually decrease the reference count of the Python object. Usually, it is
7576
preferable to use the :class:`object` class which derives from
76-
:class:`handle` and calls this function automatically.
77+
:class:`handle` and calls this function automatically. Returns a reference
78+
to itself.
7779

7880
.. function:: void handle::ref_count() const
7981

@@ -167,11 +169,11 @@ With reference counting
167169
Move constructor; steals the object from ``other`` and preserves its
168170
reference count.
169171

170-
.. function:: PyObject* object::release()
172+
.. function:: handle object::release()
171173

172-
Release ownership of underlying ``PyObject *``. Returns raw Python object
173-
pointer without decreasing its reference count and resets handle to
174-
``nullptr``-valued pointer.
174+
Resets the internal pointer to ``nullptr`` without without decreasing the
175+
object's reference count. The function returns a raw handle to the original
176+
Python object.
175177

176178
.. function:: object::~object()
177179

example/example5.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,11 @@ class Dog : public Pet {
2929
void bark() const { std::cout << "Woof!" << std::endl; }
3030
};
3131

32+
class Rabbit : public Pet {
33+
public:
34+
Rabbit(const std::string &name) : Pet(name, "parrot") {}
35+
};
36+
3237
void pet_print(const Pet &pet) {
3338
std::cout << pet.name() + " is a " + pet.species() << std::endl;
3439
}
@@ -62,9 +67,14 @@ void init_ex5(py::module &m) {
6267
.def("name", &Pet::name)
6368
.def("species", &Pet::species);
6469

70+
/* One way of declaring a subclass relationship: reference parent's class_ object */
6571
py::class_<Dog>(m, "Dog", pet_class)
6672
.def(py::init<std::string>());
6773

74+
/* Another way of declaring a subclass relationship: reference parent's C++ type */
75+
py::class_<Rabbit>(m, "Rabbit", py::base<Pet>())
76+
.def(py::init<std::string>());
77+
6878
m.def("pet_print", pet_print);
6979
m.def("dog_bark", dog_bark);
7080

example/example5.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55

66
from example import Pet
77
from example import Dog
8+
from example import Rabbit
89
from example import dog_bark
910
from example import pet_print
1011

1112
polly = Pet('Polly', 'parrot')
1213
molly = Dog('Molly')
14+
roger = Rabbit('Rabbit')
15+
print(roger.name() + " is a " + roger.species())
16+
pet_print(roger)
1317
print(polly.name() + " is a " + polly.species())
1418
pet_print(polly)
1519
print(molly.name() + " is a " + molly.species())

example/example5.ref

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,22 @@
1+
Rabbit is a parrot
12
Polly is a parrot
2-
Polly is a parrot
3-
Molly is a dog
43
Molly is a dog
54
Woof!
6-
The following error is expected: Incompatible function arguments. The following argument types are supported:
7-
1. (Dog) -> NoneType
8-
9-
Callback function 1 called!
10-
False
11-
Callback function 2 called : Hello, x, True, 5
12-
5
13-
func(43) = 44
145
func(43) = 44
156
Payload constructor
167
Payload copy constructor
178
Payload move constructor
189
Payload destructor
1910
Payload destructor
2011
Payload destructor
12+
Rabbit is a parrot
13+
Polly is a parrot
14+
Molly is a dog
15+
The following error is expected: Incompatible function arguments. The following argument types are supported:
16+
1. (example.Dog) -> NoneType
17+
18+
Callback function 1 called!
19+
False
20+
Callback function 2 called : Hello, x, True, 5
21+
5
22+
func(43) = 44

0 commit comments

Comments
 (0)