Revert "Systematically change most py::class_ to py::classh under docs/"

This reverts commit ac9d31e13f.
This commit is contained in:
Henry Schreiner
2025-02-28 16:55:37 -05:00
parent ff7c087321
commit 1e646c91b4
8 changed files with 141 additions and 114 deletions

View File

@@ -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());

View File

@@ -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

View File

@@ -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)

View File

@@ -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;

View File

@@ -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 */

View File

@@ -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&>());

View File

@@ -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;

View File

@@ -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);