@@ -163,7 +163,7 @@ struct list_accessor {
163163 return object (result, true );
164164 }
165165
166- template <typename T> inline T cast () const { return operator object ().cast <T>(); }
166+ template <typename T> T cast () const { return operator object ().cast <T>(); }
167167private:
168168 handle list;
169169 size_t index;
@@ -188,7 +188,7 @@ struct tuple_accessor {
188188 return object (result, true );
189189 }
190190
191- template <typename T> inline T cast () const { return operator object ().cast <T>(); }
191+ template <typename T> T cast () const { return operator object ().cast <T>(); }
192192private:
193193 handle tuple;
194194 size_t index;
@@ -225,6 +225,8 @@ inline bool PyIterable_Check(PyObject *obj) {
225225
226226inline bool PyNone_Check (PyObject *o) { return o == Py_None; }
227227
228+ inline bool PyUnicode_Check_Permissive (PyObject *o) { return PyUnicode_Check (o) || PYBIND11_BYTES_CHECK (o); }
229+
228230NAMESPACE_END (detail)
229231
230232#define PYBIND11_OBJECT_CVT (Name, Parent, CheckFun, CvtStmt ) \
@@ -316,21 +318,26 @@ inline iterator handle::end() const { return iterator(nullptr, false); }
316318
317319class str : public object {
318320public:
319- PYBIND11_OBJECT_DEFAULT (str, object, PyUnicode_Check)
321+ PYBIND11_OBJECT_DEFAULT (str, object, detail::PyUnicode_Check_Permissive)
322+
320323 str (const std::string &s)
321324 : object(PyUnicode_FromStringAndSize(s.c_str(), s.length()), false ) {
322325 if (!m_ptr) pybind11_fail (" Could not allocate string object!" );
323326 }
324327
325328 operator std::string () const {
326- #if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3
327- return PyUnicode_AsUTF8 (m_ptr);
328- #else
329- object temp (PyUnicode_AsUTF8String (m_ptr), false );
330- if (temp.ptr () == nullptr )
331- pybind11_fail (" Unable to extract string contents!" );
332- return PYBIND11_BYTES_AS_STRING (temp.ptr ());
333- #endif
329+ object temp = *this ;
330+ if (PyUnicode_Check (m_ptr)) {
331+ temp = object (PyUnicode_AsUTF8String (m_ptr), false );
332+ if (!temp)
333+ pybind11_fail (" Unable to extract string contents! (encoding issue)" );
334+ }
335+ char *buffer;
336+ ssize_t length;
337+ int err = PYBIND11_BYTES_AS_STRING_AND_SIZE (temp.ptr (), &buffer, &length);
338+ if (err == -1 )
339+ pybind11_fail (" Unable to extract string contents! (invalid type)" );
340+ return std::string (buffer, length);
334341 }
335342};
336343
0 commit comments