mirror of
https://github.com/pybind/pybind11.git
synced 2026-05-12 17:26:13 +00:00
Merge branch 'master' into sh_merge_master
This commit is contained in:
@@ -10,6 +10,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "detail/common.h"
|
||||
#include "cast.h"
|
||||
|
||||
#include <functional>
|
||||
@@ -477,7 +478,7 @@ struct process_attribute<arg_v> : process_attribute_default<arg_v> {
|
||||
}
|
||||
|
||||
if (!a.value) {
|
||||
#if !defined(NDEBUG)
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
std::string descr("'");
|
||||
if (a.name) {
|
||||
descr += std::string(a.name) + ": ";
|
||||
@@ -498,7 +499,8 @@ struct process_attribute<arg_v> : process_attribute_default<arg_v> {
|
||||
#else
|
||||
pybind11_fail("arg(): could not convert default argument "
|
||||
"into a Python object (type not registered yet?). "
|
||||
"Compile in debug mode for more information.");
|
||||
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
|
||||
"more information.");
|
||||
#endif
|
||||
}
|
||||
r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);
|
||||
|
||||
@@ -798,8 +798,9 @@ protected:
|
||||
return true;
|
||||
}
|
||||
throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
|
||||
#if defined(NDEBUG)
|
||||
"(compile in debug mode for type information)");
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
|
||||
"type information)");
|
||||
#else
|
||||
"of type '"
|
||||
+ type_id<holder_type>() + "''");
|
||||
@@ -1029,9 +1030,9 @@ struct return_value_policy_override<
|
||||
template <typename T, typename SFINAE>
|
||||
type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) {
|
||||
if (!conv.load(handle, true)) {
|
||||
#if defined(NDEBUG)
|
||||
throw cast_error(
|
||||
"Unable to cast Python instance to C++ type (compile in debug mode for details)");
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
throw cast_error("Unable to cast Python instance to C++ type (#define "
|
||||
"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
|
||||
#else
|
||||
throw cast_error("Unable to cast Python instance of type "
|
||||
+ (std::string) str(type::handle_of(handle)) + " to C++ type '"
|
||||
@@ -1096,10 +1097,10 @@ inline void handle::cast() const {
|
||||
template <typename T>
|
||||
detail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {
|
||||
if (obj.ref_count() > 1) {
|
||||
#if defined(NDEBUG)
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
throw cast_error(
|
||||
"Unable to cast Python instance to C++ rvalue: instance has multiple references"
|
||||
" (compile in debug mode for details)");
|
||||
" (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
|
||||
#else
|
||||
throw cast_error("Unable to move from Python " + (std::string) str(type::handle_of(obj))
|
||||
+ " instance to C++ " + type_id<T>()
|
||||
@@ -1200,10 +1201,10 @@ PYBIND11_NAMESPACE_END(detail)
|
||||
|
||||
// The overloads could coexist, i.e. the #if is not strictly speaking needed,
|
||||
// but it is an easy minor optimization.
|
||||
#if defined(NDEBUG)
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
inline cast_error cast_error_unable_to_convert_call_arg() {
|
||||
return cast_error(
|
||||
"Unable to convert call argument to Python object (compile in debug mode for details)");
|
||||
return cast_error("Unable to convert call argument to Python object (#define "
|
||||
"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
|
||||
}
|
||||
#else
|
||||
inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name,
|
||||
@@ -1225,7 +1226,7 @@ tuple make_tuple(Args &&...args_) {
|
||||
detail::make_caster<Args>::cast(std::forward<Args>(args_), policy, nullptr))...}};
|
||||
for (size_t i = 0; i < args.size(); i++) {
|
||||
if (!args[i]) {
|
||||
#if defined(NDEBUG)
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
throw cast_error_unable_to_convert_call_arg();
|
||||
#else
|
||||
std::array<std::string, size> argtypes{{type_id<Args>()...}};
|
||||
@@ -1277,7 +1278,7 @@ private:
|
||||
: arg(base), value(reinterpret_steal<object>(detail::make_caster<T>::cast(
|
||||
std::forward<T>(x), return_value_policy::automatic, {}))),
|
||||
descr(descr)
|
||||
#if !defined(NDEBUG)
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
,
|
||||
type(type_id<T>())
|
||||
#endif
|
||||
@@ -1317,7 +1318,7 @@ public:
|
||||
object value;
|
||||
/// The (optional) description of the default value
|
||||
const char *descr;
|
||||
#if !defined(NDEBUG)
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
/// The C++ type name of the default value (only available when compiled in debug mode)
|
||||
std::string type;
|
||||
#endif
|
||||
@@ -1515,7 +1516,7 @@ private:
|
||||
auto o = reinterpret_steal<object>(
|
||||
detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
|
||||
if (!o) {
|
||||
#if defined(NDEBUG)
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
throw cast_error_unable_to_convert_call_arg();
|
||||
#else
|
||||
throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()),
|
||||
@@ -1533,21 +1534,21 @@ private:
|
||||
|
||||
void process(list & /*args_list*/, arg_v a) {
|
||||
if (!a.name) {
|
||||
#if defined(NDEBUG)
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
nameless_argument_error();
|
||||
#else
|
||||
nameless_argument_error(a.type);
|
||||
#endif
|
||||
}
|
||||
if (m_kwargs.contains(a.name)) {
|
||||
#if defined(NDEBUG)
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
multiple_values_error();
|
||||
#else
|
||||
multiple_values_error(a.name);
|
||||
#endif
|
||||
}
|
||||
if (!a.value) {
|
||||
#if defined(NDEBUG)
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
throw cast_error_unable_to_convert_call_arg();
|
||||
#else
|
||||
throw cast_error_unable_to_convert_call_arg(a.name, a.type);
|
||||
@@ -1562,7 +1563,7 @@ private:
|
||||
}
|
||||
for (auto k : reinterpret_borrow<dict>(kp)) {
|
||||
if (m_kwargs.contains(k.first)) {
|
||||
#if defined(NDEBUG)
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
multiple_values_error();
|
||||
#else
|
||||
multiple_values_error(str(k.first));
|
||||
@@ -1573,9 +1574,10 @@ private:
|
||||
}
|
||||
|
||||
[[noreturn]] static void nameless_argument_error() {
|
||||
throw type_error("Got kwargs without a name; only named arguments "
|
||||
"may be passed via py::arg() to a python function call. "
|
||||
"(compile in debug mode for details)");
|
||||
throw type_error(
|
||||
"Got kwargs without a name; only named arguments "
|
||||
"may be passed via py::arg() to a python function call. "
|
||||
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
|
||||
}
|
||||
[[noreturn]] static void nameless_argument_error(const std::string &type) {
|
||||
throw type_error("Got kwargs without a name of type '" + type
|
||||
@@ -1583,8 +1585,9 @@ private:
|
||||
"arguments may be passed via py::arg() to a python function call. ");
|
||||
}
|
||||
[[noreturn]] static void multiple_values_error() {
|
||||
throw type_error("Got multiple values for keyword argument "
|
||||
"(compile in debug mode for details)");
|
||||
throw type_error(
|
||||
"Got multiple values for keyword argument "
|
||||
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
|
||||
}
|
||||
|
||||
[[noreturn]] static void multiple_values_error(const std::string &name) {
|
||||
@@ -1631,7 +1634,7 @@ unpacking_collector<policy> collect_arguments(Args &&...args) {
|
||||
template <typename Derived>
|
||||
template <return_value_policy policy, typename... Args>
|
||||
object object_api<Derived>::operator()(Args &&...args) const {
|
||||
#ifndef NDEBUG
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
if (!PyGILState_Check()) {
|
||||
pybind11_fail("pybind11::object_api<>::operator() PyGILState_Check() failure.");
|
||||
}
|
||||
|
||||
@@ -1169,5 +1169,12 @@ constexpr inline bool silence_msvc_c4127(bool cond) { return cond; }
|
||||
# define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__
|
||||
#endif
|
||||
|
||||
// Pybind offers detailed error messages by default for all builts that are debug (through the
|
||||
// negation of ndebug). This can also be manually enabled by users, for any builds, through
|
||||
// defining PYBIND11_DETAILED_ERROR_MESSAGES.
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(NDEBUG)
|
||||
# define PYBIND11_DETAILED_ERROR_MESSAGES
|
||||
#endif
|
||||
|
||||
PYBIND11_NAMESPACE_END(detail)
|
||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
||||
|
||||
@@ -394,15 +394,16 @@ instance::get_value_and_holder(const type_info *find_type /*= nullptr default in
|
||||
return value_and_holder();
|
||||
}
|
||||
|
||||
#if defined(NDEBUG)
|
||||
pybind11_fail("pybind11::detail::instance::get_value_and_holder: "
|
||||
"type is not a pybind11 base of the given instance "
|
||||
"(compile in debug mode for type details)");
|
||||
#else
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
pybind11_fail("pybind11::detail::instance::get_value_and_holder: `"
|
||||
+ get_fully_qualified_tp_name(find_type->type)
|
||||
+ "' is not a pybind11 base of the given `"
|
||||
+ get_fully_qualified_tp_name(Py_TYPE(this)) + "' instance");
|
||||
#else
|
||||
pybind11_fail(
|
||||
"pybind11::detail::instance::get_value_and_holder: "
|
||||
"type is not a pybind11 base of the given instance "
|
||||
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for type details)");
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -612,14 +613,15 @@ public:
|
||||
if (copy_constructor) {
|
||||
valueptr = copy_constructor(src);
|
||||
} else {
|
||||
#if defined(NDEBUG)
|
||||
throw cast_error("return_value_policy = copy, but type is "
|
||||
"non-copyable! (compile in debug mode for details)");
|
||||
#else
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
std::string type_name(tinfo->cpptype->name());
|
||||
detail::clean_type_id(type_name);
|
||||
throw cast_error("return_value_policy = copy, but type " + type_name
|
||||
+ " is non-copyable!");
|
||||
#else
|
||||
throw cast_error("return_value_policy = copy, but type is "
|
||||
"non-copyable! (#define PYBIND11_DETAILED_ERROR_MESSAGES or "
|
||||
"compile in debug mode for details)");
|
||||
#endif
|
||||
}
|
||||
wrapper->owned = true;
|
||||
@@ -631,15 +633,16 @@ public:
|
||||
} else if (copy_constructor) {
|
||||
valueptr = copy_constructor(src);
|
||||
} else {
|
||||
#if defined(NDEBUG)
|
||||
throw cast_error("return_value_policy = move, but type is neither "
|
||||
"movable nor copyable! "
|
||||
"(compile in debug mode for details)");
|
||||
#else
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
std::string type_name(tinfo->cpptype->name());
|
||||
detail::clean_type_id(type_name);
|
||||
throw cast_error("return_value_policy = move, but type " + type_name
|
||||
+ " is neither movable nor copyable!");
|
||||
#else
|
||||
throw cast_error("return_value_policy = move, but type is neither "
|
||||
"movable nor copyable! "
|
||||
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in "
|
||||
"debug mode for details)");
|
||||
#endif
|
||||
}
|
||||
wrapper->owned = true;
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
|
||||
if (!tstate) {
|
||||
tstate = PyThreadState_New(internals.istate);
|
||||
# if !defined(NDEBUG)
|
||||
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
if (!tstate) {
|
||||
pybind11_fail("scoped_acquire: could not create thread state!");
|
||||
}
|
||||
@@ -84,7 +84,7 @@ public:
|
||||
|
||||
PYBIND11_NOINLINE void dec_ref() {
|
||||
--tstate->gilstate_counter;
|
||||
# if !defined(NDEBUG)
|
||||
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
if (detail::get_thread_state_unchecked() != tstate) {
|
||||
pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!");
|
||||
}
|
||||
@@ -93,7 +93,7 @@ public:
|
||||
}
|
||||
# endif
|
||||
if (tstate->gilstate_counter == 0) {
|
||||
# if !defined(NDEBUG)
|
||||
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
if (!release) {
|
||||
pybind11_fail("scoped_acquire::dec_ref(): internal error!");
|
||||
}
|
||||
|
||||
@@ -263,7 +263,7 @@ private:
|
||||
static npy_api lookup() {
|
||||
module_ m = module_::import("numpy.core.multiarray");
|
||||
auto c = m.attr("_ARRAY_API");
|
||||
void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), NULL);
|
||||
void **api_ptr = (void **) PyCapsule_GetPointer(c.ptr(), nullptr);
|
||||
npy_api api;
|
||||
#define DECL_NPY_API(Func) api.Func##_ = (decltype(api.Func##_)) api_ptr[API_##Func];
|
||||
DECL_NPY_API(PyArray_GetNDArrayCFeatureVersion);
|
||||
@@ -547,9 +547,11 @@ public:
|
||||
.ptr();
|
||||
}
|
||||
|
||||
explicit dtype(const std::string &format) : dtype(from_args(pybind11::str(format))) {}
|
||||
explicit dtype(const pybind11::str &format) : dtype(from_args(format)) {}
|
||||
|
||||
explicit dtype(const char *format) : dtype(from_args(pybind11::str(format))) {}
|
||||
explicit dtype(const std::string &format) : dtype(pybind11::str(format)) {}
|
||||
|
||||
explicit dtype(const char *format) : dtype(pybind11::str(format)) {}
|
||||
|
||||
dtype(list names, list formats, list offsets, ssize_t itemsize) {
|
||||
dict args;
|
||||
@@ -557,7 +559,7 @@ public:
|
||||
args["formats"] = std::move(formats);
|
||||
args["offsets"] = std::move(offsets);
|
||||
args["itemsize"] = pybind11::int_(itemsize);
|
||||
m_ptr = from_args(std::move(args)).release().ptr();
|
||||
m_ptr = from_args(args).release().ptr();
|
||||
}
|
||||
|
||||
explicit dtype(int typenum)
|
||||
@@ -568,7 +570,7 @@ public:
|
||||
}
|
||||
|
||||
/// This is essentially the same as calling numpy.dtype(args) in Python.
|
||||
static dtype from_args(object args) {
|
||||
static dtype from_args(const object &args) {
|
||||
PyObject *ptr = nullptr;
|
||||
if ((detail::npy_api::get().PyArray_DescrConverter_(args.ptr(), &ptr) == 0) || !ptr) {
|
||||
throw error_already_set();
|
||||
@@ -645,8 +647,9 @@ private:
|
||||
for (auto field : attr("fields").attr("items")()) {
|
||||
auto spec = field.cast<tuple>();
|
||||
auto name = spec[0].cast<pybind11::str>();
|
||||
auto format = spec[1].cast<tuple>()[0].cast<dtype>();
|
||||
auto offset = spec[1].cast<tuple>()[1].cast<pybind11::int_>();
|
||||
auto spec_fo = spec[1].cast<tuple>();
|
||||
auto format = spec_fo[0].cast<dtype>();
|
||||
auto offset = spec_fo[1].cast<pybind11::int_>();
|
||||
if ((len(name) == 0u) && format.kind() == 'V') {
|
||||
continue;
|
||||
}
|
||||
@@ -1549,7 +1552,7 @@ public:
|
||||
void *data() const { return p_ptr; }
|
||||
|
||||
private:
|
||||
char *p_ptr{0};
|
||||
char *p_ptr{nullptr};
|
||||
container_type m_strides;
|
||||
};
|
||||
|
||||
|
||||
@@ -313,6 +313,10 @@ protected:
|
||||
// along the way.
|
||||
class strdup_guard {
|
||||
public:
|
||||
strdup_guard() = default;
|
||||
strdup_guard(const strdup_guard &) = delete;
|
||||
strdup_guard &operator=(const strdup_guard &) = delete;
|
||||
|
||||
~strdup_guard() {
|
||||
for (auto *s : strings) {
|
||||
std::free(s);
|
||||
@@ -367,7 +371,7 @@ protected:
|
||||
rec->is_constructor = (std::strcmp(rec->name, "__init__") == 0)
|
||||
|| (std::strcmp(rec->name, "__setstate__") == 0);
|
||||
|
||||
#if !defined(NDEBUG) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING)
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES) && !defined(PYBIND11_DISABLE_NEW_STYLE_INIT_WARNING)
|
||||
if (rec->is_constructor && !rec->is_new_style_constructor) {
|
||||
const auto class_name
|
||||
= detail::get_fully_qualified_tp_name((PyTypeObject *) rec->scope.ptr());
|
||||
@@ -515,8 +519,9 @@ protected:
|
||||
if (chain->is_method != rec->is_method) {
|
||||
pybind11_fail(
|
||||
"overloading a method with both static and instance methods is not supported; "
|
||||
#if defined(NDEBUG)
|
||||
"compile in debug mode for more details"
|
||||
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more "
|
||||
"details"
|
||||
#else
|
||||
"error while attempting to bind "
|
||||
+ std::string(rec->is_method ? "instance" : "static") + " method "
|
||||
@@ -903,7 +908,7 @@ protected:
|
||||
|
||||
// 5. Put everything in a vector. Not technically step 5, we've been building it
|
||||
// in `call.args` all along.
|
||||
#if !defined(NDEBUG)
|
||||
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||
if (call.args.size() != func.nargs || call.args_convert.size() != func.nargs) {
|
||||
pybind11_fail("Internal error: function call dispatcher inserted wrong number "
|
||||
"of arguments!");
|
||||
@@ -2592,7 +2597,7 @@ public:
|
||||
exception(handle scope, const char *name, handle base = PyExc_Exception) {
|
||||
std::string full_name
|
||||
= scope.attr("__name__").cast<std::string>() + std::string(".") + name;
|
||||
m_ptr = PyErr_NewException(const_cast<char *>(full_name.c_str()), base.ptr(), NULL);
|
||||
m_ptr = PyErr_NewException(const_cast<char *>(full_name.c_str()), base.ptr(), nullptr);
|
||||
if (hasattr(scope, "__dict__") && scope.attr("__dict__").contains(name)) {
|
||||
pybind11_fail("Error during initialization: multiple incompatible "
|
||||
"definitions with name \""
|
||||
|
||||
@@ -600,13 +600,13 @@ inline handle get_function(handle value) {
|
||||
inline PyObject *dict_getitemstring(PyObject *v, const char *key) {
|
||||
PyObject *kv = nullptr, *rv = nullptr;
|
||||
kv = PyUnicode_FromString(key);
|
||||
if (kv == NULL) {
|
||||
if (kv == nullptr) {
|
||||
throw error_already_set();
|
||||
}
|
||||
|
||||
rv = PyDict_GetItemWithError(v, kv);
|
||||
Py_DECREF(kv);
|
||||
if (rv == NULL && PyErr_Occurred()) {
|
||||
if (rv == nullptr && PyErr_Occurred()) {
|
||||
throw error_already_set();
|
||||
}
|
||||
return rv;
|
||||
@@ -614,7 +614,7 @@ inline PyObject *dict_getitemstring(PyObject *v, const char *key) {
|
||||
|
||||
inline PyObject *dict_getitem(PyObject *v, PyObject *key) {
|
||||
PyObject *rv = PyDict_GetItemWithError(v, key);
|
||||
if (rv == NULL && PyErr_Occurred()) {
|
||||
if (rv == nullptr && PyErr_Occurred()) {
|
||||
throw error_already_set();
|
||||
}
|
||||
return rv;
|
||||
@@ -1914,8 +1914,8 @@ public:
|
||||
return memoryview::from_buffer(reinterpret_cast<void *>(ptr),
|
||||
sizeof(T),
|
||||
format_descriptor<T>::value,
|
||||
shape,
|
||||
strides,
|
||||
std::move(shape),
|
||||
std::move(strides),
|
||||
readonly);
|
||||
}
|
||||
|
||||
@@ -1923,7 +1923,8 @@ public:
|
||||
static memoryview from_buffer(const T *ptr,
|
||||
detail::any_container<ssize_t> shape,
|
||||
detail::any_container<ssize_t> strides) {
|
||||
return memoryview::from_buffer(const_cast<T *>(ptr), shape, strides, true);
|
||||
return memoryview::from_buffer(
|
||||
const_cast<T *>(ptr), std::move(shape), std::move(strides), true);
|
||||
}
|
||||
|
||||
/** \rst
|
||||
|
||||
Reference in New Issue
Block a user