Skip to content

Commit

Permalink
Merge pull request #30150 from rwgk/pybind11k_merge_sh
Browse files Browse the repository at this point in the history
git merge smart_holder
  • Loading branch information
Ralf W. Grosse-Kunstleve authored Aug 23, 2024
2 parents c5a931f + 7d0f866 commit 243ae9f
Show file tree
Hide file tree
Showing 20 changed files with 171 additions and 31 deletions.
6 changes: 3 additions & 3 deletions docs/advanced/cast/stl.rst
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,7 @@ the declaration

.. code-block:: cpp
PYBIND11_MAKE_OPAQUE(std::vector<int>);
PYBIND11_MAKE_OPAQUE(std::vector<int>)
before any binding code (e.g. invocations to ``class_::def()``, etc.). This
macro must be specified at the top level (and outside of any namespaces), since
Expand Down Expand Up @@ -207,8 +207,8 @@ The following example showcases usage of :file:`pybind11/stl_bind.h`:
// Don't forget this
#include <pybind11/stl_bind.h>
PYBIND11_MAKE_OPAQUE(std::vector<int>);
PYBIND11_MAKE_OPAQUE(std::map<std::string, double>);
PYBIND11_MAKE_OPAQUE(std::vector<int>)
PYBIND11_MAKE_OPAQUE(std::map<std::string, double>)
// ...
Expand Down
6 changes: 3 additions & 3 deletions docs/advanced/smart_ptrs.rst
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ top namespace level before any binding code:

.. code-block:: cpp
PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>)
The first argument of :func:`PYBIND11_DECLARE_HOLDER_TYPE` should be a
placeholder name that is used as a template parameter of the second argument.
Expand All @@ -143,7 +143,7 @@ by default. Specify

.. code-block:: cpp
PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>, true);
PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>, true)
if ``SmartPtr<T>`` can always be initialized from a ``T*`` pointer without the
risk of inconsistencies (such as multiple independent ``SmartPtr`` instances
Expand All @@ -161,7 +161,7 @@ specialized:
.. code-block:: cpp
// Always needed for custom holder types
PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, SmartPtr<T>)
// Only needed if the type's `.get()` goes by another name
namespace PYBIND11_NAMESPACE { namespace detail {
Expand Down
7 changes: 7 additions & 0 deletions docs/basics.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,13 @@ For brevity, all code examples assume that the following two lines are present:
namespace py = pybind11;
.. note::

``pybind11/pybind11.h`` includes ``Python.h``, as such it must be the first file
included in any source file or header for `the same reasons as Python.h`_.

.. _`the same reasons as Python.h`: https://docs.python.org/3/extending/extending.html#a-simple-example

Some features may require additional headers, but those will be specified as needed.

.. _simple_example:
Expand Down
17 changes: 17 additions & 0 deletions docs/changelog.rst
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,23 @@ New Features:
* Support for CMake older than 3.15 removed. CMake 3.15-3.30 supported.
`#5304 <https://github.com/pybind/pybind11/pull/5304>`_

* The ``array_caster`` in pybind11/stl.h was enhanced to support value types that are not default-constructible.
`#5305 <https://github.com/pybind/pybind11/pull/5305>`_

Version 2.13.5 (August 22, 2024)
--------------------------------

Bug fixes:

* Fix includes when using Windows long paths (``\\?\`` prefix).
`#5321 <https://github.com/pybind/pybind11/pull/5321>`_

* Support ``-Wpedantic`` in C++20 mode.
`#5322 <https://github.com/pybind/pybind11/pull/5322>`_

* Fix and test ``<ranges>`` support for ``py::tuple`` and ``py::list``.
`#5314 <https://github.com/pybind/pybind11/pull/5314>`_

Version 2.13.4 (August 14, 2024)
--------------------------------

Expand Down
3 changes: 3 additions & 0 deletions include/pybind11/detail/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -479,6 +479,8 @@ PYBIND11_WARNING_POP
}
\endrst */
PYBIND11_WARNING_PUSH
PYBIND11_WARNING_DISABLE_CLANG("-Wgnu-zero-variadic-macro-arguments")
#define PYBIND11_MODULE(name, variable, ...) \
static ::pybind11::module_::module_def PYBIND11_CONCAT(pybind11_module_def_, name) \
PYBIND11_MAYBE_UNUSED; \
Expand All @@ -499,6 +501,7 @@ PYBIND11_WARNING_POP
PYBIND11_CATCH_INIT_EXCEPTIONS \
} \
void PYBIND11_CONCAT(pybind11_init_, name)(::pybind11::module_ & (variable))
PYBIND11_WARNING_POP

