Final manual curation in preparation for global `clang-format`ing (#3712)

* Manual line breaks to pre-empt undesired `clang-format`ing.

Informed by work under https://github.com/pybind/pybind11/pull/3683:

60b7eb410f

59572e6559

* Manual curation of clang-format diffs involving source code comments.

Very labor-intensive and dull.

* Pulling .clang-format change from @henryiii's 9057962d40

* Adding commonly used .clang-format `CommentPragmas:`

* Ensure short lambdas are allowed

Co-authored-by: Aaron Gokaslan <skylion.aaron@gmail.com>
This commit is contained in:
Ralf W. Grosse-Kunstleve 2022-02-10 11:42:03 -08:00 committed by GitHub
parent d6c66d25bb
commit e96221beff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 167 additions and 94 deletions

View File

@ -3,17 +3,36 @@
# clang-format --style=llvm --dump-config # clang-format --style=llvm --dump-config
BasedOnStyle: LLVM BasedOnStyle: LLVM
AccessModifierOffset: -4 AccessModifierOffset: -4
AllowShortLambdasOnASingleLine: true
AlwaysBreakTemplateDeclarations: Yes AlwaysBreakTemplateDeclarations: Yes
BinPackArguments: false BinPackArguments: false
BinPackParameters: false BinPackParameters: false
BreakBeforeBinaryOperators: All BreakBeforeBinaryOperators: All
BreakConstructorInitializers: BeforeColon BreakConstructorInitializers: BeforeColon
ColumnLimit: 99 ColumnLimit: 99
CommentPragmas: 'NOLINT:.*|^ IWYU pragma:'
IncludeBlocks: Regroup
IndentCaseLabels: true IndentCaseLabels: true
IndentPPDirectives: AfterHash IndentPPDirectives: AfterHash
IndentWidth: 4 IndentWidth: 4
Language: Cpp Language: Cpp
SpaceAfterCStyleCast: true SpaceAfterCStyleCast: true
Standard: Cpp11 Standard: Cpp11
StatementMacros: ['PyObject_HEAD']
TabWidth: 4 TabWidth: 4
IncludeCategories:
- Regex: '<pybind11/.*'
Priority: -1
- Regex: 'pybind11.h"$'
Priority: 1
- Regex: '^".*/?detail/'
Priority: 1
SortPriority: 2
- Regex: '^"'
Priority: 1
SortPriority: 3
- Regex: '<[[:alnum:]._]+>'
Priority: 4
- Regex: '.*'
Priority: 5
... ...

View File

@ -44,10 +44,12 @@ struct buffer_info {
void *ptr = nullptr; // Pointer to the underlying storage void *ptr = nullptr; // Pointer to the underlying storage
ssize_t itemsize = 0; // Size of individual items in bytes ssize_t itemsize = 0; // Size of individual items in bytes
ssize_t size = 0; // Total number of entries ssize_t size = 0; // Total number of entries
std::string format; // For homogeneous buffers, this should be set to format_descriptor<T>::format() std::string format; // For homogeneous buffers, this should be set to
// format_descriptor<T>::format()
ssize_t ndim = 0; // Number of dimensions ssize_t ndim = 0; // Number of dimensions
std::vector<ssize_t> shape; // Shape of the tensor (1 entry per dimension) std::vector<ssize_t> shape; // Shape of the tensor (1 entry per dimension)
std::vector<ssize_t> strides; // Number of bytes between adjacent entries (for each per dimension) std::vector<ssize_t> strides; // Number of bytes between adjacent entries
// (for each per dimension)
bool readonly = false; // flag to indicate if the underlying storage may be written to bool readonly = false; // flag to indicate if the underlying storage may be written to
buffer_info() = default; buffer_info() = default;

View File

@ -996,7 +996,9 @@ PYBIND11_NAMESPACE_BEGIN(detail)
template <typename T, enable_if_t<!is_pyobject<T>::value, int>> template <typename T, enable_if_t<!is_pyobject<T>::value, int>>
object object_or_cast(T &&o) { return pybind11::cast(std::forward<T>(o)); } object object_or_cast(T &&o) { return pybind11::cast(std::forward<T>(o)); }
struct override_unused {}; // Placeholder type for the unneeded (and dead code) static variable in the PYBIND11_OVERRIDE_OVERRIDE macro // Placeholder type for the unneeded (and dead code) static variable in the
// PYBIND11_OVERRIDE_OVERRIDE macro
struct override_unused {};
template <typename ret_type> using override_caster_t = conditional_t< template <typename ret_type> using override_caster_t = conditional_t<
cast_is_temporary_value_reference<ret_type>::value, make_caster<ret_type>, override_unused>; cast_is_temporary_value_reference<ret_type>::value, make_caster<ret_type>, override_unused>;
@ -1463,7 +1465,8 @@ handle type::handle_of() {
}} }}
/// Lets you pass a type containing a `,` through a macro parameter without needing a separate /// Lets you pass a type containing a `,` through a macro parameter without needing a separate
/// typedef, e.g.: `PYBIND11_OVERRIDE(PYBIND11_TYPE(ReturnType<A, B>), PYBIND11_TYPE(Parent<C, D>), f, arg)` /// typedef, e.g.:
/// `PYBIND11_OVERRIDE(PYBIND11_TYPE(ReturnType<A, B>), PYBIND11_TYPE(Parent<C, D>), f, arg)`
#define PYBIND11_TYPE(...) __VA_ARGS__ #define PYBIND11_TYPE(...) __VA_ARGS__
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)

