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
diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h
index 602d579..866a62d 100644
--- a/include/pybind11/pybind11.h
+++ b/include/pybind11/pybind11.h
@@ -2110,21 +2110,22 @@
}
}
-inline function get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) {
- handle self = detail::get_object_handle(this_ptr, this_type);
+PYBIND11_NAMESPACE_BEGIN(detail)
+inline function get_type_override(const void *this_ptr, const type_info *this_type, const char *name) {
+ handle self = get_object_handle(this_ptr, this_type);
if (!self)
return function();
handle type = self.get_type();
auto key = std::make_pair(type.ptr(), name);
- /* Cache functions that aren't overloaded in Python to avoid
+ /* Cache functions that aren't overridden in Python to avoid
many costly Python dictionary lookups below */
- auto &cache = detail::get_internals().inactive_overload_cache;
+ auto &cache = get_internals().inactive_override_cache;
if (cache.find(key) != cache.end())
return function();
- function overload = getattr(self, name, function());
- if (overload.is_cpp_function()) {
+ function override = getattr(self, name, function());
+ if (override.is_cpp_function()) {
cache.insert(key);
return function();
}
@@ -2164,34 +2165,36 @@
Py_DECREF(result);
#endif
- return overload;
+ return override;
}
+PYBIND11_NAMESPACE_END(detail)
/** \rst
Try to retrieve a python method by the provided name from the instance pointed to by the this_ptr.
- :this_ptr: The pointer to the object the overload should be retrieved for. This should be the first
- non-trampoline class encountered in the inheritance chain.
- :name: The name of the overloaded Python method to retrieve.
+ :this_ptr: The pointer to the object the overriden method should be retrieved for. This should be
+ the first non-trampoline class encountered in the inheritance chain.
+ :name: The name of the overridden Python method to retrieve.
:return: The Python method by this name from the object or an empty function wrapper.
\endrst */
-template <class T> function get_overload(const T *this_ptr, const char *name) {
+template <class T> function get_override(const T *this_ptr, const char *name) {
auto tinfo = detail::get_type_info(typeid(T));
- return tinfo ? get_type_overload(this_ptr, tinfo, name) : function();
+ return tinfo ? detail::get_type_override(this_ptr, tinfo, name) : function();
}
-#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...) { \
+#define PYBIND11_OVERRIDE_IMPL(ret_type, cname, name, ...) \
+ do { \
pybind11::gil_scoped_acquire gil; \
- pybind11::function overload = pybind11::get_overload(static_cast<const cname *>(this), name); \
- if (overload) { \
- auto o = overload(__VA_ARGS__); \
+ pybind11::function override = pybind11::get_override(static_cast<const cname *>(this), name); \
+ if (override) { \
+ auto o = override(__VA_ARGS__); \
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) { \
- static pybind11::detail::overload_caster_t<ret_type> caster; \
+ static pybind11::detail::override_caster_t<ret_type> caster; \
return pybind11::detail::cast_ref<ret_type>(std::move(o), caster); \
} \
else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
} \
- }
+ } while (false)
/** \rst
Macro to populate the virtual method in the trampoline class. This macro tries to look up a method named 'fn'
@@ -2202,7 +2205,7 @@
.. code-block:: cpp
std::string toString() override {
- PYBIND11_OVERLOAD_NAME(
+ PYBIND11_OVERRIDE_NAME(
std::string, // Return type (ret_type)
Animal, // Parent class (cname)
"__str__", // Name of method in Python (name)
@@ -2210,17 +2213,21 @@
);
}
\endrst */
-#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \
- PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
- return cname::fn(__VA_ARGS__)
+#define PYBIND11_OVERRIDE_NAME(ret_type, cname, name, fn, ...) \
+ do { \
+ PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \
+ return cname::fn(__VA_ARGS__); \
+ } while (false)
/** \rst
- Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERLOAD_NAME`, except that it
- throws if no overload can be found.
+ Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE_NAME`, except that it
+ throws if no override can be found.
\endrst */
-#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \
- PYBIND11_OVERLOAD_INT(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__) \
- pybind11::pybind11_fail("Tried to call pure virtual function \"" PYBIND11_STRINGIFY(cname) "::" name "\"");
+#define PYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...) \
+ do { \
+ PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__); \
+ pybind11::pybind11_fail("Tried to call pure virtual function \"" PYBIND11_STRINGIFY(cname) "::" name "\""); \
+ } while (false)
/** \rst
Macro to populate the virtual method in the trampoline class. This macro tries to look up the method
@@ -2237,7 +2244,7 @@
// Trampoline (need one for each virtual function)
std::string go(int n_times) override {
- PYBIND11_OVERLOAD_PURE(
+ PYBIND11_OVERRIDE_PURE(
std::string, // Return type (ret_type)
Animal, // Parent class (cname)
go, // Name of function in C++ (must match Python name) (fn)
@@ -2246,15 +2253,39 @@
}
};
\endrst */
-#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \
- PYBIND11_OVERLOAD_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
+#define PYBIND11_OVERRIDE(ret_type, cname, fn, ...) \
+ PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
/** \rst
- Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERLOAD`, except that it throws
- if no overload can be found.
+ Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`, except that it throws
+ if no override can be found.
\endrst */
+#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...) \
+ PYBIND11_OVERRIDE_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
+
+
+// Deprecated versions
+
+PYBIND11_DEPRECATED("get_type_overload has been deprecated")
+inline function get_type_overload(const void *this_ptr, const detail::type_info *this_type, const char *name) {
+ return detail::get_type_override(this_ptr, this_type, name);
+}
+
+template <class T>
+inline function get_overload(const T *this_ptr, const char *name) {
+ return get_override(this_ptr, name);
+}
+
+#define PYBIND11_OVERLOAD_INT(ret_type, cname, name, ...) \
+ PYBIND11_OVERRIDE_IMPL(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, __VA_ARGS__)
+#define PYBIND11_OVERLOAD_NAME(ret_type, cname, name, fn, ...) \
+ PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__)
+#define PYBIND11_OVERLOAD_PURE_NAME(ret_type, cname, name, fn, ...) \
+ PYBIND11_OVERRIDE_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), name, fn, __VA_ARGS__);
+#define PYBIND11_OVERLOAD(ret_type, cname, fn, ...) \
+ PYBIND11_OVERRIDE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__)
#define PYBIND11_OVERLOAD_PURE(ret_type, cname, fn, ...) \
- PYBIND11_OVERLOAD_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
+ PYBIND11_OVERRIDE_PURE(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), fn, __VA_ARGS__);
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)