mirror of
https://github.com/pybind/pybind11.git
synced 2026-04-20 06:49:25 +00:00
Resolve empty statement warning when using PYBIND11_OVERLOAD_PURE_NAME and PYBIND11_OVERLOAD_PURE (#2325)
* Wrap PYBIND11_OVERLOAD_NAME and PYBIND11_OVERLOAD_PURE_NAME in do { ... } while (false), and resolve trailing semicolon
* Deprecate PYBIND11_OVERLOAD_* and get_overload in favor of PYBIND11_OVERRIDE_* and get_override
* Correct erroneous usage of 'overload' instead of 'override' in the implementation and internals
* Fix tests to use non-deprecated PYBIND11_OVERRIDE_* macros
* Update docs to use override instead of overload where appropriate, and add warning about deprecated aliases
* Add semicolons to deprecated PYBIND11_OVERLOAD macros to match original behavior
* Remove deprecation of PYBIND11_OVERLOAD_* macros and get_overload
* Add note to changelog and upgrade guide
This commit is contained in:
@@ -29,9 +29,9 @@ The following Python snippet demonstrates the intended usage from the Python sid
|
||||
from example import print
|
||||
print(A())
|
||||
|
||||
To register the necessary conversion routines, it is necessary to add
|
||||
a partial overload to the ``pybind11::detail::type_caster<T>`` template.
|
||||
Although this is an implementation detail, adding partial overloads to this
|
||||
To register the necessary conversion routines, it is necessary to add an
|
||||
instantiation of the ``pybind11::detail::type_caster<T>`` template.
|
||||
Although this is an implementation detail, adding an instantiation of this
|
||||
type is explicitly allowed.
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
@@ -157,7 +157,7 @@ the declaration
|
||||
|
||||
before any binding code (e.g. invocations to ``class_::def()``, etc.). This
|
||||
macro must be specified at the top level (and outside of any namespaces), since
|
||||
it instantiates a partial template overload. If your binding code consists of
|
||||
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 ``class_`` declaration to associate them with a name
|
||||
|
||||
@@ -71,7 +71,7 @@ helper class that is defined as follows:
|
||||
|
||||
/* Trampoline (need one for each virtual function) */
|
||||
std::string go(int n_times) override {
|
||||
PYBIND11_OVERLOAD_PURE(
|
||||
PYBIND11_OVERRIDE_PURE(
|
||||
std::string, /* Return type */
|
||||
Animal, /* Parent class */
|
||||
go, /* Name of function in C++ (must match Python name) */
|
||||
@@ -80,10 +80,10 @@ helper class that is defined as follows:
|
||||
}
|
||||
};
|
||||
|
||||
The macro :c:macro:`PYBIND11_OVERLOAD_PURE` should be used for pure virtual
|
||||
functions, and :c:macro:`PYBIND11_OVERLOAD` should be used for functions which have
|
||||
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
|
||||
a default implementation. There are also two alternate macros
|
||||
:c:macro:`PYBIND11_OVERLOAD_PURE_NAME` and :c:macro:`PYBIND11_OVERLOAD_NAME` which
|
||||
:c:macro:`PYBIND11_OVERRIDE_PURE_NAME` and :c:macro:`PYBIND11_OVERRIDE_NAME` which
|
||||
take a string-valued name argument between the *Parent class* and *Name of the
|
||||
function* slots, which defines the name of function in Python. This is required
|
||||
when the C++ and Python versions of the
|
||||
@@ -122,7 +122,7 @@ Bindings should be made against the actual class, not the trampoline helper clas
|
||||
|
||||
Note, however, that the above is sufficient for allowing python classes to
|
||||
extend ``Animal``, but not ``Dog``: see :ref:`virtual_and_inheritance` for the
|
||||
necessary steps required to providing proper overload support for inherited
|
||||
necessary steps required to providing proper overriding support for inherited
|
||||
classes.
|
||||
|
||||
The Python session below shows how to override ``Animal::go`` and invoke it via
|
||||
@@ -181,15 +181,24 @@ Please take a look at the :ref:`macro_notes` before using this feature.
|
||||
|
||||
- because in these cases there is no C++ variable to reference (the value
|
||||
is stored in the referenced Python variable), pybind11 provides one in
|
||||
the PYBIND11_OVERLOAD macros (when needed) with static storage duration.
|
||||
Note that this means that invoking the overloaded method on *any*
|
||||
the PYBIND11_OVERRIDE macros (when needed) with static storage duration.
|
||||
Note that this means that invoking the overridden method on *any*
|
||||
instance will change the referenced value stored in *all* instances of
|
||||
that type.
|
||||
|
||||
- Attempts to modify a non-const reference will not have the desired
|
||||
effect: it will change only the static cache variable, but this change
|
||||
will not propagate to underlying Python instance, and the change will be
|
||||
replaced the next time the overload is invoked.
|
||||
replaced the next time the override is invoked.
|
||||
|
||||
.. warning::
|
||||
|
||||
The :c:macro:`PYBIND11_OVERRIDE` and accompanying macros used to be called
|
||||
``PYBIND11_OVERLOAD`` up until pybind11 v2.5.0, and :func:`get_override`
|
||||
used to be called ``get_overload``. This naming was corrected and the older
|
||||
macro and function names have been deprecated, in order to reduce confusion
|
||||
with overloaded functions and methods and ``py::overload_cast`` (see
|
||||
:ref:`classes`).
|
||||
|
||||
.. seealso::
|
||||
|
||||
@@ -237,20 +246,20 @@ override the ``name()`` method):
|
||||
class PyAnimal : public Animal {
|
||||
public:
|
||||
using Animal::Animal; // Inherit constructors
|
||||
std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, Animal, go, n_times); }
|
||||
std::string name() override { PYBIND11_OVERLOAD(std::string, Animal, name, ); }
|
||||
std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, Animal, go, n_times); }
|
||||
std::string name() override { PYBIND11_OVERRIDE(std::string, Animal, name, ); }
|
||||
};
|
||||
class PyDog : public Dog {
|
||||
public:
|
||||
using Dog::Dog; // Inherit constructors
|
||||
std::string go(int n_times) override { PYBIND11_OVERLOAD(std::string, Dog, go, n_times); }
|
||||
std::string name() override { PYBIND11_OVERLOAD(std::string, Dog, name, ); }
|
||||
std::string bark() override { PYBIND11_OVERLOAD(std::string, Dog, bark, ); }
|
||||
std::string go(int n_times) override { PYBIND11_OVERRIDE(std::string, Dog, go, n_times); }
|
||||
std::string name() override { PYBIND11_OVERRIDE(std::string, Dog, name, ); }
|
||||
std::string bark() override { PYBIND11_OVERRIDE(std::string, Dog, bark, ); }
|
||||
};
|
||||
|
||||
.. note::
|
||||
|
||||
Note the trailing commas in the ``PYBIND11_OVERLOAD`` calls to ``name()``
|
||||
Note the trailing commas in the ``PYBIND11_OVERIDE`` calls to ``name()``
|
||||
and ``bark()``. These are needed to portably implement a trampoline for a
|
||||
function that does not take any arguments. For functions that take
|
||||
a nonzero number of arguments, the trailing comma must be omitted.
|
||||
@@ -265,9 +274,9 @@ declare or override any virtual methods itself:
|
||||
class PyHusky : public Husky {
|
||||
public:
|
||||
using Husky::Husky; // Inherit constructors
|
||||
std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, Husky, go, n_times); }
|
||||
std::string name() override { PYBIND11_OVERLOAD(std::string, Husky, name, ); }
|
||||
std::string bark() override { PYBIND11_OVERLOAD(std::string, Husky, bark, ); }
|
||||
std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, Husky, go, n_times); }
|
||||
std::string name() override { PYBIND11_OVERRIDE(std::string, Husky, name, ); }
|
||||
std::string bark() override { PYBIND11_OVERRIDE(std::string, Husky, bark, ); }
|
||||
};
|
||||
|
||||
There is, however, a technique that can be used to avoid this duplication
|
||||
@@ -280,15 +289,15 @@ follows:
|
||||
template <class AnimalBase = Animal> class PyAnimal : public AnimalBase {
|
||||
public:
|
||||
using AnimalBase::AnimalBase; // Inherit constructors
|
||||
std::string go(int n_times) override { PYBIND11_OVERLOAD_PURE(std::string, AnimalBase, go, n_times); }
|
||||
std::string name() override { PYBIND11_OVERLOAD(std::string, AnimalBase, name, ); }
|
||||
std::string go(int n_times) override { PYBIND11_OVERRIDE_PURE(std::string, AnimalBase, go, n_times); }
|
||||
std::string name() override { PYBIND11_OVERRIDE(std::string, AnimalBase, name, ); }
|
||||
};
|
||||
template <class DogBase = Dog> class PyDog : public PyAnimal<DogBase> {
|
||||
public:
|
||||
using PyAnimal<DogBase>::PyAnimal; // Inherit constructors
|
||||
// Override PyAnimal's pure virtual go() with a non-pure one:
|
||||
std::string go(int n_times) override { PYBIND11_OVERLOAD(std::string, DogBase, go, n_times); }
|
||||
std::string bark() override { PYBIND11_OVERLOAD(std::string, DogBase, bark, ); }
|
||||
std::string go(int n_times) override { PYBIND11_OVERRIDE(std::string, DogBase, go, n_times); }
|
||||
std::string bark() override { PYBIND11_OVERRIDE(std::string, DogBase, bark, ); }
|
||||
};
|
||||
|
||||
This technique has the advantage of requiring just one trampoline method to be
|
||||
@@ -341,7 +350,7 @@ valid for the trampoline class but not the registered class. This is primarily
|
||||
for performance reasons: when the trampoline class is not needed for anything
|
||||
except virtual method dispatching, not initializing the trampoline class
|
||||
improves performance by avoiding needing to do a run-time check to see if the
|
||||
inheriting python instance has an overloaded method.
|
||||
inheriting python instance has an overridden method.
|
||||
|
||||
Sometimes, however, it is useful to always initialize a trampoline class as an
|
||||
intermediate class that does more than just handle virtual method dispatching.
|
||||
@@ -372,7 +381,7 @@ references (See also :ref:`faq_reference_arguments`). Another way of solving
|
||||
this is to use the method body of the trampoline class to do conversions to the
|
||||
input and return of the Python method.
|
||||
|
||||
The main building block to do so is the :func:`get_overload`, this function
|
||||
The main building block to do so is the :func:`get_override`, this function
|
||||
allows retrieving a method implemented in Python from within the trampoline's
|
||||
methods. Consider for example a C++ method which has the signature
|
||||
``bool myMethod(int32_t& value)``, where the return indicates whether
|
||||
@@ -384,10 +393,10 @@ Python side by allowing the Python function to return ``None`` or an ``int``:
|
||||
bool MyClass::myMethod(int32_t& value)
|
||||
{
|
||||
pybind11::gil_scoped_acquire gil; // Acquire the GIL while in this scope.
|
||||
// Try to look up the overloaded method on the Python side.
|
||||
pybind11::function overload = pybind11::get_overload(this, "myMethod");
|
||||
if (overload) { // method is found
|
||||
auto obj = overload(value); // Call the Python function.
|
||||
// Try to look up the overridden method on the Python side.
|
||||
pybind11::function override = pybind11::get_override(this, "myMethod");
|
||||
if (override) { // method is found
|
||||
auto obj = override(value); // Call the Python function.
|
||||
if (py::isinstance<py::int_>(obj)) { // check if it returned a Python integer type
|
||||
value = obj.cast<int32_t>(); // Cast it and assign it to the value.
|
||||
return true; // Return true; value should be used.
|
||||
@@ -1104,7 +1113,7 @@ described trampoline:
|
||||
|
||||
class Trampoline : public A {
|
||||
public:
|
||||
int foo() const override { PYBIND11_OVERLOAD(int, A, foo, ); }
|
||||
int foo() const override { PYBIND11_OVERRIDE(int, A, foo, ); }
|
||||
};
|
||||
|
||||
class Publicist : public A {
|
||||
|
||||
@@ -7,14 +7,14 @@ General notes regarding convenience macros
|
||||
==========================================
|
||||
|
||||
pybind11 provides a few convenience macros such as
|
||||
:func:`PYBIND11_DECLARE_HOLDER_TYPE` and ``PYBIND11_OVERLOAD_*``. Since these
|
||||
:func:`PYBIND11_DECLARE_HOLDER_TYPE` and ``PYBIND11_OVERRIDE_*``. Since these
|
||||
are "just" macros that are evaluated in the preprocessor (which has no concept
|
||||
of types), they *will* get confused by commas in a template argument; for
|
||||
example, consider:
|
||||
|
||||
.. code-block:: cpp
|
||||
|
||||
PYBIND11_OVERLOAD(MyReturnType<T1, T2>, Class<T3, T4>, func)
|
||||
PYBIND11_OVERRIDE(MyReturnType<T1, T2>, Class<T3, T4>, func)
|
||||
|
||||
The limitation of the C preprocessor interprets this as five arguments (with new
|
||||
arguments beginning after each comma) rather than three. To get around this,
|
||||
@@ -26,10 +26,10 @@ using the ``PYBIND11_TYPE`` macro:
|
||||
// Version 1: using a type alias
|
||||
using ReturnType = MyReturnType<T1, T2>;
|
||||
using ClassType = Class<T3, T4>;
|
||||
PYBIND11_OVERLOAD(ReturnType, ClassType, func);
|
||||
PYBIND11_OVERRIDE(ReturnType, ClassType, func);
|
||||
|
||||
// Version 2: using the PYBIND11_TYPE macro:
|
||||
PYBIND11_OVERLOAD(PYBIND11_TYPE(MyReturnType<T1, T2>),
|
||||
PYBIND11_OVERRIDE(PYBIND11_TYPE(MyReturnType<T1, T2>),
|
||||
PYBIND11_TYPE(Class<T3, T4>), func)
|
||||
|
||||
The ``PYBIND11_MAKE_OPAQUE`` macro does *not* require the above workarounds.
|
||||
@@ -59,7 +59,7 @@ could be realized as follows (important changes highlighted):
|
||||
/* Acquire GIL before calling Python code */
|
||||
py::gil_scoped_acquire acquire;
|
||||
|
||||
PYBIND11_OVERLOAD_PURE(
|
||||
PYBIND11_OVERRIDE_PURE(
|
||||
std::string, /* Return type */
|
||||
Animal, /* Parent class */
|
||||
go, /* Name of function */
|
||||
|
||||
Reference in New Issue
Block a user