mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-29 16:37:13 +00:00
Merge branch 'master' into smart_holder
This commit is contained in:
commit
e7d146bdbd
@ -1,11 +1,13 @@
|
|||||||
FormatStyle: file
|
FormatStyle: file
|
||||||
|
|
||||||
Checks: '
|
Checks: '
|
||||||
|
clang-analyzer-optin.cplusplus.VirtualCall,
|
||||||
llvm-namespace-comment,
|
llvm-namespace-comment,
|
||||||
misc-misplaced-const,
|
misc-misplaced-const,
|
||||||
misc-static-assert,
|
misc-static-assert,
|
||||||
misc-uniqueptr-reset-release,
|
misc-uniqueptr-reset-release,
|
||||||
modernize-avoid-bind,
|
modernize-avoid-bind,
|
||||||
|
modernize-redundant-void-arg,
|
||||||
modernize-replace-auto-ptr,
|
modernize-replace-auto-ptr,
|
||||||
modernize-replace-disallow-copy-and-assign-macro,
|
modernize-replace-disallow-copy-and-assign-macro,
|
||||||
modernize-shrink-to-fit,
|
modernize-shrink-to-fit,
|
||||||
@ -20,6 +22,7 @@ modernize-use-override,
|
|||||||
modernize-use-using,
|
modernize-use-using,
|
||||||
*performance*,
|
*performance*,
|
||||||
readability-container-size-empty,
|
readability-container-size-empty,
|
||||||
|
readability-else-after-return,
|
||||||
readability-make-member-function-const,
|
readability-make-member-function-const,
|
||||||
readability-redundant-function-ptr-dereference,
|
readability-redundant-function-ptr-dereference,
|
||||||
readability-redundant-smartptr-get,
|
readability-redundant-smartptr-get,
|
||||||
|
@ -107,25 +107,28 @@ public:
|
|||||||
operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }
|
operator std::reference_wrapper<type>() { return cast_op<type &>(subcaster); }
|
||||||
};
|
};
|
||||||
|
|
||||||
#define PYBIND11_TYPE_CASTER(type, py_name) \
|
#define PYBIND11_TYPE_CASTER(type, py_name) \
|
||||||
protected: \
|
protected: \
|
||||||
type value; \
|
type value; \
|
||||||
public: \
|
\
|
||||||
static constexpr auto name = py_name; \
|
public: \
|
||||||
template <typename T_, enable_if_t<std::is_same<type, remove_cv_t<T_>>::value, int> = 0> \
|
static constexpr auto name = py_name; \
|
||||||
static handle cast(T_ *src, return_value_policy policy, handle parent) { \
|
template <typename T_, enable_if_t<std::is_same<type, remove_cv_t<T_>>::value, int> = 0> \
|
||||||
if (!src) return none().release(); \
|
static handle cast(T_ *src, return_value_policy policy, handle parent) { \
|
||||||
if (policy == return_value_policy::take_ownership) { \
|
if (!src) \
|
||||||
auto h = cast(std::move(*src), policy, parent); delete src; return h; \
|
return none().release(); \
|
||||||
} else { \
|
if (policy == return_value_policy::take_ownership) { \
|
||||||
return cast(*src, policy, parent); \
|
auto h = cast(std::move(*src), policy, parent); \
|
||||||
} \
|
delete src; \
|
||||||
} \
|
return h; \
|
||||||
operator type*() { return &value; } \
|
} \
|
||||||
operator type&() { return value; } \
|
return cast(*src, policy, parent); \
|
||||||
operator type&&() && { return std::move(value); } \
|
} \
|
||||||
template <typename T_> using cast_op_type = pybind11::detail::movable_cast_op_type<T_>
|
operator type *() { return &value; } \
|
||||||
|
operator type &() { return value; } \
|
||||||
|
operator type &&() && { return std::move(value); } \
|
||||||
|
template <typename T_> \
|
||||||
|
using cast_op_type = pybind11::detail::movable_cast_op_type<T_>
|
||||||
|
|
||||||
template <typename CharT> using is_std_char_type = any_of<
|
template <typename CharT> using is_std_char_type = any_of<
|
||||||
std::is_same<CharT, char>, /* std::string */
|
std::is_same<CharT, char>, /* std::string */
|
||||||
@ -269,7 +272,8 @@ public:
|
|||||||
bool load(handle h, bool) {
|
bool load(handle h, bool) {
|
||||||
if (!h) {
|
if (!h) {
|
||||||
return false;
|
return false;
|
||||||
} else if (h.is_none()) {
|
}
|
||||||
|
if (h.is_none()) {
|
||||||
value = nullptr;
|
value = nullptr;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -294,8 +298,7 @@ public:
|
|||||||
static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) {
|
static handle cast(const void *ptr, return_value_policy /* policy */, handle /* parent */) {
|
||||||
if (ptr)
|
if (ptr)
|
||||||
return capsule(ptr).release();
|
return capsule(ptr).release();
|
||||||
else
|
return none().inc_ref();
|
||||||
return none().inc_ref();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T> using cast_op_type = void*&;
|
template <typename T> using cast_op_type = void*&;
|
||||||
@ -311,9 +314,15 @@ template <> class type_caster<bool> {
|
|||||||
public:
|
public:
|
||||||
bool load(handle src, bool convert) {
|
bool load(handle src, bool convert) {
|
||||||
if (!src) return false;
|
if (!src) return false;
|
||||||
else if (src.ptr() == Py_True) { value = true; return true; }
|
if (src.ptr() == Py_True) {
|
||||||
else if (src.ptr() == Py_False) { value = false; return true; }
|
value = true;
|
||||||
else if (convert || !std::strcmp("numpy.bool_", Py_TYPE(src.ptr())->tp_name)) {
|
return true;
|
||||||
|
}
|
||||||
|
if (src.ptr() == Py_False) {
|
||||||
|
value = false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (convert || !std::strcmp("numpy.bool_", Py_TYPE(src.ptr())->tp_name)) {
|
||||||
// (allow non-implicit conversion for numpy booleans)
|
// (allow non-implicit conversion for numpy booleans)
|
||||||
|
|
||||||
Py_ssize_t res = -1;
|
Py_ssize_t res = -1;
|
||||||
@ -337,9 +346,8 @@ public:
|
|||||||
if (res == 0 || res == 1) {
|
if (res == 0 || res == 1) {
|
||||||
value = (bool) res;
|
value = (bool) res;
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
PyErr_Clear();
|
|
||||||
}
|
}
|
||||||
|
PyErr_Clear();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -373,7 +381,8 @@ template <typename StringType, bool IsView = false> struct string_caster {
|
|||||||
handle load_src = src;
|
handle load_src = src;
|
||||||
if (!src) {
|
if (!src) {
|
||||||
return false;
|
return false;
|
||||||
} else if (!PyUnicode_Check(load_src.ptr())) {
|
}
|
||||||
|
if (!PyUnicode_Check(load_src.ptr())) {
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
return load_bytes(load_src);
|
return load_bytes(load_src);
|
||||||
#else
|
#else
|
||||||
@ -576,10 +585,11 @@ public:
|
|||||||
static handle cast(T *src, return_value_policy policy, handle parent) {
|
static handle cast(T *src, return_value_policy policy, handle parent) {
|
||||||
if (!src) return none().release();
|
if (!src) return none().release();
|
||||||
if (policy == return_value_policy::take_ownership) {
|
if (policy == return_value_policy::take_ownership) {
|
||||||
auto h = cast(std::move(*src), policy, parent); delete src; return h;
|
auto h = cast(std::move(*src), policy, parent);
|
||||||
} else {
|
delete src;
|
||||||
return cast(*src, policy, parent);
|
return h;
|
||||||
}
|
}
|
||||||
|
return cast(*src, policy, parent);
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr auto name = _("Tuple[") + concat(make_caster<Ts>::name...) + _("]");
|
static constexpr auto name = _("Tuple[") + concat(make_caster<Ts>::name...) + _("]");
|
||||||
@ -686,14 +696,14 @@ protected:
|
|||||||
value = v_h.value_ptr();
|
value = v_h.value_ptr();
|
||||||
holder = v_h.template holder<holder_type>();
|
holder = v_h.template holder<holder_type>();
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
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)");
|
|
||||||
#else
|
|
||||||
"of type '" + type_id<holder_type>() + "''");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
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)");
|
||||||
|
#else
|
||||||
|
"of type '"
|
||||||
|
+ type_id<holder_type>() + "''");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = holder_type, detail::enable_if_t<!std::is_constructible<T, const T &, type*>::value, int> = 0>
|
template <typename T = holder_type, detail::enable_if_t<!std::is_constructible<T, const T &, type*>::value, int> = 0>
|
||||||
@ -944,8 +954,7 @@ template <typename T> detail::enable_if_t<detail::move_always<T>::value, T> cast
|
|||||||
template <typename T> detail::enable_if_t<detail::move_if_unreferenced<T>::value, T> cast(object &&object) {
|
template <typename T> detail::enable_if_t<detail::move_if_unreferenced<T>::value, T> cast(object &&object) {
|
||||||
if (object.ref_count() > 1)
|
if (object.ref_count() > 1)
|
||||||
return cast<T>(object);
|
return cast<T>(object);
|
||||||
else
|
return move<T>(std::move(object));
|
||||||
return move<T>(std::move(object));
|
|
||||||
}
|
}
|
||||||
template <typename T> detail::enable_if_t<detail::move_never<T>::value, T> cast(object &&object) {
|
template <typename T> detail::enable_if_t<detail::move_never<T>::value, T> cast(object &&object) {
|
||||||
return cast<T>(object);
|
return cast<T>(object);
|
||||||
|
@ -53,11 +53,11 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// If invoked with a float we assume it is seconds and convert
|
// If invoked with a float we assume it is seconds and convert
|
||||||
else if (PyFloat_Check(src.ptr())) {
|
if (PyFloat_Check(src.ptr())) {
|
||||||
value = type(duration_cast<duration<rep, period>>(duration<double>(PyFloat_AsDouble(src.ptr()))));
|
value = type(duration_cast<duration<rep, period>>(duration<double>(PyFloat_AsDouble(src.ptr()))));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this is a duration just return it back
|
// If this is a duration just return it back
|
||||||
|
@ -162,9 +162,7 @@ extern "C" inline PyObject *pybind11_meta_getattro(PyObject *obj, PyObject *name
|
|||||||
Py_INCREF(descr);
|
Py_INCREF(descr);
|
||||||
return descr;
|
return descr;
|
||||||
}
|
}
|
||||||
else {
|
return PyType_Type.tp_getattro(obj, name);
|
||||||
return PyType_Type.tp_getattro(obj, name);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -670,7 +670,7 @@ public:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
// Case 2: We have a derived class
|
// Case 2: We have a derived class
|
||||||
else if (PyType_IsSubtype(srctype, typeinfo->type)) {
|
if (PyType_IsSubtype(srctype, typeinfo->type)) {
|
||||||
auto &bases = all_type_info(srctype);
|
auto &bases = all_type_info(srctype);
|
||||||
bool no_cpp_mi = typeinfo->simple_type;
|
bool no_cpp_mi = typeinfo->simple_type;
|
||||||
|
|
||||||
@ -687,7 +687,7 @@ public:
|
|||||||
// Case 2b: the python type inherits from multiple C++ bases. Check the bases to see if
|
// Case 2b: the python type inherits from multiple C++ bases. Check the bases to see if
|
||||||
// we can find an exact match (or, for a simple C++ type, an inherited match); if so, we
|
// we can find an exact match (or, for a simple C++ type, an inherited match); if so, we
|
||||||
// can safely reinterpret_cast to the relevant pointer.
|
// can safely reinterpret_cast to the relevant pointer.
|
||||||
else if (bases.size() > 1) {
|
if (bases.size() > 1) {
|
||||||
for (auto base : bases) {
|
for (auto base : bases) {
|
||||||
if (no_cpp_mi ? PyType_IsSubtype(base->type, typeinfo->type) : base->type == typeinfo->type) {
|
if (no_cpp_mi ? PyType_IsSubtype(base->type, typeinfo->type) : base->type == typeinfo->type) {
|
||||||
this_.load_value(reinterpret_cast<instance *>(src.ptr())->get_value_and_holder(base));
|
this_.load_value(reinterpret_cast<instance *>(src.ptr())->get_value_and_holder(base));
|
||||||
|
@ -169,21 +169,18 @@ template <typename Type_> struct EigenProps {
|
|||||||
return false; // Vector size mismatch
|
return false; // Vector size mismatch
|
||||||
return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
|
return {rows == 1 ? 1 : n, cols == 1 ? 1 : n, stride};
|
||||||
}
|
}
|
||||||
else if (fixed) {
|
if (fixed) {
|
||||||
// The type has a fixed size, but is not a vector: abort
|
// The type has a fixed size, but is not a vector: abort
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
else if (fixed_cols) {
|
if (fixed_cols) {
|
||||||
// Since this isn't a vector, cols must be != 1. We allow this only if it exactly
|
// Since this isn't a vector, cols must be != 1. We allow this only if it exactly
|
||||||
// equals the number of elements (rows is Dynamic, and so 1 row is allowed).
|
// equals the number of elements (rows is Dynamic, and so 1 row is allowed).
|
||||||
if (cols != n) return false;
|
if (cols != n) return false;
|
||||||
return {1, n, stride};
|
return {1, n, stride};
|
||||||
}
|
} // Otherwise it's either fully dynamic, or column dynamic; both become a column vector
|
||||||
else {
|
|
||||||
// Otherwise it's either fully dynamic, or column dynamic; both become a column vector
|
|
||||||
if (fixed_rows && rows != n) return false;
|
if (fixed_rows && rows != n) return false;
|
||||||
return {n, 1, stride};
|
return {n, 1, stride};
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static constexpr bool show_writeable = is_eigen_dense_map<Type>::value && is_eigen_mutable_map<Type>::value;
|
static constexpr bool show_writeable = is_eigen_dense_map<Type>::value && is_eigen_mutable_map<Type>::value;
|
||||||
|
@ -98,8 +98,7 @@ public:
|
|||||||
auto result = f_.template target<function_type>();
|
auto result = f_.template target<function_type>();
|
||||||
if (result)
|
if (result)
|
||||||
return cpp_function(*result, policy).release();
|
return cpp_function(*result, policy).release();
|
||||||
else
|
return cpp_function(std::forward<Func>(f_), policy).release();
|
||||||
return cpp_function(std::forward<Func>(f_), policy).release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PYBIND11_TYPE_CASTER(type, _("Callable[[") + concat(make_caster<Args>::name...) + _("], ")
|
PYBIND11_TYPE_CASTER(type, _("Callable[[") + concat(make_caster<Args>::name...) + _("], ")
|
||||||
|
@ -1340,9 +1340,8 @@ public:
|
|||||||
if (++m_index[i] != m_shape[i]) {
|
if (++m_index[i] != m_shape[i]) {
|
||||||
increment_common_iterator(i);
|
increment_common_iterator(i);
|
||||||
break;
|
break;
|
||||||
} else {
|
|
||||||
m_index[i] = 0;
|
|
||||||
}
|
}
|
||||||
|
m_index[i] = 0;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
@ -1493,8 +1492,7 @@ struct vectorize_returned_array {
|
|||||||
static Type create(broadcast_trivial trivial, const std::vector<ssize_t> &shape) {
|
static Type create(broadcast_trivial trivial, const std::vector<ssize_t> &shape) {
|
||||||
if (trivial == broadcast_trivial::f_trivial)
|
if (trivial == broadcast_trivial::f_trivial)
|
||||||
return array_t<Return, array::f_style>(shape);
|
return array_t<Return, array::f_style>(shape);
|
||||||
else
|
return array_t<Return>(shape);
|
||||||
return array_t<Return>(shape);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Return *mutable_data(Type &array) {
|
static Return *mutable_data(Type &array) {
|
||||||
|
@ -370,7 +370,7 @@ protected:
|
|||||||
std::memset(rec->def, 0, sizeof(PyMethodDef));
|
std::memset(rec->def, 0, sizeof(PyMethodDef));
|
||||||
rec->def->ml_name = rec->name;
|
rec->def->ml_name = rec->name;
|
||||||
rec->def->ml_meth
|
rec->def->ml_meth
|
||||||
= reinterpret_cast<PyCFunction>(reinterpret_cast<void (*)(void)>(dispatcher));
|
= reinterpret_cast<PyCFunction>(reinterpret_cast<void (*)()>(dispatcher));
|
||||||
rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS;
|
rec->def->ml_flags = METH_VARARGS | METH_KEYWORDS;
|
||||||
|
|
||||||
capsule rec_capsule(unique_rec.release(), [](void *ptr) {
|
capsule rec_capsule(unique_rec.release(), [](void *ptr) {
|
||||||
@ -898,20 +898,20 @@ protected:
|
|||||||
append_note_if_missing_header_is_suspected(msg);
|
append_note_if_missing_header_is_suspected(msg);
|
||||||
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else if (!result) {
|
}
|
||||||
|
if (!result) {
|
||||||
std::string msg = "Unable to convert function return value to a "
|
std::string msg = "Unable to convert function return value to a "
|
||||||
"Python type! The signature was\n\t";
|
"Python type! The signature was\n\t";
|
||||||
msg += it->signature;
|
msg += it->signature;
|
||||||
append_note_if_missing_header_is_suspected(msg);
|
append_note_if_missing_header_is_suspected(msg);
|
||||||
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
PyErr_SetString(PyExc_TypeError, msg.c_str());
|
||||||
return nullptr;
|
return nullptr;
|
||||||
} else {
|
|
||||||
if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) {
|
|
||||||
auto *pi = reinterpret_cast<instance *>(parent.ptr());
|
|
||||||
self_value_and_holder.type->init_instance(pi, nullptr);
|
|
||||||
}
|
|
||||||
return result.ptr();
|
|
||||||
}
|
}
|
||||||
|
if (overloads->is_constructor && !self_value_and_holder.holder_constructed()) {
|
||||||
|
auto *pi = reinterpret_cast<instance *>(parent.ptr());
|
||||||
|
self_value_and_holder.type->init_instance(pi, nullptr);
|
||||||
|
}
|
||||||
|
return result.ptr();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1946,9 +1946,9 @@ PYBIND11_NOINLINE inline void keep_alive_impl(size_t Nurse, size_t Patient, func
|
|||||||
auto get_arg = [&](size_t n) {
|
auto get_arg = [&](size_t n) {
|
||||||
if (n == 0)
|
if (n == 0)
|
||||||
return ret;
|
return ret;
|
||||||
else if (n == 1 && call.init_self)
|
if (n == 1 && call.init_self)
|
||||||
return call.init_self;
|
return call.init_self;
|
||||||
else if (n <= call.args.size())
|
if (n <= call.args.size())
|
||||||
return call.args[n - 1];
|
return call.args[n - 1];
|
||||||
return handle();
|
return handle();
|
||||||
};
|
};
|
||||||
@ -2272,18 +2272,19 @@ template <class T> function get_override(const T *this_ptr, const char *name) {
|
|||||||
return tinfo ? detail::get_type_override(this_ptr, tinfo, name) : function();
|
return tinfo ? detail::get_type_override(this_ptr, tinfo, name) : function();
|
||||||
}
|
}
|
||||||
|
|
||||||
#define PYBIND11_OVERRIDE_IMPL(ret_type, cname, name, ...) \
|
#define PYBIND11_OVERRIDE_IMPL(ret_type, cname, name, ...) \
|
||||||
do { \
|
do { \
|
||||||
pybind11::gil_scoped_acquire gil; \
|
pybind11::gil_scoped_acquire gil; \
|
||||||
pybind11::function override = pybind11::get_override(static_cast<const cname *>(this), name); \
|
pybind11::function override \
|
||||||
if (override) { \
|
= pybind11::get_override(static_cast<const cname *>(this), name); \
|
||||||
auto o = override(__VA_ARGS__); \
|
if (override) { \
|
||||||
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) { \
|
auto o = override(__VA_ARGS__); \
|
||||||
static pybind11::detail::override_caster_t<ret_type> caster; \
|
if (pybind11::detail::cast_is_temporary_value_reference<ret_type>::value) { \
|
||||||
return pybind11::detail::cast_ref<ret_type>(std::move(o), caster); \
|
static pybind11::detail::override_caster_t<ret_type> caster; \
|
||||||
} \
|
return pybind11::detail::cast_ref<ret_type>(std::move(o), caster); \
|
||||||
else return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
|
} \
|
||||||
} \
|
return pybind11::detail::cast_safe<ret_type>(std::move(o)); \
|
||||||
|
} \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
/** \rst
|
/** \rst
|
||||||
|
@ -440,19 +440,17 @@ inline object getattr(handle obj, const char *name) {
|
|||||||
inline object getattr(handle obj, handle name, handle default_) {
|
inline object getattr(handle obj, handle name, handle default_) {
|
||||||
if (PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr())) {
|
if (PyObject *result = PyObject_GetAttr(obj.ptr(), name.ptr())) {
|
||||||
return reinterpret_steal<object>(result);
|
return reinterpret_steal<object>(result);
|
||||||
} else {
|
|
||||||
PyErr_Clear();
|
|
||||||
return reinterpret_borrow<object>(default_);
|
|
||||||
}
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
return reinterpret_borrow<object>(default_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline object getattr(handle obj, const char *name, handle default_) {
|
inline object getattr(handle obj, const char *name, handle default_) {
|
||||||
if (PyObject *result = PyObject_GetAttrString(obj.ptr(), name)) {
|
if (PyObject *result = PyObject_GetAttrString(obj.ptr(), name)) {
|
||||||
return reinterpret_steal<object>(result);
|
return reinterpret_steal<object>(result);
|
||||||
} else {
|
|
||||||
PyErr_Clear();
|
|
||||||
return reinterpret_borrow<object>(default_);
|
|
||||||
}
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
return reinterpret_borrow<object>(default_);
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void setattr(handle obj, handle name, handle value) {
|
inline void setattr(handle obj, handle name, handle value) {
|
||||||
@ -791,10 +789,9 @@ inline bool PyIterable_Check(PyObject *obj) {
|
|||||||
if (iter) {
|
if (iter) {
|
||||||
Py_DECREF(iter);
|
Py_DECREF(iter);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
|
||||||
PyErr_Clear();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
PyErr_Clear();
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline bool PyNone_Check(PyObject *o) { return o == Py_None; }
|
inline bool PyNone_Check(PyObject *o) { return o == Py_None; }
|
||||||
@ -1188,10 +1185,8 @@ Unsigned as_unsigned(PyObject *o) {
|
|||||||
unsigned long v = PyLong_AsUnsignedLong(o);
|
unsigned long v = PyLong_AsUnsignedLong(o);
|
||||||
return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;
|
return v == (unsigned long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;
|
||||||
}
|
}
|
||||||
else {
|
unsigned long long v = PyLong_AsUnsignedLongLong(o);
|
||||||
unsigned long long v = PyLong_AsUnsignedLongLong(o);
|
return v == (unsigned long long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;
|
||||||
return v == (unsigned long long) -1 && PyErr_Occurred() ? (Unsigned) -1 : (Unsigned) v;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
PYBIND11_NAMESPACE_END(detail)
|
PYBIND11_NAMESPACE_END(detail)
|
||||||
|
|
||||||
|
@ -278,7 +278,8 @@ template<typename T> struct optional_caster {
|
|||||||
bool load(handle src, bool convert) {
|
bool load(handle src, bool convert) {
|
||||||
if (!src) {
|
if (!src) {
|
||||||
return false;
|
return false;
|
||||||
} else if (src.is_none()) {
|
}
|
||||||
|
if (src.is_none()) {
|
||||||
return true; // default-constructed value is already empty
|
return true; // default-constructed value is already empty
|
||||||
}
|
}
|
||||||
value_conv inner_caster;
|
value_conv inner_caster;
|
||||||
|
@ -414,13 +414,12 @@ void vector_buffer_impl(Class_& cl, std::true_type) {
|
|||||||
if (step == 1) {
|
if (step == 1) {
|
||||||
return Vector(p, end);
|
return Vector(p, end);
|
||||||
}
|
}
|
||||||
else {
|
Vector vec;
|
||||||
Vector vec;
|
vec.reserve((size_t) info.shape[0]);
|
||||||
vec.reserve((size_t) info.shape[0]);
|
for (; p != end; p += step)
|
||||||
for (; p != end; p += step)
|
vec.push_back(*p);
|
||||||
vec.push_back(*p);
|
return vec;
|
||||||
return vec;
|
|
||||||
}
|
|
||||||
}));
|
}));
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
@ -82,7 +82,7 @@ TEST_SUBMODULE(callbacks, m) {
|
|||||||
// Export the payload constructor statistics for testing purposes:
|
// Export the payload constructor statistics for testing purposes:
|
||||||
m.def("payload_cstats", &ConstructorStats::get<Payload>);
|
m.def("payload_cstats", &ConstructorStats::get<Payload>);
|
||||||
/* Test cleanup of lambda closure */
|
/* Test cleanup of lambda closure */
|
||||||
m.def("test_cleanup", []() -> std::function<void(void)> {
|
m.def("test_cleanup", []() -> std::function<void()> {
|
||||||
Payload p;
|
Payload p;
|
||||||
|
|
||||||
return [p]() {
|
return [p]() {
|
||||||
@ -108,12 +108,13 @@ TEST_SUBMODULE(callbacks, m) {
|
|||||||
if (!result) {
|
if (!result) {
|
||||||
auto r = f(1);
|
auto r = f(1);
|
||||||
return "can't convert to function pointer: eval(1) = " + std::to_string(r);
|
return "can't convert to function pointer: eval(1) = " + std::to_string(r);
|
||||||
} else if (*result == dummy_function) {
|
}
|
||||||
|
if (*result == dummy_function) {
|
||||||
auto r = (*result)(1);
|
auto r = (*result)(1);
|
||||||
return "matches dummy_function: eval(1) = " + std::to_string(r);
|
return "matches dummy_function: eval(1) = " + std::to_string(r);
|
||||||
} else {
|
|
||||||
return "argument does NOT match dummy_function. This should never happen!";
|
|
||||||
}
|
}
|
||||||
|
return "argument does NOT match dummy_function. This should never happen!";
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
class AbstractBase {
|
class AbstractBase {
|
||||||
|
@ -173,8 +173,7 @@ TEST_SUBMODULE(class_, m) {
|
|||||||
// return py::type::of<int>();
|
// return py::type::of<int>();
|
||||||
if (category == 1)
|
if (category == 1)
|
||||||
return py::type::of<DerivedClass1>();
|
return py::type::of<DerivedClass1>();
|
||||||
else
|
return py::type::of<Invalid>();
|
||||||
return py::type::of<Invalid>();
|
|
||||||
});
|
});
|
||||||
|
|
||||||
m.def("get_type_of", [](py::object ob) { return py::type::of(std::move(ob)); });
|
m.def("get_type_of", [](py::object ob) { return py::type::of(std::move(ob)); });
|
||||||
|
@ -203,8 +203,7 @@ TEST_SUBMODULE(copy_move_policies, m) {
|
|||||||
void *ptr = std::malloc(bytes);
|
void *ptr = std::malloc(bytes);
|
||||||
if (ptr)
|
if (ptr)
|
||||||
return ptr;
|
return ptr;
|
||||||
else
|
throw std::bad_alloc{};
|
||||||
throw std::bad_alloc{};
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
py::class_<PrivateOpNew>(m, "PrivateOpNew").def_readonly("value", &PrivateOpNew::value);
|
py::class_<PrivateOpNew>(m, "PrivateOpNew").def_readonly("value", &PrivateOpNew::value);
|
||||||
|
@ -263,13 +263,13 @@ TEST_SUBMODULE(pytypes, m) {
|
|||||||
if (type == "bytes") {
|
if (type == "bytes") {
|
||||||
return move ? py::bytes(std::move(value)) : py::bytes(value);
|
return move ? py::bytes(std::move(value)) : py::bytes(value);
|
||||||
}
|
}
|
||||||
else if (type == "none") {
|
if (type == "none") {
|
||||||
return move ? py::none(std::move(value)) : py::none(value);
|
return move ? py::none(std::move(value)) : py::none(value);
|
||||||
}
|
}
|
||||||
else if (type == "ellipsis") {
|
if (type == "ellipsis") {
|
||||||
return move ? py::ellipsis(std::move(value)) : py::ellipsis(value);
|
return move ? py::ellipsis(std::move(value)) : py::ellipsis(value);
|
||||||
}
|
}
|
||||||
else if (type == "type") {
|
if (type == "type") {
|
||||||
return move ? py::type(std::move(value)) : py::type(value);
|
return move ? py::type(std::move(value)) : py::type(value);
|
||||||
}
|
}
|
||||||
throw std::runtime_error("Invalid type");
|
throw std::runtime_error("Invalid type");
|
||||||
@ -385,9 +385,7 @@ TEST_SUBMODULE(pytypes, m) {
|
|||||||
if (is_unsigned)
|
if (is_unsigned)
|
||||||
return py::memoryview::from_buffer(
|
return py::memoryview::from_buffer(
|
||||||
ui16, { 4 }, { sizeof(uint16_t) });
|
ui16, { 4 }, { sizeof(uint16_t) });
|
||||||
else
|
return py::memoryview::from_buffer(si16, {5}, {sizeof(int16_t)});
|
||||||
return py::memoryview::from_buffer(
|
|
||||||
si16, { 5 }, { sizeof(int16_t) });
|
|
||||||
});
|
});
|
||||||
|
|
||||||
m.def("test_memoryview_from_buffer_nativeformat", []() {
|
m.def("test_memoryview_from_buffer_nativeformat", []() {
|
||||||
|
@ -112,7 +112,9 @@ public:
|
|||||||
void operator=(const NonCopyable &) = delete;
|
void operator=(const NonCopyable &) = delete;
|
||||||
void operator=(NonCopyable &&) = delete;
|
void operator=(NonCopyable &&) = delete;
|
||||||
std::string get_value() const {
|
std::string get_value() const {
|
||||||
if (value) return std::to_string(*value); else return "(null)";
|
if (value)
|
||||||
|
return std::to_string(*value);
|
||||||
|
return "(null)";
|
||||||
}
|
}
|
||||||
~NonCopyable() { print_destroyed(this); }
|
~NonCopyable() { print_destroyed(this); }
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user