mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-26 23:22:01 +00:00
Merge branch 'pybind:master' into master
This commit is contained in:
commit
e3df9d8f71
@ -20,7 +20,28 @@ New Features:
|
|||||||
* Support for Python 3.7 was removed. (Official end-of-life: 2023-06-27).
|
* Support for Python 3.7 was removed. (Official end-of-life: 2023-06-27).
|
||||||
`#5191 <https://github.com/pybind/pybind11/pull/5191>`_
|
`#5191 <https://github.com/pybind/pybind11/pull/5191>`_
|
||||||
|
|
||||||
Support for CMake older than 3.15 and some older compilers will also be removed.
|
* stl.h ``list|set|map_caster`` were made more user friendly: it is no longer
|
||||||
|
necessary to explicitly convert Python iterables to ``tuple()``, ``set()``,
|
||||||
|
or ``map()`` in many common situations.
|
||||||
|
`#4686 <https://github.com/pybind/pybind11/pull/4686>`_
|
||||||
|
|
||||||
|
* Support for CMake older than 3.15 removed. CMake 3.15-3.30 supported.
|
||||||
|
`#5304 <https://github.com/pybind/pybind11/pull/5304>`_
|
||||||
|
|
||||||
|
Version 2.13.4 (August 14, 2024)
|
||||||
|
--------------------------------
|
||||||
|
|
||||||
|
Bug fixes:
|
||||||
|
|
||||||
|
* Fix paths with spaces, including on Windows.
|
||||||
|
(Replaces regression from `#5302 <https://github.com/pybind/pybind11/pull/5302>`_)
|
||||||
|
`#4874 <https://github.com/pybind/pybind11/pull/4874>`_
|
||||||
|
|
||||||
|
Documentation:
|
||||||
|
|
||||||
|
* Remove repetitive words.
|
||||||
|
`#5308 <https://github.com/pybind/pybind11/pull/5308>`_
|
||||||
|
|
||||||
|
|
||||||
Version 2.13.3 (August 13, 2024)
|
Version 2.13.3 (August 13, 2024)
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
@ -11,11 +11,14 @@
|
|||||||
|
|
||||||
#include "pybind11.h"
|
#include "pybind11.h"
|
||||||
#include "detail/common.h"
|
#include "detail/common.h"
|
||||||
|
#include "detail/descr.h"
|
||||||
|
#include "detail/type_caster_base.h"
|
||||||
|
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <initializer_list>
|
#include <initializer_list>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <memory>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
@ -349,39 +352,68 @@ struct type_caster<std::deque<Type, Alloc>> : list_caster<std::deque<Type, Alloc
|
|||||||
template <typename Type, typename Alloc>
|
template <typename Type, typename Alloc>
|
||||||
struct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};
|
struct type_caster<std::list<Type, Alloc>> : list_caster<std::list<Type, Alloc>, Type> {};
|
||||||
|
|
||||||
|
template <typename ArrayType, typename V, size_t... I>
|
||||||
|
ArrayType vector_to_array_impl(V &&v, index_sequence<I...>) {
|
||||||
|
return {{std::move(v[I])...}};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Based on https://en.cppreference.com/w/cpp/container/array/to_array
|
||||||
|
template <typename ArrayType, size_t N, typename V>
|
||||||
|
ArrayType vector_to_array(V &&v) {
|
||||||
|
return vector_to_array_impl<ArrayType, V>(std::forward<V>(v), make_index_sequence<N>{});
|
||||||
|
}
|
||||||
|
|
||||||
template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>
|
template <typename ArrayType, typename Value, bool Resizable, size_t Size = 0>
|
||||||
struct array_caster {
|
struct array_caster {
|
||||||
using value_conv = make_caster<Value>;
|
using value_conv = make_caster<Value>;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
template <bool R = Resizable>
|
std::unique_ptr<ArrayType> value;
|
||||||
bool require_size(enable_if_t<R, size_t> size) {
|
|
||||||
if (value.size() != size) {
|
|
||||||
value.resize(size);
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
template <bool R = Resizable>
|
|
||||||
bool require_size(enable_if_t<!R, size_t> size) {
|
|
||||||
return size == Size;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
template <bool R = Resizable, enable_if_t<R, int> = 0>
|
||||||
bool convert_elements(handle seq, bool convert) {
|
bool convert_elements(handle seq, bool convert) {
|
||||||
auto l = reinterpret_borrow<sequence>(seq);
|
auto l = reinterpret_borrow<sequence>(seq);
|
||||||
if (!require_size(l.size())) {
|
value.reset(new ArrayType{});
|
||||||
return false;
|
// Using `resize` to preserve the behavior exactly as it was before PR #5305
|
||||||
}
|
// For the `resize` to work, `Value` must be default constructible.
|
||||||
|
// For `std::valarray`, this is a requirement:
|
||||||
|
// https://en.cppreference.com/w/cpp/named_req/NumericType
|
||||||
|
value->resize(l.size());
|
||||||
size_t ctr = 0;
|
size_t ctr = 0;
|
||||||
for (const auto &it : l) {
|
for (const auto &it : l) {
|
||||||
value_conv conv;
|
value_conv conv;
|
||||||
if (!conv.load(it, convert)) {
|
if (!conv.load(it, convert)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
value[ctr++] = cast_op<Value &&>(std::move(conv));
|
(*value)[ctr++] = cast_op<Value &&>(std::move(conv));
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <bool R = Resizable, enable_if_t<!R, int> = 0>
|
||||||
|
bool convert_elements(handle seq, bool convert) {
|
||||||
|
auto l = reinterpret_borrow<sequence>(seq);
|
||||||
|
if (l.size() != Size) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
// The `temp` storage is needed to support `Value` types that are not
|
||||||
|
// default-constructible.
|
||||||
|
// Deliberate choice: no template specializations, for simplicity, and
|
||||||
|
// because the compile time overhead for the specializations is deemed
|
||||||
|
// more significant than the runtime overhead for the `temp` storage.
|
||||||
|
std::vector<Value> temp;
|
||||||
|
temp.reserve(l.size());
|
||||||
|
for (auto it : l) {
|
||||||
|
value_conv conv;
|
||||||
|
if (!conv.load(it, convert)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
temp.emplace_back(cast_op<Value &&>(std::move(conv)));
|
||||||
|
}
|
||||||
|
value.reset(new ArrayType(vector_to_array<ArrayType, Size>(std::move(temp))));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool load(handle src, bool convert) {
|
bool load(handle src, bool convert) {
|
||||||
if (!PyObjectTypeIsConvertibleToStdVector(src.ptr())) {
|
if (!PyObjectTypeIsConvertibleToStdVector(src.ptr())) {
|
||||||
@ -416,12 +448,36 @@ public:
|
|||||||
return l.release();
|
return l.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_TYPE_CASTER(ArrayType,
|
// Code copied from PYBIND11_TYPE_CASTER macro.
|
||||||
const_name<Resizable>(const_name(""), const_name("Annotated["))
|
// Intentionally preserving the behavior exactly as it was before PR #5305
|
||||||
+ const_name("list[") + value_conv::name + const_name("]")
|
template <typename T_, enable_if_t<std::is_same<ArrayType, remove_cv_t<T_>>::value, int> = 0>
|
||||||
+ const_name<Resizable>(const_name(""),
|
static handle cast(T_ *src, return_value_policy policy, handle parent) {
|
||||||
const_name(", FixedSize(")
|
if (!src) {
|
||||||
+ const_name<Size>() + const_name(")]")));
|
return none().release();
|
||||||
|
}
|
||||||
|
if (policy == return_value_policy::take_ownership) {
|
||||||
|
auto h = cast(std::move(*src), policy, parent);
|
||||||
|
delete src; // WARNING: Assumes `src` was allocated with `new`.
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
return cast(*src, policy, parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
|
operator ArrayType *() { return &(*value); }
|
||||||
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
|
operator ArrayType &() { return *value; }
|
||||||
|
// NOLINTNEXTLINE(google-explicit-constructor)
|
||||||
|
operator ArrayType &&() && { return std::move(*value); }
|
||||||
|
|
||||||
|
template <typename T_>
|
||||||
|
using cast_op_type = movable_cast_op_type<T_>;
|
||||||
|
|
||||||
|
static constexpr auto name
|
||||||
|
= const_name<Resizable>(const_name(""), const_name("Annotated[")) + const_name("list[")
|
||||||
|
+ value_conv::name + const_name("]")
|
||||||
|
+ const_name<Resizable>(
|
||||||
|
const_name(""), const_name(", FixedSize(") + const_name<Size>() + const_name(")]"));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename Type, size_t Size>
|
template <typename Type, size_t Size>
|
||||||
|
@ -201,6 +201,23 @@ TEST_SUBMODULE(stl, m) {
|
|||||||
m.def("cast_array", []() { return std::array<int, 2>{{1, 2}}; });
|
m.def("cast_array", []() { return std::array<int, 2>{{1, 2}}; });
|
||||||
m.def("load_array", [](const std::array<int, 2> &a) { return a[0] == 1 && a[1] == 2; });
|
m.def("load_array", [](const std::array<int, 2> &a) { return a[0] == 1 && a[1] == 2; });
|
||||||
|
|
||||||
|
struct NoDefaultCtor {
|
||||||
|
explicit constexpr NoDefaultCtor(int val) : val{val} {}
|
||||||
|
int val;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct NoDefaultCtorArray {
|
||||||
|
explicit constexpr NoDefaultCtorArray(int i)
|
||||||
|
: arr{{NoDefaultCtor(10 + i), NoDefaultCtor(20 + i)}} {}
|
||||||
|
std::array<NoDefaultCtor, 2> arr;
|
||||||
|
};
|
||||||
|
|
||||||
|
// test_array_no_default_ctor
|
||||||
|
py::class_<NoDefaultCtor>(m, "NoDefaultCtor").def_readonly("val", &NoDefaultCtor::val);
|
||||||
|
py::class_<NoDefaultCtorArray>(m, "NoDefaultCtorArray")
|
||||||
|
.def(py::init<int>())
|
||||||
|
.def_readwrite("arr", &NoDefaultCtorArray::arr);
|
||||||
|
|
||||||
// test_valarray
|
// test_valarray
|
||||||
m.def("cast_valarray", []() { return std::valarray<int>{1, 4, 9}; });
|
m.def("cast_valarray", []() { return std::valarray<int>{1, 4, 9}; });
|
||||||
m.def("load_valarray", [](const std::valarray<int> &v) {
|
m.def("load_valarray", [](const std::valarray<int> &v) {
|
||||||
|
@ -48,6 +48,13 @@ def test_array(doc):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_array_no_default_ctor():
|
||||||
|
lst = m.NoDefaultCtorArray(3)
|
||||||
|
assert [e.val for e in lst.arr] == [13, 23]
|
||||||
|
lst.arr = m.NoDefaultCtorArray(4).arr
|
||||||
|
assert [e.val for e in lst.arr] == [14, 24]
|
||||||
|
|
||||||
|
|
||||||
def test_valarray(doc):
|
def test_valarray(doc):
|
||||||
"""std::valarray <-> list"""
|
"""std::valarray <-> list"""
|
||||||
lst = m.cast_valarray()
|
lst = m.cast_valarray()
|
||||||
|
Loading…
Reference in New Issue
Block a user