generalized str::operator std::string() to accept 'bytes'(3.x)/'string'(2.7)

This commit is contained in:
Wenzel Jakob 2016-05-01 00:32:18 +02:00
parent fc92d82bba
commit 5612a0c1c2
2 changed files with 20 additions and 11 deletions

View File

@ -81,6 +81,7 @@
#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize #define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize
#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize #define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize
#define PYBIND11_BYTES_AS_STRING PyBytes_AsString #define PYBIND11_BYTES_AS_STRING PyBytes_AsString
#define PYBIND11_BYTES_CHECK PyBytes_Check
#define PYBIND11_LONG_CHECK(o) PyLong_Check(o) #define PYBIND11_LONG_CHECK(o) PyLong_Check(o)
#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o) #define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)
#define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) PyLong_AsUnsignedLongLong(o) #define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) PyLong_AsUnsignedLongLong(o)
@ -98,6 +99,7 @@
#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize #define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize
#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize #define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize
#define PYBIND11_BYTES_AS_STRING PyString_AsString #define PYBIND11_BYTES_AS_STRING PyString_AsString
#define PYBIND11_BYTES_CHECK PyString_Check
#define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o)) #define PYBIND11_LONG_CHECK(o) (PyInt_Check(o) || PyLong_Check(o))
#define PYBIND11_LONG_AS_LONGLONG(o) (PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o)) #define PYBIND11_LONG_AS_LONGLONG(o) (PyInt_Check(o) ? (long long) PyLong_AsLong(o) : PyLong_AsLongLong(o))
#define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) (PyInt_Check(o) ? (unsigned long long) PyLong_AsUnsignedLong(o) : PyLong_AsUnsignedLongLong(o)) #define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) (PyInt_Check(o) ? (unsigned long long) PyLong_AsUnsignedLong(o) : PyLong_AsUnsignedLongLong(o))

View File

@ -163,7 +163,7 @@ public:
return object(result, true); return object(result, true);
} }
template <typename T> inline T cast() const { return operator object().cast<T>(); } template <typename T> T cast() const { return operator object().cast<T>(); }
private: private:
handle list; handle list;
size_t index; size_t index;
@ -188,7 +188,7 @@ public:
return object(result, true); return object(result, true);
} }
template <typename T> inline T cast() const { return operator object().cast<T>(); } template <typename T> T cast() const { return operator object().cast<T>(); }
private: private:
handle tuple; handle tuple;
size_t index; size_t index;
@ -225,6 +225,8 @@ inline bool PyIterable_Check(PyObject *obj) {
inline bool PyNone_Check(PyObject *o) { return o == Py_None; } inline bool PyNone_Check(PyObject *o) { return o == Py_None; }
inline bool PyUnicode_Check_Permissive(PyObject *o) { return PyUnicode_Check(o) || PYBIND11_BYTES_CHECK(o); }
NAMESPACE_END(detail) NAMESPACE_END(detail)
#define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, CvtStmt) \ #define PYBIND11_OBJECT_CVT(Name, Parent, CheckFun, CvtStmt) \
@ -316,21 +318,26 @@ inline iterator handle::end() const { return iterator(nullptr, false); }
class str : public object { class str : public object {
public: public:
PYBIND11_OBJECT_DEFAULT(str, object, PyUnicode_Check) PYBIND11_OBJECT_DEFAULT(str, object, detail::PyUnicode_Check_Permissive)
str(const std::string &s) str(const std::string &s)
: object(PyUnicode_FromStringAndSize(s.c_str(), s.length()), false) { : object(PyUnicode_FromStringAndSize(s.c_str(), s.length()), false) {
if (!m_ptr) pybind11_fail("Could not allocate string object!"); if (!m_ptr) pybind11_fail("Could not allocate string object!");
} }
operator std::string() const { operator std::string() const {
#if PY_MAJOR_VERSION >= 3 && PY_MINOR_VERSION >= 3 object temp = *this;
return PyUnicode_AsUTF8(m_ptr); if (PyUnicode_Check(m_ptr)) {
#else temp = object(PyUnicode_AsUTF8String(m_ptr), false);
object temp(PyUnicode_AsUTF8String(m_ptr), false); if (!temp)
if (temp.ptr() == nullptr) pybind11_fail("Unable to extract string contents! (encoding issue)");
pybind11_fail("Unable to extract string contents!"); }
return PYBIND11_BYTES_AS_STRING(temp.ptr()); char *buffer;
#endif ssize_t length;
int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(temp.ptr(), &buffer, &length);
if (err == -1)
pybind11_fail("Unable to extract string contents! (invalid type)");
return std::string(buffer, length);
} }
}; };