PYBIND11_NAMESPACE_BEGIN(PYBIND11_NAMESPACE)

Expand Down
2 changes: 2 additions & 0 deletions include/pybind11/pytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -1267,6 +1267,7 @@ class sequence_fast_readonly {
using pointer = arrow_proxy<const handle>;

sequence_fast_readonly(handle obj, ssize_t n) : ptr(PySequence_Fast_ITEMS(obj.ptr()) + n) {}
sequence_fast_readonly() = default;

// NOLINTNEXTLINE(readability-const-return-type) // PR #3263
reference dereference() const { return *ptr; }
Expand All @@ -1289,6 +1290,7 @@ class sequence_slow_readwrite {
using pointer = arrow_proxy<const sequence_accessor>;

sequence_slow_readwrite(handle obj, ssize_t index) : obj(obj), index(index) {}
sequence_slow_readwrite() = default;

reference dereference() const { return {obj, static_cast<size_t>(index)}; }
void increment() { ++index; }
Expand Down
3 changes: 3 additions & 0 deletions tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -412,6 +412,9 @@ function(pybind11_enable_warnings target_name)
-Wdeprecated
-Wundef
-Wnon-virtual-dtor)
if(DEFINED CMAKE_CXX_STANDARD AND NOT CMAKE_CXX_STANDARD VERSION_LESS 20)
target_compile_options(${target_name} PRIVATE -Wpedantic)
endif()
endif()

if(PYBIND11_WERROR)
Expand Down
16 changes: 8 additions & 8 deletions tests/local_bindings.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,21 +56,21 @@ class LocalSimpleException : public std::exception {
std::string message = "";
};

PYBIND11_MAKE_OPAQUE(LocalVec);
PYBIND11_MAKE_OPAQUE(LocalVec2);
PYBIND11_MAKE_OPAQUE(LocalMap);
PYBIND11_MAKE_OPAQUE(NonLocalVec);
// PYBIND11_MAKE_OPAQUE(NonLocalVec2); // same type as LocalVec2
PYBIND11_MAKE_OPAQUE(NonLocalMap);
PYBIND11_MAKE_OPAQUE(NonLocalMap2);
PYBIND11_MAKE_OPAQUE(LocalVec)
PYBIND11_MAKE_OPAQUE(LocalVec2)
PYBIND11_MAKE_OPAQUE(LocalMap)
PYBIND11_MAKE_OPAQUE(NonLocalVec)
// PYBIND11_MAKE_OPAQUE(NonLocalVec2) // same type as LocalVec2
PYBIND11_MAKE_OPAQUE(NonLocalMap)
PYBIND11_MAKE_OPAQUE(NonLocalMap2)

// Simple bindings (used with the above):
template <typename T, int Adjust = 0, typename... Args>
py::class_<T> bind_local(Args &&...args) {
return py::class_<T>(std::forward<Args>(args)...).def(py::init<int>()).def("get", [](T &i) {
return i.i + Adjust;
});
};
}

