Inheritance¶
Configuration for classes that inherit from one another, whether within a single module or across module and package boundaries.
exclude_inherited_overrides¶
Normally, cppwg emits a .def binding for every class method, even if it merely
overrides a virtual method already wrapped on a base class. This is redundant:
pybind11 inheritance and C++ virtual dispatch already expose the override to
Python through the base class’s binding.
Set exclude_inherited_overrides: True to remove these extra .def bindings.
This can shrink the size of wrappers in large projects. The virtual
trampoline
is still generated, so Python subclasses can still override the
method.
exclude_inherited_overrides: True # package level: applies to all classes
modules:
- name: primitives
classes:
- name: Shape # declares virtual GetArea()
- name: Rectangle # overrides GetArea()
With the configuration above, Rectangle’s wrapper omits the redundant binding:
py::class_<Rectangle, Shape>(m, "Rectangle")
.def(py::init<>())
// .def("GetArea", ...) is not emitted; Shape's binding already exposes it
;
Note
An override is only skipped when a wrapped base declares a matching virtual (same
name, argument types, and const-ness). It is kept when another overload of the
same name would otherwise be shadowed. It is also kept when the base class is in
a module not listed in imports or when it has been excluded from the base.
imports¶
A wrapped class can inherit from a base class registered in a different
module, as long as that module is imported first. Use imports to list the
modules to import at the start of the generated module.
cppwg only emits an external base when it can confirm the base is registered.
This avoids a py::class_<...> with an unregistered base, which would fail
further downstream during Python import.
Base wrapped in another module of the same package
These are detected automatically when the relevant module is added to imports:
modules:
- name: primitives # defines the base class, e.g. Rectangle
- name: composites
imports:
- pyshapes.primitives._pyshapes_primitives
classes:
- name: Square # inherits Rectangle, wrapped in `primitives`
Caution
Listing a module in its own imports will cause a circular import.
Base wrapped in another package
Add the relevant module to imports as above, and also list the base class name
under external_bases so cppwg knows it is registered by an imported module:
modules:
- name: all
imports:
- ext_pkg._ext_mod
external_bases:
- AbstractFoo # MyFoo inherits AbstractFoo, wrapped in ext_pkg
classes:
- name: MyFoo
Note
Names in external_bases match without template arguments, and with or without
namespace qualification.
See also
See the pybind11 docs on partitioning code over multiple extension modules.
See Reference for a list of all configuration options.