From d69b79a3431e7b304e9cb918333bae3d2e8324f4 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Mon, 12 Jul 2021 18:27:58 -0700 Subject: [PATCH 1/4] * Removing stray semicolons (discovered by running clang-format v12 followed by tools/check-style.sh). * Manually moving `// NOLINT` comments so that clang-format does not move them to the wrong places. * Manually reformatting comments related to `static_assert`s so that clang-format does not need two passes. * Empty lines between #includes, to prevent clang-format from shuffling the order and thereby confusing MSVC 2015. * git diff -U0 --no-color HEAD^ | python3 $HOME/clone/llvm-project/clang/tools/clang-format/clang-format-diff.py -p1 -style=file -i --- include/pybind11/attr.h | 3 ++- include/pybind11/detail/common.h | 3 ++- tests/pybind11_tests.h | 7 ++++++- tests/test_buffers.cpp | 2 +- tests/test_callbacks.cpp | 2 +- tests/test_eigen.cpp | 5 ++++- tests/test_methods_and_attributes.cpp | 12 ++++++------ tests/test_smart_ptr.cpp | 2 +- 8 files changed, 23 insertions(+), 13 deletions(-) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 97147904ce..60ed9fd90e 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -62,7 +62,8 @@ struct metaclass { handle value; PYBIND11_DEPRECATED("py::metaclass() is no longer required. It's turned on by default now.") - metaclass() { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute + // NOLINTNEXTLINE(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute + metaclass() {} /// Override pybind11's default metaclass explicit metaclass(handle value) : value(value) { } diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 1f7446103e..f804e7c85a 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -801,7 +801,8 @@ struct nodelete { template void operator()(T*) { } }; PYBIND11_NAMESPACE_BEGIN(detail) template struct overload_cast_impl { - constexpr overload_cast_impl() {}; // NOLINT(modernize-use-equals-default): MSVC 2015 needs this + // NOLINTNEXTLINE(modernize-use-equals-default): MSVC 2015 needs this + constexpr overload_cast_impl() {} template constexpr auto operator()(Return (*pf)(Args...)) const noexcept diff --git a/tests/pybind11_tests.h b/tests/pybind11_tests.h index ccb0529787..d970ba8bd4 100644 --- a/tests/pybind11_tests.h +++ b/tests/pybind11_tests.h @@ -1,10 +1,15 @@ #pragma once + +// This must be kept first for MSVC 2015. +// Do not remove the empty line between the #includes. #include + #include #if defined(_MSC_VER) && _MSC_VER < 1910 // We get some really long type names here which causes MSVC 2015 to emit warnings -# pragma warning(disable: 4503) // warning C4503: decorated name length exceeded, name was truncated +# pragma warning( \ + disable : 4503) // warning C4503: decorated name length exceeded, name was truncated #endif namespace py = pybind11; diff --git a/tests/test_buffers.cpp b/tests/test_buffers.cpp index 15dd4f1c74..e77c626f87 100644 --- a/tests/test_buffers.cpp +++ b/tests/test_buffers.cpp @@ -154,7 +154,7 @@ TEST_SUBMODULE(buffers, m) { py::format_descriptor::format(), 1); } - ConstBuffer() : value(new int32_t{0}) { }; + ConstBuffer() : value(new int32_t{0}) {} }; py::class_(m, "ConstBuffer", py::buffer_protocol()) .def(py::init<>()) diff --git a/tests/test_callbacks.cpp b/tests/test_callbacks.cpp index 7e79217a3d..a208b44d04 100644 --- a/tests/test_callbacks.cpp +++ b/tests/test_callbacks.cpp @@ -122,7 +122,7 @@ TEST_SUBMODULE(callbacks, m) { // [workaround(intel)] = default does not work here // Defaulting this destructor results in linking errors with the Intel compiler // (in Debug builds only, tested with icpc (ICC) 2021.1 Beta 20200827) - virtual ~AbstractBase() {}; // NOLINT(modernize-use-equals-default) + virtual ~AbstractBase() {} // NOLINT(modernize-use-equals-default) virtual unsigned int func() = 0; }; m.def("func_accepting_func_accepting_base", diff --git a/tests/test_eigen.cpp b/tests/test_eigen.cpp index ba74f58156..651be0575f 100644 --- a/tests/test_eigen.cpp +++ b/tests/test_eigen.cpp @@ -258,7 +258,10 @@ TEST_SUBMODULE(eigen, m) { m.def("dense_copy_r", [](const DenseMatrixR &m) -> DenseMatrixR { return m; }); m.def("dense_copy_c", [](const DenseMatrixC &m) -> DenseMatrixC { return m; }); // test_sparse, test_sparse_signature - m.def("sparse_r", [mat]() -> SparseMatrixR { return Eigen::SparseView(mat); }); //NOLINT(clang-analyzer-core.uninitialized.UndefReturn) + m.def("sparse_r", [mat]() -> SparseMatrixR { + // NOLINTNEXTLINE(clang-analyzer-core.uninitialized.UndefReturn) + return Eigen::SparseView(mat); + }); m.def("sparse_c", [mat]() -> SparseMatrixC { return Eigen::SparseView(mat); }); m.def("sparse_copy_r", [](const SparseMatrixR &m) -> SparseMatrixR { return m; }); m.def("sparse_copy_c", [](const SparseMatrixC &m) -> SparseMatrixC { return m; }); diff --git a/tests/test_methods_and_attributes.cpp b/tests/test_methods_and_attributes.cpp index 6e5999f0c4..9db31a0b82 100644 --- a/tests/test_methods_and_attributes.cpp +++ b/tests/test_methods_and_attributes.cpp @@ -123,7 +123,7 @@ class NoneCastTester { public: int answer = -1; NoneCastTester() = default; - NoneCastTester(int v) : answer(v) {}; + NoneCastTester(int v) : answer(v) {} }; struct StrIssue { @@ -390,14 +390,14 @@ TEST_SUBMODULE(methods_and_attributes, m) { .def("increase_value", &RegisteredDerived::increase_value) .def_readwrite("rw_value", &RegisteredDerived::rw_value) .def_readonly("ro_value", &RegisteredDerived::ro_value) - // These should trigger a static_assert if uncommented - //.def_readwrite("fails", &UserType::value) // should trigger a static_assert if uncommented - //.def_readonly("fails", &UserType::value) // should trigger a static_assert if uncommented + // Uncommenting the next line should trigger a static_assert: + // .def_readwrite("fails", &UserType::value) + // Uncommenting the next line should trigger a static_assert: + // .def_readonly("fails", &UserType::value) .def_property("rw_value_prop", &RegisteredDerived::get_int, &RegisteredDerived::set_int) .def_property_readonly("ro_value_prop", &RegisteredDerived::get_double) // This one is in the registered class: - .def("sum", &RegisteredDerived::sum) - ; + .def("sum", &RegisteredDerived::sum); using Adapted = decltype(py::method_adaptor(&RegisteredDerived::do_nothing)); static_assert(std::is_same::value, ""); diff --git a/tests/test_smart_ptr.cpp b/tests/test_smart_ptr.cpp index 534dec0be4..7fd5a9b36e 100644 --- a/tests/test_smart_ptr.cpp +++ b/tests/test_smart_ptr.cpp @@ -24,7 +24,7 @@ template class huge_unique_ptr { std::unique_ptr ptr; uint64_t padding[10]; public: - huge_unique_ptr(T *p) : ptr(p) {}; + huge_unique_ptr(T *p) : ptr(p) {} T *get() { return ptr.get(); } }; From 52401cee1f50820f6c1fde79bdf1dcf461549677 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 13 Jul 2021 13:06:16 -0700 Subject: [PATCH 2/4] Automatically inserted clang-format off-on around rst blocks (NO manual changes). --- include/pybind11/attr.h | 2 ++ include/pybind11/cast.h | 2 ++ include/pybind11/detail/common.h | 4 +++ include/pybind11/embed.h | 8 ++++++ include/pybind11/iostream.h | 6 +++++ include/pybind11/pybind11.h | 18 +++++++++++++ include/pybind11/pytypes.h | 46 ++++++++++++++++++++++++++++++++ 7 files changed, 86 insertions(+) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 60ed9fd90e..ea33c6a4c1 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -78,6 +78,7 @@ struct arithmetic { }; /// Mark a function for addition at the beginning of the existing overload chain instead of the end struct prepend { }; +// clang-format off /** \rst A call policy which places one or more guard variables (``Ts...``) around the function call. @@ -96,6 +97,7 @@ struct prepend { }; return foo(args...); // forwarded arguments }); \endrst */ +// clang-format on template struct call_guard; template <> struct call_guard<> { using type = detail::void_type; }; diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index a748c77c0f..9a39dab586 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -1095,9 +1095,11 @@ arg_v arg::operator=(T &&value) const { template using arg_t = arg_v; inline namespace literals { +// clang-format off /** \rst String literal version of `arg` \endrst */ +// clang-format on constexpr arg operator"" _a(const char *name, size_t) { return arg(name); } } // namespace literals diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index f804e7c85a..b409c0541d 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -281,6 +281,7 @@ extern "C" { return nullptr; \ } \ +// clang-format off /** \rst ***Deprecated in favor of PYBIND11_MODULE*** @@ -296,6 +297,7 @@ extern "C" { return m.ptr(); } \endrst */ +// clang-format on #define PYBIND11_PLUGIN(name) \ PYBIND11_DEPRECATED("PYBIND11_PLUGIN is deprecated, use PYBIND11_MODULE") \ static PyObject *pybind11_init(); \ @@ -308,6 +310,7 @@ extern "C" { } \ PyObject *pybind11_init() +// clang-format off /** \rst This macro creates the entry point that will be invoked when the Python interpreter imports an extension module. The module name is given as the fist argument and it @@ -329,6 +332,7 @@ extern "C" { }); } \endrst */ +// clang-format on #define PYBIND11_MODULE(name, variable) \ static ::pybind11::module_::module_def \ PYBIND11_CONCAT(pybind11_module_def_, name) PYBIND11_MAYBE_UNUSED; \ diff --git a/include/pybind11/embed.h b/include/pybind11/embed.h index 204aaf989f..d36b37f8d9 100644 --- a/include/pybind11/embed.h +++ b/include/pybind11/embed.h @@ -30,6 +30,7 @@ } #endif +// clang-format off /** \rst Add a new module to the table of builtins for the interpreter. Must be defined in global scope. The first macro parameter is the name of the @@ -45,6 +46,7 @@ }); } \endrst */ +// clang-format on #define PYBIND11_EMBEDDED_MODULE(name, variable) \ static ::pybind11::module_::module_def \ PYBIND11_CONCAT(pybind11_module_def_, name); \ @@ -87,6 +89,7 @@ struct embedded_module { PYBIND11_NAMESPACE_END(detail) +// clang-format off /** \rst Initialize the Python interpreter. No other pybind11 or CPython API functions can be called before this is done; with the exception of `PYBIND11_EMBEDDED_MODULE`. The @@ -100,6 +103,7 @@ PYBIND11_NAMESPACE_END(detail) .. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx \endrst */ +// clang-format on inline void initialize_interpreter(bool init_signal_handlers = true) { if (Py_IsInitialized()) pybind11_fail("The interpreter is already running"); @@ -110,6 +114,7 @@ inline void initialize_interpreter(bool init_signal_handlers = true) { module_::import("sys").attr("path").cast().append("."); } +// clang-format off /** \rst Shut down the Python interpreter. No pybind11 or CPython API functions can be called after this. In addition, pybind11 objects must not outlive the interpreter: @@ -145,6 +150,7 @@ inline void initialize_interpreter(bool init_signal_handlers = true) { freed, either due to reference cycles or user-created global data. \endrst */ +// clang-format on inline void finalize_interpreter() { handle builtins(PyEval_GetBuiltins()); const char *id = PYBIND11_INTERNALS_ID; @@ -165,6 +171,7 @@ inline void finalize_interpreter() { } } +// clang-format off /** \rst Scope guard version of `initialize_interpreter` and `finalize_interpreter`. This a move-only guard and only a single instance can exist. @@ -178,6 +185,7 @@ inline void finalize_interpreter() { py::print(Hello, World!); } // <-- interpreter shutdown \endrst */ +// clang-format on class scoped_interpreter { public: scoped_interpreter(bool init_signal_handlers = true) { diff --git a/include/pybind11/iostream.h b/include/pybind11/iostream.h index e4d2095857..b1a94dfd19 100644 --- a/include/pybind11/iostream.h +++ b/include/pybind11/iostream.h @@ -140,6 +140,7 @@ class pythonbuf : public std::streambuf { PYBIND11_NAMESPACE_END(detail) +// clang-format off /** \rst This a move-only guard that redirects output. @@ -164,6 +165,7 @@ PYBIND11_NAMESPACE_END(detail) std::cout << "Hello, World!"; } \endrst */ +// clang-format on class scoped_ostream_redirect { protected: std::streambuf *old; @@ -188,6 +190,7 @@ class scoped_ostream_redirect { }; +// clang-format off /** \rst Like `scoped_ostream_redirect`, but redirects cerr by default. This class is provided primary to make ``py::call_guard`` easier to make. @@ -199,6 +202,7 @@ class scoped_ostream_redirect { scoped_estream_redirect>()); \endrst */ +// clang-format on class scoped_estream_redirect : public scoped_ostream_redirect { public: scoped_estream_redirect(std::ostream &costream = std::cerr, @@ -235,6 +239,7 @@ class OstreamRedirect { PYBIND11_NAMESPACE_END(detail) +// clang-format off /** \rst This is a helper function to add a C++ redirect context manager to Python instead of using a C++ guard. To use it, add the following to your binding code: @@ -262,6 +267,7 @@ PYBIND11_NAMESPACE_END(detail) m.noisy_function_with_error_printing() \endrst */ +// clang-format on inline class_ add_ostream_redirect(module_ m, const std::string &name = "ostream_redirect") { return class_(std::move(m), name.c_str(), module_local()) diff --git a/include/pybind11/pybind11.h b/include/pybind11/pybind11.h index 616fa70255..401ee4824a 100644 --- a/include/pybind11/pybind11.h +++ b/include/pybind11/pybind11.h @@ -956,11 +956,13 @@ class module_ : public object { #endif } + // clang-format off /** \rst Create Python binding for a new function within the module scope. ``Func`` can be a plain C++ function, a function pointer, or a lambda function. For details on the ``Extra&& ... extra`` argument, see section :ref:`extras`. \endrst */ + // clang-format on template module_ &def(const char *name_, Func &&f, const Extra& ... extra) { cpp_function func(std::forward(f), name(name_), scope(*this), @@ -971,6 +973,7 @@ class module_ : public object { return *this; } + // clang-format off /** \rst Create and return a new Python submodule with the given name and docstring. This also works recursively, i.e. @@ -981,6 +984,7 @@ class module_ : public object { py::module_ m2 = m.def_submodule("sub", "A submodule of 'example'"); py::module_ m3 = m2.def_submodule("subsub", "A submodule of 'example.sub'"); \endrst */ + // clang-format on module_ def_submodule(const char *name, const char *doc = nullptr) { std::string full_name = std::string(PyModule_GetName(m_ptr)) + std::string(".") + std::string(name); @@ -1007,6 +1011,7 @@ class module_ : public object { *this = reinterpret_steal(obj); } + // clang-format off /** \rst Adds an object to the module using the given name. Throws if an object with the given name already exists. @@ -1014,6 +1019,7 @@ class module_ : public object { ``overwrite`` should almost always be false: attempting to overwrite objects that pybind11 has established will, in most cases, break things. \endrst */ + // clang-format on PYBIND11_NOINLINE void add_object(const char *name, handle obj, bool overwrite = false) { if (!overwrite && hasattr(*this, name)) pybind11_fail("Error during initialization: multiple incompatible definitions with name \"" + @@ -1028,12 +1034,14 @@ class module_ : public object { struct module_def {}; #endif + // clang-format off /** \rst Create a new top-level module that can be used as the main module of a C extension. For Python 3, ``def`` should point to a statically allocated module_def. For Python 2, ``def`` can be a nullptr and is completely ignored. \endrst */ + // clang-format on static module_ create_extension_module(const char *name, const char *doc, module_def *def) { #if PY_MAJOR_VERSION >= 3 // module_def is PyModuleDef @@ -2173,6 +2181,7 @@ inline function get_type_override(const void *this_ptr, const type_info *this_ty } PYBIND11_NAMESPACE_END(detail) +// clang-format off /** \rst Try to retrieve a python method by the provided name from the instance pointed to by the this_ptr. @@ -2181,6 +2190,7 @@ PYBIND11_NAMESPACE_END(detail) :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 */ +// clang-format on template function get_override(const T *this_ptr, const char *name) { auto tinfo = detail::get_type_info(typeid(T)); return tinfo ? detail::get_type_override(this_ptr, tinfo, name) : function(); @@ -2201,6 +2211,7 @@ template function get_override(const T *this_ptr, const char *name) { } \ } while (false) +// clang-format off /** \rst Macro to populate the virtual method in the trampoline class. This macro tries to look up a method named 'fn' from the Python side, deals with the :ref:`gil` and necessary argument conversions to call this method and return @@ -2218,22 +2229,26 @@ template function get_override(const T *this_ptr, const char *name) { ); } \endrst */ +// clang-format on #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) +// clang-format off /** \rst 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 */ +// clang-format on #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) +// clang-format off /** \rst Macro to populate the virtual method in the trampoline class. This macro tries to look up the method from the Python side, deals with the :ref:`gil` and necessary argument conversions to call this method and return @@ -2258,13 +2273,16 @@ template function get_override(const T *this_ptr, const char *name) { } }; \endrst */ +// clang-format on #define PYBIND11_OVERRIDE(ret_type, cname, fn, ...) \ PYBIND11_OVERRIDE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__) +// clang-format off /** \rst 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 */ +// clang-format on #define PYBIND11_OVERRIDE_PURE(ret_type, cname, fn, ...) \ PYBIND11_OVERRIDE_PURE_NAME(PYBIND11_TYPE(ret_type), PYBIND11_TYPE(cname), #fn, fn, __VA_ARGS__) diff --git a/include/pybind11/pytypes.h b/include/pybind11/pytypes.h index 0fca32a4e9..db758807a6 100644 --- a/include/pybind11/pytypes.h +++ b/include/pybind11/pytypes.h @@ -47,54 +47,65 @@ using tuple_accessor = accessor; class pyobject_tag { }; template using is_pyobject = std::is_base_of>; +// clang-format off /** \rst A mixin class which adds common functions to `handle`, `object` and various accessors. The only requirement for `Derived` is to implement ``PyObject *Derived::ptr() const``. \endrst */ +// clang-format on template class object_api : public pyobject_tag { const Derived &derived() const { return static_cast(*this); } public: + // clang-format off /** \rst Return an iterator equivalent to calling ``iter()`` in Python. The object must be a collection which supports the iteration protocol. \endrst */ + // clang-format on iterator begin() const; /// Return a sentinel which ends iteration. iterator end() const; + // clang-format off /** \rst Return an internal functor to invoke the object's sequence protocol. Casting the returned ``detail::item_accessor`` instance to a `handle` or `object` subclass causes a corresponding call to ``__getitem__``. Assigning a `handle` or `object` subclass causes a call to ``__setitem__``. \endrst */ + // clang-format on item_accessor operator[](handle key) const; /// See above (the only difference is that they key is provided as a string literal) item_accessor operator[](const char *key) const; + // clang-format off /** \rst Return an internal functor to access the object's attributes. Casting the returned ``detail::obj_attr_accessor`` instance to a `handle` or `object` subclass causes a corresponding call to ``getattr``. Assigning a `handle` or `object` subclass causes a call to ``setattr``. \endrst */ + // clang-format on obj_attr_accessor attr(handle key) const; /// See above (the only difference is that they key is provided as a string literal) str_attr_accessor attr(const char *key) const; + // clang-format off /** \rst Matches * unpacking in Python, e.g. to unpack arguments out of a ``tuple`` or ``list`` for a function call. Applying another * to the result yields ** unpacking, e.g. to unpack a dict as function keyword arguments. See :ref:`calling_python_functions`. \endrst */ + // clang-format on args_proxy operator*() const; /// Check if the given item is contained within this object, i.e. ``item in obj``. template bool contains(T &&item) const; + // clang-format off /** \rst Assuming the Python object is a function or implements the ``__call__`` protocol, ``operator()`` invokes the underlying function, passing an @@ -105,6 +116,7 @@ class object_api : public pyobject_tag { function will throw a `cast_error` exception. When the Python function call fails, a `error_already_set` exception is thrown. \endrst */ + // clang-format on template object operator()(Args &&...args) const; template @@ -162,6 +174,7 @@ class object_api : public pyobject_tag { PYBIND11_NAMESPACE_END(detail) +// clang-format off /** \rst Holds a reference to a Python object (no reference counting) @@ -173,6 +186,7 @@ PYBIND11_NAMESPACE_END(detail) The `object` class inherits from `handle` and adds automatic reference counting features. \endrst */ +// clang-format on class handle : public detail::object_api { public: /// The default constructor creates a handle with a ``nullptr``-valued pointer @@ -184,31 +198,39 @@ class handle : public detail::object_api { PyObject *ptr() const { return m_ptr; } PyObject *&ptr() { return m_ptr; } + // clang-format off /** \rst Manually increase the reference count of the Python object. Usually, it is preferable to use the `object` class which derives from `handle` and calls this function automatically. Returns a reference to itself. \endrst */ + // clang-format on const handle& inc_ref() const & { Py_XINCREF(m_ptr); return *this; } + // clang-format off /** \rst Manually decrease the reference count of the Python object. Usually, it is preferable to use the `object` class which derives from `handle` and calls this function automatically. Returns a reference to itself. \endrst */ + // clang-format on const handle& dec_ref() const & { Py_XDECREF(m_ptr); return *this; } + // clang-format off /** \rst Attempt to cast the Python object into the given C++ type. A `cast_error` will be throw upon failure. \endrst */ + // clang-format on template T cast() const; /// Return ``true`` when the `handle` wraps a valid Python object explicit operator bool() const { return m_ptr != nullptr; } + // clang-format off /** \rst Deprecated: Check that the underlying pointers are the same. Equivalent to ``obj1 is obj2`` in Python. \endrst */ + // clang-format on PYBIND11_DEPRECATED("Use obj1.is(obj2) instead") bool operator==(const handle &h) const { return m_ptr == h.m_ptr; } PYBIND11_DEPRECATED("Use !obj1.is(obj2) instead") @@ -219,6 +241,7 @@ class handle : public detail::object_api { PyObject *m_ptr = nullptr; }; +// clang-format off /** \rst Holds a reference to a Python object (with reference counting) @@ -229,6 +252,7 @@ class handle : public detail::object_api { scope and is destructed. When using `object` instances consistently, it is much easier to get reference counting right at the first attempt. \endrst */ +// clang-format on class object : public handle { public: object() = default; @@ -241,11 +265,13 @@ class object : public handle { /// Destructor; automatically calls `handle::dec_ref()` ~object() { dec_ref(); } + // clang-format off /** \rst Resets the internal pointer to ``nullptr`` without decreasing the object's reference count. The function returns a raw handle to the original Python object. \endrst */ + // clang-format on handle release() { PyObject *tmp = m_ptr; m_ptr = nullptr; @@ -290,6 +316,7 @@ class object : public handle { object(handle h, stolen_t) : handle(h) { } }; +// clang-format off /** \rst Declare that a `handle` or ``PyObject *`` is a certain type and borrow the reference. The target type ``T`` must be `object` or one of its derived classes. The function @@ -303,8 +330,10 @@ class object : public handle { // or py::tuple t = reinterpret_borrow(p); // <-- `p` must be already be a `tuple` \endrst */ +// clang-format on template T reinterpret_borrow(handle h) { return {h, object::borrowed_t{}}; } +// clang-format off /** \rst Like `reinterpret_borrow`, but steals the reference. @@ -313,6 +342,7 @@ template T reinterpret_borrow(handle h) { return {h, object::borrow PyObject *p = PyObject_Str(obj); py::str s = reinterpret_steal(p); // <-- `p` must be already be a `str` \endrst */ +// clang-format on template T reinterpret_steal(handle h) { return {h, object::stolen_t{}}; } PYBIND11_NAMESPACE_BEGIN(detail) @@ -386,10 +416,12 @@ class PYBIND11_EXPORT error_already_set : public std::runtime_error { */ /** \ingroup python_builtins + // clang-format off \rst Return true if ``obj`` is an instance of ``T``. Type ``T`` must be a subclass of `object` or a class which was exposed to Python as ``py::class_``. \endrst */ + // clang-format on template ::value, int> = 0> bool isinstance(handle obj) { return T::check_(obj); } @@ -885,6 +917,7 @@ PYBIND11_NAMESPACE_END(detail) /// \addtogroup pytypes /// @{ +// clang-format off /** \rst Wraps a Python iterator so that it can also be used as a C++ input iterator @@ -893,6 +926,7 @@ PYBIND11_NAMESPACE_END(detail) operator. This iterator should only be used to retrieve the current value using ``operator*()``. \endrst */ +// clang-format on class iterator : public object { public: using iterator_category = std::input_iterator_tag; @@ -924,6 +958,7 @@ class iterator : public object { pointer operator->() const { operator*(); return &value; } + // clang-format off /** \rst The value which marks the end of the iteration. ``it == iterator::sentinel()`` is equivalent to catching ``StopIteration`` in Python. @@ -937,6 +972,7 @@ class iterator : public object { } } \endrst */ + // clang-format on static iterator sentinel() { return {}; } friend bool operator==(const iterator &a, const iterator &b) { return a->ptr() == b->ptr(); } @@ -1004,10 +1040,12 @@ class str : public object { explicit str(const bytes &b); + // clang-format off /** \rst Return a string representation of the object. This is analogous to the ``str()`` function in Python. \endrst */ + // clang-format on explicit str(handle h) : object(raw_str(h.ptr()), stolen_t{}) { if (!m_ptr) throw error_already_set(); } operator std::string() const { @@ -1044,9 +1082,11 @@ class str : public object { /// @} pytypes inline namespace literals { +// clang-format off /** \rst String literal version of `str` \endrst */ +// clang-format on inline str operator"" _s(const char *s, size_t size) { return {s, size}; } } // namespace literals @@ -1488,6 +1528,7 @@ class memoryview : public object { public: PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject) + // clang-format off /** \rst Creates ``memoryview`` from ``buffer_info``. @@ -1497,6 +1538,7 @@ class memoryview : public object { For creating a ``memoryview`` from objects that support buffer protocol, use ``memoryview(const object& obj)`` instead of this constructor. \endrst */ + // clang-format on explicit memoryview(const buffer_info& info) { if (!info.view()) pybind11_fail("Prohibited to create memoryview without Py_buffer"); @@ -1508,6 +1550,7 @@ class memoryview : public object { pybind11_fail("Unable to create memoryview from buffer descriptor"); } + // clang-format off /** \rst Creates ``memoryview`` from static buffer. @@ -1531,6 +1574,7 @@ class memoryview : public object { :param readonly: Flag to indicate if the underlying storage may be written to. \endrst */ + // clang-format on static memoryview from_buffer( void *ptr, ssize_t itemsize, const char *format, detail::any_container shape, @@ -1562,6 +1606,7 @@ class memoryview : public object { } #if PY_MAJOR_VERSION >= 3 + // clang-format off /** \rst Creates ``memoryview`` from static memory. @@ -1575,6 +1620,7 @@ class memoryview : public object { .. _PyMemoryView_FromMemory: https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromMemory \endrst */ + // clang-format on static memoryview from_memory(void *mem, ssize_t size, bool readonly = false) { PyObject* ptr = PyMemoryView_FromMemory( reinterpret_cast(mem), size, From 46ee6e0eeb6fc76a101e7e53230b994c7a1cdd6f Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 9 Jul 2021 07:31:57 -0700 Subject: [PATCH 3/4] Adding docker-clang-format hook to .pre-commit-config.yaml --- .pre-commit-config.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 133eb6df4e..6af90465ae 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,6 +12,10 @@ # # See https://github.com/pre-commit/pre-commit +ci: + skip: + - docker-clang-format + repos: # Standard hooks - repo: https://github.com/pre-commit/pre-commit-hooks @@ -108,6 +112,19 @@ repos: entry: PyBind|Numpy|Cmake|CCache exclude: .pre-commit-config.yaml +- repo: local + hooks: + - id: docker-clang-format + name: Docker Clang Format + language: docker_image + types: + - c++ + entry: silkeh/clang:12 + args: + - clang-format + - -style=file + - -i + - repo: local hooks: - id: check-style From e2089eb30febe20e8882ae42b4fc60654891033a Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Tue, 13 Jul 2021 13:54:05 -0700 Subject: [PATCH 4/4] Bulk docker-clang-format (NO manual changes). --- include/pybind11/attr.h | 251 ++-- include/pybind11/buffer_info.h | 118 +- include/pybind11/cast.h | 802 ++++++++----- include/pybind11/chrono.h | 128 +- include/pybind11/complex.h | 22 +- include/pybind11/detail/class.h | 81 +- include/pybind11/detail/common.h | 850 +++++++------ include/pybind11/detail/descr.h | 55 +- include/pybind11/detail/init.h | 259 ++-- include/pybind11/detail/internals.h | 232 ++-- include/pybind11/detail/type_caster_base.h | 332 +++--- include/pybind11/detail/typeid.h | 12 +- include/pybind11/eigen.h | 437 ++++--- include/pybind11/embed.h | 57 +- include/pybind11/eval.h | 79 +- include/pybind11/functional.h | 16 +- include/pybind11/gil.h | 48 +- include/pybind11/iostream.h | 45 +- include/pybind11/numpy.h | 1081 ++++++++++------- include/pybind11/operators.h | 259 ++-- include/pybind11/options.h | 41 +- include/pybind11/pybind11.h | 1248 ++++++++++++-------- include/pybind11/pytypes.h | 879 ++++++++------ include/pybind11/stl.h | 164 +-- include/pybind11/stl/filesystem.h | 41 +- include/pybind11/stl_bind.h | 441 +++---- tests/constructor_stats.h | 127 +- tests/cross_module_gil_utils.cpp | 38 +- tests/local_bindings.h | 26 +- tests/object.h | 66 +- tests/pybind11_cross_module_tests.cpp | 65 +- tests/pybind11_tests.cpp | 19 +- tests/pybind11_tests.h | 31 +- tests/test_async.cpp | 5 +- tests/test_buffers.cpp | 73 +- tests/test_builtin_casters.cpp | 281 +++-- tests/test_call_policies.cpp | 43 +- tests/test_callbacks.cpp | 63 +- tests/test_chrono.cpp | 31 +- tests/test_class.cpp | 284 +++-- tests/test_constants_and_functions.cpp | 67 +- tests/test_copy_move.cpp | 177 ++- tests/test_custom_type_casters.cpp | 100 +- tests/test_docstring_options.cpp | 55 +- tests/test_eigen.cpp | 186 +-- tests/test_embed/catch.cpp | 6 +- tests/test_embed/external_module.cpp | 9 +- tests/test_embed/test_interpreter.cpp | 53 +- tests/test_enum.cpp | 40 +- tests/test_eval.cpp | 23 +- tests/test_exceptions.cpp | 89 +- tests/test_factory_constructors.cpp | 119 +- tests/test_gil_scoped.cpp | 43 +- tests/test_iostream.cpp | 30 +- tests/test_kwargs_and_defaults.cpp | 166 ++- tests/test_local_bindings.cpp | 38 +- tests/test_methods_and_attributes.cpp | 188 +-- tests/test_modules.cpp | 65 +- tests/test_multiple_inheritance.cpp | 156 ++- tests/test_numpy_array.cpp | 268 +++-- tests/test_numpy_dtypes.cpp | 295 +++-- tests/test_numpy_vectorize.cpp | 29 +- tests/test_opaque_types.cpp | 11 +- tests/test_operator_overloading.cpp | 160 ++- tests/test_pickling.cpp | 6 +- tests/test_pytypes.cpp | 156 ++- tests/test_sequences_and_iterators.cpp | 92 +- tests/test_smart_ptr.cpp | 98 +- tests/test_stl.cpp | 155 +-- tests/test_stl_binders.cpp | 74 +- tests/test_tagbased_polymorphic.cpp | 108 +- tests/test_virtual_functions.cpp | 237 ++-- 72 files changed, 7243 insertions(+), 5186 deletions(-) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index ea33c6a4c1..b749f2c141 100644 --- a/include/pybind11/attr.h +++ b/include/pybind11/attr.h @@ -18,44 +18,62 @@ PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) /// @{ /// Annotation for methods -struct is_method { handle class_; is_method(const handle &c) : class_(c) { } }; +struct is_method { + handle class_; + is_method(const handle &c) : class_(c) {} +}; /// Annotation for operators -struct is_operator { }; +struct is_operator {}; /// Annotation for classes that cannot be subclassed -struct is_final { }; +struct is_final {}; /// Annotation for parent scope -struct scope { handle value; scope(const handle &s) : value(s) { } }; +struct scope { + handle value; + scope(const handle &s) : value(s) {} +}; /// Annotation for documentation -struct doc { const char *value; doc(const char *value) : value(value) { } }; +struct doc { + const char *value; + doc(const char *value) : value(value) {} +}; /// Annotation for function names -struct name { const char *value; name(const char *value) : value(value) { } }; +struct name { + const char *value; + name(const char *value) : value(value) {} +}; /// Annotation indicating that a function is an overload associated with a given "sibling" -struct sibling { handle value; sibling(const handle &value) : value(value.ptr()) { } }; +struct sibling { + handle value; + sibling(const handle &value) : value(value.ptr()) {} +}; /// Annotation indicating that a class derives from another given type -template struct base { +template +struct base { - PYBIND11_DEPRECATED("base() was deprecated in favor of specifying 'T' as a template argument to class_") - base() { } // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute + PYBIND11_DEPRECATED( + "base() was deprecated in favor of specifying 'T' as a template argument to class_") + base() {} // NOLINT(modernize-use-equals-default): breaks MSVC 2015 when adding an attribute }; /// Keep patient alive while nurse lives -template struct keep_alive { }; +template +struct keep_alive {}; /// Annotation indicating that a class is involved in a multiple inheritance relationship -struct multiple_inheritance { }; +struct multiple_inheritance {}; /// Annotation which enables dynamic attributes, i.e. adds `__dict__` to a class -struct dynamic_attr { }; +struct dynamic_attr {}; /// Annotation which enables the buffer protocol for a type -struct buffer_protocol { }; +struct buffer_protocol {}; /// Annotation which requests that a special metaclass is created for a type struct metaclass { @@ -66,17 +84,20 @@ struct metaclass { metaclass() {} /// Override pybind11's default metaclass - explicit metaclass(handle value) : value(value) { } + explicit metaclass(handle value) : value(value) {} }; /// Annotation that marks a class as local to the module: -struct module_local { const bool value; constexpr module_local(bool v = true) : value(v) { } }; +struct module_local { + const bool value; + constexpr module_local(bool v = true) : value(v) {} +}; /// Annotation to mark enums as an arithmetic type -struct arithmetic { }; +struct arithmetic {}; /// Mark a function for addition at the beginning of the existing overload chain instead of the end -struct prepend { }; +struct prepend {}; // clang-format off /** \rst @@ -98,9 +119,13 @@ struct prepend { }; }); \endrst */ // clang-format on -template struct call_guard; +template +struct call_guard; -template <> struct call_guard<> { using type = detail::void_type; }; +template <> +struct call_guard<> { + using type = detail::void_type; +}; template struct call_guard { @@ -125,7 +150,8 @@ PYBIND11_NAMESPACE_BEGIN(detail) enum op_id : int; enum op_type : int; struct undefined_t; -template struct op_; +template +struct op_; inline void keep_alive_impl(size_t Nurse, size_t Patient, function_call &call, handle ret); /// Internal data structure which holds metadata about a keyword argument @@ -137,15 +163,16 @@ struct argument_record { bool none : 1; ///< True if None is allowed when loading argument_record(const char *name, const char *descr, handle value, bool convert, bool none) - : name(name), descr(descr), value(value), convert(convert), none(none) { } + : name(name), descr(descr), value(value), convert(convert), none(none) {} }; -/// Internal data structure which holds metadata about a bound function (signature, overloads, etc.) +/// Internal data structure which holds metadata about a bound function (signature, overloads, +/// etc.) struct function_record { function_record() : is_constructor(false), is_new_style_constructor(false), is_stateless(false), - is_operator(false), is_method(false), has_args(false), - has_kwargs(false), has_kw_only_args(false), prepend(false) { } + is_operator(false), is_method(false), has_args(false), has_kwargs(false), + has_kw_only_args(false), prepend(false) {} /// Function name char *name = nullptr; /* why no C++ strings? They generate heavier code.. */ @@ -160,13 +187,13 @@ struct function_record { std::vector args; /// Pointer to lambda function which converts arguments and performs the actual call - handle (*impl) (function_call &) = nullptr; + handle (*impl)(function_call &) = nullptr; /// Storage for the wrapped function pointer and captured data, if any - void *data[3] = { }; + void *data[3] = {}; /// Pointer to custom destructor for 'data' (if needed) - void (*free_data) (function_record *ptr) = nullptr; + void (*free_data)(function_record *ptr) = nullptr; /// Return value policy associated with this function return_value_policy policy = return_value_policy::automatic; @@ -224,7 +251,7 @@ struct function_record { struct type_record { PYBIND11_NOINLINE type_record() : multiple_inheritance(false), dynamic_attr(false), buffer_protocol(false), - default_holder(true), module_local(false), is_final(false) { } + default_holder(true), module_local(false), is_final(false) {} /// Handle to the parent scope handle scope; @@ -280,22 +307,22 @@ struct type_record { /// Is the class inheritable from python classes? bool is_final : 1; - PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *)) { + PYBIND11_NOINLINE void add_base(const std::type_info &base, void *(*caster)(void *) ) { auto base_info = detail::get_type_info(base, false); if (!base_info) { std::string tname(base.name()); detail::clean_type_id(tname); - pybind11_fail("generic_type: type \"" + std::string(name) + - "\" referenced unknown base type \"" + tname + "\""); + pybind11_fail("generic_type: type \"" + std::string(name) + + "\" referenced unknown base type \"" + tname + "\""); } if (default_holder != base_info->default_holder) { std::string tname(base.name()); detail::clean_type_id(tname); - pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + - (default_holder ? "does not have" : "has") + - " a non-default holder type while its base \"" + tname + "\" " + - (base_info->default_holder ? "does not" : "does")); + pybind11_fail("generic_type: type \"" + std::string(name) + "\" " + + (default_holder ? "does not have" : "has") + + " a non-default holder type while its base \"" + tname + "\" " + + (base_info->default_holder ? "does not" : "does")); } bases.append((PyObject *) base_info->type); @@ -308,14 +335,13 @@ struct type_record { } }; -inline function_call::function_call(const function_record &f, handle p) : - func(f), parent(p) { +inline function_call::function_call(const function_record &f, handle p) : func(f), parent(p) { args.reserve(f.nargs); args_convert.reserve(f.nargs); } /// Tag for a new-style `__init__` defined in `detail/init.h` -struct is_new_style_constructor { }; +struct is_new_style_constructor {}; /** * Partial template specializations to process custom attributes provided to @@ -323,60 +349,79 @@ struct is_new_style_constructor { }; * fields in the type_record and function_record data structures or executed at * runtime to deal with custom call policies (e.g. keep_alive). */ -template struct process_attribute; +template +struct process_attribute; -template struct process_attribute_default { +template +struct process_attribute_default { /// Default implementation: do nothing - static void init(const T &, function_record *) { } - static void init(const T &, type_record *) { } - static void precall(function_call &) { } - static void postcall(function_call &, handle) { } + static void init(const T &, function_record *) {} + static void init(const T &, type_record *) {} + static void precall(function_call &) {} + static void postcall(function_call &, handle) {} }; /// Process an attribute specifying the function's name -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const name &n, function_record *r) { r->name = const_cast(n.value); } }; /// Process an attribute specifying the function's docstring -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const doc &n, function_record *r) { r->doc = const_cast(n.value); } }; /// Process an attribute specifying the function's docstring (provided as a C-style string) -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const char *d, function_record *r) { r->doc = const_cast(d); } static void init(const char *d, type_record *r) { r->doc = const_cast(d); } }; -template <> struct process_attribute : process_attribute { }; +template <> +struct process_attribute : process_attribute {}; /// Process an attribute indicating the function's return value policy -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const return_value_policy &p, function_record *r) { r->policy = p; } }; -/// Process an attribute which indicates that this is an overloaded function associated with a given sibling -template <> struct process_attribute : process_attribute_default { +/// Process an attribute which indicates that this is an overloaded function associated with a +/// given sibling +template <> +struct process_attribute : process_attribute_default { static void init(const sibling &s, function_record *r) { r->sibling = s.value; } }; /// Process an attribute which indicates that this function is a method -template <> struct process_attribute : process_attribute_default { - static void init(const is_method &s, function_record *r) { r->is_method = true; r->scope = s.class_; } +template <> +struct process_attribute : process_attribute_default { + static void init(const is_method &s, function_record *r) { + r->is_method = true; + r->scope = s.class_; + } }; /// Process an attribute which indicates the parent scope of a method -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const scope &s, function_record *r) { r->scope = s.value; } }; /// Process an attribute which indicates that this function is an operator -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const is_operator &, function_record *r) { r->is_operator = true; } }; -template <> struct process_attribute : process_attribute_default { - static void init(const is_new_style_constructor &, function_record *r) { r->is_new_style_constructor = true; } +template <> +struct process_attribute + : process_attribute_default { + static void init(const is_new_style_constructor &, function_record *r) { + r->is_new_style_constructor = true; + } }; inline void process_kw_only_arg(const arg &a, function_record *r) { @@ -386,37 +431,47 @@ inline void process_kw_only_arg(const arg &a, function_record *r) { } /// Process a keyword argument attribute (*without* a default value) -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const arg &a, function_record *r) { if (r->is_method && r->args.empty()) - r->args.emplace_back("self", nullptr, handle(), true /*convert*/, false /*none not allowed*/); + r->args.emplace_back( + "self", nullptr, handle(), true /*convert*/, false /*none not allowed*/); r->args.emplace_back(a.name, nullptr, handle(), !a.flag_noconvert, a.flag_none); - if (r->has_kw_only_args) process_kw_only_arg(a, r); + if (r->has_kw_only_args) + process_kw_only_arg(a, r); } }; /// Process a keyword argument attribute (*with* a default value) -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const arg_v &a, function_record *r) { if (r->is_method && r->args.empty()) - r->args.emplace_back("self", nullptr /*descr*/, handle() /*parent*/, true /*convert*/, false /*none not allowed*/); + r->args.emplace_back("self", + nullptr /*descr*/, + handle() /*parent*/, + true /*convert*/, + false /*none not allowed*/); if (!a.value) { #if !defined(NDEBUG) std::string descr("'"); - if (a.name) descr += std::string(a.name) + ": "; + if (a.name) + descr += std::string(a.name) + ": "; descr += a.type + "'"; if (r->is_method) { if (r->name) - descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'"; + descr += " in method '" + (std::string) str(r->scope) + "." + + (std::string) r->name + "'"; else descr += " in method of '" + (std::string) str(r->scope) + "'"; } else if (r->name) { descr += " in function '" + (std::string) r->name + "'"; } - pybind11_fail("arg(): could not convert default argument " - + descr + " into a Python object (type not registered yet?)"); + pybind11_fail("arg(): could not convert default argument " + descr + + " into a Python object (type not registered yet?)"); #else pybind11_fail("arg(): could not convert default argument " "into a Python object (type not registered yet?). " @@ -425,27 +480,30 @@ template <> struct process_attribute : process_attribute_default { } r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none); - if (r->has_kw_only_args) process_kw_only_arg(a, r); + if (r->has_kw_only_args) + process_kw_only_arg(a, r); } }; /// Process a keyword-only-arguments-follow pseudo argument -template <> struct process_attribute : process_attribute_default { - static void init(const kw_only &, function_record *r) { - r->has_kw_only_args = true; - } +template <> +struct process_attribute : process_attribute_default { + static void init(const kw_only &, function_record *r) { r->has_kw_only_args = true; } }; /// Process a positional-only-argument maker -template <> struct process_attribute : process_attribute_default { +template <> +struct process_attribute : process_attribute_default { static void init(const pos_only &, function_record *r) { r->nargs_pos_only = static_cast(r->args.size()); } }; -/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees that) +/// Process a parent class attribute. Single inheritance only (class_ itself already guarantees +/// that) template -struct process_attribute::value>> : process_attribute_default { +struct process_attribute::value>> + : process_attribute_default { static void init(const handle &h, type_record *r) { r->bases.append(h); } }; @@ -458,7 +516,9 @@ struct process_attribute> : process_attribute_default> { /// Process a multiple inheritance attribute template <> struct process_attribute : process_attribute_default { - static void init(const multiple_inheritance &, type_record *r) { r->multiple_inheritance = true; } + static void init(const multiple_inheritance &, type_record *r) { + r->multiple_inheritance = true; + } }; template <> @@ -497,40 +557,51 @@ template <> struct process_attribute : process_attribute_default {}; template -struct process_attribute> : process_attribute_default> { }; +struct process_attribute> : process_attribute_default> {}; /** * Process a keep_alive call policy -- invokes keep_alive_impl during the * pre-call handler if both Nurse, Patient != 0 and use the post-call handler * otherwise */ -template struct process_attribute> : public process_attribute_default> { +template +struct process_attribute> + : public process_attribute_default> { template = 0> - static void precall(function_call &call) { keep_alive_impl(Nurse, Patient, call, handle()); } + static void precall(function_call &call) { + keep_alive_impl(Nurse, Patient, call, handle()); + } template = 0> - static void postcall(function_call &, handle) { } + static void postcall(function_call &, handle) {} template = 0> - static void precall(function_call &) { } + static void precall(function_call &) {} template = 0> - static void postcall(function_call &call, handle ret) { keep_alive_impl(Nurse, Patient, call, ret); } + static void postcall(function_call &call, handle ret) { + keep_alive_impl(Nurse, Patient, call, ret); + } }; /// Recursively iterate over variadic template arguments -template struct process_attributes { - static void init(const Args&... args, function_record *r) { - int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; +template +struct process_attributes { + static void init(const Args &...args, function_record *r) { + int unused[] + = {0, (process_attribute::type>::init(args, r), 0)...}; ignore_unused(unused); } - static void init(const Args&... args, type_record *r) { - int unused[] = { 0, (process_attribute::type>::init(args, r), 0) ... }; + static void init(const Args &...args, type_record *r) { + int unused[] + = {0, (process_attribute::type>::init(args, r), 0)...}; ignore_unused(unused); } static void precall(function_call &call) { - int unused[] = { 0, (process_attribute::type>::precall(call), 0) ... }; + int unused[] + = {0, (process_attribute::type>::precall(call), 0)...}; ignore_unused(unused); } static void postcall(function_call &call, handle fn_ret) { - int unused[] = { 0, (process_attribute::type>::postcall(call, fn_ret), 0) ... }; + int unused[] = { + 0, (process_attribute::type>::postcall(call, fn_ret), 0)...}; ignore_unused(unused); } }; @@ -545,7 +616,7 @@ using extract_guard_t = typename exactly_one_t, Extr /// Check the number of named arguments at compile time template ::value...), - size_t self = constexpr_sum(std::is_same::value...)> + size_t self = constexpr_sum(std::is_same::value...)> constexpr bool expected_num_args(size_t nargs, bool has_args, bool has_kwargs) { return named == 0 || (self + named + size_t(has_args) + size_t(has_kwargs)) == nargs; } diff --git a/include/pybind11/buffer_info.h b/include/pybind11/buffer_info.h index 47dc39d4ea..45d88d7ab8 100644 --- a/include/pybind11/buffer_info.h +++ b/include/pybind11/buffer_info.h @@ -38,21 +38,28 @@ PYBIND11_NAMESPACE_END(detail) /// Information record describing a Python buffer object struct buffer_info { - void *ptr = nullptr; // Pointer to the underlying storage - ssize_t itemsize = 0; // Size of individual items in bytes - ssize_t size = 0; // Total number of entries - std::string format; // For homogeneous buffers, this should be set to format_descriptor::format() - ssize_t ndim = 0; // Number of dimensions - std::vector shape; // Shape of the tensor (1 entry per dimension) - std::vector 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 + void *ptr = nullptr; // Pointer to the underlying storage + ssize_t itemsize = 0; // Size of individual items in bytes + ssize_t size = 0; // Total number of entries + std::string + format; // For homogeneous buffers, this should be set to format_descriptor::format() + ssize_t ndim = 0; // Number of dimensions + std::vector shape; // Shape of the tensor (1 entry per dimension) + std::vector + 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 buffer_info() = default; - buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, - detail::any_container shape_in, detail::any_container strides_in, bool readonly=false) - : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), - shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) { + buffer_info(void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t ndim, + detail::any_container shape_in, + detail::any_container strides_in, + bool readonly = false) + : ptr(ptr), itemsize(itemsize), size(1), format(format), ndim(ndim), + shape(std::move(shape_in)), strides(std::move(strides_in)), readonly(readonly) { if (ndim != (ssize_t) shape.size() || ndim != (ssize_t) strides.size()) pybind11_fail("buffer_info: ndim doesn't match shape and/or strides length"); for (size_t i = 0; i < (size_t) ndim; ++i) @@ -60,36 +67,55 @@ struct buffer_info { } template - buffer_info(T *ptr, detail::any_container shape_in, detail::any_container strides_in, bool readonly=false) - : buffer_info(private_ctr_tag(), ptr, sizeof(T), format_descriptor::format(), static_cast(shape_in->size()), std::move(shape_in), std::move(strides_in), readonly) { } - - buffer_info(void *ptr, ssize_t itemsize, const std::string &format, ssize_t size, bool readonly=false) - : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) { } + buffer_info(T *ptr, + detail::any_container shape_in, + detail::any_container strides_in, + bool readonly = false) + : buffer_info(private_ctr_tag(), + ptr, + sizeof(T), + format_descriptor::format(), + static_cast(shape_in->size()), + std::move(shape_in), + std::move(strides_in), + readonly) {} + + buffer_info(void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t size, + bool readonly = false) + : buffer_info(ptr, itemsize, format, 1, {size}, {itemsize}, readonly) {} template - buffer_info(T *ptr, ssize_t size, bool readonly=false) - : buffer_info(ptr, sizeof(T), format_descriptor::format(), size, readonly) { } + buffer_info(T *ptr, ssize_t size, bool readonly = false) + : buffer_info(ptr, sizeof(T), format_descriptor::format(), size, readonly) {} template - buffer_info(const T *ptr, ssize_t size, bool readonly=true) - : buffer_info(const_cast(ptr), sizeof(T), format_descriptor::format(), size, readonly) { } + buffer_info(const T *ptr, ssize_t size, bool readonly = true) + : buffer_info( + const_cast(ptr), sizeof(T), format_descriptor::format(), size, readonly) {} explicit buffer_info(Py_buffer *view, bool ownview = true) - : buffer_info(view->buf, view->itemsize, view->format, view->ndim, + : buffer_info( + view->buf, + view->itemsize, + view->format, + view->ndim, {view->shape, view->shape + view->ndim}, /* Though buffer::request() requests PyBUF_STRIDES, ctypes objects * ignore this flag and return a view with NULL strides. * When strides are NULL, build them manually. */ view->strides - ? std::vector(view->strides, view->strides + view->ndim) - : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize), + ? std::vector(view->strides, view->strides + view->ndim) + : detail::c_strides({view->shape, view->shape + view->ndim}, view->itemsize), view->readonly) { this->m_view = view; this->ownview = ownview; } buffer_info(const buffer_info &) = delete; - buffer_info& operator=(const buffer_info &) = delete; + buffer_info &operator=(const buffer_info &) = delete; buffer_info(buffer_info &&other) noexcept { (*this) = std::move(other); } @@ -108,17 +134,28 @@ struct buffer_info { } ~buffer_info() { - if (m_view && ownview) { PyBuffer_Release(m_view); delete m_view; } + if (m_view && ownview) { + PyBuffer_Release(m_view); + delete m_view; + } } Py_buffer *view() const { return m_view; } Py_buffer *&view() { return m_view; } -private: - struct private_ctr_tag { }; - buffer_info(private_ctr_tag, void *ptr, ssize_t itemsize, const std::string &format, ssize_t ndim, - detail::any_container &&shape_in, detail::any_container &&strides_in, bool readonly) - : buffer_info(ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) { } +private: + struct private_ctr_tag {}; + + buffer_info(private_ctr_tag, + void *ptr, + ssize_t itemsize, + const std::string &format, + ssize_t ndim, + detail::any_container &&shape_in, + detail::any_container &&strides_in, + bool readonly) + : buffer_info( + ptr, itemsize, format, ndim, std::move(shape_in), std::move(strides_in), readonly) {} Py_buffer *m_view = nullptr; bool ownview = false; @@ -126,17 +163,22 @@ struct buffer_info { PYBIND11_NAMESPACE_BEGIN(detail) -template struct compare_buffer_info { - static bool compare(const buffer_info& b) { +template +struct compare_buffer_info { + static bool compare(const buffer_info &b) { return b.format == format_descriptor::format() && b.itemsize == (ssize_t) sizeof(T); } }; -template struct compare_buffer_info::value>> { - static bool compare(const buffer_info& b) { - return (size_t) b.itemsize == sizeof(T) && (b.format == format_descriptor::value || - ((sizeof(T) == sizeof(long)) && b.format == (std::is_unsigned::value ? "L" : "l")) || - ((sizeof(T) == sizeof(size_t)) && b.format == (std::is_unsigned::value ? "N" : "n"))); +template +struct compare_buffer_info::value>> { + static bool compare(const buffer_info &b) { + return (size_t) b.itemsize == sizeof(T) + && (b.format == format_descriptor::value + || ((sizeof(T) == sizeof(long)) + && b.format == (std::is_unsigned::value ? "L" : "l")) + || ((sizeof(T) == sizeof(size_t)) + && b.format == (std::is_unsigned::value ? "N" : "n"))); } }; diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h index 9a39dab586..79b39c9577 100644 --- a/include/pybind11/cast.h +++ b/include/pybind11/cast.h @@ -10,11 +10,11 @@ #pragma once -#include "pytypes.h" #include "detail/common.h" #include "detail/descr.h" #include "detail/type_caster_base.h" #include "detail/typeid.h" +#include "pytypes.h" #include #include #include @@ -28,60 +28,69 @@ #include #if defined(PYBIND11_CPP17) -# if defined(__has_include) -# if __has_include() -# define PYBIND11_HAS_STRING_VIEW +# if defined(__has_include) +# if __has_include() +# define PYBIND11_HAS_STRING_VIEW +# endif +# elif defined(_MSC_VER) +# define PYBIND11_HAS_STRING_VIEW # endif -# elif defined(_MSC_VER) -# define PYBIND11_HAS_STRING_VIEW -# endif #endif #ifdef PYBIND11_HAS_STRING_VIEW -#include +# include #endif #if defined(__cpp_lib_char8_t) && __cpp_lib_char8_t >= 201811L -# define PYBIND11_HAS_U8STRING +# define PYBIND11_HAS_U8STRING #endif PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE) PYBIND11_NAMESPACE_BEGIN(detail) -template class type_caster : public type_caster_base { }; -template using make_caster = type_caster>; +template +class type_caster : public type_caster_base {}; +template +using make_caster = type_caster>; // Shortcut for calling a caster's `cast_op_type` cast operator for casting a type_caster to a T -template typename make_caster::template cast_op_type cast_op(make_caster &caster) { +template +typename make_caster::template cast_op_type cast_op(make_caster &caster) { return caster.operator typename make_caster::template cast_op_type(); } -template typename make_caster::template cast_op_type::type> +template +typename make_caster::template cast_op_type::type> cast_op(make_caster &&caster) { - return std::move(caster).operator - typename make_caster::template cast_op_type::type>(); + return std::move(caster).operator typename make_caster:: + template cast_op_type::type>(); } -template class type_caster> { +template +class type_caster> { private: using caster_t = make_caster; caster_t subcaster; - using reference_t = type&; - using subcaster_cast_op_type = - typename caster_t::template cast_op_type; - - static_assert(std::is_same::type &, subcaster_cast_op_type>::value || - std::is_same::value, - "std::reference_wrapper caster requires T to have a caster with an " - "`operator T &()` or `operator const T &()`"); + using reference_t = type &; + using subcaster_cast_op_type = typename caster_t::template cast_op_type; + + static_assert( + std::is_same::type &, subcaster_cast_op_type>::value + || std::is_same::value, + "std::reference_wrapper caster requires T to have a caster with an " + "`operator T &()` or `operator const T &()`"); + public: bool load(handle src, bool convert) { return subcaster.load(src, convert); } static constexpr auto name = caster_t::name; - static handle cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { + static handle + cast(const std::reference_wrapper &src, return_value_policy policy, handle parent) { // It is definitely wrong to take ownership of this pointer, so mask that rvp - if (policy == return_value_policy::take_ownership || policy == return_value_policy::automatic) + if (policy == return_value_policy::take_ownership + || policy == return_value_policy::automatic) policy = return_value_policy::automatic_reference; return caster_t::cast(&src.get(), policy, parent); } - template using cast_op_type = std::reference_wrapper; + template + using cast_op_type = std::reference_wrapper; operator std::reference_wrapper() { return cast_op(subcaster); } }; @@ -108,24 +117,25 @@ public: template \ using cast_op_type = pybind11::detail::movable_cast_op_type -template using is_std_char_type = any_of< - std::is_same, /* std::string */ +template +using is_std_char_type = any_of, /* std::string */ #if defined(PYBIND11_HAS_U8STRING) - std::is_same, /* std::u8string */ + std::is_same, /* std::u8string */ #endif - std::is_same, /* std::u16string */ - std::is_same, /* std::u32string */ - std::is_same /* std::wstring */ ->; - + std::is_same, /* std::u16string */ + std::is_same, /* std::u32string */ + std::is_same /* std::wstring */ + >; template struct type_caster::value && !is_std_char_type::value>> { using _py_type_0 = conditional_t; - using _py_type_1 = conditional_t::value, _py_type_0, typename std::make_unsigned<_py_type_0>::type>; + using _py_type_1 = conditional_t::value, + _py_type_0, + typename std::make_unsigned<_py_type_0>::type>; using py_type = conditional_t::value, double, _py_type_1>; -public: +public: bool load(handle src, bool convert) { py_type py_value; @@ -153,14 +163,13 @@ struct type_caster::value && !is_std_char_t handle src_or_index = src; #if PY_VERSION_HEX < 0x03080000 object index; - if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr()) + if (!PYBIND11_LONG_CHECK(src.ptr())) { // So: index_check(src.ptr()) index = reinterpret_steal(PyNumber_Index(src.ptr())); if (!index) { PyErr_Clear(); if (!convert) return false; - } - else { + } else { src_or_index = index; } } @@ -169,8 +178,8 @@ struct type_caster::value && !is_std_char_t py_value = as_unsigned(src_or_index.ptr()); } else { // signed integer: py_value = sizeof(T) <= sizeof(long) - ? (py_type) PyLong_AsLong(src_or_index.ptr()) - : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr()); + ? (py_type) PyLong_AsLong(src_or_index.ptr()) + : (py_type) PYBIND11_LONG_AS_LONGLONG(src_or_index.ptr()); } } @@ -179,12 +188,14 @@ struct type_caster::value && !is_std_char_t // Check to see if the conversion is valid (integers should match exactly) // Signed/unsigned checks happen elsewhere - if (py_err || (std::is_integral::value && sizeof(py_type) != sizeof(T) && py_value != (py_type) (T) py_value)) { + if (py_err + || (std::is_integral::value && sizeof(py_type) != sizeof(T) + && py_value != (py_type) (T) py_value)) { PyErr_Clear(); if (py_err && convert && PyNumber_Check(src.ptr())) { auto tmp = reinterpret_steal(std::is_floating_point::value - ? PyNumber_Float(src.ptr()) - : PyNumber_Long(src.ptr())); + ? PyNumber_Float(src.ptr()) + : PyNumber_Long(src.ptr())); PyErr_Clear(); return load(tmp, false); } @@ -195,32 +206,40 @@ struct type_caster::value && !is_std_char_t return true; } - template + template static typename std::enable_if::value, handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PyFloat_FromDouble((double) src); } - template - static typename std::enable_if::value && std::is_signed::value && (sizeof(U) <= sizeof(long)), handle>::type + template + static typename std::enable_if::value && std::is_signed::value + && (sizeof(U) <= sizeof(long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PYBIND11_LONG_FROM_SIGNED((long) src); } - template - static typename std::enable_if::value && std::is_unsigned::value && (sizeof(U) <= sizeof(unsigned long)), handle>::type + template + static typename std::enable_if::value && std::is_unsigned::value + && (sizeof(U) <= sizeof(unsigned long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PYBIND11_LONG_FROM_UNSIGNED((unsigned long) src); } - template - static typename std::enable_if::value && std::is_signed::value && (sizeof(U) > sizeof(long)), handle>::type + template + static typename std::enable_if::value && std::is_signed::value + && (sizeof(U) > sizeof(long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PyLong_FromLongLong((long long) src); } - template - static typename std::enable_if::value && std::is_unsigned::value && (sizeof(U) > sizeof(unsigned long)), handle>::type + template + static typename std::enable_if::value && std::is_unsigned::value + && (sizeof(U) > sizeof(unsigned long)), + handle>::type cast(U src, return_value_policy /* policy */, handle /* parent */) { return PyLong_FromUnsignedLongLong((unsigned long long) src); } @@ -228,7 +247,8 @@ struct type_caster::value && !is_std_char_t PYBIND11_TYPE_CASTER(T, _::value>("int", "float")); }; -template struct void_caster { +template +struct void_caster { public: bool load(handle src, bool) { if (src && src.is_none()) @@ -241,9 +261,11 @@ template struct void_caster { PYBIND11_TYPE_CASTER(T, _("None")); }; -template <> class type_caster : public void_caster {}; +template <> +class type_caster : public void_caster {}; -template <> class type_caster : public type_caster { +template <> +class type_caster : public type_caster { public: using type_caster::cast; @@ -279,19 +301,24 @@ template <> class type_caster : public type_caster { return none().inc_ref(); } - template using cast_op_type = void*&; + template + using cast_op_type = void *&; operator void *&() { return value; } static constexpr auto name = _("capsule"); + private: void *value = nullptr; }; -template <> class type_caster : public void_caster { }; +template <> +class type_caster : public void_caster {}; -template <> class type_caster { +template <> +class type_caster { public: bool load(handle src, bool convert) { - if (!src) return false; + if (!src) + return false; if (src.ptr() == Py_True) { value = true; return true; @@ -305,22 +332,22 @@ template <> class type_caster { Py_ssize_t res = -1; if (src.is_none()) { - res = 0; // None is implicitly converted to False + res = 0; // None is implicitly converted to False } - #if defined(PYPY_VERSION) +#if defined(PYPY_VERSION) // On PyPy, check that "__bool__" (or "__nonzero__" on Python 2.7) attr exists else if (hasattr(src, PYBIND11_BOOL_ATTR)) { res = PyObject_IsTrue(src.ptr()); } - #else +#else // Alternate approach for CPython: this does the same as the above, but optimized // using the CPython API so as to avoid an unneeded attribute lookup. else if (auto tp_as_number = src.ptr()->ob_type->tp_as_number) { if (PYBIND11_NB_BOOL(tp_as_number)) { - res = (*PYBIND11_NB_BOOL(tp_as_number))(src.ptr()); + res = (*PYBIND11_NB_BOOL(tp_as_number)) (src.ptr()); } } - #endif +#endif if (res == 0 || res == 1) { value = (bool) res; return true; @@ -336,20 +363,25 @@ template <> class type_caster { }; // Helper class for UTF-{8,16,32} C++ stl strings: -template struct string_caster { +template +struct string_caster { using CharT = typename StringType::value_type; // Simplify life by being able to assume standard char sizes (the standard only guarantees // minimums, but Python requires exact sizes) - static_assert(!std::is_same::value || sizeof(CharT) == 1, "Unsupported char size != 1"); + static_assert(!std::is_same::value || sizeof(CharT) == 1, + "Unsupported char size != 1"); #if defined(PYBIND11_HAS_U8STRING) - static_assert(!std::is_same::value || sizeof(CharT) == 1, "Unsupported char8_t size != 1"); + static_assert(!std::is_same::value || sizeof(CharT) == 1, + "Unsupported char8_t size != 1"); #endif - static_assert(!std::is_same::value || sizeof(CharT) == 2, "Unsupported char16_t size != 2"); - static_assert(!std::is_same::value || sizeof(CharT) == 4, "Unsupported char32_t size != 4"); + static_assert(!std::is_same::value || sizeof(CharT) == 2, + "Unsupported char16_t size != 2"); + static_assert(!std::is_same::value || sizeof(CharT) == 4, + "Unsupported char32_t size != 4"); // wchar_t can be either 16 bits (Windows) or 32 (everywhere else) static_assert(!std::is_same::value || sizeof(CharT) == 2 || sizeof(CharT) == 4, - "Unsupported wchar_t size != 2/4"); + "Unsupported wchar_t size != 2/4"); static constexpr size_t UTF_N = 8 * sizeof(CharT); bool load(handle src, bool) { @@ -373,18 +405,32 @@ template struct string_caster { return false; temp = reinterpret_steal(PyUnicode_FromObject(load_src.ptr())); - if (!temp) { PyErr_Clear(); return false; } + if (!temp) { + PyErr_Clear(); + return false; + } load_src = temp; #endif } - auto utfNbytes = reinterpret_steal(PyUnicode_AsEncodedString( - load_src.ptr(), UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr)); - if (!utfNbytes) { PyErr_Clear(); return false; } + auto utfNbytes + = reinterpret_steal(PyUnicode_AsEncodedString(load_src.ptr(), + UTF_N == 8 ? "utf-8" + : UTF_N == 16 ? "utf-16" + : "utf-32", + nullptr)); + if (!utfNbytes) { + PyErr_Clear(); + return false; + } - const auto *buffer = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); + const auto *buffer + = reinterpret_cast(PYBIND11_BYTES_AS_STRING(utfNbytes.ptr())); size_t length = (size_t) PYBIND11_BYTES_SIZE(utfNbytes.ptr()) / sizeof(CharT); - if (UTF_N > 8) { buffer++; length--; } // Skip BOM for UTF-16/32 + if (UTF_N > 8) { + buffer++; + length--; + } // Skip BOM for UTF-16/32 value = StringType(buffer, length); // If we're loading a string_view we need to keep the encoded Python object alive: @@ -394,11 +440,13 @@ template struct string_caster { return true; } - static handle cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { + static handle + cast(const StringType &src, return_value_policy /* policy */, handle /* parent */) { const char *buffer = reinterpret_cast(src.data()); auto nbytes = ssize_t(src.size() * sizeof(CharT)); handle s = decode_utfN(buffer, nbytes); - if (!s) throw error_already_set(); + if (!s) + throw error_already_set(); return s; } @@ -407,14 +455,19 @@ template struct string_caster { private: static handle decode_utfN(const char *buffer, ssize_t nbytes) { #if !defined(PYPY_VERSION) - return - UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) : - UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) : - PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); + return UTF_N == 8 ? PyUnicode_DecodeUTF8(buffer, nbytes, nullptr) + : UTF_N == 16 ? PyUnicode_DecodeUTF16(buffer, nbytes, nullptr, nullptr) + : PyUnicode_DecodeUTF32(buffer, nbytes, nullptr, nullptr); #else - // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as well), - // so bypass the whole thing by just passing the encoding as a string value, which works properly: - return PyUnicode_Decode(buffer, nbytes, UTF_N == 8 ? "utf-8" : UTF_N == 16 ? "utf-16" : "utf-32", nullptr); + // PyPy segfaults when on PyUnicode_DecodeUTF16 (and possibly on PyUnicode_DecodeUTF32 as + // well), so bypass the whole thing by just passing the encoding as a string value, which + // works properly: + return PyUnicode_Decode(buffer, + nbytes, + UTF_N == 8 ? "utf-8" + : UTF_N == 16 ? "utf-16" + : "utf-32", + nullptr); #endif } @@ -437,33 +490,41 @@ template struct string_caster { } template - bool load_bytes(enable_if_t::value, handle>) { return false; } + bool load_bytes(enable_if_t::value, handle>) { + return false; + } }; template -struct type_caster, enable_if_t::value>> +struct type_caster, + enable_if_t::value>> : string_caster> {}; #ifdef PYBIND11_HAS_STRING_VIEW template -struct type_caster, enable_if_t::value>> +struct type_caster, + enable_if_t::value>> : string_caster, true> {}; #endif // Type caster for C-style strings. We basically use a std::string type caster, but also add the // ability to use None as a nullptr char* (which the string caster doesn't allow). -template struct type_caster::value>> { +template +struct type_caster::value>> { using StringType = std::basic_string; using StringCaster = type_caster; StringCaster str_caster; bool none = false; CharT one_char = 0; + public: bool load(handle src, bool convert) { - if (!src) return false; + if (!src) + return false; if (src.is_none()) { // Defer accepting None to other overloads (if we aren't in convert mode): - if (!convert) return false; + if (!convert) + return false; none = true; return true; } @@ -471,21 +532,25 @@ template struct type_caster::value) { handle s = PyUnicode_DecodeLatin1((const char *) &src, 1, nullptr); - if (!s) throw error_already_set(); + if (!s) + throw error_already_set(); return s; } return StringCaster::cast(StringType(1, src), policy, parent); } - operator CharT*() { return none ? nullptr : const_cast(static_cast(str_caster).c_str()); } - operator CharT&() { + operator CharT *() { + return none ? nullptr : const_cast(static_cast(str_caster).c_str()); + } + operator CharT &() { if (none) throw value_error("Cannot convert None to a character"); @@ -495,21 +560,24 @@ template struct type_caster 1 && str_len <= 4) { auto v0 = static_cast(value[0]); size_t char0_bytes = !(v0 & 0x80) ? 1 : // low bits only: 0-127 - (v0 & 0xE0) == 0xC0 ? 2 : // 0b110xxxxx - start of 2-byte sequence - (v0 & 0xF0) == 0xE0 ? 3 : // 0b1110xxxx - start of 3-byte sequence - 4; // 0b11110xxx - start of 4-byte sequence + (v0 & 0xE0) == 0xC0 ? 2 + : // 0b110xxxxx - start of 2-byte sequence + (v0 & 0xF0) == 0xE0 ? 3 + : // 0b1110xxxx - start of 3-byte sequence + 4; // 0b11110xxx - start of 4-byte sequence if (char0_bytes == str_len) { // If we have a 128-255 value, we can decode it into a single char: if (char0_bytes == 2 && (v0 & 0xFC) == 0xC0) { // 0x110000xx 0x10xxxxxx - one_char = static_cast(((v0 & 3) << 6) + (static_cast(value[1]) & 0x3F)); + one_char = static_cast(((v0 & 3) << 6) + + (static_cast(value[1]) & 0x3F)); return one_char; } // Otherwise we have a single character, but it's > U+00FF @@ -534,16 +602,18 @@ template struct type_caster using cast_op_type = pybind11::detail::cast_op_type<_T>; + template + using cast_op_type = pybind11::detail::cast_op_type<_T>; }; // Base implementation for std::tuple and std::pair -template class Tuple, typename... Ts> class tuple_caster { +template