mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-11 08:03:55 +00:00
Replace error printing code gated by NDEBUG with a new flag: PYBIND11_DETAILED_ERROR_MESSAGES (#3913)
* Update cast.h * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Move definition to detail/common, change name, apply everywhere * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Rename debug_enabled in tests to detailed_error_messages_enabled
This commit is contained in:
parent
75007dda72
commit
f0b9f755e4
@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "detail/common.h"
|
||||||
#include "cast.h"
|
#include "cast.h"
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
@ -477,7 +478,7 @@ struct process_attribute<arg_v> : process_attribute_default<arg_v> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!a.value) {
|
if (!a.value) {
|
||||||
#if !defined(NDEBUG)
|
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
std::string descr("'");
|
std::string descr("'");
|
||||||
if (a.name) {
|
if (a.name) {
|
||||||
descr += std::string(a.name) + ": ";
|
descr += std::string(a.name) + ": ";
|
||||||
@ -498,7 +499,8 @@ struct process_attribute<arg_v> : process_attribute_default<arg_v> {
|
|||||||
#else
|
#else
|
||||||
pybind11_fail("arg(): could not convert default argument "
|
pybind11_fail("arg(): could not convert default argument "
|
||||||
"into a Python object (type not registered yet?). "
|
"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
|
#endif
|
||||||
}
|
}
|
||||||
r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);
|
r->args.emplace_back(a.name, a.descr, a.value.inc_ref(), !a.flag_noconvert, a.flag_none);
|
||||||
|
@ -777,8 +777,9 @@ protected:
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
|
throw cast_error("Unable to cast from non-held to held instance (T& to Holder<T>) "
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
"(compile in debug mode for type information)");
|
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for "
|
||||||
|
"type information)");
|
||||||
#else
|
#else
|
||||||
"of type '"
|
"of type '"
|
||||||
+ type_id<holder_type>() + "''");
|
+ type_id<holder_type>() + "''");
|
||||||
@ -1001,9 +1002,9 @@ struct return_value_policy_override<
|
|||||||
template <typename T, typename SFINAE>
|
template <typename T, typename SFINAE>
|
||||||
type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) {
|
type_caster<T, SFINAE> &load_type(type_caster<T, SFINAE> &conv, const handle &handle) {
|
||||||
if (!conv.load(handle, true)) {
|
if (!conv.load(handle, true)) {
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
throw cast_error(
|
throw cast_error("Unable to cast Python instance to C++ type (#define "
|
||||||
"Unable to cast Python instance to C++ type (compile in debug mode for details)");
|
"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
|
||||||
#else
|
#else
|
||||||
throw cast_error("Unable to cast Python instance of type "
|
throw cast_error("Unable to cast Python instance of type "
|
||||||
+ (std::string) str(type::handle_of(handle)) + " to C++ type '"
|
+ (std::string) str(type::handle_of(handle)) + " to C++ type '"
|
||||||
@ -1068,10 +1069,10 @@ inline void handle::cast() const {
|
|||||||
template <typename T>
|
template <typename T>
|
||||||
detail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {
|
detail::enable_if_t<!detail::move_never<T>::value, T> move(object &&obj) {
|
||||||
if (obj.ref_count() > 1) {
|
if (obj.ref_count() > 1) {
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
throw cast_error(
|
throw cast_error(
|
||||||
"Unable to cast Python instance to C++ rvalue: instance has multiple references"
|
"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
|
#else
|
||||||
throw cast_error("Unable to move from Python " + (std::string) str(type::handle_of(obj))
|
throw cast_error("Unable to move from Python " + (std::string) str(type::handle_of(obj))
|
||||||
+ " instance to C++ " + type_id<T>()
|
+ " instance to C++ " + type_id<T>()
|
||||||
@ -1172,10 +1173,10 @@ PYBIND11_NAMESPACE_END(detail)
|
|||||||
|
|
||||||
// The overloads could coexist, i.e. the #if is not strictly speaking needed,
|
// The overloads could coexist, i.e. the #if is not strictly speaking needed,
|
||||||
// but it is an easy minor optimization.
|
// 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() {
|
inline cast_error cast_error_unable_to_convert_call_arg() {
|
||||||
return cast_error(
|
return cast_error("Unable to convert call argument to Python object (#define "
|
||||||
"Unable to convert call argument to Python object (compile in debug mode for details)");
|
"PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name,
|
inline cast_error cast_error_unable_to_convert_call_arg(const std::string &name,
|
||||||
@ -1197,7 +1198,7 @@ tuple make_tuple(Args &&...args_) {
|
|||||||
detail::make_caster<Args>::cast(std::forward<Args>(args_), policy, nullptr))...}};
|
detail::make_caster<Args>::cast(std::forward<Args>(args_), policy, nullptr))...}};
|
||||||
for (size_t i = 0; i < args.size(); i++) {
|
for (size_t i = 0; i < args.size(); i++) {
|
||||||
if (!args[i]) {
|
if (!args[i]) {
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
throw cast_error_unable_to_convert_call_arg();
|
throw cast_error_unable_to_convert_call_arg();
|
||||||
#else
|
#else
|
||||||
std::array<std::string, size> argtypes{{type_id<Args>()...}};
|
std::array<std::string, size> argtypes{{type_id<Args>()...}};
|
||||||
@ -1249,7 +1250,7 @@ private:
|
|||||||
: arg(base), value(reinterpret_steal<object>(detail::make_caster<T>::cast(
|
: arg(base), value(reinterpret_steal<object>(detail::make_caster<T>::cast(
|
||||||
std::forward<T>(x), return_value_policy::automatic, {}))),
|
std::forward<T>(x), return_value_policy::automatic, {}))),
|
||||||
descr(descr)
|
descr(descr)
|
||||||
#if !defined(NDEBUG)
|
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
,
|
,
|
||||||
type(type_id<T>())
|
type(type_id<T>())
|
||||||
#endif
|
#endif
|
||||||
@ -1289,7 +1290,7 @@ public:
|
|||||||
object value;
|
object value;
|
||||||
/// The (optional) description of the default value
|
/// The (optional) description of the default value
|
||||||
const char *descr;
|
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)
|
/// The C++ type name of the default value (only available when compiled in debug mode)
|
||||||
std::string type;
|
std::string type;
|
||||||
#endif
|
#endif
|
||||||
@ -1487,7 +1488,7 @@ private:
|
|||||||
auto o = reinterpret_steal<object>(
|
auto o = reinterpret_steal<object>(
|
||||||
detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
|
detail::make_caster<T>::cast(std::forward<T>(x), policy, {}));
|
||||||
if (!o) {
|
if (!o) {
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
throw cast_error_unable_to_convert_call_arg();
|
throw cast_error_unable_to_convert_call_arg();
|
||||||
#else
|
#else
|
||||||
throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()),
|
throw cast_error_unable_to_convert_call_arg(std::to_string(args_list.size()),
|
||||||
@ -1505,21 +1506,21 @@ private:
|
|||||||
|
|
||||||
void process(list & /*args_list*/, arg_v a) {
|
void process(list & /*args_list*/, arg_v a) {
|
||||||
if (!a.name) {
|
if (!a.name) {
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
nameless_argument_error();
|
nameless_argument_error();
|
||||||
#else
|
#else
|
||||||
nameless_argument_error(a.type);
|
nameless_argument_error(a.type);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (m_kwargs.contains(a.name)) {
|
if (m_kwargs.contains(a.name)) {
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
multiple_values_error();
|
multiple_values_error();
|
||||||
#else
|
#else
|
||||||
multiple_values_error(a.name);
|
multiple_values_error(a.name);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
if (!a.value) {
|
if (!a.value) {
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
throw cast_error_unable_to_convert_call_arg();
|
throw cast_error_unable_to_convert_call_arg();
|
||||||
#else
|
#else
|
||||||
throw cast_error_unable_to_convert_call_arg(a.name, a.type);
|
throw cast_error_unable_to_convert_call_arg(a.name, a.type);
|
||||||
@ -1534,7 +1535,7 @@ private:
|
|||||||
}
|
}
|
||||||
for (auto k : reinterpret_borrow<dict>(kp)) {
|
for (auto k : reinterpret_borrow<dict>(kp)) {
|
||||||
if (m_kwargs.contains(k.first)) {
|
if (m_kwargs.contains(k.first)) {
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
multiple_values_error();
|
multiple_values_error();
|
||||||
#else
|
#else
|
||||||
multiple_values_error(str(k.first));
|
multiple_values_error(str(k.first));
|
||||||
@ -1545,9 +1546,10 @@ private:
|
|||||||
}
|
}
|
||||||
|
|
||||||
[[noreturn]] static void nameless_argument_error() {
|
[[noreturn]] static void nameless_argument_error() {
|
||||||
throw type_error("Got kwargs without a name; only named arguments "
|
throw type_error(
|
||||||
|
"Got kwargs without a name; only named arguments "
|
||||||
"may be passed via py::arg() to a python function call. "
|
"may be passed via py::arg() to a python function call. "
|
||||||
"(compile in debug mode for details)");
|
"(#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)");
|
||||||
}
|
}
|
||||||
[[noreturn]] static void nameless_argument_error(const std::string &type) {
|
[[noreturn]] static void nameless_argument_error(const std::string &type) {
|
||||||
throw type_error("Got kwargs without a name of type '" + type
|
throw type_error("Got kwargs without a name of type '" + type
|
||||||
@ -1555,8 +1557,9 @@ private:
|
|||||||
"arguments may be passed via py::arg() to a python function call. ");
|
"arguments may be passed via py::arg() to a python function call. ");
|
||||||
}
|
}
|
||||||
[[noreturn]] static void multiple_values_error() {
|
[[noreturn]] static void multiple_values_error() {
|
||||||
throw type_error("Got multiple values for keyword argument "
|
throw type_error(
|
||||||
"(compile in debug mode for details)");
|
"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) {
|
[[noreturn]] static void multiple_values_error(const std::string &name) {
|
||||||
@ -1603,7 +1606,7 @@ unpacking_collector<policy> collect_arguments(Args &&...args) {
|
|||||||
template <typename Derived>
|
template <typename Derived>
|
||||||
template <return_value_policy policy, typename... Args>
|
template <return_value_policy policy, typename... Args>
|
||||||
object object_api<Derived>::operator()(Args &&...args) const {
|
object object_api<Derived>::operator()(Args &&...args) const {
|
||||||
#ifndef NDEBUG
|
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
if (!PyGILState_Check()) {
|
if (!PyGILState_Check()) {
|
||||||
pybind11_fail("pybind11::object_api<>::operator() PyGILState_Check() failure.");
|
pybind11_fail("pybind11::object_api<>::operator() PyGILState_Check() failure.");
|
||||||
}
|
}
|
||||||
|
@ -1157,5 +1157,12 @@ constexpr inline bool silence_msvc_c4127(bool cond) { return cond; }
|
|||||||
# define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__
|
# define PYBIND11_SILENCE_MSVC_C4127(...) __VA_ARGS__
|
||||||
#endif
|
#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(detail)
|
||||||
PYBIND11_NAMESPACE_END(PYBIND11_NAMESPACE)
|
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();
|
return value_and_holder();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(NDEBUG)
|
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
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
|
|
||||||
pybind11_fail("pybind11::detail::instance::get_value_and_holder: `"
|
pybind11_fail("pybind11::detail::instance::get_value_and_holder: `"
|
||||||
+ get_fully_qualified_tp_name(find_type->type)
|
+ get_fully_qualified_tp_name(find_type->type)
|
||||||
+ "' is not a pybind11 base of the given `"
|
+ "' is not a pybind11 base of the given `"
|
||||||
+ get_fully_qualified_tp_name(Py_TYPE(this)) + "' instance");
|
+ 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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -612,14 +613,15 @@ public:
|
|||||||
if (copy_constructor) {
|
if (copy_constructor) {
|
||||||
valueptr = copy_constructor(src);
|
valueptr = copy_constructor(src);
|
||||||
} else {
|
} else {
|
||||||
#if defined(NDEBUG)
|
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
throw cast_error("return_value_policy = copy, but type is "
|
|
||||||
"non-copyable! (compile in debug mode for details)");
|
|
||||||
#else
|
|
||||||
std::string type_name(tinfo->cpptype->name());
|
std::string type_name(tinfo->cpptype->name());
|
||||||
detail::clean_type_id(type_name);
|
detail::clean_type_id(type_name);
|
||||||
throw cast_error("return_value_policy = copy, but type " + type_name
|
throw cast_error("return_value_policy = copy, but type " + type_name
|
||||||
+ " is non-copyable!");
|
+ " 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
|
#endif
|
||||||
}
|
}
|
||||||
wrapper->owned = true;
|
wrapper->owned = true;
|
||||||
@ -631,15 +633,16 @@ public:
|
|||||||
} else if (copy_constructor) {
|
} else if (copy_constructor) {
|
||||||
valueptr = copy_constructor(src);
|
valueptr = copy_constructor(src);
|
||||||
} else {
|
} else {
|
||||||
#if defined(NDEBUG)
|
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
throw cast_error("return_value_policy = move, but type is neither "
|
|
||||||
"movable nor copyable! "
|
|
||||||
"(compile in debug mode for details)");
|
|
||||||
#else
|
|
||||||
std::string type_name(tinfo->cpptype->name());
|
std::string type_name(tinfo->cpptype->name());
|
||||||
detail::clean_type_id(type_name);
|
detail::clean_type_id(type_name);
|
||||||
throw cast_error("return_value_policy = move, but type " + type_name
|
throw cast_error("return_value_policy = move, but type " + type_name
|
||||||
+ " is neither movable nor copyable!");
|
+ " 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
|
#endif
|
||||||
}
|
}
|
||||||
wrapper->owned = true;
|
wrapper->owned = true;
|
||||||
|
@ -62,7 +62,7 @@ public:
|
|||||||
|
|
||||||
if (!tstate) {
|
if (!tstate) {
|
||||||
tstate = PyThreadState_New(internals.istate);
|
tstate = PyThreadState_New(internals.istate);
|
||||||
# if !defined(NDEBUG)
|
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
if (!tstate) {
|
if (!tstate) {
|
||||||
pybind11_fail("scoped_acquire: could not create thread state!");
|
pybind11_fail("scoped_acquire: could not create thread state!");
|
||||||
}
|
}
|
||||||
@ -84,7 +84,7 @@ public:
|
|||||||
|
|
||||||
PYBIND11_NOINLINE void dec_ref() {
|
PYBIND11_NOINLINE void dec_ref() {
|
||||||
--tstate->gilstate_counter;
|
--tstate->gilstate_counter;
|
||||||
# if !defined(NDEBUG)
|
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
if (detail::get_thread_state_unchecked() != tstate) {
|
if (detail::get_thread_state_unchecked() != tstate) {
|
||||||
pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!");
|
pybind11_fail("scoped_acquire::dec_ref(): thread state must be current!");
|
||||||
}
|
}
|
||||||
@ -93,7 +93,7 @@ public:
|
|||||||
}
|
}
|
||||||
# endif
|
# endif
|
||||||
if (tstate->gilstate_counter == 0) {
|
if (tstate->gilstate_counter == 0) {
|
||||||
# if !defined(NDEBUG)
|
# if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
if (!release) {
|
if (!release) {
|
||||||
pybind11_fail("scoped_acquire::dec_ref(): internal error!");
|
pybind11_fail("scoped_acquire::dec_ref(): internal error!");
|
||||||
}
|
}
|
||||||
|
@ -370,7 +370,7 @@ protected:
|
|||||||
rec->is_constructor = (std::strcmp(rec->name, "__init__") == 0)
|
rec->is_constructor = (std::strcmp(rec->name, "__init__") == 0)
|
||||||
|| (std::strcmp(rec->name, "__setstate__") == 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) {
|
if (rec->is_constructor && !rec->is_new_style_constructor) {
|
||||||
const auto class_name
|
const auto class_name
|
||||||
= detail::get_fully_qualified_tp_name((PyTypeObject *) rec->scope.ptr());
|
= detail::get_fully_qualified_tp_name((PyTypeObject *) rec->scope.ptr());
|
||||||
@ -518,8 +518,9 @@ protected:
|
|||||||
if (chain->is_method != rec->is_method) {
|
if (chain->is_method != rec->is_method) {
|
||||||
pybind11_fail(
|
pybind11_fail(
|
||||||
"overloading a method with both static and instance methods is not supported; "
|
"overloading a method with both static and instance methods is not supported; "
|
||||||
#if defined(NDEBUG)
|
#if !defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
"compile in debug mode for more details"
|
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more "
|
||||||
|
"details"
|
||||||
#else
|
#else
|
||||||
"error while attempting to bind "
|
"error while attempting to bind "
|
||||||
+ std::string(rec->is_method ? "instance" : "static") + " method "
|
+ std::string(rec->is_method ? "instance" : "static") + " method "
|
||||||
@ -906,7 +907,7 @@ protected:
|
|||||||
|
|
||||||
// 5. Put everything in a vector. Not technically step 5, we've been building it
|
// 5. Put everything in a vector. Not technically step 5, we've been building it
|
||||||
// in `call.args` all along.
|
// 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) {
|
if (call.args.size() != func.nargs || call.args_convert.size() != func.nargs) {
|
||||||
pybind11_fail("Internal error: function call dispatcher inserted wrong number "
|
pybind11_fail("Internal error: function call dispatcher inserted wrong number "
|
||||||
"of arguments!");
|
"of arguments!");
|
||||||
|
@ -67,10 +67,10 @@ PYBIND11_MODULE(pybind11_tests, m) {
|
|||||||
|
|
||||||
bind_ConstructorStats(m);
|
bind_ConstructorStats(m);
|
||||||
|
|
||||||
#if !defined(NDEBUG)
|
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
m.attr("debug_enabled") = true;
|
m.attr("detailed_error_messages_enabled") = true;
|
||||||
#else
|
#else
|
||||||
m.attr("debug_enabled") = false;
|
m.attr("detailed_error_messages_enabled") = false;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
py::class_<UserType>(m, "UserType", "A `py::class_` type for testing")
|
py::class_<UserType>(m, "UserType", "A `py::class_` type for testing")
|
||||||
|
@ -361,10 +361,10 @@ TEST_SUBMODULE(methods_and_attributes, m) {
|
|||||||
|
|
||||||
// test_bad_arg_default
|
// test_bad_arg_default
|
||||||
// Issue/PR #648: bad arg default debugging output
|
// Issue/PR #648: bad arg default debugging output
|
||||||
#if !defined(NDEBUG)
|
#if defined(PYBIND11_DETAILED_ERROR_MESSAGES)
|
||||||
m.attr("debug_enabled") = true;
|
m.attr("detailed_error_messages_enabled") = true;
|
||||||
#else
|
#else
|
||||||
m.attr("debug_enabled") = false;
|
m.attr("detailed_error_messages_enabled") = false;
|
||||||
#endif
|
#endif
|
||||||
m.def("bad_arg_def_named", [] {
|
m.def("bad_arg_def_named", [] {
|
||||||
auto m = py::module_::import("pybind11_tests");
|
auto m = py::module_::import("pybind11_tests");
|
||||||
|
@ -216,15 +216,15 @@ def test_metaclass_override():
|
|||||||
|
|
||||||
|
|
||||||
def test_no_mixed_overloads():
|
def test_no_mixed_overloads():
|
||||||
from pybind11_tests import debug_enabled
|
from pybind11_tests import detailed_error_messages_enabled
|
||||||
|
|
||||||
with pytest.raises(RuntimeError) as excinfo:
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
m.ExampleMandA.add_mixed_overloads1()
|
m.ExampleMandA.add_mixed_overloads1()
|
||||||
assert str(
|
assert str(
|
||||||
excinfo.value
|
excinfo.value
|
||||||
) == "overloading a method with both static and instance methods is not supported; " + (
|
) == "overloading a method with both static and instance methods is not supported; " + (
|
||||||
"compile in debug mode for more details"
|
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more details"
|
||||||
if not debug_enabled
|
if not detailed_error_messages_enabled
|
||||||
else "error while attempting to bind static method ExampleMandA.overload_mixed1"
|
else "error while attempting to bind static method ExampleMandA.overload_mixed1"
|
||||||
"(arg0: float) -> str"
|
"(arg0: float) -> str"
|
||||||
)
|
)
|
||||||
@ -234,8 +234,8 @@ def test_no_mixed_overloads():
|
|||||||
assert str(
|
assert str(
|
||||||
excinfo.value
|
excinfo.value
|
||||||
) == "overloading a method with both static and instance methods is not supported; " + (
|
) == "overloading a method with both static and instance methods is not supported; " + (
|
||||||
"compile in debug mode for more details"
|
"#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more details"
|
||||||
if not debug_enabled
|
if not detailed_error_messages_enabled
|
||||||
else "error while attempting to bind instance method ExampleMandA.overload_mixed2"
|
else "error while attempting to bind instance method ExampleMandA.overload_mixed2"
|
||||||
"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)"
|
"(self: pybind11_tests.methods_and_attributes.ExampleMandA, arg0: int, arg1: int)"
|
||||||
" -> str"
|
" -> str"
|
||||||
@ -344,16 +344,16 @@ def test_cyclic_gc():
|
|||||||
|
|
||||||
|
|
||||||
def test_bad_arg_default(msg):
|
def test_bad_arg_default(msg):
|
||||||
from pybind11_tests import debug_enabled
|
from pybind11_tests import detailed_error_messages_enabled
|
||||||
|
|
||||||
with pytest.raises(RuntimeError) as excinfo:
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
m.bad_arg_def_named()
|
m.bad_arg_def_named()
|
||||||
assert msg(excinfo.value) == (
|
assert msg(excinfo.value) == (
|
||||||
"arg(): could not convert default argument 'a: UnregisteredType' in function "
|
"arg(): could not convert default argument 'a: UnregisteredType' in function "
|
||||||
"'should_fail' into a Python object (type not registered yet?)"
|
"'should_fail' into a Python object (type not registered yet?)"
|
||||||
if debug_enabled
|
if detailed_error_messages_enabled
|
||||||
else "arg(): could not convert default argument into a Python object (type not registered "
|
else "arg(): could not convert default argument into a Python object (type not registered "
|
||||||
"yet?). Compile in debug mode for more information."
|
"yet?). #define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more information."
|
||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(RuntimeError) as excinfo:
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
@ -361,9 +361,9 @@ def test_bad_arg_default(msg):
|
|||||||
assert msg(excinfo.value) == (
|
assert msg(excinfo.value) == (
|
||||||
"arg(): could not convert default argument 'UnregisteredType' in function "
|
"arg(): could not convert default argument 'UnregisteredType' in function "
|
||||||
"'should_fail' into a Python object (type not registered yet?)"
|
"'should_fail' into a Python object (type not registered yet?)"
|
||||||
if debug_enabled
|
if detailed_error_messages_enabled
|
||||||
else "arg(): could not convert default argument into a Python object (type not registered "
|
else "arg(): could not convert default argument into a Python object (type not registered "
|
||||||
"yet?). Compile in debug mode for more information."
|
"yet?). #define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for more information."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@ import sys
|
|||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
import env
|
import env
|
||||||
from pybind11_tests import debug_enabled
|
from pybind11_tests import detailed_error_messages_enabled
|
||||||
from pybind11_tests import pytypes as m
|
from pybind11_tests import pytypes as m
|
||||||
|
|
||||||
|
|
||||||
@ -416,8 +416,8 @@ def test_print(capture):
|
|||||||
m.print_failure()
|
m.print_failure()
|
||||||
assert str(excinfo.value) == "Unable to convert call argument " + (
|
assert str(excinfo.value) == "Unable to convert call argument " + (
|
||||||
"'1' of type 'UnregisteredType' to Python object"
|
"'1' of type 'UnregisteredType' to Python object"
|
||||||
if debug_enabled
|
if detailed_error_messages_enabled
|
||||||
else "to Python object (compile in debug mode for details)"
|
else "to Python object (#define PYBIND11_DETAILED_ERROR_MESSAGES or compile in debug mode for details)"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user