diff options
author | Ondrej Certik <ondrej.certik@gmail.com> | 2012-07-27 12:16:12 -0700 |
---|---|---|
committer | Ondrej Certik <ondrej.certik@gmail.com> | 2012-08-03 07:45:12 -0700 |
commit | a9d58ab42da8d2ed9071044848a54c5e066b557a (patch) | |
tree | 2e1e7be17dea21f480551de7cd37dc9085e5c3c2 | |
parent | fd15162fbff5dd68c548284947d39bb2a2481183 (diff) | |
download | numpy-a9d58ab42da8d2ed9071044848a54c5e066b557a.tar.gz |
FIX: Fixes the PyUnicodeObject problem in py-3.3
Previously NumPy did not compile in Python 3.3 due to the changes in PEP 393.
This patch simply calls PyUnicode_FromKindAndData() from the new Python 3.3 API
and possibly swaps the data before calling it if needed. The data in NumPy is always UCS4 and the PyUnicode_FromKindAndData() internally converts it to UCS1, UCS2 or UCS4 depending on the maximum code point.
The following tests now fail, because they produce invalid unicode in the
process (will be fixed in the next patch):
======================================================================
ERROR: Check byteorder of 0-dimensional objects
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ondrej/py33/lib/python3.3/site-packages/numpy/core/tests/test_unicode.py", line 277, in test_values0D
self.assertTrue(ua[()] != ua2[()])
SystemError: invalid maximum character passed to PyUnicode_New
======================================================================
ERROR: Check byteorder of multi-dimensional objects
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ondrej/py33/lib/python3.3/site-packages/numpy/core/tests/test_unicode.py", line 297, in test_valuesMD
self.assertTrue(ua[0,0,0] != ua2[0,0,0])
SystemError: invalid maximum character passed to PyUnicode_New
======================================================================
ERROR: Check byteorder of single-dimensional objects
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ondrej/py33/lib/python3.3/site-packages/numpy/core/tests/test_unicode.py", line 286, in test_valuesSD
self.assertTrue(ua[0] != ua2[0])
SystemError: invalid maximum character passed to PyUnicode_New
======================================================================
ERROR: Check byteorder of 0-dimensional objects
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ondrej/py33/lib/python3.3/site-packages/numpy/core/tests/test_unicode.py", line 277, in test_values0D
self.assertTrue(ua[()] != ua2[()])
SystemError: invalid maximum character passed to PyUnicode_New
======================================================================
ERROR: Check byteorder of multi-dimensional objects
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ondrej/py33/lib/python3.3/site-packages/numpy/core/tests/test_unicode.py", line 297, in test_valuesMD
self.assertTrue(ua[0,0,0] != ua2[0,0,0])
SystemError: invalid maximum character passed to PyUnicode_New
======================================================================
ERROR: Check byteorder of single-dimensional objects
----------------------------------------------------------------------
Traceback (most recent call last):
File "/home/ondrej/py33/lib/python3.3/site-packages/numpy/core/tests/test_unicode.py", line 286, in test_valuesSD
self.assertTrue(ua[0] != ua2[0])
SystemError: invalid maximum character passed to PyUnicode_New
-rw-r--r-- | numpy/core/src/multiarray/scalarapi.c | 36 | ||||
-rw-r--r-- | numpy/core/src/multiarray/scalartypes.c.src | 4 |
2 files changed, 40 insertions, 0 deletions
diff --git a/numpy/core/src/multiarray/scalarapi.c b/numpy/core/src/multiarray/scalarapi.c index 00c71f913..0afdc1700 100644 --- a/numpy/core/src/multiarray/scalarapi.c +++ b/numpy/core/src/multiarray/scalarapi.c @@ -641,6 +641,40 @@ PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base) itemsize = (((itemsize - 1) >> 2) + 1) << 2; } } +#if PY_VERSION_HEX >= 0x03030000 + if (type_num == NPY_UNICODE) { + PyObject *u, *args; + char *buffer; + if (swap) { + buffer = malloc(itemsize); + if (buffer == NULL) { + PyErr_NoMemory(); + return NULL; + } + memcpy(buffer, data, itemsize); + byte_swap_vector(buffer, itemsize >> 2, 4); + } else { + buffer = data; + } + u = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, buffer, + itemsize >> 2); + if (swap) { + free(buffer); + } + if (u == NULL) { + return NULL; + } + args = Py_BuildValue("(O)", u); + if (args == NULL) { + Py_DECREF(u); + return NULL; + } + obj = type->tp_new(type, args, NULL); + Py_DECREF(u); + Py_DECREF(args); + return obj; + } +#endif if (type->tp_itemsize != 0) { /* String type */ obj = type->tp_alloc(type, itemsize); @@ -672,6 +706,7 @@ PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base) memcpy(destptr, data, itemsize); return obj; } +#if PY_VERSION_HEX < 0x03030000 else if (type_num == NPY_UNICODE) { /* tp_alloc inherited from Python PyBaseObject_Type */ PyUnicodeObject *uni = (PyUnicodeObject*)obj; @@ -743,6 +778,7 @@ PyArray_Scalar(void *data, PyArray_Descr *descr, PyObject *base) #endif return obj; } +#endif // PY_VERSION_HEX < 0x03030000 else { PyVoidScalarObject *vobj = (PyVoidScalarObject *)obj; vobj->base = NULL; diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src index e547071cc..12745d720 100644 --- a/numpy/core/src/multiarray/scalartypes.c.src +++ b/numpy/core/src/multiarray/scalartypes.c.src @@ -2592,7 +2592,11 @@ finish: *((npy_@name@ *)dest) = *((npy_@name@ *)src); #elif @default@ == 1 /* unicode and strings */ if (itemsize == 0) { /* unicode */ +#if PY_VERSION_HEX >= 0x03030000 + itemsize = PyUnicode_GetLength(robj) * PyUnicode_KIND(robj); +#else itemsize = ((PyUnicodeObject *)robj)->length * sizeof(Py_UNICODE); +#endif } memcpy(dest, src, itemsize); /* @default@ == 2 won't get here */ |