From e9e8b37f545e2cee442e1b466669a3a38e90eaf9 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 2 Jul 2021 20:38:48 -0700 Subject: [PATCH 1/4] * Removing clang-format off-on-off directives. * Inserting clang-format using the same docker container as used for clang-tidy (silkeh/clang:12). * Removing stray semicolons (discovered by running clang-format v12 followed by tools/check-style.sh). * Manually moving `// NOLINT` and `// NOLINTNEXTLINE` 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. * 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 | 2 +- tests/pybind11_cross_module_tests.cpp | 9 ++++-- tests/test_buffers.cpp | 2 +- tests/test_builtin_casters.cpp | 11 ++++--- tests/test_callbacks.cpp | 2 +- tests/test_eigen.cpp | 43 +++++++++++++++++---------- tests/test_kwargs_and_defaults.cpp | 12 +++++--- tests/test_local_bindings.cpp | 9 ++++-- tests/test_methods_and_attributes.cpp | 12 ++++---- tests/test_numpy_array.cpp | 14 ++++++--- tests/test_numpy_vectorize.cpp | 22 ++++++++------ tests/test_pickling.cpp | 5 ---- tests/test_pytypes.cpp | 5 ++-- tests/test_smart_ptr.cpp | 2 +- tests/test_stl.cpp | 15 ++++++---- 16 files changed, 102 insertions(+), 66 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..b39a385238 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -801,7 +801,7 @@ 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 + constexpr overload_cast_impl() {} // NOLINT(modernize-use-equals-default): MSVC 2015 needs this template constexpr auto operator()(Return (*pf)(Args...)) const noexcept diff --git a/tests/pybind11_cross_module_tests.cpp b/tests/pybind11_cross_module_tests.cpp index f238ddb042..8e1edcc207 100644 --- a/tests/pybind11_cross_module_tests.cpp +++ b/tests/pybind11_cross_module_tests.cpp @@ -104,9 +104,12 @@ PYBIND11_MODULE(pybind11_cross_module_tests, m) { m.def("return_self", [](LocalVec *v) { return v; }); m.def("return_copy", [](const LocalVec &v) { return LocalVec(v); }); - // Changing this broke things with pygrep. TODO fix - // NOLINTNEXTLINE - class Dog : public pets::Pet { public: Dog(std::string name) : Pet(name) {}; }; + class Dog : public pets::Pet { + public: + // Changing this broke things with pygrep. TODO fix + // NOLINTNEXTLINE + Dog(std::string name) : Pet(name) {} + }; py::class_(m, "Pet", py::module_local()) .def("name", &pets::Pet::name); // Binding for local extending class: diff --git a/tests/test_buffers.cpp b/tests/test_buffers.cpp index 9902c1084e..8f4a3f96db 100644 --- a/tests/test_buffers.cpp +++ b/tests/test_buffers.cpp @@ -155,7 +155,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_builtin_casters.cpp b/tests/test_builtin_casters.cpp index a98b67bdbd..e299d9136d 100644 --- a/tests/test_builtin_casters.cpp +++ b/tests/test_builtin_casters.cpp @@ -151,10 +151,13 @@ TEST_SUBMODULE(builtin_casters, m) { m.def("int_passthrough_noconvert", [](int arg) { return arg; }, py::arg{}.noconvert()); // test_tuple - // NOLINTNEXTLINE(performance-unnecessary-value-param) - m.def("pair_passthrough", [](std::pair input) { - return std::make_pair(input.second, input.first); - }, "Return a pair in reversed order"); + m.def( + "pair_passthrough", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](std::pair input) { + return std::make_pair(input.second, input.first); + }, + "Return a pair in reversed order"); m.def("tuple_passthrough", [](std::tuple input) { return std::make_tuple(std::get<2>(input), std::get<1>(input), std::get<0>(input)); }, "Return a triple in reversed order"); 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 a24bf273d2..8957ba3059 100644 --- a/tests/test_eigen.cpp +++ b/tests/test_eigen.cpp @@ -98,12 +98,14 @@ TEST_SUBMODULE(eigen, m) { // test_eigen_ref_to_python // Different ways of passing via Eigen::Ref; the first and second are the Eigen-recommended - // NOLINTNEXTLINE (performance-unnecessary-value-param) - m.def("cholesky1", [](Eigen::Ref x) -> Eigen::MatrixXd { return x.llt().matrixL(); }); + m.def("cholesky1", + // NOLINTNEXTLINE (performance-unnecessary-value-param) + [](Eigen::Ref x) -> Eigen::MatrixXd { return x.llt().matrixL(); }); m.def("cholesky2", [](const Eigen::Ref &x) -> Eigen::MatrixXd { return x.llt().matrixL(); }); m.def("cholesky3", [](const Eigen::Ref &x) -> Eigen::MatrixXd { return x.llt().matrixL(); }); - // NOLINTNEXTLINE (performance-unnecessary-value-param) - m.def("cholesky4", [](Eigen::Ref x) -> Eigen::MatrixXd { return x.llt().matrixL(); }); + m.def("cholesky4", + // NOLINTNEXTLINE (performance-unnecessary-value-param) + [](Eigen::Ref x) -> Eigen::MatrixXd { return x.llt().matrixL(); }); // test_eigen_ref_mutators // Mutators: these add some value to the given element using Eigen, but Eigen should be mapping into @@ -260,7 +262,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; }); @@ -284,9 +289,11 @@ TEST_SUBMODULE(eigen, m) { // that would allow copying (if types or strides don't match) for comparison: m.def("get_elem", &get_elem); // Now this alternative that calls the tells pybind to fail rather than copy: - // NOLINTNEXTLINE (performance-unnecessary-value-param) - m.def("get_elem_nocopy", [](Eigen::Ref m) -> double { return get_elem(m); }, - py::arg{}.noconvert()); + m.def( + "get_elem_nocopy", + // NOLINTNEXTLINE (performance-unnecessary-value-param) + [](Eigen::Ref m) -> double { return get_elem(m); }, + py::arg{}.noconvert()); // Also test a row-major-only no-copy const ref: m.def("get_elem_rm_nocopy", [](Eigen::Ref> &m) -> long { return m(2, 1); }, py::arg{}.noconvert()); @@ -301,7 +308,7 @@ TEST_SUBMODULE(eigen, m) { // test_issue1105 // Issue #1105: when converting from a numpy two-dimensional (Nx1) or (1xN) value into a dense // eigen Vector or RowVector, the argument would fail to load because the numpy copy would - // fail: numpy won't broadcast a Nx1 into a 1-dimensional vector. NOLINTNEXTLINE + // fail: numpy won't broadcast a Nx1 into a 1-dimensional vector. // NOLINTNEXTLINE (performance-unnecessary-value-param) m.def("iss1105_col", [](Eigen::VectorXd) { return true; }); // NOLINTNEXTLINE (performance-unnecessary-value-param) @@ -309,12 +316,18 @@ TEST_SUBMODULE(eigen, m) { // test_named_arguments // Make sure named arguments are working properly: - // NOLINTNEXTLINE (performance-unnecessary-value-param) - m.def("matrix_multiply", [](const py::EigenDRef A, const py::EigenDRef B) - -> Eigen::MatrixXd { - if (A.cols() != B.rows()) throw std::domain_error("Nonconformable matrices!"); - return A * B; - }, py::arg("A"), py::arg("B")); + m.def( + "matrix_multiply", + // NOLINTNEXTLINE (performance-unnecessary-value-param) + [](const py::EigenDRef A, + // NOLINTNEXTLINE (performance-unnecessary-value-param) + const py::EigenDRef B) -> Eigen::MatrixXd { + if (A.cols() != B.rows()) + throw std::domain_error("Nonconformable matrices!"); + return A * B; + }, + py::arg("A"), + py::arg("B")); // test_custom_operator_new py::class_(m, "CustomOperatorNew") diff --git a/tests/test_kwargs_and_defaults.cpp b/tests/test_kwargs_and_defaults.cpp index a349d43184..c464a4276b 100644 --- a/tests/test_kwargs_and_defaults.cpp +++ b/tests/test_kwargs_and_defaults.cpp @@ -106,10 +106,14 @@ TEST_SUBMODULE(kwargs_and_defaults, m) { py::arg() = 3, "j"_a = 4, py::kw_only(), "k"_a = 5, "z"_a); m.def("kw_only_mixed", [](int i, int j) { return py::make_tuple(i, j); }, "i"_a, py::kw_only(), "j"_a); - // NOLINTNEXTLINE(performance-unnecessary-value-param) - m.def("kw_only_plus_more", [](int i, int j, int k, py::kwargs kwargs) { - return py::make_tuple(i, j, k, kwargs); }, - py::arg() /* positional */, py::arg("j") = -1 /* both */, py::kw_only(), py::arg("k") /* kw-only */); + m.def( + "kw_only_plus_more", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](int i, int j, int k, py::kwargs kwargs) { return py::make_tuple(i, j, k, kwargs); }, + py::arg() /* positional */, + py::arg("j") = -1 /* both */, + py::kw_only(), + py::arg("k") /* kw-only */); m.def("register_invalid_kw_only", [](py::module_ m) { m.def("bad_kw_only", [](int i, int j) { return py::make_tuple(i, j); }, diff --git a/tests/test_local_bindings.cpp b/tests/test_local_bindings.cpp index 2ac77b143b..472b129b71 100644 --- a/tests/test_local_bindings.cpp +++ b/tests/test_local_bindings.cpp @@ -86,9 +86,12 @@ TEST_SUBMODULE(local_bindings, m) { m.def("return_self", [](LocalVec *v) { return v; }); m.def("return_copy", [](const LocalVec &v) { return LocalVec(v); }); - // Reformatting this class broke pygrep checks - // NOLINTNEXTLINE - class Cat : public pets::Pet { public: Cat(std::string name) : Pet(name) {}; }; + class Cat : public pets::Pet { + public: + // Reformatting this class broke pygrep checks + // NOLINTNEXTLINE + Cat(std::string name) : Pet(name) {} + }; py::class_(m, "Pet", py::module_local()) .def("get_name", &pets::Pet::name); // Binding for local extending class: diff --git a/tests/test_methods_and_attributes.cpp b/tests/test_methods_and_attributes.cpp index 67ee117c6c..5e06d923a9 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 { @@ -393,14 +393,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_numpy_array.cpp b/tests/test_numpy_array.cpp index a6c7ae8d74..cb7e6f30e6 100644 --- a/tests/test_numpy_array.cpp +++ b/tests/test_numpy_array.cpp @@ -275,10 +275,16 @@ TEST_SUBMODULE(numpy_array, sm) { // [workaround(intel)] ICC 20/21 breaks with py::arg().stuff, using py::arg{}.stuff works. // Only accept the exact types: - // NOLINTNEXTLINE(performance-unnecessary-value-param) - sm.def("overloaded3", [](py::array_t) { return "int"; }, py::arg{}.noconvert()); - // NOLINTNEXTLINE(performance-unnecessary-value-param) - sm.def("overloaded3", [](py::array_t) { return "double"; }, py::arg{}.noconvert()); + sm.def( + "overloaded3", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](py::array_t) { return "int"; }, + py::arg{}.noconvert()); + sm.def( + "overloaded3", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](py::array_t) { return "double"; }, + py::arg{}.noconvert()); // Make sure we don't do unsafe coercion (e.g. float to int) when not using forcecast, but // rather that float gets converted via the safe (conversion to double) overload: diff --git a/tests/test_numpy_vectorize.cpp b/tests/test_numpy_vectorize.cpp index 0be30d8e88..5335c043ee 100644 --- a/tests/test_numpy_vectorize.cpp +++ b/tests/test_numpy_vectorize.cpp @@ -38,15 +38,19 @@ TEST_SUBMODULE(numpy_vectorize, m) { )); // test_type_selection - // NumPy function which only accepts specific data types - // A lot of these no lints could be replaced with const refs, and probably should at some point. - // NOLINTNEXTLINE(performance-unnecessary-value-param) - m.def("selective_func", [](py::array_t) { return "Int branch taken."; }); - // NOLINTNEXTLINE(performance-unnecessary-value-param) - m.def("selective_func", [](py::array_t) { return "Float branch taken."; }); - // NOLINTNEXTLINE(performance-unnecessary-value-param) - m.def("selective_func", [](py::array_t, py::array::c_style>) { return "Complex float branch taken."; }); - + // A lot of these no lints could be replaced with const refs, + // and probably should at some point. + m.def("selective_func", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](py::array_t) { return "Int branch taken."; }); + m.def("selective_func", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](py::array_t) { return "Float branch taken."; }); + m.def("selective_func", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](py::array_t, py::array::c_style>) { + return "Complex float branch taken."; + }); // test_passthrough_arguments // Passthrough test: references and non-pod types should be automatically passed through (in the diff --git a/tests/test_pickling.cpp b/tests/test_pickling.cpp index 0d5827315f..297980f626 100644 --- a/tests/test_pickling.cpp +++ b/tests/test_pickling.cpp @@ -1,4 +1,3 @@ -// clang-format off /* tests/test_pickling.cpp -- pickle support @@ -11,8 +10,6 @@ #include "pybind11_tests.h" -// clang-format on - #include #include #include @@ -61,8 +58,6 @@ void wrap(py::module m) { } // namespace exercise_trampoline -// clang-format off - TEST_SUBMODULE(pickling, m) { // test_roundtrip class Pickleable { diff --git a/tests/test_pytypes.cpp b/tests/test_pytypes.cpp index 2b91af37b0..9e47d6ea7b 100644 --- a/tests/test_pytypes.cpp +++ b/tests/test_pytypes.cpp @@ -258,8 +258,9 @@ TEST_SUBMODULE(pytypes, m) { // NOLINTNEXTLINE(performance-unnecessary-value-param) m.def("convert_to_pybind11_str", [](py::object o) { return py::str(o); }); - // NOLINTNEXTLINE(performance-unnecessary-value-param) - m.def("nonconverting_constructor", [](std::string type, py::object value, bool move) -> py::object { + m.def("nonconverting_constructor", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](std::string type, py::object value, bool move) -> py::object { if (type == "bytes") { return move ? py::bytes(std::move(value)) : py::bytes(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(); } }; diff --git a/tests/test_stl.cpp b/tests/test_stl.cpp index dc75762e85..bafa232766 100644 --- a/tests/test_stl.cpp +++ b/tests/test_stl.cpp @@ -299,12 +299,15 @@ TEST_SUBMODULE(stl, m) { m.def("stl_pass_by_pointer", [](std::vector* v) { return *v; }, "v"_a=nullptr); // #1258: pybind11/stl.h converts string to vector - // NOLINTNEXTLINE(performance-unnecessary-value-param) - m.def("func_with_string_or_vector_string_arg_overload", [](std::vector) { return 1; }); - // NOLINTNEXTLINE(performance-unnecessary-value-param) - m.def("func_with_string_or_vector_string_arg_overload", [](std::list) { return 2; }); - // NOLINTNEXTLINE(performance-unnecessary-value-param) - m.def("func_with_string_or_vector_string_arg_overload", [](std::string) { return 3; }); + m.def("func_with_string_or_vector_string_arg_overload", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](std::vector) { return 1; }); + m.def("func_with_string_or_vector_string_arg_overload", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](std::list) { return 2; }); + m.def("func_with_string_or_vector_string_arg_overload", + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](std::string) { return 3; }); class Placeholder { public: From 306bd3be333b62403fb58ddf1459cb439df7940d Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 7 Jul 2021 16:54:57 -0700 Subject: [PATCH 2/4] Systematically adding `// clang-format off`, `on` around all `\rst` `\endrst` blocks. --- include/pybind11/attr.h | 4 ++- include/pybind11/cast.h | 4 ++- include/pybind11/detail/common.h | 4 +++ include/pybind11/embed.h | 16 +++++++--- include/pybind11/iostream.h | 10 ++++-- include/pybind11/pybind11.h | 20 +++++++++++- include/pybind11/pytypes.h | 54 +++++++++++++++++++++++++++++--- 7 files changed, 99 insertions(+), 13 deletions(-) diff --git a/include/pybind11/attr.h b/include/pybind11/attr.h index 60ed9fd90e..d9c32c9218 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. @@ -95,7 +96,8 @@ struct prepend { }; T scope_guard; return foo(args...); // forwarded arguments }); - \endrst */ +\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..9739a5f266 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 */ +\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 b39a385238..80e8355a99 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..1c46da95a0 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 @@ -44,7 +45,8 @@ return "Hello, World!"; }); } - \endrst */ +\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 @@ -99,7 +102,8 @@ PYBIND11_NAMESPACE_END(detail) of throwing exceptions on errors.) .. _Python documentation: https://docs.python.org/3/c-api/init.html#c.Py_InitializeEx - \endrst */ +\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: @@ -144,7 +149,8 @@ inline void initialize_interpreter(bool init_signal_handlers = true) { in the CPython documentation. In short, not all interpreter memory may be freed, either due to reference cycles or user-created global data. - \endrst */ +\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. @@ -177,7 +184,8 @@ inline void finalize_interpreter() { py::scoped_interpreter guard{}; py::print(Hello, World!); } // <-- interpreter shutdown - \endrst */ +\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 89d1813ba8..ffd747cae1 100644 --- a/include/pybind11/iostream.h +++ b/include/pybind11/iostream.h @@ -135,6 +135,7 @@ class pythonbuf : public std::streambuf { PYBIND11_NAMESPACE_END(detail) +// clang-format off /** \rst This a move-only guard that redirects output. @@ -158,7 +159,8 @@ PYBIND11_NAMESPACE_END(detail) py::scoped_ostream_redirect output{std::cerr, py::module::import("sys").attr("stderr")}; std::cout << "Hello, World!"; } - \endrst */ +\endrst */ +// clang-format on class scoped_ostream_redirect { protected: std::streambuf *old; @@ -183,6 +185,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. @@ -194,6 +197,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, @@ -230,6 +234,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: @@ -256,7 +261,8 @@ PYBIND11_NAMESPACE_END(detail) with m.ostream_redirect(stdout=true, stderr=true): m.noisy_function_with_error_printing() - \endrst */ +\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..10d33709bc 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. @@ -2180,7 +2189,8 @@ PYBIND11_NAMESPACE_END(detail) the first non-trampoline class encountered in the inheritance chain. :name: The name of the overridden Python method to retrieve. :return: The Python method by this name from the object or an empty function wrapper. - \endrst */ +\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 fb9680dfa1..dc8983dacc 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) @@ -384,11 +414,13 @@ class PYBIND11_EXPORT error_already_set : public std::runtime_error { as their Python counterparts. */ +// clang-format off /** \ingroup python_builtins \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); } @@ -884,6 +916,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 @@ -892,6 +925,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; @@ -923,6 +957,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. @@ -936,6 +971,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(); } @@ -1003,10 +1039,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 { @@ -1043,9 +1081,11 @@ class str : public object { /// @} pytypes inline namespace literals { +// clang-format off /** \rst String literal version of `str` - \endrst */ +\endrst */ +// clang-format on inline str operator"" _s(const char *s, size_t size) { return {s, size}; } } // namespace literals @@ -1487,6 +1527,7 @@ class memoryview : public object { public: PYBIND11_OBJECT_CVT(memoryview, object, PyMemoryView_Check, PyMemoryView_FromObject) + // clang-format off /** \rst Creates ``memoryview`` from ``buffer_info``. @@ -1495,7 +1536,8 @@ class memoryview : public object { For creating a ``memoryview`` from objects that support buffer protocol, use ``memoryview(const object& obj)`` instead of this constructor. - \endrst */ + \endrst */ + // clang-format on explicit memoryview(const buffer_info& info) { if (!info.view()) pybind11_fail("Prohibited to create memoryview without Py_buffer"); @@ -1507,6 +1549,7 @@ class memoryview : public object { pybind11_fail("Unable to create memoryview from buffer descriptor"); } + // clang-format off /** \rst Creates ``memoryview`` from static buffer. @@ -1529,7 +1572,8 @@ class memoryview : public object { per dimension). :param readonly: Flag to indicate if the underlying storage may be written to. - \endrst */ + \endrst */ + // clang-format on static memoryview from_buffer( void *ptr, ssize_t itemsize, const char *format, detail::any_container shape, @@ -1561,6 +1605,7 @@ class memoryview : public object { } #if PY_MAJOR_VERSION >= 3 + // clang-format off /** \rst Creates ``memoryview`` from static memory. @@ -1573,7 +1618,8 @@ class memoryview : public object { See also: Python C API documentation for `PyMemoryView_FromBuffer`_. .. _PyMemoryView_FromMemory: https://docs.python.org/c-api/memoryview.html#c.PyMemoryView_FromMemory - \endrst */ + \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 7945c348c0cdb93027ca19f86342ef5ae395e417 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Wed, 7 Jul 2021 23:35:11 -0700 Subject: [PATCH 3/4] Empty lines between #includes, to prevent clang-format from shuffling the order and thereby confusing MSVC 2015. --- tests/pybind11_tests.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/pybind11_tests.h b/tests/pybind11_tests.h index ccb0529787..2ced95ae3a 100644 --- a/tests/pybind11_tests.h +++ b/tests/pybind11_tests.h @@ -1,5 +1,9 @@ #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 From eb0a55bf7bd71fba60d1debe353bd338bc93f182 Mon Sep 17 00:00:00 2001 From: "Ralf W. Grosse-Kunstleve" Date: Fri, 9 Jul 2021 07:23:04 -0700 Subject: [PATCH 4/4] Resolving merge conflict in tests/test_pytypes.cpp when rebasing after the just-merged PR #3080. Also rerunning clang-format-diff.py to pick up a few fixes missed before. --- include/pybind11/detail/common.h | 17 +++++++++-------- include/pybind11/iostream.h | 2 -- tests/pybind11_tests.h | 3 ++- tests/test_pytypes.cpp | 32 ++++++++++++++++---------------- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/include/pybind11/detail/common.h b/include/pybind11/detail/common.h index 80e8355a99..ea1b4a1c9c 100644 --- a/include/pybind11/detail/common.h +++ b/include/pybind11/detail/common.h @@ -272,14 +272,15 @@ extern "C" { } \ } -#define PYBIND11_CATCH_INIT_EXCEPTIONS \ - catch (pybind11::error_already_set &e) { \ - PyErr_SetString(PyExc_ImportError, e.what()); \ - return nullptr; \ - } catch (const std::exception &e) { \ - PyErr_SetString(PyExc_ImportError, e.what()); \ - return nullptr; \ - } \ +#define PYBIND11_CATCH_INIT_EXCEPTIONS \ + catch (pybind11::error_already_set & e) { \ + PyErr_SetString(PyExc_ImportError, e.what()); \ + return nullptr; \ + } \ + catch (const std::exception &e) { \ + PyErr_SetString(PyExc_ImportError, e.what()); \ + return nullptr; \ + } // clang-format off /** \rst diff --git a/include/pybind11/iostream.h b/include/pybind11/iostream.h index ffd747cae1..960904d4e3 100644 --- a/include/pybind11/iostream.h +++ b/include/pybind11/iostream.h @@ -134,7 +134,6 @@ class pythonbuf : public std::streambuf { PYBIND11_NAMESPACE_END(detail) - // clang-format off /** \rst This a move-only guard that redirects output. @@ -184,7 +183,6 @@ class scoped_ostream_redirect { scoped_ostream_redirect &operator=(scoped_ostream_redirect &&) = delete; }; - // clang-format off /** \rst Like `scoped_ostream_redirect`, but redirects cerr by default. This class diff --git a/tests/pybind11_tests.h b/tests/pybind11_tests.h index 2ced95ae3a..d970ba8bd4 100644 --- a/tests/pybind11_tests.h +++ b/tests/pybind11_tests.h @@ -8,7 +8,8 @@ #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_pytypes.cpp b/tests/test_pytypes.cpp index 9e47d6ea7b..fc67e6caf7 100644 --- a/tests/test_pytypes.cpp +++ b/tests/test_pytypes.cpp @@ -259,22 +259,22 @@ TEST_SUBMODULE(pytypes, m) { m.def("convert_to_pybind11_str", [](py::object o) { return py::str(o); }); m.def("nonconverting_constructor", - // NOLINTNEXTLINE(performance-unnecessary-value-param) - [](std::string type, py::object value, bool move) -> py::object { - if (type == "bytes") { - return move ? py::bytes(std::move(value)) : py::bytes(value); - } - if (type == "none") { - return move ? py::none(std::move(value)) : py::none(value); - } - if (type == "ellipsis") { - return move ? py::ellipsis(std::move(value)) : py::ellipsis(value); - } - if (type == "type") { - return move ? py::type(std::move(value)) : py::type(value); - } - throw std::runtime_error("Invalid type"); - }); + // NOLINTNEXTLINE(performance-unnecessary-value-param) + [](std::string type, py::object value, bool move) -> py::object { + if (type == "bytes") { + return move ? py::bytes(std::move(value)) : py::bytes(value); + } + if (type == "none") { + return move ? py::none(std::move(value)) : py::none(value); + } + if (type == "ellipsis") { + return move ? py::ellipsis(std::move(value)) : py::ellipsis(value); + } + if (type == "type") { + return move ? py::type(std::move(value)) : py::type(value); + } + throw std::runtime_error("Invalid type"); + }); m.def("get_implicit_casting", []() { py::dict d;