summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOndrej Certik <ondrej.certik@gmail.com>2012-07-27 12:16:12 -0700
committerOndrej Certik <ondrej.certik@gmail.com>2012-08-03 07:45:12 -0700
commita9d58ab42da8d2ed9071044848a54c5e066b557a (patch)
tree2e1e7be17dea21f480551de7cd37dc9085e5c3c2
parentfd15162fbff5dd68c548284947d39bb2a2481183 (diff)
downloadnumpy-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.c36
-rw-r--r--numpy/core/src/multiarray/scalartypes.c.src4
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 */