From df0fff45adbd3f291632b23c0cbd256bbbe912bb Mon Sep 17 00:00:00 2001 From: Eric Wieser Date: Tue, 26 Sep 2017 23:45:15 -0700 Subject: [PATCH] BUG: str(arr0d) and unicode(arr0d) should never go through np.set_string_function It's more important that scalars and 0d arrays are consistent here. Previously, unicode(arr0d) would crash on 2.7 --- numpy/core/src/multiarray/methods.c | 6 ++++++ numpy/core/src/multiarray/strfuncs.c | 32 ++++++++++++++++++++++++++++ numpy/core/src/multiarray/strfuncs.h | 5 +++++ numpy/core/tests/test_arrayprint.py | 4 +++- numpy/ma/core.py | 8 +++++++ numpy/ma/tests/test_core.py | 10 +++++++++ 6 files changed, 64 insertions(+), 1 deletion(-) diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c index 572352304e34..3f461b375b7c 100644 --- a/numpy/core/src/multiarray/methods.c +++ b/numpy/core/src/multiarray/methods.c @@ -2505,6 +2505,12 @@ NPY_NO_EXPORT PyMethodDef array_methods[] = { (PyCFunction)array_ufunc, METH_VARARGS | METH_KEYWORDS, NULL}, +#ifndef NPY_PY3K + {"__unicode__", + (PyCFunction)array_unicode, + METH_NOARGS, NULL}, +#endif + /* for the sys module */ {"__sizeof__", (PyCFunction) array_sizeof, diff --git a/numpy/core/src/multiarray/strfuncs.c b/numpy/core/src/multiarray/strfuncs.c index bb94eb9f305f..646d15cdbced 100644 --- a/numpy/core/src/multiarray/strfuncs.c +++ b/numpy/core/src/multiarray/strfuncs.c @@ -225,3 +225,35 @@ array_format(PyArrayObject *self, PyObject *args) ); } } + +#ifndef NPY_PY3K + +NPY_NO_EXPORT PyObject * +array_unicode(PyArrayObject *self) +{ + PyObject *uni; + + if (PyArray_NDIM(self) == 0) { + PyObject *item = PyArray_ToScalar(PyArray_DATA(self), self); + if (item == NULL){ + return NULL; + } + + /* defer to invoking `unicode` on the scalar */ + uni = PyObject_CallFunctionObjArgs( + (PyObject *)&PyUnicode_Type, item, NULL); + Py_DECREF(item); + } + else { + /* Do what unicode(self) would normally do */ + PyObject *str = PyObject_Str((PyObject *)self); + if (str == NULL){ + return NULL; + } + uni = PyUnicode_FromObject(str); + Py_DECREF(str); + } + return uni; +} + +#endif diff --git a/numpy/core/src/multiarray/strfuncs.h b/numpy/core/src/multiarray/strfuncs.h index 5dd661a20dc4..7e869d926da9 100644 --- a/numpy/core/src/multiarray/strfuncs.h +++ b/numpy/core/src/multiarray/strfuncs.h @@ -13,4 +13,9 @@ array_str(PyArrayObject *self); NPY_NO_EXPORT PyObject * array_format(PyArrayObject *self, PyObject *args); +#ifndef NPY_PY3K + NPY_NO_EXPORT PyObject * + array_unicode(PyArrayObject *self); +#endif + #endif diff --git a/numpy/core/tests/test_arrayprint.py b/numpy/core/tests/test_arrayprint.py index 6eef65292e52..02dda5151343 100644 --- a/numpy/core/tests/test_arrayprint.py +++ b/numpy/core/tests/test_arrayprint.py @@ -254,8 +254,10 @@ def test_formatter_reset(self): assert_equal(repr(x), "array([0., 1., 2.])") def test_0d_arrays(self): + unicode = type(u'') + assert_equal(unicode(np.array(u'café', np.unicode_)), u'café') + if sys.version_info[0] >= 3: - assert_equal(str(np.array('café', np.unicode_)), 'café') assert_equal(repr(np.array('café', np.unicode_)), "array('café',\n dtype='