View File

@ -38,7 +38,8 @@ public:
using rep = typename type::rep; using rep = typename type::rep;
using period = typename type::period; using period = typename type::period;
using days = std::chrono::duration<int_least32_t, std::ratio<86400>>; // signed 25 bits required by the standard. // signed 25 bits required by the standard.
using days = std::chrono::duration<int_least32_t, std::ratio<86400>>;
bool load(handle src, bool) { bool load(handle src, bool) {
using namespace std::chrono; using namespace std::chrono;

View File

@ -42,8 +42,9 @@
# endif # endif
# endif # endif
#elif defined(_MSC_VER) && __cplusplus == 199711L #elif defined(_MSC_VER) && __cplusplus == 199711L
// MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully implemented) // MSVC sets _MSVC_LANG rather than __cplusplus (supposedly until the standard is fully
// Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3 or newer // implemented). Unless you use the /Zc:__cplusplus flag on Visual Studio 2017 15.7 Preview 3
// or newer.
# if _MSVC_LANG >= 201402L # if _MSVC_LANG >= 201402L
# define PYBIND11_CPP14 # define PYBIND11_CPP14
# if _MSVC_LANG > 201402L && _MSC_VER >= 1910 # if _MSVC_LANG > 201402L && _MSC_VER >= 1910
@ -722,8 +723,8 @@ template <typename T, typename... Ts>
constexpr int last(int i, int result, T v, Ts... vs) { return last(i + 1, v ? i : result, vs...); } constexpr int last(int i, int result, T v, Ts... vs) { return last(i + 1, v ? i : result, vs...); }
PYBIND11_NAMESPACE_END(constexpr_impl) PYBIND11_NAMESPACE_END(constexpr_impl)
/// Return the index of the first type in Ts which satisfies Predicate<T>. Returns sizeof...(Ts) if /// Return the index of the first type in Ts which satisfies Predicate<T>.
/// none match. /// Returns sizeof...(Ts) if none match.
template <template<typename> class Predicate, typename... Ts> template <template<typename> class Predicate, typename... Ts>
constexpr int constexpr_first() { return constexpr_impl::first(0, Predicate<Ts>::value...); } constexpr int constexpr_first() { return constexpr_impl::first(0, Predicate<Ts>::value...); }
@ -842,7 +843,9 @@ PYBIND11_NAMESPACE_END(detail)
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(push) # pragma warning(push)
# pragma warning(disable: 4275) // warning C4275: An exported class was derived from a class that wasn't exported. Can be ignored when derived from a STL class. # pragma warning(disable: 4275)
// warning C4275: An exported class was derived from a class that wasn't exported.
// Can be ignored when derived from a STL class.
#endif #endif
/// C++ bindings of builtin Python exceptions /// C++ bindings of builtin Python exceptions
class PYBIND11_EXPORT_EXCEPTION builtin_exception : public std::runtime_error { class PYBIND11_EXPORT_EXCEPTION builtin_exception : public std::runtime_error {
@ -870,7 +873,9 @@ PYBIND11_RUNTIME_EXCEPTION(type_error, PyExc_TypeError)
PYBIND11_RUNTIME_EXCEPTION(buffer_error, PyExc_BufferError) PYBIND11_RUNTIME_EXCEPTION(buffer_error, PyExc_BufferError)
PYBIND11_RUNTIME_EXCEPTION(import_error, PyExc_ImportError) PYBIND11_RUNTIME_EXCEPTION(import_error, PyExc_ImportError)
PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError) PYBIND11_RUNTIME_EXCEPTION(attribute_error, PyExc_AttributeError)
PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or handle::call fail due to a type casting error PYBIND11_RUNTIME_EXCEPTION(cast_error, PyExc_RuntimeError) /// Thrown when pybind11::cast or
/// handle::call fail due to a type
/// casting error
PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally PYBIND11_RUNTIME_EXCEPTION(reference_cast_error, PyExc_RuntimeError) /// Used internally
[[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason) { throw std::runtime_error(reason); } [[noreturn]] PYBIND11_NOINLINE void pybind11_fail(const char *reason) { throw std::runtime_error(reason); }
@ -974,13 +979,14 @@ public:
template <typename It, typename = enable_if_t<is_input_iterator<It>::value>> template <typename It, typename = enable_if_t<is_input_iterator<It>::value>>
any_container(It first, It last) : v(first, last) { } any_container(It first, It last) : v(first, last) { }
// Implicit conversion constructor from any arbitrary container type with values convertible to T // Implicit conversion constructor from any arbitrary container type
// with values convertible to T
template <typename Container, typename = enable_if_t<std::is_convertible<decltype(*std::begin(std::declval<const Container &>())), T>::value>> template <typename Container, typename = enable_if_t<std::is_convertible<decltype(*std::begin(std::declval<const Container &>())), T>::value>>
// NOLINTNEXTLINE(google-explicit-constructor) // NOLINTNEXTLINE(google-explicit-constructor)
any_container(const Container &c) : any_container(std::begin(c), std::end(c)) { } any_container(const Container &c) : any_container(std::begin(c), std::end(c)) { }
// initializer_list's aren't deducible, so don't get matched by the above template; we need this // initializer_list's aren't deducible, so don't get matched by the above template;
// to explicitly allow implicit conversion from one: // we need this to explicitly allow implicit conversion from one:
template <typename TIn, typename = enable_if_t<std::is_convertible<TIn, T>::value>> template <typename TIn, typename = enable_if_t<std::is_convertible<TIn, T>::value>>
any_container(const std::initializer_list<TIn> &c) : any_container(c.begin(), c.end()) { } any_container(const std::initializer_list<TIn> &c) : any_container(c.begin(), c.end()) { }

View File

@ -147,18 +147,22 @@ struct override_hash {
/// Whenever binary incompatible changes are made to this structure, /// Whenever binary incompatible changes are made to this structure,
/// `PYBIND11_INTERNALS_VERSION` must be incremented. /// `PYBIND11_INTERNALS_VERSION` must be incremented.
struct internals { struct internals {
type_map<type_info *> registered_types_cpp; // std::type_index -> pybind11's type information // std::type_index -> pybind11's type information
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py; // PyTypeObject* -> base type_info(s) type_map<type_info *> registered_types_cpp;
// PyTypeObject* -> base type_info(s)
std::unordered_map<PyTypeObject *, std::vector<type_info *>> registered_types_py;
std::unordered_multimap<const void *, instance*> registered_instances; // void * -> instance* std::unordered_multimap<const void *, instance*> registered_instances; // void * -> instance*
std::unordered_set<std::pair<const PyObject *, const char *>, override_hash> inactive_override_cache; std::unordered_set<std::pair<const PyObject *, const char *>, override_hash> inactive_override_cache;
type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions; type_map<std::vector<bool (*)(PyObject *, void *&)>> direct_conversions;
std::unordered_map<const PyObject *, std::vector<PyObject *>> patients; std::unordered_map<const PyObject *, std::vector<PyObject *>> patients;
std::forward_list<ExceptionTranslator> registered_exception_translators; std::forward_list<ExceptionTranslator> registered_exception_translators;
std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across extensions std::unordered_map<std::string, void *> shared_data; // Custom data to be shared across
// extensions
#if PYBIND11_INTERNALS_VERSION == 4 #if PYBIND11_INTERNALS_VERSION == 4
std::vector<PyObject *> unused_loader_patient_stack_remove_at_v5; std::vector<PyObject *> unused_loader_patient_stack_remove_at_v5;
#endif #endif
std::forward_list<std::string> static_strings; // Stores the std::strings backing detail::c_str() std::forward_list<std::string> static_strings; // Stores the std::strings backing
// detail::c_str()
PyTypeObject *static_property_type; PyTypeObject *static_property_type;
PyTypeObject *default_metaclass; PyTypeObject *default_metaclass;
PyObject *instance_base; PyObject *instance_base;

View File

@ -426,7 +426,8 @@ PYBIND11_NOINLINE void instance::allocate_layout() {
space += t->holder_size_in_ptrs; // holder instance space += t->holder_size_in_ptrs; // holder instance
} }
size_t flags_at = space; size_t flags_at = space;
space += size_in_ptrs(n_types); // status bytes (holder_constructed and instance_registered) space += size_in_ptrs(n_types); // status bytes (holder_constructed and
// instance_registered)
// Allocate space for flags, values, and holders, and initialize it to 0 (flags and values, // Allocate space for flags, values, and holders, and initialize it to 0 (flags and values,
// in particular, need to be 0). Use Python's memory allocation functions: in Python 3.6 // in particular, need to be 0). Use Python's memory allocation functions: in Python 3.6

View File

@ -164,7 +164,8 @@ PYBIND11_NAMESPACE_END(detail)
.. code-block:: cpp .. code-block:: cpp
{ {
py::scoped_ostream_redirect output{std::cerr, py::module::import("sys").attr("stderr")}; py::scoped_ostream_redirect output{
std::cerr, py::module::import("sys").attr("stderr")};
std::cout << "Hello, World!"; std::cout << "Hello, World!";
} }
\endrst */ \endrst */

View File

@ -325,7 +325,8 @@ template <typename T, size_t N> struct array_info<T[N]> : array_info<std::array<
template <typename T> using remove_all_extents_t = typename array_info<T>::type; template <typename T> using remove_all_extents_t = typename array_info<T>::type;
template <typename T> using is_pod_struct = all_of< template <typename T> using is_pod_struct = all_of<
std::is_standard_layout<T>, // since we're accessing directly in memory we need a standard layout type std::is_standard_layout<T>, // since we're accessing directly in memory
// we need a standard layout type
#if defined(__GLIBCXX__) && (__GLIBCXX__ < 20150422 || __GLIBCXX__ == 20150426 || __GLIBCXX__ == 20150623 || __GLIBCXX__ == 20150626 || __GLIBCXX__ == 20160803) #if defined(__GLIBCXX__) && (__GLIBCXX__ < 20150422 || __GLIBCXX__ == 20150426 || __GLIBCXX__ == 20150623 || __GLIBCXX__ == 20150626 || __GLIBCXX__ == 20160803)
// libstdc++ < 5 (including versions 4.8.5, 4.9.3 and 4.9.4 which were released after 5) // libstdc++ < 5 (including versions 4.8.5, 4.9.3 and 4.9.4 which were released after 5)
// don't implement is_trivially_copyable, so approximate it // don't implement is_trivially_copyable, so approximate it

View File

@ -51,7 +51,8 @@ private:
struct state { struct state {
bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings. bool show_user_defined_docstrings = true; //< Include user-supplied texts in docstrings.
bool show_function_signatures = true; //< Include auto-generated function signatures in docstrings. bool show_function_signatures = true; //< Include auto-generated function signatures
// in docstrings.
}; };
static state &global_state() { static state &global_state() {

View File

@ -242,7 +242,8 @@ protected:
rec->nargs_pos = cast_in::args_pos >= 0 rec->nargs_pos = cast_in::args_pos >= 0
? static_cast<std::uint16_t>(cast_in::args_pos) ? static_cast<std::uint16_t>(cast_in::args_pos)
: sizeof...(Args) - cast_in::has_kwargs; // Will get reduced more if we have a kw_only : sizeof...(Args) - cast_in::has_kwargs; // Will get reduced more if
// we have a kw_only
rec->has_args = cast_in::args_pos >= 0; rec->has_args = cast_in::args_pos >= 0;
rec->has_kwargs = cast_in::has_kwargs; rec->has_kwargs = cast_in::has_kwargs;
@ -263,7 +264,8 @@ protected:
static_assert(!(has_kw_only_args && has_pos_only_args) || pos_only_pos < kw_only_pos, "py::pos_only must come before py::kw_only"); static_assert(!(has_kw_only_args && has_pos_only_args) || pos_only_pos < kw_only_pos, "py::pos_only must come before py::kw_only");
} }
/* Generate a readable signature describing the function's arguments and return value types */ /* Generate a readable signature describing the function's arguments and return
value types */
static constexpr auto signature = const_name("(") + cast_in::arg_names + const_name(") -> ") + cast_out::name; static constexpr auto signature = const_name("(") + cast_in::arg_names + const_name(") -> ") + cast_out::name;
PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types(); PYBIND11_DESCR_CONSTEXPR auto types = decltype(signature)::types();
@ -400,7 +402,8 @@ protected:
handle th((PyObject *) tinfo->type); handle th((PyObject *) tinfo->type);
signature += signature +=
th.attr("__module__").cast<std::string>() + "." + th.attr("__module__").cast<std::string>() + "." +
th.attr("__qualname__").cast<std::string>(); // Python 3.3+, but we backport it to earlier versions // Python 3.3+, but we backport it to earlier versions
th.attr("__qualname__").cast<std::string>();
} else if (rec->is_new_style_constructor && arg_index == 0) { } else if (rec->is_new_style_constructor && arg_index == 0) {
// A new-style `__init__` takes `self` as `value_and_holder`. // A new-style `__init__` takes `self` as `value_and_holder`.
// Rewrite it to the proper class type. // Rewrite it to the proper class type.
@ -639,7 +642,8 @@ protected:
const function_record *overloads = (function_record *) PyCapsule_GetPointer(self, nullptr), const function_record *overloads = (function_record *) PyCapsule_GetPointer(self, nullptr),
*it = overloads; *it = overloads;
/* Need to know how many arguments + keyword arguments there are to pick the right overload */ /* Need to know how many arguments + keyword arguments there are to pick the right
overload */
const auto n_args_in = (size_t) PyTuple_GET_SIZE(args_in); const auto n_args_in = (size_t) PyTuple_GET_SIZE(args_in);
handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr, handle parent = n_args_in > 0 ? PyTuple_GET_ITEM(args_in, 0) : nullptr,
@ -715,7 +719,8 @@ protected:
function_call call(func, parent); function_call call(func, parent);
size_t args_to_copy = (std::min)(pos_args, n_args_in); // Protect std::min with parentheses // Protect std::min with parentheses
size_t args_to_copy = (std::min)(pos_args, n_args_in);
size_t args_copied = 0; size_t args_copied = 0;
// 0. Inject new-style `self` argument // 0. Inject new-style `self` argument
@ -956,7 +961,8 @@ protected:
- catch the exception and call PyErr_SetString or PyErr_SetObject - catch the exception and call PyErr_SetString or PyErr_SetObject
to set a standard (or custom) Python exception, or to set a standard (or custom) Python exception, or
- do nothing and let the exception fall through to the next translator, or - do nothing and let the exception fall through to the next translator, or
- delegate translation to the next translator by throwing a new type of exception. */ - delegate translation to the next translator by throwing a new type of exception.
*/
auto &local_exception_translators = get_local_internals().registered_exception_translators; auto &local_exception_translators = get_local_internals().registered_exception_translators;
if (detail::apply_exception_translators(local_exception_translators)) { if (detail::apply_exception_translators(local_exception_translators)) {
@ -1169,8 +1175,8 @@ public:
Adds an object to the module using the given name. Throws if an object with the given name Adds an object to the module using the given name. Throws if an object with the given name
already exists. already exists.
``overwrite`` should almost always be false: attempting to overwrite objects that pybind11 has ``overwrite`` should almost always be false: attempting to overwrite objects that pybind11
established will, in most cases, break things. has established will, in most cases, break things.
\endrst */ \endrst */
PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) { PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) {
if (!overwrite && hasattr(*this, name)) { if (!overwrite && hasattr(*this, name)) {
@ -1197,7 +1203,8 @@ public:
static module_ create_extension_module(const char *name, const char *doc, module_def *def) { static module_ create_extension_module(const char *name, const char *doc, module_def *def) {
#if PY_MAJOR_VERSION >= 3 #if PY_MAJOR_VERSION >= 3
// module_def is PyModuleDef // module_def is PyModuleDef
def = new (def) PyModuleDef { // Placement new (not an allocation). // Placement new (not an allocation).
def = new (def) PyModuleDef {
/* m_base */ PyModuleDef_HEAD_INIT, /* m_base */ PyModuleDef_HEAD_INIT,
/* m_name */ name, /* m_name */ name,
/* m_doc */ options::show_user_defined_docstrings() ? doc : nullptr, /* m_doc */ options::show_user_defined_docstrings() ? doc : nullptr,
@ -1456,7 +1463,8 @@ public:
none_of<is_pyobject<Extra>...>::value || // no base class arguments, or: none_of<is_pyobject<Extra>...>::value || // no base class arguments, or:
( constexpr_sum(is_pyobject<Extra>::value...) == 1 && // Exactly one base ( constexpr_sum(is_pyobject<Extra>::value...) == 1 && // Exactly one base
constexpr_sum(is_base<options>::value...) == 0 && // no template option bases constexpr_sum(is_base<options>::value...) == 0 && // no template option bases
none_of<std::is_same<multiple_inheritance, Extra>...>::value), // no multiple_inheritance attr // no multiple_inheritance attr
none_of<std::is_same<multiple_inheritance, Extra>...>::value),
"Error: multiple inheritance bases must be specified via class_ template options"); "Error: multiple inheritance bases must be specified via class_ template options");
type_record record; type_record record;
@ -2562,10 +2570,11 @@ inline function get_type_override(const void *this_ptr, const type_info *this_ty
PYBIND11_NAMESPACE_END(detail) PYBIND11_NAMESPACE_END(detail)
/** \rst /** \rst
Try to retrieve a python method by the provided name from the instance pointed to by the this_ptr. 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 overridden method should be retrieved for. This should be :this_ptr: The pointer to the object the overridden method should be retrieved for. This should
the first non-trampoline class encountered in the inheritance chain. be the first non-trampoline class encountered in the inheritance chain.
:name: The name of the overridden Python method to retrieve. :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. :return: The Python method by this name from the object or an empty function wrapper.
\endrst */ \endrst */
@ -2590,9 +2599,10 @@ template <class T> function get_override(const T *this_ptr, const char *name) {
} while (false) } while (false)
/** \rst /** \rst
Macro to populate the virtual method in the trampoline class. This macro tries to look up a method named 'fn' Macro to populate the virtual method in the trampoline class. This macro tries to look up a
from the Python side, deals with the :ref:`gil` and necessary argument conversions to call this method and return method named 'fn' from the Python side, deals with the :ref:`gil` and necessary argument
the appropriate type. See :ref:`overriding_virtuals` for more information. This macro should be used when the method conversions to call this method and return the appropriate type.
See :ref:`overriding_virtuals` for more information. This macro should be used when the method
name in C is not the same as the method name in Python. For example with `__str__`. name in C is not the same as the method name in Python. For example with `__str__`.
.. code-block:: cpp .. code-block:: cpp
@ -2613,8 +2623,8 @@ template <class T> function get_override(const T *this_ptr, const char *name) {
} while (false) } while (false)
/** \rst /** \rst
Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE_NAME`, except that it Macro for pure virtual functions, this function is identical to
throws if no override can be found. :c:macro:`PYBIND11_OVERRIDE_NAME`, except that it throws if no override can be found.
\endrst */ \endrst */
#define PYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...) \ #define PYBIND11_OVERRIDE_PURE_NAME(ret_type, cname, name, fn, ...) \
do { \ do { \
@ -2623,9 +2633,10 @@ template <class T> function get_override(const T *this_ptr, const char *name) {
} while (false) } while (false)
/** \rst /** \rst
Macro to populate the virtual method in the trampoline class. This macro tries to look up the method Macro to populate the virtual method in the trampoline class. This macro tries to look up the
from the Python side, deals with the :ref:`gil` and necessary argument conversions to call this method and return method from the Python side, deals with the :ref:`gil` and necessary argument conversions to
the appropriate type. This macro should be used if the method name in C and in Python are identical. call this method and return the appropriate type. This macro should be used if the method name
in C and in Python are identical.
See :ref:`overriding_virtuals` for more information. See :ref:`overriding_virtuals` for more information.
.. code-block:: cpp .. code-block:: cpp
@ -2650,8 +2661,8 @@ template <class T> function get_override(const T *this_ptr, const char *name) {
PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__) PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)
/** \rst /** \rst
Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`, except that it throws Macro for pure virtual functions, this function is identical to :c:macro:`PYBIND11_OVERRIDE`,
if no override can be found. except that it throws if no override can be found.
\endrst */ \endrst */
#define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...) \ #define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...) \
PYBIND11_OVERRIDE_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__) PYBIND11_OVERRIDE_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__)

View File

@ -161,7 +161,8 @@ public:
/// Return the object's current reference count /// Return the object's current reference count
int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); } int ref_count() const { return static_cast<int>(Py_REFCNT(derived().ptr())); }
// TODO PYBIND11_DEPRECATED("Call py::type::handle_of(h) or py::type::of(h) instead of h.get_type()") // TODO PYBIND11_DEPRECATED(
// "Call py::type::handle_of(h) or py::type::of(h) instead of h.get_type()")
handle get_type() const; handle get_type() const;
private: private:
@ -337,7 +338,9 @@ PYBIND11_NAMESPACE_END(detail)
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(push) # pragma warning(push)
# pragma warning(disable: 4275 4251) // warning C4275: An exported class was derived from a class that wasn't exported. Can be ignored when derived from a STL class. # pragma warning(disable: 4275 4251)
// warning C4275: An exported class was derived from a class that wasn't exported.
// Can be ignored when derived from a STL class.
#endif #endif
/// Fetch and hold an error which was already set in Python. An instance of this is typically /// Fetch and hold an error which was already set in Python. An instance of this is typically
/// thrown to propagate python-side errors back through C++ which can either be caught manually or /// thrown to propagate python-side errors back through C++ which can either be caught manually or
@ -1745,7 +1748,8 @@ public:
See also: Python C API documentation for `PyMemoryView_FromBuffer`_. See also: Python C API documentation for `PyMemoryView_FromBuffer`_.
.. _PyMemoryView_FromBuffer: https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromBuffer .. _PyMemoryView_FromBuffer:
https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromBuffer
:param ptr: Pointer to the buffer. :param ptr: Pointer to the buffer.
:param itemsize: Byte size of an element. :param itemsize: Byte size of an element.
@ -1800,7 +1804,8 @@ public:
See also: Python C API documentation for `PyMemoryView_FromBuffer`_. See also: Python C API documentation for `PyMemoryView_FromBuffer`_.
.. _PyMemoryView_FromMemory: https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromMemory .. _PyMemoryView_FromMemory:
https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromMemory
\endrst */ \endrst */
static memoryview from_memory(void *mem, ssize_t size, bool readonly = false) { static memoryview from_memory(void *mem, ssize_t size, bool readonly = false) {
PyObject* ptr = PyMemoryView_FromMemory( PyObject* ptr = PyMemoryView_FromMemory(

View File

@ -44,7 +44,8 @@ struct is_comparable<
container_traits<T>::is_comparable>> container_traits<T>::is_comparable>>
: std::true_type { }; : std::true_type { };
/* For a vector/map data structure, recursively check the value type (which is std::pair for maps) */ /* For a vector/map data structure, recursively check the value type
(which is std::pair for maps) */
template <typename T> template <typename T>
struct is_comparable<T, enable_if_t<container_traits<T>::is_vector>> { struct is_comparable<T, enable_if_t<container_traits<T>::is_vector>> {
static constexpr const bool value = static constexpr const bool value =
@ -384,7 +385,8 @@ template <typename Vector, typename Class_> auto vector_if_insertion_operator(Cl
} }
// Provide the buffer interface for vectors if we have data() and we have a format for it // Provide the buffer interface for vectors if we have data() and we have a format for it
// GCC seems to have "void std::vector<bool>::data()" - doing SFINAE on the existence of data() is insufficient, we need to check it returns an appropriate pointer // GCC seems to have "void std::vector<bool>::data()" - doing SFINAE on the existence of data()
// is insufficient, we need to check it returns an appropriate pointer
template <typename Vector, typename = void> template <typename Vector, typename = void>
struct vector_has_data_and_format : std::false_type {}; struct vector_has_data_and_format : std::false_type {};
template <typename Vector> template <typename Vector>
@ -408,7 +410,8 @@ void vector_buffer_impl(Class_& cl, std::true_type) {
static_assert(vector_has_data_and_format<Vector>::value, "There is not an appropriate format descriptor for this vector"); static_assert(vector_has_data_and_format<Vector>::value, "There is not an appropriate format descriptor for this vector");
// numpy.h declares this for arbitrary types, but it may raise an exception and crash hard at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here // numpy.h declares this for arbitrary types, but it may raise an exception and crash hard
// at runtime if PYBIND11_NUMPY_DTYPE hasn't been called, so check here
format_descriptor<T>::format(); format_descriptor<T>::format();
cl.def_buffer([](Vector& v) -> buffer_info { cl.def_buffer([](Vector& v) -> buffer_info {

View File

@ -72,8 +72,10 @@ inspection/testing in python) by using the functions with `print_` replaced with
class ConstructorStats { class ConstructorStats {
protected: protected:
std::unordered_map<void*, int> _instances; // Need a map rather than set because members can shared address with parents std::unordered_map<void*, int> _instances; // Need a map rather than set because members can
std::list<std::string> _values; // Used to track values (e.g. of value constructors) // shared address with parents
std::list<std::string> _values; // Used to track values
// (e.g. of value constructors)
public: public:
int default_constructions = 0; int default_constructions = 0;
int copy_constructions = 0; int copy_constructions = 0;

View File

@ -5,8 +5,7 @@
#if defined(_MSC_VER) && _MSC_VER < 1910 #if defined(_MSC_VER) && _MSC_VER < 1910
// We get some really long type names here which causes MSVC 2015 to emit warnings // We get some really long type names here which causes MSVC 2015 to emit warnings
# pragma warning( \ # pragma warning(disable : 4503) // NOLINT: warning C4503: decorated name length exceeded, name was truncated
disable : 4503) // warning C4503: decorated name length exceeded, name was truncated
#endif #endif
namespace py = pybind11; namespace py = pybind11;

View File

@ -22,7 +22,8 @@
#include <utility> #include <utility>
#if defined(_MSC_VER) #if defined(_MSC_VER)
# pragma warning(disable: 4324) // warning C4324: structure was padded due to alignment specifier # pragma warning(disable: 4324)
// warning C4324: structure was padded due to alignment specifier
#endif #endif
// test_brace_initialization // test_brace_initialization
@ -534,22 +535,24 @@ CHECK_HOLDER(6, shared); CHECK_HOLDER(7, shared); CHECK_HOLDER(8, shared);
#define CHECK_BROKEN(N) static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-(N)>>::value, \ #define CHECK_BROKEN(N) static_assert(std::is_same<typename Breaks##N::type, BreaksBase<-(N)>>::value, \
"Breaks1 has wrong type!"); "Breaks1 has wrong type!");
//// Two holder classes: #ifdef PYBIND11_NEVER_DEFINED_EVER
//typedef py::class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>> Breaks1; // Two holder classes:
//CHECK_BROKEN(1); typedef py::class_<BreaksBase<-1>, std::unique_ptr<BreaksBase<-1>>, std::unique_ptr<BreaksBase<-1>>> Breaks1;
//// Two aliases: CHECK_BROKEN(1);
//typedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2; // Two aliases:
//CHECK_BROKEN(2); typedef py::class_<BreaksBase<-2>, BreaksTramp<-2>, BreaksTramp<-2>> Breaks2;
//// Holder + 2 aliases CHECK_BROKEN(2);
//typedef py::class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>> Breaks3; // Holder + 2 aliases
//CHECK_BROKEN(3); typedef py::class_<BreaksBase<-3>, std::unique_ptr<BreaksBase<-3>>, BreaksTramp<-3>, BreaksTramp<-3>> Breaks3;
//// Alias + 2 holders CHECK_BROKEN(3);
//typedef py::class_<BreaksBase<-4>, std::unique_ptr<BreaksBase<-4>>, BreaksTramp<-4>, std::shared_ptr<BreaksBase<-4>>> Breaks4; // Alias + 2 holders
//CHECK_BROKEN(4); typedef py::class_<BreaksBase<-4>, std::unique_ptr<BreaksBase<-4>>, BreaksTramp<-4>, std::shared_ptr<BreaksBase<-4>>> Breaks4;
//// Invalid option (not a subclass or holder) CHECK_BROKEN(4);
//typedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5; // Invalid option (not a subclass or holder)
//CHECK_BROKEN(5); typedef py::class_<BreaksBase<-5>, BreaksTramp<-4>> Breaks5;
//// Invalid option: multiple inheritance not supported: CHECK_BROKEN(5);
//template <> struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {}; // Invalid option: multiple inheritance not supported:
//typedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8; template <> struct BreaksBase<-8> : BreaksBase<-6>, BreaksBase<-7> {};
//CHECK_BROKEN(8); typedef py::class_<BreaksBase<-8>, BreaksBase<-6>, BreaksBase<-7>> Breaks8;
CHECK_BROKEN(8);
#endif

View File

@ -153,10 +153,12 @@ TEST_SUBMODULE(kwargs_and_defaults, m) {
// These should fail to compile: // These should fail to compile:
#ifdef PYBIND11_NEVER_DEFINED_EVER
// argument annotations are required when using kw_only // argument annotations are required when using kw_only
// m.def("bad_kw_only1", [](int) {}, py::kw_only()); m.def("bad_kw_only1", [](int) {}, py::kw_only());
// can't specify both `py::kw_only` and a `py::args` argument // can't specify both `py::kw_only` and a `py::args` argument
// m.def("bad_kw_only2", [](int i, py::args) {}, py::kw_only(), "i"_a); m.def("bad_kw_only2", [](int i, py::args) {}, py::kw_only(), "i"_a);
#endif
// test_function_signatures (along with most of the above) // test_function_signatures (along with most of the above)
struct KWClass { void foo(int, float) {} }; struct KWClass { void foo(int, float) {} };

View File

@ -49,7 +49,8 @@ TEST_SUBMODULE(modules, m) {
.def(py::init<>()) .def(py::init<>())
.def("get_a1", &B::get_a1, "Return the internal A 1", py::return_value_policy::reference_internal) .def("get_a1", &B::get_a1, "Return the internal A 1", py::return_value_policy::reference_internal)
.def("get_a2", &B::get_a2, "Return the internal A 2", py::return_value_policy::reference_internal) .def("get_a2", &B::get_a2, "Return the internal A 2", py::return_value_policy::reference_internal)
.def_readwrite("a1", &B::a1) // def_readonly uses an internal reference return policy by default .def_readwrite("a1", &B::a1) // def_readonly uses an internal
// reference return policy by default
.def_readwrite("a2", &B::a2); .def_readwrite("a2", &B::a2);
// This is intentionally "py::module" to verify it still can be used in place of "py::module_" // This is intentionally "py::module" to verify it still can be used in place of "py::module_"

View File

@ -399,7 +399,8 @@ TEST_SUBMODULE(numpy_array, sm) {
// test_initializer_list // test_initializer_list
// Issue (unnumbered; reported in #788): regression: initializer lists can be ambiguous // Issue (unnumbered; reported in #788): regression: initializer lists can be ambiguous
sm.def("array_initializer_list1", []() { return py::array_t<float>(1); }); // { 1 } also works, but clang warns about it sm.def("array_initializer_list1", []() { return py::array_t<float>(1); });
// { 1 } also works for the above, but clang warns about it
sm.def("array_initializer_list2", []() { return py::array_t<float>({ 1, 2 }); }); sm.def("array_initializer_list2", []() { return py::array_t<float>({ 1, 2 }); });
sm.def("array_initializer_list3", []() { return py::array_t<float>({ 1, 2, 3 }); }); sm.def("array_initializer_list3", []() { return py::array_t<float>({ 1, 2, 3 }); });
sm.def("array_initializer_list4", []() { return py::array_t<float>({ 1, 2, 3, 4 }); }); sm.def("array_initializer_list4", []() { return py::array_t<float>({ 1, 2, 3, 4 }); });

View File

@ -308,10 +308,12 @@ TEST_SUBMODULE(numpy_dtypes, m) {
PYBIND11_NUMPY_DTYPE_EX(StructWithUglyNames, __x__, "x", __y__, "y"); PYBIND11_NUMPY_DTYPE_EX(StructWithUglyNames, __x__, "x", __y__, "y");
// If uncommented, this should produce a static_assert failure telling the user that the struct #ifdef PYBIND11_NEVER_DEFINED_EVER
// If enabled, this should produce a static_assert failure telling the user that the struct
// is not a POD type // is not a POD type
// struct NotPOD { std::string v; NotPOD() : v("hi") {}; }; struct NotPOD { std::string v; NotPOD() : v("hi") {}; };
// PYBIND11_NUMPY_DTYPE(NotPOD, v); PYBIND11_NUMPY_DTYPE(NotPOD, v);
#endif
// Check that dtypes can be registered programmatically, both from // Check that dtypes can be registered programmatically, both from
// initializer lists of field descriptors and from other containers. // initializer lists of field descriptors and from other containers.

View File

@ -370,9 +370,12 @@ TEST_SUBMODULE(virtual_functions, m) {
public: public:
using OverrideTest::OverrideTest; using OverrideTest::OverrideTest;
std::string str_value() override { PYBIND11_OVERRIDE(std::string, OverrideTest, str_value); } std::string str_value() override { PYBIND11_OVERRIDE(std::string, OverrideTest, str_value); }
// Not allowed (uncommenting should hit a static_assert failure): we can't get a reference // Not allowed (enabling the below should hit a static_assert failure): we can't get a
// to a python numeric value, since we only copy values in the numeric type caster: // reference to a python numeric value, since we only copy values in the numeric type
// std::string &str_ref() override { PYBIND11_OVERRIDE(std::string &, OverrideTest, str_ref); } // caster:
#ifdef PYBIND11_NEVER_DEFINED_EVER
std::string &str_ref() override { PYBIND11_OVERRIDE(std::string &, OverrideTest, str_ref); }
#endif
// But we can work around it like this: // But we can work around it like this:
private: private:
std::string _tmp; std::string _tmp;
@ -389,7 +392,9 @@ TEST_SUBMODULE(virtual_functions, m) {
py::class_<OverrideTest, PyOverrideTest>(m, "OverrideTest") py::class_<OverrideTest, PyOverrideTest>(m, "OverrideTest")
.def(py::init<const std::string &>()) .def(py::init<const std::string &>())
.def("str_value", &OverrideTest::str_value) .def("str_value", &OverrideTest::str_value)
// .def("str_ref", &OverrideTest::str_ref) #ifdef PYBIND11_NEVER_DEFINED_EVER
.def("str_ref", &OverrideTest::str_ref)
#endif
.def("A_value", &OverrideTest::A_value) .def("A_value", &OverrideTest::A_value)
.def("A_ref", &OverrideTest::A_ref); .def("A_ref", &OverrideTest::A_ref);
@ -492,11 +497,11 @@ public:
// Inheritance approach 2: templated trampoline classes. // Inheritance approach 2: templated trampoline classes.
// //
// Advantages: // Advantages:
// - we have only 2 (template) class and 4 method declarations (one per virtual method, plus one for // - we have only 2 (template) class and 4 method declarations (one per virtual method, plus one
// any override of a pure virtual method), versus 4 classes and 6 methods (MI) or 4 classes and 11 // for any override of a pure virtual method), versus 4 classes and 6 methods (MI) or 4 classes
// methods (repeat). // and 11 methods (repeat).
// - Compared to MI, we also don't have to change the non-trampoline inheritance to virtual, and can // - Compared to MI, we also don't have to change the non-trampoline inheritance to virtual, and
// properly inherit constructors. // can properly inherit constructors.
// //
// Disadvantage: // Disadvantage:
// - the compiler must still generate and compile 14 different methods (more, even, than the 11 // - the compiler must still generate and compile 14 different methods (more, even, than the 11
@ -518,8 +523,8 @@ public:
int unlucky_number() override { PYBIND11_OVERRIDE(int, Base, unlucky_number, ); } int unlucky_number() override { PYBIND11_OVERRIDE(int, Base, unlucky_number, ); }
double lucky_number() override { PYBIND11_OVERRIDE(double, Base, lucky_number, ); } double lucky_number() override { PYBIND11_OVERRIDE(double, Base, lucky_number, ); }
}; };
// Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these (we can // Since C_Tpl and D_Tpl don't declare any new virtual methods, we don't actually need these
// use PyB_Tpl<C_Tpl> and PyB_Tpl<D_Tpl> for the trampoline classes instead): // (we can use PyB_Tpl<C_Tpl> and PyB_Tpl<D_Tpl> for the trampoline classes instead):
/* /*
template <class Base = C_Tpl> class PyC_Tpl : public PyB_Tpl<Base> { template <class Base = C_Tpl> class PyC_Tpl : public PyB_Tpl<Base> {
public: public: