-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add format_descriptor<>
& npy_format_descriptor<>
PyObject *
specializations.
#4674
Changes from all commits
5168c13
d53a796
5bea2a8
50eaa3a
82ce80f
20b9baf
0640eb3
ddb625e
03dafde
28492ed
1593ebc
3f04188
38aa697
7f124bb
d432ce7
18e1bd2
029b157
d9e3bd3
e9a289c
8abe0e9
b09e75b
ba7063e
a4d61b4
ef34d29
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// Copyright (c) 2023 The pybind Community. | ||
|
||
#pragma once | ||
|
||
// Common message for `static_assert()`s, which are useful to easily | ||
// preempt much less obvious errors. | ||
#define PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED \ | ||
"Pointer types (in particular `PyObject *`) are not supported as scalar types for Eigen " \ | ||
"types." |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
#pragma once | ||
|
||
#include "../numpy.h" | ||
#include "common.h" | ||
|
||
#if defined(__GNUC__) && !defined(__clang__) && !defined(__INTEL_COMPILER) | ||
static_assert(__GNUC__ > 5, "Eigen Tensor support in pybind11 requires GCC > 5.0"); | ||
|
@@ -164,6 +165,8 @@ PYBIND11_WARNING_POP | |
|
||
template <typename Type> | ||
struct type_caster<Type, typename eigen_tensor_helper<Type>::ValidType> { | ||
static_assert(!std::is_pointer<typename Type::Scalar>::value, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Any reason to not add the assert to eigen_tensor_helper instead to avoid duplicate lines? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See above. |
||
PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED); | ||
using Helper = eigen_tensor_helper<Type>; | ||
static constexpr auto temp_name = get_tensor_descriptor<Type, false>::value; | ||
PYBIND11_TYPE_CASTER(Type, temp_name); | ||
|
@@ -359,6 +362,8 @@ struct get_storage_pointer_type<MapType, void_t<typename MapType::PointerArgType | |
template <typename Type, int Options> | ||
struct type_caster<Eigen::TensorMap<Type, Options>, | ||
typename eigen_tensor_helper<remove_cv_t<Type>>::ValidType> { | ||
static_assert(!std::is_pointer<typename Type::Scalar>::value, | ||
PYBIND11_EIGEN_MESSAGE_POINTER_TYPES_ARE_NOT_SUPPORTED); | ||
using MapType = Eigen::TensorMap<Type, Options>; | ||
using Helper = eigen_tensor_helper<remove_cv_t<Type>>; | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -523,4 +523,30 @@ TEST_SUBMODULE(numpy_array, sm) { | |||||||||||||||||||||||||||||||||||
sm.def("test_fmt_desc_const_double", [](const py::array_t<const double> &) {}); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
sm.def("round_trip_float", [](double d) { return d; }); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
sm.def("pass_array_pyobject_ptr_return_sum_str_values", | ||||||||||||||||||||||||||||||||||||
[](const py::array_t<PyObject *> &objs) { | ||||||||||||||||||||||||||||||||||||
std::string sum_str_values; | ||||||||||||||||||||||||||||||||||||
for (const auto &obj : objs) { | ||||||||||||||||||||||||||||||||||||
sum_str_values += py::str(obj.attr("value")); | ||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
return sum_str_values; | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
sm.def("pass_array_pyobject_ptr_return_as_list", | ||||||||||||||||||||||||||||||||||||
[](const py::array_t<PyObject *> &objs) -> py::list { return objs; }); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
sm.def("return_array_pyobject_ptr_cpp_loop", [](const py::list &objs) { | ||||||||||||||||||||||||||||||||||||
py::size_t arr_size = py::len(objs); | ||||||||||||||||||||||||||||||||||||
py::array_t<PyObject *> arr_from_list(static_cast<py::ssize_t>(arr_size)); | ||||||||||||||||||||||||||||||||||||
PyObject **data = arr_from_list.mutable_data(); | ||||||||||||||||||||||||||||||||||||
for (py::size_t i = 0; i < arr_size; i++) { | ||||||||||||||||||||||||||||||||||||
assert(data[i] == nullptr); | ||||||||||||||||||||||||||||||||||||
data[i] = py::cast<PyObject *>(objs[i].attr("value")); | ||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This might be a silly question, but does this appropriately increase the reference count? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Not a silly question, this was something I was struggling with quite a bit: pybind11/include/pybind11/cast.h Lines 1062 to 1078 in d72ffb4
|
||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||
return arr_from_list; | ||||||||||||||||||||||||||||||||||||
}); | ||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
sm.def("return_array_pyobject_ptr_from_list", | ||||||||||||||||||||||||||||||||||||
[](const py::list &objs) -> py::array_t<PyObject *> { return objs; }); | ||||||||||||||||||||||||||||||||||||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you might be able to move these asserts to EigenProps, which would reduce the amount of redundant code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was ambivalent before and still am a little bit, but decided to keep the 5
static_assert()
:Cons: 2-3 x 2 more lines of code.
Pros:
The
static_assert()
s appear at or near the top of each of thetype_caster
s, which makes them essentially a kind of documentation.In case a
static_assert()
fails, it will be much more obvious that the message we want to send is: thetype_caster
does not support pointer types as scalar types.