Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions include/pybind11/pybind11.h
Original file line number Diff line number Diff line change
Expand Up @@ -776,7 +776,11 @@ class cpp_function : public function {
for (size_t ti = overloads->is_constructor ? 1 : 0; ti < args_.size(); ++ti) {
if (!some_args) some_args = true;
else msg += ", ";
msg += pybind11::repr(args_[ti]);
try {
msg += pybind11::repr(args_[ti]);
} catch (const error_already_set&) {
msg += "<repr raised Error>";
}
}
if (kwargs_in) {
auto kwargs = reinterpret_borrow<dict>(kwargs_in);
Expand All @@ -787,7 +791,12 @@ class cpp_function : public function {
for (auto kwarg : kwargs) {
if (first) first = false;
else msg += ", ";
msg += pybind11::str("{}={!r}").format(kwarg.first, kwarg.second);
msg += pybind11::str("{}=").format(kwarg.first);
try {
msg += pybind11::repr(kwarg.second);
} catch (const error_already_set&) {
msg += "<repr raised Error>";
}
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions tests/test_exceptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,7 @@ TEST_SUBMODULE(exceptions, m) {
}
});

// Test repr that cannot be displayed
m.def("simple_bool_passthrough", [](bool x) {return x;});

}
11 changes: 11 additions & 0 deletions tests/test_exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,3 +149,14 @@ def pycatch(exctype, f, *args):
with pytest.raises(m.MyException5) as excinfo:
m.try_catch(m.MyException, pycatch, m.MyException, m.throws5)
assert str(excinfo.value) == "this is a helper-defined translated exception"


# This can often happen if you wrap a pybind11 class in a Python wrapper
def test_invalid_repr():

class MyRepr(object):
def __repr__(self):
raise AttributeError("Example error")

with pytest.raises(TypeError):
m.simple_bool_passthrough(MyRepr())