Report type names in return value policy-related cast exceptions (#1965)
diff --git a/include/pybind11/cast.h b/include/pybind11/cast.h
index efc10d6..e1bbf03 100644
--- a/include/pybind11/cast.h
+++ b/include/pybind11/cast.h
@@ -533,9 +533,17 @@
case return_value_policy::copy:
if (copy_constructor)
valueptr = copy_constructor(src);
- else
- throw cast_error("return_value_policy = copy, but the "
- "object is non-copyable!");
+ else {
+#if defined(NDEBUG)
+ 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());
+ detail::clean_type_id(type_name);
+ throw cast_error("return_value_policy = copy, but type " +
+ type_name + " is non-copyable!");
+#endif
+ }
wrapper->owned = true;
break;
@@ -544,9 +552,18 @@
valueptr = move_constructor(src);
else if (copy_constructor)
valueptr = copy_constructor(src);
- else
- throw cast_error("return_value_policy = move, but the "
- "object is neither movable nor copyable!");
+ 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
+ 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!");
+#endif
+ }
wrapper->owned = true;
break;
diff --git a/tests/test_copy_move.py b/tests/test_copy_move.py
index aff2d99..0e671d9 100644
--- a/tests/test_copy_move.py
+++ b/tests/test_copy_move.py
@@ -5,13 +5,13 @@
def test_lacking_copy_ctor():
with pytest.raises(RuntimeError) as excinfo:
m.lacking_copy_ctor.get_one()
- assert "the object is non-copyable!" in str(excinfo.value)
+ assert "is non-copyable!" in str(excinfo.value)
def test_lacking_move_ctor():
with pytest.raises(RuntimeError) as excinfo:
m.lacking_move_ctor.get_one()
- assert "the object is neither movable nor copyable!" in str(excinfo.value)
+ assert "is neither movable nor copyable!" in str(excinfo.value)
def test_move_and_copy_casts():
@@ -98,7 +98,7 @@
with pytest.raises(RuntimeError) as excinfo:
m.private_op_new_value()
- assert "the object is neither movable nor copyable" in str(excinfo.value)
+ assert "is neither movable nor copyable" in str(excinfo.value)
assert m.private_op_new_reference().value == 1