1
1
2
2
from cpython cimport PyTypeObject
3
+ from cpython.version cimport PY_MAJOR_VERSION
3
4
4
5
cdef extern from * :
5
6
"""
@@ -14,6 +15,29 @@ cdef extern from *:
14
15
object char_to_string(const char * data)
15
16
16
17
18
+ cdef extern from * :
19
+ """
20
+ #if PY_VERSION_HEX >= 0x03000000
21
+ #define PyBytes_AsStringAndSize(py_string, buffer, length) \
22
+ PyBytes_AsStringAndSize(py_string, buffer, length)
23
+
24
+ #define PyUnicode_AsUTF8AndSize(py_string, buffer, length) \
25
+ buffer = PyUnicode_AsUTF8AndSize(py_string, length)
26
+
27
+ #else
28
+ #define PyBytes_AsStringAndSize(py_string, buffer, length) \
29
+ PyString_AsStringAndSize(py_string, buffer, length)
30
+
31
+ #define PyUnicode_AsUTF8AndSize(py_string, buffer, length) \
32
+ do { \
33
+ buffer = PyUnicode_AS_DATA(py_string); \
34
+ *length = PyUnicode_GET_SIZE(py_string); \
35
+ } while(0)
36
+ #endif
37
+ """
38
+ void PyUnicode_AsUTF8AndSize(object py_string, const char * buffer , Py_ssize_t* length)
39
+ void PyBytes_AsStringAndSize(object py_string, char ** buffer , Py_ssize_t* length)
40
+
17
41
cdef extern from " Python.h" :
18
42
# Note: importing extern-style allows us to declare these as nogil
19
43
# functions, whereas `from cpython cimport` does not.
@@ -24,15 +48,6 @@ cdef extern from "Python.h":
24
48
bint PyComplex_Check(object obj) nogil
25
49
bint PyObject_TypeCheck(object obj, PyTypeObject* type ) nogil
26
50
27
- # Note that following functions can potentially raise an exception,
28
- # thus they cannot be declared 'nogil'. Also PyUnicode_AsUTF8AndSize() can
29
- # potentially allocate memory inside in unlikely case of when underlying
30
- # unicode object was stored as non-utf8 and utf8 wasn't requested before.
31
- bint PyBytes_AsStringAndSize(object obj, char ** buf,
32
- Py_ssize_t* length) except - 1
33
- const char * PyUnicode_AsUTF8AndSize(object obj,
34
- Py_ssize_t* length) except NULL
35
-
36
51
from numpy cimport int64_t, float64_t
37
52
38
53
cdef extern from " numpy/arrayobject.h" :
@@ -243,7 +258,7 @@ cdef inline bint is_nan(object val):
243
258
244
259
245
260
cdef inline const char * get_c_string_buf_and_size(object py_string,
246
- Py_ssize_t * length):
261
+ Py_ssize_t * length) except NULL :
247
262
"""
248
263
Extract internal char* buffer of unicode or bytes object `py_string` with
249
264
getting length of this internal buffer saved in `length`.
@@ -263,10 +278,13 @@ cdef inline const char* get_c_string_buf_and_size(object py_string,
263
278
buf : const char*
264
279
"""
265
280
cdef:
266
- const char * buf
281
+ const char * buf = NULL
267
282
268
283
if PyUnicode_Check(py_string):
269
- buf = PyUnicode_AsUTF8AndSize(py_string, length)
284
+ if PY_MAJOR_VERSION > 2 :
285
+ PyUnicode_AsUTF8AndSize(py_string, buf, length)
286
+ else :
287
+ buf = py_string
270
288
else :
271
289
PyBytes_AsStringAndSize(py_string, < char ** > & buf, length)
272
290
return buf
0 commit comments