// Simulate a foreign library base class (to match the example in the docs):
namespace pets {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_callbacks.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ TEST_SUBMODULE(callbacks, m) {
m.def("dummy_function2", [](int i, int j) { return i + j; });
m.def(
"roundtrip",
[](std::function<int(int)> f, bool expect_none = false) {
[](std::function<int(int)> f, bool expect_none) {
if (expect_none && f) {
throw std::runtime_error("Expected None to be converted to empty std::function");
}
Expand Down
4 changes: 2 additions & 2 deletions tests/test_eigen_matrix.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void reset_refs() {
}

// Returns element 2,1 from a matrix (used to test copy/nocopy)
double get_elem(const Eigen::Ref<const Eigen::MatrixXd> &m) { return m(2, 1); };
double get_elem(const Eigen::Ref<const Eigen::MatrixXd> &m) { return m(2, 1); }

// Returns a matrix with 10*r + 100*c added to each matrix element (to help test that the matrix
// reference is referencing rows/columns correctly).
Expand All @@ -76,7 +76,7 @@ struct CustomOperatorNew {
Eigen::Matrix4d a = Eigen::Matrix4d::Zero();
Eigen::Matrix4d b = Eigen::Matrix4d::Identity();

EIGEN_MAKE_ALIGNED_OPERATOR_NEW;
EIGEN_MAKE_ALIGNED_OPERATOR_NEW
};

TEST_SUBMODULE(eigen_matrix, m) {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_opaque_types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
// This also deliberately doesn't use the below StringList type alias to test
// that MAKE_OPAQUE can handle a type containing a `,`. (The `std::allocator`
// bit is just the default `std::vector` allocator).
PYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>);
PYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>)

using StringList = std::vector<std::string, std::allocator<std::string>>;

Expand Down
63 changes: 63 additions & 0 deletions tests/test_pytypes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,14 @@

#include <utility>

//__has_include has been part of C++17, no need to check it
#if defined(PYBIND11_CPP20) && __has_include(<ranges>)
# if !defined(PYBIND11_COMPILER_CLANG) || __clang_major__ >= 16 // llvm/llvm-project#52696
# define PYBIND11_TEST_PYTYPES_HAS_RANGES
# include <ranges>
# endif
#endif

namespace external {
namespace detail {
bool check(PyObject *o) { return PyFloat_Check(o) != 0; }
Expand Down Expand Up @@ -923,4 +931,59 @@ TEST_SUBMODULE(pytypes, m) {
#else
m.attr("defined_PYBIND11_TYPING_H_HAS_STRING_LITERAL") = false;
#endif

#if defined(PYBIND11_TEST_PYTYPES_HAS_RANGES)

// test_tuple_ranges
m.def("tuple_iterator_default_initialization", []() {
using TupleIterator = decltype(std::declval<py::tuple>().begin());
static_assert(std::random_access_iterator<TupleIterator>);
return TupleIterator{} == TupleIterator{};
});

m.def("transform_tuple_plus_one", [](py::tuple &tpl) {
py::list ret{};
for (auto it : tpl | std::views::transform([](auto &o) { return py::cast<int>(o) + 1; })) {
ret.append(py::int_(it));
}
return ret;
});

// test_list_ranges
m.def("list_iterator_default_initialization", []() {
using ListIterator = decltype(std::declval<py::list>().begin());
static_assert(std::random_access_iterator<ListIterator>);
return ListIterator{} == ListIterator{};
});

m.def("transform_list_plus_one", [](py::list &lst) {
py::list ret{};
for (auto it : lst | std::views::transform([](auto &o) { return py::cast<int>(o) + 1; })) {
ret.append(py::int_(it));
}
return ret;
});

// test_dict_ranges
m.def("dict_iterator_default_initialization", []() {
using DictIterator = decltype(std::declval<py::dict>().begin());
static_assert(std::forward_iterator<DictIterator>);
return DictIterator{} == DictIterator{};
});

m.def("transform_dict_plus_one", [](py::dict &dct) {
py::list ret{};
for (auto it : dct | std::views::transform([](auto &o) {
return std::pair{py::cast<int>(o.first) + 1,
py::cast<int>(o.second) + 1};
})) {
ret.append(py::make_tuple(py::int_(it.first), py::int_(it.second)));
}
return ret;
});

m.attr("defined_PYBIND11_TEST_PYTYPES_HAS_RANGES") = true;
#else
m.attr("defined_PYBIND11_TEST_PYTYPES_HAS_RANGES") = false;
#endif
}
42 changes: 42 additions & 0 deletions tests/test_pytypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -1048,3 +1048,45 @@ def test_typevar(doc):
assert doc(m.annotate_listT_to_T) == "annotate_listT_to_T(arg0: list[T]) -> T"

assert doc(m.annotate_object_to_T) == "annotate_object_to_T(arg0: object) -> T"


@pytest.mark.skipif(
not m.defined_PYBIND11_TEST_PYTYPES_HAS_RANGES,
reason="<ranges> not available.",
)
@pytest.mark.parametrize(
("tested_tuple", "expected"),
[((1,), [2]), ((3, 4), [4, 5]), ((7, 8, 9), [8, 9, 10])],
)
def test_tuple_ranges(tested_tuple, expected):
assert m.tuple_iterator_default_initialization()
assert m.transform_tuple_plus_one(tested_tuple) == expected


@pytest.mark.skipif(
not m.defined_PYBIND11_TEST_PYTYPES_HAS_RANGES,
reason="<ranges> not available.",
)
@pytest.mark.parametrize(
("tested_list", "expected"), [([1], [2]), ([3, 4], [4, 5]), ([7, 8, 9], [8, 9, 10])]
)
def test_list_ranges(tested_list, expected):
assert m.list_iterator_default_initialization()
assert m.transform_list_plus_one(tested_list) == expected


@pytest.mark.skipif(
not m.defined_PYBIND11_TEST_PYTYPES_HAS_RANGES,
reason="<ranges> not available.",
)
@pytest.mark.parametrize(
("tested_dict", "expected"),
[
({1: 2}, [(2, 3)]),
({3: 4, 5: 6}, [(4, 5), (6, 7)]),
({7: 8, 9: 10, 11: 12}, [(8, 9), (10, 11), (12, 13)]),
],
)
def test_dict_ranges(tested_dict, expected):
assert m.dict_iterator_default_initialization()
assert m.transform_dict_plus_one(tested_dict) == expected
2 changes: 1 addition & 1 deletion tests/test_return_value_policy_override.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -217,7 +217,7 @@ const char *return_value_policy_name(return_value_policy policy) {
default:
return "Expected to be unreachable.";
}
};
}

template <>
struct type_caster<some_type> : type_caster_base<some_type> {
Expand Down
4 changes: 2 additions & 2 deletions tests/test_sequences_and_iterators.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ class NonCopyableInt {
};
using NonCopyableIntPair = std::pair<NonCopyableInt, NonCopyableInt>;

PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableInt>);
PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableIntPair>);
PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableInt>)
PYBIND11_MAKE_OPAQUE(std::vector<NonCopyableIntPair>)

template <typename PythonType>
py::list test_random_access_iterator(PythonType x) {
Expand Down
15 changes: 9 additions & 6 deletions tests/test_smart_ptr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@
#include "object.h"
#include "pybind11_tests.h"

// This breaks on PYBIND11_DECLARE_HOLDER_TYPE
PYBIND11_WARNING_DISABLE_GCC("-Wpedantic")

namespace {

// This is just a wrapper around unique_ptr, but with extra fields to deliberately bloat up the
Expand Down Expand Up @@ -279,13 +282,13 @@ struct holder_helper<ref<T>> {
} // namespace PYBIND11_NAMESPACE

// Make pybind aware of the ref-counted wrapper type (s):
PYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>, true);
PYBIND11_DECLARE_HOLDER_TYPE(T, ref<T>, true)
// The following is not required anymore for std::shared_ptr, but it should compile without error:
PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, huge_unique_ptr<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_with_addressof_operator<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>);
PYBIND11_DECLARE_HOLDER_TYPE(T, std::shared_ptr<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, huge_unique_ptr<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, custom_unique_ptr<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, shared_ptr_with_addressof_operator<T>)
PYBIND11_DECLARE_HOLDER_TYPE(T, unique_ptr_with_addressof_operator<T>)

TEST_SUBMODULE(smart_ptr, m) {
// Please do not interleave `struct` and `class` definitions with bindings code,
Expand Down
2 changes: 1 addition & 1 deletion tests/test_stl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ struct visit_helper<boost::variant> {
} // namespace PYBIND11_NAMESPACE
#endif

PYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>);
PYBIND11_MAKE_OPAQUE(std::vector<std::string, std::allocator<std::string>>)

/// Issue #528: templated constructor
struct TplCtorClass {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_tagbased_polymorphic.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,4 @@ TEST_SUBMODULE(tagbased_polymorphic, m) {
.def(py::init<std::string>())
.def("purr", &Panther::purr);
m.def("create_zoo", &create_zoo);
};
}
2 changes: 1 addition & 1 deletion tests/test_type_caster_odr_guard_2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ inline void pass_vector_type_mrc(const std::vector<type_mrc> &) {}

} // namespace mrc_ns

PYBIND11_MAKE_OPAQUE(std::vector<mrc_ns::type_mrc>);
PYBIND11_MAKE_OPAQUE(std::vector<mrc_ns::type_mrc>)

namespace pybind11 {
namespace detail {
Expand Down
2 changes: 1 addition & 1 deletion tests/test_virtual_functions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,4 +589,4 @@ void initialize_inherited_virtuals(py::module_ &m) {
// Fix issue #1454 (crash when acquiring/releasing GIL on another thread in Python 2.7)
m.def("test_gil", &test_gil);
m.def("test_gil_from_thread", &test_gil_from_thread);
};
}

0 comments on commit 243ae9f

Please sign in to comment.