mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
Fix debugging output for nameless py::arg_v annotations (#648)
* Fix debugging output for nameless py::arg annotations This fixes a couple bugs with nameless py::arg() (introduced in #634) annotations: - the argument name was being used in debug mode without checking that it exists (which would result in the std::string construction throwing an exception for being invoked with a nullptr) - the error output says "keyword arguments", but py::arg_v() can now also be used for positional argument defaults. - the debugging output "in function named 'blah'" was overly verbose: changed it to just "in function 'blah'". * Fix missing space in debug test string * Moved tests from issues to methods_and_attributes
This commit is contained in:
parent
93cc4bd6d7
commit
1eaacd19f6
@ -303,19 +303,21 @@ template <> struct process_attribute<arg_v> : process_attribute_default<arg_v> {
|
|||||||
|
|
||||||
if (!a.value) {
|
if (!a.value) {
|
||||||
#if !defined(NDEBUG)
|
#if !defined(NDEBUG)
|
||||||
auto descr = "'" + std::string(a.name) + ": " + a.type + "'";
|
std::string descr("'");
|
||||||
|
if (a.name) descr += std::string(a.name) + ": ";
|
||||||
|
descr += a.type + "'";
|
||||||
if (r->is_method) {
|
if (r->is_method) {
|
||||||
if (r->name)
|
if (r->name)
|
||||||
descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'";
|
descr += " in method '" + (std::string) str(r->scope) + "." + (std::string) r->name + "'";
|
||||||
else
|
else
|
||||||
descr += " in method of '" + (std::string) str(r->scope) + "'";
|
descr += " in method of '" + (std::string) str(r->scope) + "'";
|
||||||
} else if (r->name) {
|
} else if (r->name) {
|
||||||
descr += " in function named '" + (std::string) r->name + "'";
|
descr += " in function '" + (std::string) r->name + "'";
|
||||||
}
|
}
|
||||||
pybind11_fail("arg(): could not convert default keyword argument "
|
pybind11_fail("arg(): could not convert default argument "
|
||||||
+ descr + " into a Python object (type not registered yet?)");
|
+ descr + " into a Python object (type not registered yet?)");
|
||||||
#else
|
#else
|
||||||
pybind11_fail("arg(): could not convert default keyword 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.");
|
"Compile in debug mode for more information.");
|
||||||
#endif
|
#endif
|
||||||
|
@ -74,7 +74,6 @@ namespace std {
|
|||||||
template <> struct hash<TplConstrClass> { size_t operator()(const TplConstrClass &t) const { return std::hash<std::string>()(t.str); } };
|
template <> struct hash<TplConstrClass> { size_t operator()(const TplConstrClass &t) const { return std::hash<std::string>()(t.str); } };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void init_issues(py::module &m) {
|
void init_issues(py::module &m) {
|
||||||
py::module m2 = m.def_submodule("issues");
|
py::module m2 = m.def_submodule("issues");
|
||||||
|
|
||||||
@ -397,5 +396,5 @@ void init_issues(py::module &m) {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
// MSVC workaround: trying to use a lambda here crashes MSCV
|
// MSVC workaround: trying to use a lambda here crashes MSVC
|
||||||
test_initializer issues(&init_issues);
|
test_initializer issues(&init_issues);
|
||||||
|
@ -150,6 +150,9 @@ public:
|
|||||||
};
|
};
|
||||||
}}
|
}}
|
||||||
|
|
||||||
|
/// Issue/PR #648: bad arg default debugging output
|
||||||
|
class NotRegistered {};
|
||||||
|
|
||||||
test_initializer methods_and_attributes([](py::module &m) {
|
test_initializer methods_and_attributes([](py::module &m) {
|
||||||
py::class_<ExampleMandA>(m, "ExampleMandA")
|
py::class_<ExampleMandA>(m, "ExampleMandA")
|
||||||
.def(py::init<>())
|
.def(py::init<>())
|
||||||
@ -270,4 +273,18 @@ test_initializer methods_and_attributes([](py::module &m) {
|
|||||||
m.def("floats_preferred", [](double f) { return 0.5 * f; }, py::arg("f"));
|
m.def("floats_preferred", [](double f) { return 0.5 * f; }, py::arg("f"));
|
||||||
m.def("floats_only", [](double f) { return 0.5 * f; }, py::arg("f").noconvert());
|
m.def("floats_only", [](double f) { return 0.5 * f; }, py::arg("f").noconvert());
|
||||||
|
|
||||||
|
/// Issue/PR #648: bad arg default debugging output
|
||||||
|
#if !defined(NDEBUG)
|
||||||
|
m.attr("debug_enabled") = true;
|
||||||
|
#else
|
||||||
|
m.attr("debug_enabled") = false;
|
||||||
|
#endif
|
||||||
|
m.def("bad_arg_def_named", []{
|
||||||
|
auto m = py::module::import("pybind11_tests.issues");
|
||||||
|
m.def("should_fail", [](int, NotRegistered) {}, py::arg(), py::arg("a") = NotRegistered());
|
||||||
|
});
|
||||||
|
m.def("bad_arg_def_unnamed", []{
|
||||||
|
auto m = py::module::import("pybind11_tests.issues");
|
||||||
|
m.def("should_fail", [](int, NotRegistered) {}, py::arg(), py::arg() = NotRegistered());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
@ -255,3 +255,27 @@ def test_noconvert_args(msg):
|
|||||||
|
|
||||||
Invoked with: 4
|
Invoked with: 4
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
def test_bad_arg_default(msg):
|
||||||
|
from pybind11_tests import debug_enabled, bad_arg_def_named, bad_arg_def_unnamed
|
||||||
|
|
||||||
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
|
bad_arg_def_named()
|
||||||
|
assert msg(excinfo.value) == (
|
||||||
|
"arg(): could not convert default argument 'a: NotRegistered' in function 'should_fail' "
|
||||||
|
"into a Python object (type not registered yet?)"
|
||||||
|
if debug_enabled else
|
||||||
|
"arg(): could not convert default argument into a Python object (type not registered "
|
||||||
|
"yet?). Compile in debug mode for more information."
|
||||||
|
)
|
||||||
|
|
||||||
|
with pytest.raises(RuntimeError) as excinfo:
|
||||||
|
bad_arg_def_unnamed()
|
||||||
|
assert msg(excinfo.value) == (
|
||||||
|
"arg(): could not convert default argument 'NotRegistered' in function 'should_fail' "
|
||||||
|
"into a Python object (type not registered yet?)"
|
||||||
|
if debug_enabled else
|
||||||
|
"arg(): could not convert default argument into a Python object (type not registered "
|
||||||
|
"yet?). Compile in debug mode for more information."
|
||||||
|
)
|
||||||
|
Loading…
Reference in New Issue
Block a user