mirror of
https://github.com/pybind/pybind11.git
synced 2026-03-14 20:27:47 +00:00
Revert "Systematically change most py::class_ to py::classh under docs/"
This reverts commit ac9d31e13f.
This commit is contained in:
@@ -102,7 +102,7 @@ example:
|
||||
};
|
||||
|
||||
// Later, in binding code:
|
||||
py::classh<MyClass>(m, "MyClass")
|
||||
py::class_<MyClass>(m, "MyClass")
|
||||
.def(py::init<>())
|
||||
.def("copy_matrix", &MyClass::getMatrix) // Makes a copy!
|
||||
.def("get_matrix", &MyClass::getMatrix, py::return_value_policy::reference_internal)
|
||||
@@ -250,7 +250,7 @@ copying to take place:
|
||||
|
||||
// The associated binding code:
|
||||
using namespace pybind11::literals; // for "arg"_a
|
||||
py::classh<MyClass>(m, "MyClass")
|
||||
py::class_<MyClass>(m, "MyClass")
|
||||
// ... other class definitions
|
||||
.def("some_method", &MyClass::some_method, py::arg().noconvert());
|
||||
|
||||
|
||||
@@ -3,13 +3,13 @@ Overview
|
||||
|
||||
.. rubric:: 1. Native type in C++, wrapper in Python
|
||||
|
||||
Exposing a custom C++ type using ``py::classh`` (or ``py::class_``) was
|
||||
covered in detail in the :doc:`/classes` section. There, the underlying
|
||||
data structure is always the original C++ class while the ``py::classh``
|
||||
wrapper provides a Python interface. Internally, when an object like this
|
||||
is sent from C++ to Python, pybind11 will just add the outer wrapper layer
|
||||
over the native C++ object. Getting it back from Python is just a matter of
|
||||
peeling off the wrapper.
|
||||
Exposing a custom C++ type using :class:`py::class_` was covered in detail
|
||||
in the :doc:`/classes` section. There, the underlying data structure is
|
||||
always the original C++ class while the :class:`py::class_` wrapper provides
|
||||
a Python interface. Internally, when an object like this is sent from C++ to
|
||||
Python, pybind11 will just add the outer wrapper layer over the native C++
|
||||
object. Getting it back from Python is just a matter of peeling off the
|
||||
wrapper.
|
||||
|
||||
.. rubric:: 2. Wrapper in C++, native type in Python
|
||||
|
||||
|
||||
@@ -135,7 +135,7 @@ functions:
|
||||
|
||||
/* ... binding code ... */
|
||||
|
||||
py::classh<MyClass>(m, "MyClass")
|
||||
py::class_<MyClass>(m, "MyClass")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("contents", &MyClass::contents);
|
||||
|
||||
@@ -169,12 +169,12 @@ macro must be specified at the top level (and outside of any namespaces), since
|
||||
it adds a template instantiation of ``type_caster``. If your binding code consists of
|
||||
multiple compilation units, it must be present in every file (typically via a
|
||||
common header) preceding any usage of ``std::vector<int>``. Opaque types must
|
||||
also have a corresponding ``py::classh`` declaration to associate them with a name
|
||||
also have a corresponding ``class_`` declaration to associate them with a name
|
||||
in Python, and to define a set of available operations, e.g.:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<std::vector<int>>(m, "IntVector")
|
||||
py::class_<std::vector<int>>(m, "IntVector")
|
||||
.def(py::init<>())
|
||||
.def("clear", &std::vector<int>::clear)
|
||||
.def("pop_back", &std::vector<int>::pop_back)
|
||||
|
||||
@@ -46,10 +46,10 @@ Normally, the binding code for these classes would look as follows:
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
py::classh<Animal>(m, "Animal")
|
||||
py::class_<Animal>(m, "Animal")
|
||||
.def("go", &Animal::go);
|
||||
|
||||
py::classh<Dog, Animal>(m, "Dog")
|
||||
py::class_<Dog, Animal>(m, "Dog")
|
||||
.def(py::init<>());
|
||||
|
||||
m.def("call_go", &call_go);
|
||||
@@ -64,7 +64,7 @@ helper class that is defined as follows:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class PyAnimal : public Animal, py::trampoline_self_life_support {
|
||||
class PyAnimal : public Animal {
|
||||
public:
|
||||
/* Inherit the constructors */
|
||||
using Animal::Animal;
|
||||
@@ -83,12 +83,13 @@ helper class that is defined as follows:
|
||||
The ``py::trampoline_self_life_support`` base class is needed to ensure
|
||||
that a ``std::unique_ptr`` can safely be passed between Python and C++. To
|
||||
steer clear of notorious pitfalls (e.g. inheritance slicing), it is best
|
||||
practice to always use the base class, in combination with ``py::classh``.
|
||||
practice to always use the base class, in combination with
|
||||
``py::smart_holder``.
|
||||
|
||||
.. note::
|
||||
For completeness, the base class has no effect if a holder other than
|
||||
``py::smart_holder`` (usually via ``py::classh``) is used. Please think
|
||||
twice, though, the pitfalls are very real.
|
||||
``py::smart_holder`` used, including the default ``std::unique_ptr<T>``.
|
||||
Please think twice, though, the pitfalls are very real.
|
||||
|
||||
The macro :c:macro:`PYBIND11_OVERRIDE_PURE` should be used for pure virtual
|
||||
functions, and :c:macro:`PYBIND11_OVERRIDE` should be used for functions which have
|
||||
@@ -105,30 +106,28 @@ The binding code also needs a few minor adaptations (highlighted):
|
||||
:emphasize-lines: 2,3
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
py::classh<Animal, PyAnimal /* <--- trampoline*/>(m, "Animal")
|
||||
py::class_<Animal, PyAnimal /* <--- trampoline*/>(m, "Animal")
|
||||
.def(py::init<>())
|
||||
.def("go", &Animal::go);
|
||||
|
||||
py::classh<Dog, Animal>(m, "Dog")
|
||||
py::class_<Dog, Animal>(m, "Dog")
|
||||
.def(py::init<>());
|
||||
|
||||
m.def("call_go", &call_go);
|
||||
}
|
||||
|
||||
Importantly, pybind11 is made aware of the trampoline helper class by
|
||||
specifying it as an extra template argument to ``py::classh``. (This can also
|
||||
be combined with other template arguments; the order of template types does
|
||||
not matter). Using ``py::classh`` (vs ``py::class_``) is to ensure that
|
||||
a ``std::unique_ptr`` can safely be passed between Python and C++ (see
|
||||
:ref:`smart_holder`).
|
||||
specifying it as an extra template argument to :class:`class_`. (This can also
|
||||
be combined with other template arguments such as a custom holder type; the
|
||||
order of template types does not matter). Following this, we are able to
|
||||
define a constructor as usual.
|
||||
|
||||
A constructor can be defined as usual. Bindings should be made against the
|
||||
actual class, not the trampoline helper class:
|
||||
Bindings should be made against the actual class, not the trampoline helper class.
|
||||
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 3
|
||||
|
||||
py::classh<Animal, PyAnimal /* <--- trampoline*/>(m, "Animal");
|
||||
py::class_<Animal, PyAnimal /* <--- trampoline*/>(m, "Animal");
|
||||
.def(py::init<>())
|
||||
.def("go", &Animal::go); /* <--- DO NOT USE &PyAnimal::go HERE */
|
||||
|
||||
@@ -137,6 +136,32 @@ extend ``Animal``, but not ``Dog``: see :ref:`virtual_and_inheritance` for the
|
||||
necessary steps required to providing proper overriding support for inherited
|
||||
classes.
|
||||
|
||||
To enable safely passing a ``std::unique_ptr`` to a trampoline object between
|
||||
Python and C++,
|
||||
|
||||
1. the C++ type (``Animal`` above) must be wrapped with ``py::classh``
|
||||
(see :ref:`smart_holder`), and
|
||||
|
||||
2. the trampoline helper class must inherit from
|
||||
``py::trampoline_self_life_support``.
|
||||
|
||||
I.e. the example above needs these two changes:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
class PyAnimal : public Animal, public py::trampoline_self_life_support {
|
||||
...
|
||||
};
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Animal, PyAnimal>(m, "Animal");
|
||||
|
||||
.. seealso::
|
||||
|
||||
A fairly minimal but complete example is in
|
||||
:file:`tests/test_class_sh_trampoline_unique_ptr.cpp`.
|
||||
|
||||
The Python session below shows how to override ``Animal::go`` and invoke it via
|
||||
a virtual method call.
|
||||
|
||||
@@ -323,9 +348,9 @@ The classes are then registered with pybind11 using:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Animal, PyAnimal<>> animal(m, "Animal");
|
||||
py::classh<Dog, Animal, PyDog<>> dog(m, "Dog");
|
||||
py::classh<Husky, Dog, PyDog<Husky>> husky(m, "Husky");
|
||||
py::class_<Animal, PyAnimal<>> animal(m, "Animal");
|
||||
py::class_<Dog, Animal, PyDog<>> dog(m, "Dog");
|
||||
py::class_<Husky, Dog, PyDog<Husky>> husky(m, "Husky");
|
||||
// ... add animal, dog, husky definitions
|
||||
|
||||
Note that ``Husky`` did not require a dedicated trampoline template class at
|
||||
@@ -442,7 +467,7 @@ class like this:
|
||||
static Example create(int a) { return Example(a); }
|
||||
};
|
||||
|
||||
py::classh<Example>(m, "Example")
|
||||
py::class_<Example>(m, "Example")
|
||||
.def(py::init(&Example::create));
|
||||
|
||||
While it is possible to create a straightforward binding of the static
|
||||
@@ -469,7 +494,7 @@ The following example shows the different approaches:
|
||||
Example(std::string);
|
||||
};
|
||||
|
||||
py::classh<Example>(m, "Example")
|
||||
py::class_<Example>(m, "Example")
|
||||
// Bind the factory function as a constructor:
|
||||
.def(py::init(&Example::create))
|
||||
// Bind a lambda function returning a pointer wrapped in a holder:
|
||||
@@ -516,7 +541,7 @@ an alias:
|
||||
using Example::Example;
|
||||
PyExample(Example &&base) : Example(std::move(base)) {}
|
||||
};
|
||||
py::classh<Example, PyExample>(m, "Example")
|
||||
py::class_<Example, PyExample>(m, "Example")
|
||||
// Returns an Example pointer. If a PyExample is needed, the Example
|
||||
// instance will be moved via the extra constructor in PyExample, above.
|
||||
.def(py::init([]() { return new Example(); }))
|
||||
@@ -541,7 +566,7 @@ constructor of the target class. This means that it can be used to bind
|
||||
std::string b;
|
||||
};
|
||||
|
||||
py::classh<Aggregate>(m, "Aggregate")
|
||||
py::class_<Aggregate>(m, "Aggregate")
|
||||
.def(py::init<int, const std::string &>());
|
||||
|
||||
.. note::
|
||||
@@ -558,11 +583,13 @@ Non-public destructors
|
||||
|
||||
If a class has a private or protected destructor (as might e.g. be the case in
|
||||
a singleton pattern), a compile error will occur when creating bindings via
|
||||
pybind11. In order to expose classes with private or protected destructors,
|
||||
it is possible to override the holder type via a holder type argument to
|
||||
``py::class_``. Pybind11 provides a helper class ``py::nodelete`` that disables
|
||||
any destructor invocations. (If the instance is not a singleton, it is
|
||||
crucial that it is deallocated on the C++ side to avoid memory leaks.)
|
||||
pybind11. The underlying issue is that the ``std::unique_ptr`` holder type that
|
||||
is responsible for managing the lifetime of instances will reference the
|
||||
destructor even if no deallocations ever take place. In order to expose classes
|
||||
with private or protected destructors, it is possible to override the holder
|
||||
type via a holder type argument to ``class_``. Pybind11 provides a helper class
|
||||
``py::nodelete`` that disables any destructor invocations. In this case, it is
|
||||
crucial that instances are deallocated on the C++ side to avoid memory leaks.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -629,10 +656,10 @@ could be a fixed and an arbitrary precision number type).
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<A>(m, "A")
|
||||
py::class_<A>(m, "A")
|
||||
/// ... members ...
|
||||
|
||||
py::classh<B>(m, "B")
|
||||
py::class_<B>(m, "B")
|
||||
.def(py::init<A>())
|
||||
/// ... members ...
|
||||
|
||||
@@ -679,7 +706,7 @@ that ignores it:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Foo>(m, "Foo")
|
||||
py::class_<Foo>(m, "Foo")
|
||||
.def_property_readonly_static("foo", [](py::object /* self */) { return Foo(); });
|
||||
|
||||
Operator overloading
|
||||
@@ -719,7 +746,7 @@ to Python.
|
||||
#include <pybind11/operators.h>
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
py::classh<Vector2>(m, "Vector2")
|
||||
py::class_<Vector2>(m, "Vector2")
|
||||
.def(py::init<float, float>())
|
||||
.def(py::self + py::self)
|
||||
.def(py::self += py::self)
|
||||
@@ -791,7 +818,7 @@ to bind these two functions:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pickleable>(m, "Pickleable")
|
||||
py::class_<Pickleable>(m, "Pickleable")
|
||||
.def(py::init<std::string>())
|
||||
.def("value", &Pickleable::value)
|
||||
.def("extra", &Pickleable::extra)
|
||||
@@ -862,7 +889,7 @@ which should look as follows:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Copyable>(m, "Copyable")
|
||||
py::class_<Copyable>(m, "Copyable")
|
||||
.def("__copy__", [](const Copyable &self) {
|
||||
return Copyable(self);
|
||||
})
|
||||
@@ -881,11 +908,11 @@ Multiple Inheritance
|
||||
|
||||
pybind11 can create bindings for types that derive from multiple base types
|
||||
(aka. *multiple inheritance*). To do so, specify all bases in the template
|
||||
arguments of the ``py::classh`` declaration:
|
||||
arguments of the ``class_`` declaration:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<MyType, BaseType1, BaseType2, BaseType3>(m, "MyType")
|
||||
py::class_<MyType, BaseType1, BaseType2, BaseType3>(m, "MyType")
|
||||
...
|
||||
|
||||
The base types can be specified in arbitrary order, and they can even be
|
||||
@@ -905,7 +932,7 @@ inheritance, which can lead to undefined behavior. In such cases, add the tag
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<MyType, BaseType2>(m, "MyType", py::multiple_inheritance());
|
||||
py::class_<MyType, BaseType2>(m, "MyType", py::multiple_inheritance());
|
||||
|
||||
The tag is redundant and does not need to be specified when multiple base types
|
||||
are listed.
|
||||
@@ -923,7 +950,7 @@ example, this allows the following:
|
||||
.. code-block:: cpp
|
||||
|
||||
// In the module1.cpp binding code for module1:
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<std::string>())
|
||||
.def_readonly("name", &Pet::name);
|
||||
|
||||
@@ -956,11 +983,11 @@ because of conflicting definitions on the external type:
|
||||
// dogs.cpp
|
||||
|
||||
// Binding for external library class:
|
||||
py::classh<pets::Pet>(m, "Pet")
|
||||
py::class<pets::Pet>(m, "Pet")
|
||||
.def("name", &pets::Pet::name);
|
||||
|
||||
// Binding for local extension class:
|
||||
py::classh<Dog, pets::Pet>(m, "Dog")
|
||||
py::class<Dog, pets::Pet>(m, "Dog")
|
||||
.def(py::init<std::string>());
|
||||
|
||||
.. code-block:: cpp
|
||||
@@ -968,11 +995,11 @@ because of conflicting definitions on the external type:
|
||||
// cats.cpp, in a completely separate project from the above dogs.cpp.
|
||||
|
||||
// Binding for external library class:
|
||||
py::classh<pets::Pet>(m, "Pet")
|
||||
py::class<pets::Pet>(m, "Pet")
|
||||
.def("get_name", &pets::Pet::name);
|
||||
|
||||
// Binding for local extending class:
|
||||
py::classh<Cat, pets::Pet>(m, "Cat")
|
||||
py::class<Cat, pets::Pet>(m, "Cat")
|
||||
.def(py::init<std::string>());
|
||||
|
||||
.. code-block:: pycon
|
||||
@@ -985,18 +1012,18 @@ because of conflicting definitions on the external type:
|
||||
|
||||
To get around this, you can tell pybind11 to keep the external class binding
|
||||
localized to the module by passing the ``py::module_local()`` attribute into
|
||||
the ``py::classh`` constructor:
|
||||
the ``py::class_`` constructor:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Pet binding in dogs.cpp:
|
||||
py::classh<pets::Pet>(m, "Pet", py::module_local())
|
||||
py::class<pets::Pet>(m, "Pet", py::module_local())
|
||||
.def("name", &pets::Pet::name);
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
// Pet binding in cats.cpp:
|
||||
py::classh<pets::Pet>(m, "Pet", py::module_local())
|
||||
py::class<pets::Pet>(m, "Pet", py::module_local())
|
||||
.def("get_name", &pets::Pet::name);
|
||||
|
||||
This makes the Python-side ``dogs.Pet`` and ``cats.Pet`` into distinct classes,
|
||||
@@ -1071,7 +1098,7 @@ It's normally not possible to expose ``protected`` member functions to Python:
|
||||
int foo() const { return 42; }
|
||||
};
|
||||
|
||||
py::classh<A>(m, "A")
|
||||
py::class_<A>(m, "A")
|
||||
.def("foo", &A::foo); // error: 'foo' is a protected member of 'A'
|
||||
|
||||
On one hand, this is good because non-``public`` members aren't meant to be
|
||||
@@ -1092,7 +1119,7 @@ The following pattern makes this possible:
|
||||
using A::foo; // inherited with different access modifier
|
||||
};
|
||||
|
||||
py::classh<A>(m, "A") // bind the primary class
|
||||
py::class_<A>(m, "A") // bind the primary class
|
||||
.def("foo", &Publicist::foo); // expose protected methods via the publicist
|
||||
|
||||
This works because ``&Publicist::foo`` is exactly the same function as
|
||||
@@ -1124,7 +1151,7 @@ described trampoline:
|
||||
using A::foo;
|
||||
};
|
||||
|
||||
py::classh<A, Trampoline>(m, "A") // <-- `Trampoline` here
|
||||
py::class_<A, Trampoline>(m, "A") // <-- `Trampoline` here
|
||||
.def("foo", &Publicist::foo); // <-- `Publicist` here, not `Trampoline`!
|
||||
|
||||
Binding final classes
|
||||
@@ -1140,7 +1167,7 @@ to be declared final.
|
||||
|
||||
class IsFinal final {};
|
||||
|
||||
py::classh<IsFinal>(m, "IsFinal", py::is_final());
|
||||
py::class_<IsFinal>(m, "IsFinal", py::is_final());
|
||||
|
||||
When you try to inherit from such a class in Python, you will now get this
|
||||
error:
|
||||
@@ -1178,7 +1205,7 @@ wrap instantiated templated classes. You cannot wrap a non-instantiated template
|
||||
.. code-block:: cpp
|
||||
|
||||
// BROKEN (this will not compile)
|
||||
py::classh<Cage>(m, "Cage");
|
||||
py::class_<Cage>(m, "Cage");
|
||||
.def("get", &Cage::get);
|
||||
|
||||
You must explicitly specify each template/type combination that you want to
|
||||
@@ -1187,11 +1214,11 @@ wrap separately.
|
||||
.. code-block:: cpp
|
||||
|
||||
// ok
|
||||
py::classh<Cage<Cat>>(m, "CatCage")
|
||||
py::class_<Cage<Cat>>(m, "CatCage")
|
||||
.def("get", &Cage<Cat>::get);
|
||||
|
||||
// ok
|
||||
py::classh<Cage<Dog>>(m, "DogCage")
|
||||
py::class_<Cage<Dog>>(m, "DogCage")
|
||||
.def("get", &Cage<Dog>::get);
|
||||
|
||||
If your class methods have template parameters you can wrap those as well,
|
||||
@@ -1205,7 +1232,7 @@ but once again each instantiation must be explicitly specified:
|
||||
T fn(V v);
|
||||
};
|
||||
|
||||
py::classh<MyClass<int>>(m, "MyClassT")
|
||||
py::class<MyClass<int>>(m, "MyClassT")
|
||||
.def("fn", &MyClass<int>::fn<std::string>);
|
||||
|
||||
Custom automatic downcasters
|
||||
@@ -1314,7 +1341,7 @@ Custom type setup
|
||||
|
||||
For advanced use cases, such as enabling garbage collection support, you may
|
||||
wish to directly manipulate the ``PyHeapTypeObject`` corresponding to a
|
||||
``py::classh`` definition.
|
||||
``py::class_`` definition.
|
||||
|
||||
You can do that using ``py::custom_type_setup``:
|
||||
|
||||
@@ -1323,7 +1350,7 @@ You can do that using ``py::custom_type_setup``:
|
||||
struct OwnsPythonObjects {
|
||||
py::object value = py::none();
|
||||
};
|
||||
py::classh<OwnsPythonObjects> cls(
|
||||
py::class_<OwnsPythonObjects> cls(
|
||||
m, "OwnsPythonObjects", py::custom_type_setup([](PyHeapTypeObject *heap_type) {
|
||||
auto *type = &heap_type->ht_type;
|
||||
type->tp_flags |= Py_TPFLAGS_HAVE_GC;
|
||||
|
||||
@@ -110,7 +110,7 @@ Return value policies can also be applied to properties:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<MyClass>(m, "MyClass")
|
||||
class_<MyClass>(m, "MyClass")
|
||||
.def_property("data", &MyClass::getData, &MyClass::setData,
|
||||
py::return_value_policy::copy);
|
||||
|
||||
@@ -121,7 +121,7 @@ targeted arguments can be passed through the :class:`cpp_function` constructor:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<MyClass>(m, "MyClass")
|
||||
class_<MyClass>(m, "MyClass")
|
||||
.def_property("data",
|
||||
py::cpp_function(&MyClass::getData, py::return_value_policy::copy),
|
||||
py::cpp_function(&MyClass::setData)
|
||||
@@ -194,7 +194,7 @@ container:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<List>(m, "List")
|
||||
py::class_<List>(m, "List")
|
||||
.def("append", &List::append, py::keep_alive<1, 2>());
|
||||
|
||||
For consistency, the argument indexing is identical for constructors. Index
|
||||
@@ -205,7 +205,7 @@ ties the lifetime of the constructor element to the constructed object:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Nurse>(m, "Nurse")
|
||||
py::class_<Nurse>(m, "Nurse")
|
||||
.def(py::init<Patient &>(), py::keep_alive<1, 2>());
|
||||
|
||||
.. note::
|
||||
@@ -332,11 +332,11 @@ Consider the following example:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<MyClass>("MyClass")
|
||||
py::class_<MyClass>("MyClass")
|
||||
.def("myFunction", py::arg("arg") = SomeType(123));
|
||||
|
||||
In this case, pybind11 must already be set up to deal with values of the type
|
||||
``SomeType`` (via a prior instantiation of ``py::classh<SomeType>``), or an
|
||||
``SomeType`` (via a prior instantiation of ``py::class_<SomeType>``), or an
|
||||
exception will be thrown.
|
||||
|
||||
Another aspect worth highlighting is that the "preview" of the default argument
|
||||
@@ -357,7 +357,7 @@ default argument manually using the ``arg_v`` notation:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<MyClass>("MyClass")
|
||||
py::class_<MyClass>("MyClass")
|
||||
.def("myFunction", py::arg_v("arg", SomeType(123), "SomeType(123)"));
|
||||
|
||||
Sometimes it may be necessary to pass a null pointer value as a default
|
||||
@@ -366,7 +366,7 @@ like so:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<MyClass>("MyClass")
|
||||
py::class_<MyClass>("MyClass")
|
||||
.def("myFunction", py::arg("arg") = static_cast<SomeType *>(nullptr));
|
||||
|
||||
.. _keyword_only_arguments:
|
||||
@@ -489,7 +489,7 @@ name, i.e. by specifying ``py::arg().noconvert()``.
|
||||
Allow/Prohibiting None arguments
|
||||
================================
|
||||
|
||||
When a C++ type registered with :class:`py::classh` is passed as an argument to
|
||||
When a C++ type registered with :class:`py::class_` is passed as an argument to
|
||||
a function taking the instance as pointer or shared holder (e.g. ``shared_ptr``
|
||||
or a custom, copyable holder as described in :ref:`smart_pointers`), pybind
|
||||
allows ``None`` to be passed from Python which results in calling the C++
|
||||
@@ -500,8 +500,8 @@ To explicitly enable or disable this behaviour, using the
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Dog>(m, "Dog").def(py::init<>());
|
||||
py::classh<Cat>(m, "Cat").def(py::init<>());
|
||||
py::class_<Dog>(m, "Dog").def(py::init<>());
|
||||
py::class_<Cat>(m, "Cat").def(py::init<>());
|
||||
m.def("bark", [](Dog *dog) -> std::string {
|
||||
if (dog) return "woof!"; /* Called with a Dog instance */
|
||||
else return "(no dog)"; /* Called with None, dog == nullptr */
|
||||
|
||||
@@ -80,7 +80,7 @@ could be realized as follows (important changes highlighted):
|
||||
.. code-block:: cpp
|
||||
:emphasize-lines: 8,30,31
|
||||
|
||||
class PyAnimal : public Animal, py::trampoline_self_life_support {
|
||||
class PyAnimal : public Animal {
|
||||
public:
|
||||
/* Inherit the constructors */
|
||||
using Animal::Animal;
|
||||
@@ -98,12 +98,12 @@ could be realized as follows (important changes highlighted):
|
||||
};
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
py::classh<Animal, PyAnimal> animal(m, "Animal");
|
||||
py::class_<Animal, PyAnimal> animal(m, "Animal");
|
||||
animal
|
||||
.def(py::init<>())
|
||||
.def("go", &Animal::go);
|
||||
|
||||
py::classh<Dog>(m, "Dog", animal)
|
||||
py::class_<Dog>(m, "Dog", animal)
|
||||
.def(py::init<>());
|
||||
|
||||
m.def("call_go", [](Animal *animal) -> std::string {
|
||||
@@ -177,30 +177,30 @@ from Section :ref:`inheritance`.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet> pet(m, "Pet");
|
||||
py::class_<Pet> pet(m, "Pet");
|
||||
pet.def(py::init<const std::string &>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
py::classh<Dog>(m, "Dog", pet /* <- specify parent */)
|
||||
py::class_<Dog>(m, "Dog", pet /* <- specify parent */)
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
Suppose now that ``Pet`` bindings are defined in a module named ``basic``,
|
||||
whereas the ``Dog`` bindings are defined somewhere else. The challenge is of
|
||||
course that the variable ``pet`` is not available anymore though it is needed
|
||||
to indicate the inheritance relationship to the constructor of
|
||||
``py::classh<Dog>``. However, it can be acquired as follows:
|
||||
to indicate the inheritance relationship to the constructor of ``class_<Dog>``.
|
||||
However, it can be acquired as follows:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::object pet = (py::object) py::module_::import("basic").attr("Pet");
|
||||
|
||||
py::classh<Dog>(m, "Dog", pet)
|
||||
py::class_<Dog>(m, "Dog", pet)
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
Alternatively, you can specify the base class as a template parameter option to
|
||||
``py::classh``, which performs an automated lookup of the corresponding Python
|
||||
``class_``, which performs an automated lookup of the corresponding Python
|
||||
type. Like the above code, however, this also requires invoking the ``import``
|
||||
function once to ensure that the pybind11 binding code of the module ``basic``
|
||||
has been executed:
|
||||
@@ -209,7 +209,7 @@ has been executed:
|
||||
|
||||
py::module_::import("basic");
|
||||
|
||||
py::classh<Dog, Pet>(m, "Dog")
|
||||
py::class_<Dog, Pet>(m, "Dog")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
@@ -382,7 +382,7 @@ Avoiding C++ types in docstrings
|
||||
|
||||
Docstrings are generated at the time of the declaration, e.g. when ``.def(...)`` is called.
|
||||
At this point parameter and return types should be known to pybind11.
|
||||
If a custom type is not exposed yet through a ``py::classh`` constructor or a custom type caster,
|
||||
If a custom type is not exposed yet through a ``py::class_`` constructor or a custom type caster,
|
||||
its C++ type name will be used instead to generate the signature in the docstring:
|
||||
|
||||
.. code-block:: text
|
||||
@@ -399,8 +399,8 @@ before they are used as a parameter or return type of a function:
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
|
||||
auto pyFoo = py::classh<ns::Foo>(m, "Foo");
|
||||
auto pyBar = py::classh<ns::Bar>(m, "Bar");
|
||||
auto pyFoo = py::class_<ns::Foo>(m, "Foo");
|
||||
auto pyBar = py::class_<ns::Bar>(m, "Bar");
|
||||
|
||||
pyFoo.def(py::init<const ns::Bar&>());
|
||||
pyBar.def(py::init<const ns::Foo&>());
|
||||
|
||||
@@ -33,7 +33,7 @@ completely avoid copy operations with Python expressions like
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Matrix>(m, "Matrix", py::buffer_protocol())
|
||||
py::class_<Matrix>(m, "Matrix", py::buffer_protocol())
|
||||
.def_buffer([](Matrix &m) -> py::buffer_info {
|
||||
return py::buffer_info(
|
||||
m.data(), /* Pointer to buffer */
|
||||
@@ -47,7 +47,7 @@ completely avoid copy operations with Python expressions like
|
||||
});
|
||||
|
||||
Supporting the buffer protocol in a new type involves specifying the special
|
||||
``py::buffer_protocol()`` tag in the ``py::classh`` constructor and calling the
|
||||
``py::buffer_protocol()`` tag in the ``py::class_`` constructor and calling the
|
||||
``def_buffer()`` method with a lambda function that creates a
|
||||
``py::buffer_info`` description record on demand describing a given matrix
|
||||
instance. The contents of ``py::buffer_info`` mirror the Python buffer protocol
|
||||
@@ -80,7 +80,7 @@ buffer objects (e.g. a NumPy matrix).
|
||||
typedef Matrix::Scalar Scalar;
|
||||
constexpr bool rowMajor = Matrix::Flags & Eigen::RowMajorBit;
|
||||
|
||||
py::classh<Matrix>(m, "Matrix", py::buffer_protocol())
|
||||
py::class_<Matrix>(m, "Matrix", py::buffer_protocol())
|
||||
.def(py::init([](py::buffer b) {
|
||||
typedef Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic> Strides;
|
||||
|
||||
|
||||
@@ -28,13 +28,13 @@ The binding code for ``Pet`` looks as follows:
|
||||
namespace py = pybind11;
|
||||
|
||||
PYBIND11_MODULE(example, m) {
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("setName", &Pet::setName)
|
||||
.def("getName", &Pet::getName);
|
||||
}
|
||||
|
||||
``py::classh`` creates bindings for a C++ *class* or *struct*-style data
|
||||
:class:`class_` creates bindings for a C++ *class* or *struct*-style data
|
||||
structure. :func:`init` is a convenience function that takes the types of a
|
||||
constructor's parameters as template arguments and wraps the corresponding
|
||||
constructor (see the :ref:`custom_constructors` section for details).
|
||||
@@ -98,7 +98,7 @@ Lambda function instead:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("setName", &Pet::setName)
|
||||
.def("getName", &Pet::getName)
|
||||
@@ -129,7 +129,7 @@ method also exists for ``const`` fields.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def_readwrite("name", &Pet::name)
|
||||
// ... remainder ...
|
||||
@@ -166,7 +166,7 @@ the setter and getter functions:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def_property("name", &Pet::getName, &Pet::setName)
|
||||
// ... remainder ...
|
||||
@@ -202,7 +202,7 @@ or :func:`class_::def_property`.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
@@ -220,7 +220,7 @@ must be added to the :class:`py::class_` constructor:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet>(m, "Pet", py::dynamic_attr())
|
||||
py::class_<Pet>(m, "Pet", py::dynamic_attr())
|
||||
.def(py::init<>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
@@ -268,12 +268,12 @@ parameter of the :class:`class_`:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
// Method 1: template parameter:
|
||||
py::classh<Dog, Pet /* <- specify C++ parent type */>(m, "Dog")
|
||||
py::class_<Dog, Pet /* <- specify C++ parent type */>(m, "Dog")
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
@@ -282,12 +282,12 @@ Alternatively, we can also assign a name to the previously bound ``Pet``
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet> pet(m, "Pet");
|
||||
py::class_<Pet> pet(m, "Pet");
|
||||
pet.def(py::init<const std::string &>())
|
||||
.def_readwrite("name", &Pet::name);
|
||||
|
||||
// Method 2: pass parent py::classh object:
|
||||
py::classh<Dog>(m, "Dog", pet /* <- specify Python parent type */)
|
||||
// Method 2: pass parent class_ object:
|
||||
py::class_<Dog>(m, "Dog", pet /* <- specify Python parent type */)
|
||||
.def(py::init<const std::string &>())
|
||||
.def("bark", &Dog::bark);
|
||||
|
||||
@@ -334,8 +334,8 @@ will automatically recognize this:
|
||||
};
|
||||
|
||||
// Same binding code
|
||||
py::classh<PolymorphicPet>(m, "PolymorphicPet");
|
||||
py::classh<PolymorphicDog, PolymorphicPet>(m, "PolymorphicDog")
|
||||
py::class_<PolymorphicPet>(m, "PolymorphicPet");
|
||||
py::class_<PolymorphicDog, PolymorphicPet>(m, "PolymorphicDog")
|
||||
.def(py::init<>())
|
||||
.def("bark", &PolymorphicDog::bark);
|
||||
|
||||
@@ -387,7 +387,7 @@ sequence.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def(py::init<const std::string &, int>())
|
||||
.def("set", static_cast<void (Pet::*)(int)>(&Pet::set), "Set the pet's age")
|
||||
.def("set", static_cast<void (Pet::*)(const std::string &)>(&Pet::set), "Set the pet's name");
|
||||
@@ -418,7 +418,7 @@ syntax to cast the overloaded function:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def("set", py::overload_cast<int>(&Pet::set), "Set the pet's age")
|
||||
.def("set", py::overload_cast<const std::string &>(&Pet::set), "Set the pet's name");
|
||||
|
||||
@@ -434,7 +434,7 @@ on constness, the ``py::const_`` tag should be used:
|
||||
int foo(int x, float y) const;
|
||||
};
|
||||
|
||||
py::classh<Widget>(m, "Widget")
|
||||
py::class_<Widget>(m, "Widget")
|
||||
.def("foo_mutable", py::overload_cast<int, float>(&Widget::foo))
|
||||
.def("foo_const", py::overload_cast<int, float>(&Widget::foo, py::const_));
|
||||
|
||||
@@ -446,7 +446,7 @@ you can use ``py::detail::overload_cast_impl`` with an additional set of parenth
|
||||
template <typename... Args>
|
||||
using overload_cast_ = pybind11::detail::overload_cast_impl<Args...>;
|
||||
|
||||
py::classh<Pet>(m, "Pet")
|
||||
py::class_<Pet>(m, "Pet")
|
||||
.def("set", overload_cast_<int>()(&Pet::set), "Set the pet's age")
|
||||
.def("set", overload_cast_<const std::string &>()(&Pet::set), "Set the pet's name");
|
||||
|
||||
@@ -486,7 +486,7 @@ The binding code for this example looks as follows:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
py::classh<Pet> pet(m, "Pet");
|
||||
py::class_<Pet> pet(m, "Pet");
|
||||
|
||||
pet.def(py::init<const std::string &, Pet::Kind>())
|
||||
.def_readwrite("name", &Pet::name)
|
||||
@@ -498,7 +498,7 @@ The binding code for this example looks as follows:
|
||||
.value("Cat", Pet::Kind::Cat)
|
||||
.export_values();
|
||||
|
||||
py::classh<Pet::Attributes>(pet, "Attributes")
|
||||
py::class_<Pet::Attributes>(pet, "Attributes")
|
||||
.def(py::init<>())
|
||||
.def_readwrite("age", &Pet::Attributes::age);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user