mirror of
https://github.com/pybind/pybind11.git
synced 2024-11-22 13:15:12 +00:00
added new type pybind11::bytes, cleanup of various macros (fixes #49)
This commit is contained in:
parent
2dfbadee5d
commit
27e8e1066b
@ -801,9 +801,9 @@ For instance, the following statement iterates over a Python ``dict``:
|
|||||||
}
|
}
|
||||||
|
|
||||||
Available types include :class:`handle`, :class:`object`, :class:`bool_`,
|
Available types include :class:`handle`, :class:`object`, :class:`bool_`,
|
||||||
:class:`int_`, :class:`float_`, :class:`str`, :class:`tuple`, :class:`list`,
|
:class:`int_`, :class:`float_`, :class:`str`, :class:`bytes`, :class:`tuple`,
|
||||||
:class:`dict`, :class:`slice`, :class:`capsule`, :class:`function`,
|
:class:`list`, :class:`dict`, :class:`slice`, :class:`capsule`,
|
||||||
:class:`buffer`, :class:`array`, and :class:`array_t`.
|
:class:`function`, :class:`buffer`, :class:`array`, and :class:`array_t`.
|
||||||
|
|
||||||
In this kind of mixed code, it is often necessary to convert arbitrary C++
|
In this kind of mixed code, it is often necessary to convert arbitrary C++
|
||||||
types to Python, which can be done using :func:`cast`:
|
types to Python, which can be done using :func:`cast`:
|
||||||
|
@ -72,24 +72,12 @@ public:
|
|||||||
std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
|
std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* STL data types are automatically casted from Python */
|
/* Easily iterate over a set using a C++11 range-based for loop */
|
||||||
void print_dict_2(const std::map<std::string, std::string> &dict) {
|
|
||||||
for (auto item : dict)
|
|
||||||
std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Easily iterate over a setionary using a C++11 range-based for loop */
|
|
||||||
void print_set(py::set set) {
|
void print_set(py::set set) {
|
||||||
for (auto item : set)
|
for (auto item : set)
|
||||||
std::cout << "key: " << item << std::endl;
|
std::cout << "key: " << item << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* STL data types are automatically casted from Python */
|
|
||||||
void print_set_2(const std::set<std::string> &set) {
|
|
||||||
for (auto item : set)
|
|
||||||
std::cout << "key: " << item << std::endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Easily iterate over a list using a C++11 range-based for loop */
|
/* Easily iterate over a list using a C++11 range-based for loop */
|
||||||
void print_list(py::list list) {
|
void print_list(py::list list) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
@ -97,7 +85,19 @@ public:
|
|||||||
std::cout << "list item " << index++ << ": " << item << std::endl;
|
std::cout << "list item " << index++ << ": " << item << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* STL data types are automatically casted from Python */
|
/* STL data types (such as maps) are automatically casted from Python */
|
||||||
|
void print_dict_2(const std::map<std::string, std::string> &dict) {
|
||||||
|
for (auto item : dict)
|
||||||
|
std::cout << "key: " << item.first << ", value=" << item.second << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* STL data types (such as sets) are automatically casted from Python */
|
||||||
|
void print_set_2(const std::set<std::string> &set) {
|
||||||
|
for (auto item : set)
|
||||||
|
std::cout << "key: " << item << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* STL data types (such as vectors) are automatically casted from Python */
|
||||||
void print_list_2(std::vector<std::string> &list) {
|
void print_list_2(std::vector<std::string> &list) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (auto item : list)
|
for (auto item : list)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
example/example4.cpp -- global constants and functions, enumerations
|
example/example4.cpp -- global constants and functions, enumerations, raw byte strings
|
||||||
|
|
||||||
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
|
Copyright (c) 2015 Wenzel Jakob <wenzel@inf.ethz.ch>
|
||||||
|
|
||||||
@ -40,6 +40,17 @@ float test_function3(int i) {
|
|||||||
return i / 2.f;
|
return i / 2.f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
py::bytes return_bytes() {
|
||||||
|
const char *data = "\x01\x00\x02\x00";
|
||||||
|
return py::bytes(std::string(data, 4));
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_bytes(py::bytes bytes) {
|
||||||
|
std::string value = (std::string) bytes;
|
||||||
|
for (size_t i = 0; i < value.length(); ++i)
|
||||||
|
std::cout << "bytes[" << i << "]=" << (int) value[i] << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
void init_ex4(py::module &m) {
|
void init_ex4(py::module &m) {
|
||||||
m.def("test_function", &test_function1);
|
m.def("test_function", &test_function1);
|
||||||
m.def("test_function", &test_function2);
|
m.def("test_function", &test_function2);
|
||||||
@ -57,4 +68,7 @@ void init_ex4(py::module &m) {
|
|||||||
.value("EFirstMode", Example4::EFirstMode)
|
.value("EFirstMode", Example4::EFirstMode)
|
||||||
.value("ESecondMode", Example4::ESecondMode)
|
.value("ESecondMode", Example4::ESecondMode)
|
||||||
.export_values();
|
.export_values();
|
||||||
|
|
||||||
|
m.def("return_bytes", &return_bytes);
|
||||||
|
m.def("print_bytes", &print_bytes);
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,8 @@ from example import some_constant
|
|||||||
from example import EMyEnumeration
|
from example import EMyEnumeration
|
||||||
from example import EFirstEntry
|
from example import EFirstEntry
|
||||||
from example import Example4
|
from example import Example4
|
||||||
|
from example import return_bytes
|
||||||
|
from example import print_bytes
|
||||||
|
|
||||||
print(EMyEnumeration)
|
print(EMyEnumeration)
|
||||||
print(EMyEnumeration.EFirstEntry)
|
print(EMyEnumeration.EFirstEntry)
|
||||||
@ -23,3 +25,5 @@ print(Example4.EMode)
|
|||||||
print(Example4.EMode.EFirstMode)
|
print(Example4.EMode.EFirstMode)
|
||||||
print(Example4.EFirstMode)
|
print(Example4.EFirstMode)
|
||||||
Example4.test_function(Example4.EFirstMode)
|
Example4.test_function(Example4.EFirstMode)
|
||||||
|
|
||||||
|
print_bytes(return_bytes())
|
||||||
|
@ -14,3 +14,7 @@ None
|
|||||||
EMode.EFirstMode
|
EMode.EFirstMode
|
||||||
EMode.EFirstMode
|
EMode.EFirstMode
|
||||||
Example4::test_function(enum=1)
|
Example4::test_function(enum=1)
|
||||||
|
bytes[0]=1
|
||||||
|
bytes[1]=0
|
||||||
|
bytes[2]=2
|
||||||
|
bytes[3]=0
|
||||||
|
@ -21,6 +21,7 @@ def sanitize(lines):
|
|||||||
line = shorten_floats.sub(r'\1', line)
|
line = shorten_floats.sub(r'\1', line)
|
||||||
line = line.replace('__builtin__', 'builtins')
|
line = line.replace('__builtin__', 'builtins')
|
||||||
line = line.replace('example.', '')
|
line = line.replace('example.', '')
|
||||||
|
line = line.replace('unicode', 'str')
|
||||||
line = line.replace('method of builtins.PyCapsule instance', '')
|
line = line.replace('method of builtins.PyCapsule instance', '')
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
if sys.platform == 'win32':
|
if sys.platform == 'win32':
|
||||||
|
@ -19,12 +19,6 @@
|
|||||||
NAMESPACE_BEGIN(pybind11)
|
NAMESPACE_BEGIN(pybind11)
|
||||||
NAMESPACE_BEGIN(detail)
|
NAMESPACE_BEGIN(detail)
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
#define PYBIND11_AS_STRING PyBytes_AsString
|
|
||||||
#else
|
|
||||||
#define PYBIND11_AS_STRING PyString_AsString
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class type_caster_custom {
|
class type_caster_custom {
|
||||||
public:
|
public:
|
||||||
PYBIND11_NOINLINE type_caster_custom(const std::type_info *type_info) {
|
PYBIND11_NOINLINE type_caster_custom(const std::type_info *type_info) {
|
||||||
@ -185,9 +179,9 @@ public:
|
|||||||
py_value = (py_type) PyLong_AsUnsignedLong(src);
|
py_value = (py_type) PyLong_AsUnsignedLong(src);
|
||||||
} else {
|
} else {
|
||||||
if (std::is_signed<T>::value)
|
if (std::is_signed<T>::value)
|
||||||
py_value = (py_type) detail::PyLong_AsLongLong_(src);
|
py_value = (py_type) PYBIND11_LONG_AS_LONGLONG(src);
|
||||||
else
|
else
|
||||||
py_value = (py_type) detail::PyLong_AsUnsignedLongLong_(src);
|
py_value = (py_type) PYBIND11_LONG_AS_UNSIGNED_LONGLONG(src);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((py_value == (py_type) -1 && PyErr_Occurred()) ||
|
if ((py_value == (py_type) -1 && PyErr_Occurred()) ||
|
||||||
@ -265,35 +259,41 @@ public:
|
|||||||
template <> class type_caster<std::string> {
|
template <> class type_caster<std::string> {
|
||||||
public:
|
public:
|
||||||
bool load(PyObject *src, bool) {
|
bool load(PyObject *src, bool) {
|
||||||
#if PY_MAJOR_VERSION < 3
|
object temp;
|
||||||
if (PyString_Check(src)) { value = PyString_AsString(src); return true; }
|
PyObject *load_src = src;
|
||||||
#endif
|
if (PyUnicode_Check(src)) {
|
||||||
object temp(PyUnicode_AsUTF8String(src), false);
|
temp = object(PyUnicode_AsUTF8String(src), false);
|
||||||
const char *ptr = nullptr;
|
if (!temp) { PyErr_Clear(); return false; } // UnicodeEncodeError
|
||||||
if (temp)
|
load_src = temp.ptr();
|
||||||
ptr = PYBIND11_AS_STRING(temp.ptr());
|
}
|
||||||
if (!ptr) { PyErr_Clear(); return false; }
|
char *buffer;
|
||||||
value = ptr;
|
ssize_t length;
|
||||||
|
int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(load_src, &buffer, &length);
|
||||||
|
if (err == -1) { PyErr_Clear(); return false; } // TypeError
|
||||||
|
value = std::string(buffer, length);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static PyObject *cast(const std::string &src, return_value_policy /* policy */, PyObject * /* parent */) {
|
static PyObject *cast(const std::string &src, return_value_policy /* policy */, PyObject * /* parent */) {
|
||||||
return PyUnicode_FromString(src.c_str());
|
return PyUnicode_FromStringAndSize(src.c_str(), src.length());
|
||||||
}
|
}
|
||||||
PYBIND11_TYPE_CASTER(std::string, _("str"));
|
|
||||||
|
PYBIND11_TYPE_CASTER(std::string, _(PYBIND11_STRING_NAME));
|
||||||
};
|
};
|
||||||
|
|
||||||
template <> class type_caster<char> {
|
template <> class type_caster<char> {
|
||||||
public:
|
public:
|
||||||
bool load(PyObject *src, bool) {
|
bool load(PyObject *src, bool) {
|
||||||
#if PY_MAJOR_VERSION < 3
|
object temp;
|
||||||
if (PyString_Check(src)) { value = PyString_AsString(src); return true; }
|
PyObject *load_src = src;
|
||||||
#endif
|
if (PyUnicode_Check(src)) {
|
||||||
object temp(PyUnicode_AsUTF8String(src), false);
|
temp = object(PyUnicode_AsUTF8String(src), false);
|
||||||
const char *ptr = nullptr;
|
if (!temp) { PyErr_Clear(); return false; } // UnicodeEncodeError
|
||||||
if (temp)
|
load_src = temp.ptr();
|
||||||
ptr = PYBIND11_AS_STRING(temp.ptr());
|
}
|
||||||
if (!ptr) { PyErr_Clear(); return false; }
|
const char *ptr = PYBIND11_BYTES_AS_STRING(load_src);
|
||||||
value = ptr;
|
if (!ptr) { PyErr_Clear(); return false; } // TypeError
|
||||||
|
value = std::string(ptr);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,10 +306,10 @@ public:
|
|||||||
return PyUnicode_DecodeLatin1(str, 1, nullptr);
|
return PyUnicode_DecodeLatin1(str, 1, nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
static PYBIND11_DESCR name() { return type_descr(_("str")); }
|
|
||||||
|
|
||||||
operator char*() { return (char *) value.c_str(); }
|
operator char*() { return (char *) value.c_str(); }
|
||||||
operator char() { if (value.length() > 0) return value[0]; else return '\0'; }
|
operator char() { if (value.length() > 0) return value[0]; else return '\0'; }
|
||||||
|
|
||||||
|
static PYBIND11_DESCR name() { return type_descr(_(PYBIND11_STRING_NAME)); }
|
||||||
protected:
|
protected:
|
||||||
std::string value;
|
std::string value;
|
||||||
};
|
};
|
||||||
|
@ -85,6 +85,29 @@
|
|||||||
} \
|
} \
|
||||||
PyObject *pybind11_init()
|
PyObject *pybind11_init()
|
||||||
|
|
||||||
|
#if PY_MAJOR_VERSION >= 3 /// Compatibility macros for various Python versions
|
||||||
|
#define PYBIND11_BYTES_CHECK PyBytes_Check
|
||||||
|
#define PYBIND11_BYTES_FROM_STRING PyBytes_FromString
|
||||||
|
#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyBytes_FromStringAndSize
|
||||||
|
#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyBytes_AsStringAndSize
|
||||||
|
#define PYBIND11_BYTES_AS_STRING PyBytes_AsString
|
||||||
|
#define PYBIND11_LONG_CHECK(o) PyLong_Check(o)
|
||||||
|
#define PYBIND11_LONG_AS_LONGLONG(o) PyLong_AsLongLong(o)
|
||||||
|
#define PYBIND11_LONG_AS_UNSIGNED_LONGLONG(o) PyLong_AsUnsignedLongLong(o)
|
||||||
|
#define PYBIND11_STRING_NAME "str"
|
||||||
|
#define PYBIND11_SLICE_OBJECT PyObject
|
||||||
|
#else
|
||||||
|
#define PYBIND11_BYTES_CHECK PyString_Check
|
||||||
|
#define PYBIND11_BYTES_FROM_STRING PyString_FromString
|
||||||
|
#define PYBIND11_BYTES_FROM_STRING_AND_SIZE PyString_FromStringAndSize
|
||||||
|
#define PYBIND11_BYTES_AS_STRING_AND_SIZE PyString_AsStringAndSize
|
||||||
|
#define PYBIND11_BYTES_AS_STRING PyString_AsString
|
||||||
|
#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_UNSIGNED_LONGLONG(o) (PyInt_Check(o) ? (unsigned long long) PyLong_AsUnsignedLong(o) : PyLong_AsUnsignedLongLong(o))
|
||||||
|
#define PYBIND11_STRING_NAME "unicode"
|
||||||
|
#define PYBIND11_SLICE_OBJECT PySliceObject
|
||||||
|
#endif
|
||||||
|
|
||||||
NAMESPACE_BEGIN(pybind11)
|
NAMESPACE_BEGIN(pybind11)
|
||||||
|
|
||||||
|
@ -337,7 +337,7 @@ private:
|
|||||||
if (a.descr)
|
if (a.descr)
|
||||||
a.descr = strdup(a.descr);
|
a.descr = strdup(a.descr);
|
||||||
else if (a.value)
|
else if (a.value)
|
||||||
a.descr = strdup(((object) handle(a.value).attr("__repr__")).call().str());
|
a.descr = strdup(((std::string) ((object) handle(a.value).attr("__repr__")).call().str()).c_str());
|
||||||
}
|
}
|
||||||
auto const ®istered_types = detail::get_internals().registered_types;
|
auto const ®istered_types = detail::get_internals().registered_types;
|
||||||
|
|
||||||
@ -367,7 +367,7 @@ private:
|
|||||||
} else if (c == '%') {
|
} else if (c == '%') {
|
||||||
const std::type_info *t = types[type_index++];
|
const std::type_info *t = types[type_index++];
|
||||||
if (!t)
|
if (!t)
|
||||||
throw std::runtime_error("Internal error while generating type signature (1)");
|
throw std::runtime_error("Internal error while parsing type signature (1)");
|
||||||
auto it = registered_types.find(t);
|
auto it = registered_types.find(t);
|
||||||
if (it != registered_types.end()) {
|
if (it != registered_types.end()) {
|
||||||
signature += it->second.type->tp_name;
|
signature += it->second.type->tp_name;
|
||||||
@ -381,7 +381,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (type_depth != 0 && types[type_index ] != nullptr)
|
if (type_depth != 0 && types[type_index ] != nullptr)
|
||||||
throw std::runtime_error("Internal error while generating type signature (2)");
|
throw std::runtime_error("Internal error while parsing type signature (2)");
|
||||||
|
|
||||||
#if !defined(PYBIND11_CPP14)
|
#if !defined(PYBIND11_CPP14)
|
||||||
delete[] types;
|
delete[] types;
|
||||||
@ -694,8 +694,8 @@ protected:
|
|||||||
view->format = const_cast<char *>(info->format.c_str());
|
view->format = const_cast<char *>(info->format.c_str());
|
||||||
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
|
if ((flags & PyBUF_STRIDES) == PyBUF_STRIDES) {
|
||||||
view->ndim = info->ndim;
|
view->ndim = info->ndim;
|
||||||
view->strides = (Py_ssize_t *)&info->strides[0];
|
view->strides = (ssize_t *) &info->strides[0];
|
||||||
view->shape = (Py_ssize_t *) &info->shape[0];
|
view->shape = (ssize_t *) &info->shape[0];
|
||||||
}
|
}
|
||||||
Py_INCREF(view->obj);
|
Py_INCREF(view->obj);
|
||||||
return 0;
|
return 0;
|
||||||
@ -903,7 +903,7 @@ public:
|
|||||||
void export_values() {
|
void export_values() {
|
||||||
PyObject *dict = ((PyTypeObject *) this->m_ptr)->tp_dict;
|
PyObject *dict = ((PyTypeObject *) this->m_ptr)->tp_dict;
|
||||||
PyObject *key, *value;
|
PyObject *key, *value;
|
||||||
Py_ssize_t pos = 0;
|
ssize_t pos = 0;
|
||||||
while (PyDict_Next(dict, &pos, &key, &value))
|
while (PyDict_Next(dict, &pos, &key, &value))
|
||||||
if (PyObject_IsInstance(value, this->m_ptr))
|
if (PyObject_IsInstance(value, this->m_ptr))
|
||||||
m_parent.attr(key) = value;
|
m_parent.attr(key) = value;
|
||||||
@ -983,9 +983,10 @@ inline function get_overload(const void *this_ptr, const char *name) {
|
|||||||
cache.insert(key);
|
cache.insert(key);
|
||||||
return function();
|
return function();
|
||||||
}
|
}
|
||||||
|
|
||||||
PyFrameObject *frame = PyThreadState_Get()->frame;
|
PyFrameObject *frame = PyThreadState_Get()->frame;
|
||||||
pybind11::str caller = pybind11::handle(frame->f_code->co_name).str();
|
pybind11::str caller = pybind11::handle(frame->f_code->co_name).str();
|
||||||
if (strcmp((const char *) caller, name) == 0)
|
if ((std::string) caller == name)
|
||||||
return function();
|
return function();
|
||||||
return overload;
|
return overload;
|
||||||
}
|
}
|
||||||
|
@ -215,30 +215,6 @@ private:
|
|||||||
ssize_t pos = 0;
|
ssize_t pos = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
#if PY_MAJOR_VERSION >= 3
|
|
||||||
inline long long PyLong_AsLongLong_(PyObject *o) { return PyLong_AsLongLong(o); }
|
|
||||||
inline unsigned long long PyLong_AsUnsignedLongLong_(PyObject *o) { return PyLong_AsUnsignedLongLong(o); }
|
|
||||||
inline bool PyLong_Check_(PyObject *o) { return PyLong_Check(o); }
|
|
||||||
#else
|
|
||||||
inline long long PyLong_AsLongLong_(PyObject *o) {
|
|
||||||
if (PyInt_Check(o)) /// workaround: PyLong_AsLongLong doesn't accept 'int' on Python 2.x
|
|
||||||
return (long long) PyLong_AsLong(o);
|
|
||||||
else
|
|
||||||
return PyLong_AsLongLong(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline unsigned long long PyLong_AsUnsignedLongLong_(PyObject *o) {
|
|
||||||
if (PyInt_Check(o)) /// workaround: PyLong_AsUnsignedLongLong doesn't accept 'int' on Python 2.x
|
|
||||||
return (unsigned long long) PyLong_AsUnsignedLong(o);
|
|
||||||
else
|
|
||||||
return PyLong_AsUnsignedLongLong(o);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline bool PyLong_Check_(PyObject *o) {
|
|
||||||
return PyInt_Check(o) || PyLong_Check(o);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
NAMESPACE_END(detail)
|
NAMESPACE_END(detail)
|
||||||
|
|
||||||
inline detail::accessor handle::operator[](handle key) const { return detail::accessor(ptr(), key.ptr(), false); }
|
inline detail::accessor handle::operator[](handle key) const { return detail::accessor(ptr(), key.ptr(), false); }
|
||||||
@ -266,21 +242,18 @@ inline iterator handle::end() const { return iterator(nullptr); }
|
|||||||
class str : public object {
|
class str : public object {
|
||||||
public:
|
public:
|
||||||
PYBIND11_OBJECT_DEFAULT(str, object, PyUnicode_Check)
|
PYBIND11_OBJECT_DEFAULT(str, object, PyUnicode_Check)
|
||||||
str(const char *s) : object(PyUnicode_FromString(s), false) { }
|
str(const std::string &s) : object(PyUnicode_FromStringAndSize(s.c_str(), s.length()), false) { }
|
||||||
operator const char *() const {
|
|
||||||
|
operator std::string() const {
|
||||||
#if PY_MAJOR_VERSION >= 3
|
#if PY_MAJOR_VERSION >= 3
|
||||||
return PyUnicode_AsUTF8(m_ptr);
|
return PyUnicode_AsUTF8(m_ptr);
|
||||||
#else
|
#else
|
||||||
m_temp = object(PyUnicode_AsUTF8String(m_ptr), false);
|
object temp(PyUnicode_AsUTF8String(m_ptr), false);
|
||||||
if (m_temp.ptr() == nullptr)
|
if (temp.ptr() == nullptr)
|
||||||
return nullptr;
|
throw std::runtime_error("Unable to extract string contents!");
|
||||||
return PyString_AsString(m_temp.ptr());
|
return PyString_AsString(temp.ptr());
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
private:
|
|
||||||
#if PY_MAJOR_VERSION < 3
|
|
||||||
mutable object m_temp;
|
|
||||||
#endif
|
|
||||||
};
|
};
|
||||||
|
|
||||||
inline pybind11::str handle::str() const {
|
inline pybind11::str handle::str() const {
|
||||||
@ -292,6 +265,23 @@ inline pybind11::str handle::str() const {
|
|||||||
return pybind11::str(str, false);
|
return pybind11::str(str, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class bytes : public object {
|
||||||
|
public:
|
||||||
|
PYBIND11_OBJECT_DEFAULT(bytes, object, PYBIND11_BYTES_CHECK)
|
||||||
|
|
||||||
|
bytes(const std::string &s)
|
||||||
|
: object(PYBIND11_BYTES_FROM_STRING_AND_SIZE(s.data(), s.size()), false) { }
|
||||||
|
|
||||||
|
operator std::string() const {
|
||||||
|
char *buffer;
|
||||||
|
ssize_t length;
|
||||||
|
int err = PYBIND11_BYTES_AS_STRING_AND_SIZE(m_ptr, &buffer, &length);
|
||||||
|
if (err == -1)
|
||||||
|
throw std::runtime_error("Unable to extract bytes contents!");
|
||||||
|
return std::string(buffer, length);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
class bool_ : public object {
|
class bool_ : public object {
|
||||||
public:
|
public:
|
||||||
PYBIND11_OBJECT_DEFAULT(bool_, object, PyBool_Check)
|
PYBIND11_OBJECT_DEFAULT(bool_, object, PyBool_Check)
|
||||||
@ -301,7 +291,7 @@ public:
|
|||||||
|
|
||||||
class int_ : public object {
|
class int_ : public object {
|
||||||
public:
|
public:
|
||||||
PYBIND11_OBJECT_DEFAULT(int_, object, detail::PyLong_Check_)
|
PYBIND11_OBJECT_DEFAULT(int_, object, PYBIND11_LONG_CHECK)
|
||||||
template <typename T,
|
template <typename T,
|
||||||
typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
|
typename std::enable_if<std::is_integral<T>::value, int>::type = 0>
|
||||||
int_(T value) {
|
int_(T value) {
|
||||||
@ -328,9 +318,9 @@ public:
|
|||||||
return (T) PyLong_AsUnsignedLong(m_ptr);
|
return (T) PyLong_AsUnsignedLong(m_ptr);
|
||||||
} else {
|
} else {
|
||||||
if (std::is_signed<T>::value)
|
if (std::is_signed<T>::value)
|
||||||
return (T) detail::PyLong_AsLongLong_(m_ptr);
|
return (T) PYBIND11_LONG_AS_LONGLONG(m_ptr);
|
||||||
else
|
else
|
||||||
return (T) detail::PyLong_AsUnsignedLongLong_(m_ptr);
|
return (T) PYBIND11_LONG_AS_UNSIGNED_LONGLONG(m_ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -352,13 +342,8 @@ public:
|
|||||||
m_ptr = PySlice_New(start.ptr(), stop.ptr(), step.ptr());
|
m_ptr = PySlice_New(start.ptr(), stop.ptr(), step.ptr());
|
||||||
}
|
}
|
||||||
bool compute(ssize_t length, ssize_t *start, ssize_t *stop, ssize_t *step, ssize_t *slicelength) const {
|
bool compute(ssize_t length, ssize_t *start, ssize_t *stop, ssize_t *step, ssize_t *slicelength) const {
|
||||||
return PySlice_GetIndicesEx(
|
return PySlice_GetIndicesEx((PYBIND11_SLICE_OBJECT *) m_ptr, length,
|
||||||
#if PY_MAJOR_VERSION >= 3
|
start, stop, step, slicelength) == 0;
|
||||||
m_ptr,
|
|
||||||
#else
|
|
||||||
(PySliceObject *) m_ptr,
|
|
||||||
#endif
|
|
||||||
length, start, stop, step, slicelength) == 0;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -377,7 +362,7 @@ public:
|
|||||||
class tuple : public object {
|
class tuple : public object {
|
||||||
public:
|
public:
|
||||||
PYBIND11_OBJECT(tuple, object, PyTuple_Check)
|
PYBIND11_OBJECT(tuple, object, PyTuple_Check)
|
||||||
tuple(size_t size = 0) : object(PyTuple_New((Py_ssize_t) size), false) { }
|
tuple(size_t size = 0) : object(PyTuple_New((ssize_t) size), false) { }
|
||||||
size_t size() const { return (size_t) PyTuple_Size(m_ptr); }
|
size_t size() const { return (size_t) PyTuple_Size(m_ptr); }
|
||||||
detail::tuple_accessor operator[](size_t index) const { return detail::tuple_accessor(ptr(), index); }
|
detail::tuple_accessor operator[](size_t index) const { return detail::tuple_accessor(ptr(), index); }
|
||||||
};
|
};
|
||||||
@ -466,11 +451,11 @@ inline std::string error_string() {
|
|||||||
return "";
|
return "";
|
||||||
|
|
||||||
if (tstate->curexc_type) {
|
if (tstate->curexc_type) {
|
||||||
errorString += (const char *) handle(tstate->curexc_type).str();
|
errorString += (std::string) handle(tstate->curexc_type).str();
|
||||||
errorString += ": ";
|
errorString += ": ";
|
||||||
}
|
}
|
||||||
if (tstate->curexc_value)
|
if (tstate->curexc_value)
|
||||||
errorString += (const char *) handle(tstate->curexc_value).str();
|
errorString += (std::string) handle(tstate->curexc_value).str();
|
||||||
|
|
||||||
return errorString;
|
return errorString;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +131,7 @@ public:
|
|||||||
|
|
||||||
NAMESPACE_END(detail)
|
NAMESPACE_END(detail)
|
||||||
|
|
||||||
inline std::ostream &operator<<(std::ostream &os, const object &obj) { os << (const char *) obj.str(); return os; }
|
inline std::ostream &operator<<(std::ostream &os, const object &obj) { os << (std::string) obj.str(); return os; }
|
||||||
|
|
||||||
NAMESPACE_END(pybind11)
|
NAMESPACE_END(pybind11)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user