Skip to content

Commit

Permalink
Adds check if str(handle) correctly converted the object, and throw…
Browse files Browse the repository at this point in the history
… py::error_already_set if not.

Similar to pybind#2392, but does not depend on pybind#2409.

Splitting out this PR from pybind#2409 to make that PR as simple as possible.

Net effects of this PR:
* Adds missing test coverage.
* Changes TypeError to UnicodeDecodeError for Python 2.

This PR has two commits. Please do not squash, to make the behavior change obvious in the commit history.
  • Loading branch information
Ralf W. Grosse-Kunstleve committed Sep 8, 2020
1 parent 44b3941 commit d629d5e
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 3 deletions.
4 changes: 2 additions & 2 deletions include/pybind11/pytypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -920,7 +920,7 @@ class str : public object {
Return a string representation of the object. This is analogous to
the ``str()`` function in Python.
\endrst */
explicit str(handle h) : object(raw_str(h.ptr()), stolen_t{}) { }
explicit str(handle h) : object(raw_str(h.ptr()), stolen_t{}) { if (!m_ptr) throw error_already_set(); }

operator std::string() const {
object temp = *this;
Expand All @@ -945,8 +945,8 @@ class str : public object {
/// Return string representation -- always returns a new reference, even if already a str
static PyObject *raw_str(PyObject *op) {
PyObject *str_value = PyObject_Str(op);
if (!str_value) throw error_already_set();
#if PY_MAJOR_VERSION < 3
if (!str_value) throw error_already_set();
PyObject *unicode = PyUnicode_FromEncodedObject(str_value, "utf-8", nullptr);
Py_XDECREF(str_value); str_value = unicode;
#endif
Expand Down
2 changes: 1 addition & 1 deletion tests/test_pytypes.py
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ def __repr__(self):
malformed_utf8 = b"\x80"
assert m.str_from_object(malformed_utf8) is malformed_utf8 # Probably surprising.
if env.PY2:
with pytest.raises(TypeError):
with pytest.raises(UnicodeDecodeError):
m.str_from_handle(malformed_utf8)
else:
assert m.str_from_handle(malformed_utf8) == "b'\\x80'"
Expand Down

0 comments on commit d629d5e

Please sign in to comment.