summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Wieser <wieser.eric@gmail.com>2017-09-26 23:45:15 -0700
committerEric Wieser <wieser.eric@gmail.com>2017-11-12 11:38:35 -0800
commitdf0fff45adbd3f291632b23c0cbd256bbbe912bb (patch)
tree120f4082267ac217783f8453cb97dd6f335a62dc
parenta4e47e0205b78eb96248e71918c2558e25a9d3c7 (diff)
downloadnumpy-df0fff45adbd3f291632b23c0cbd256bbbe912bb.tar.gz
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
-rw-r--r--numpy/core/src/multiarray/methods.c6
-rw-r--r--numpy/core/src/multiarray/strfuncs.c32
-rw-r--r--numpy/core/src/multiarray/strfuncs.h5
-rw-r--r--numpy/core/tests/test_arrayprint.py4
-rw-r--r--numpy/ma/core.py8
-rw-r--r--numpy/ma/tests/test_core.py10
6 files changed, 64 insertions, 1 deletions
diff --git a/numpy/core/src/multiarray/methods.c b/numpy/core/src/multiarray/methods.c
index 572352304..3f461b375 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 bb94eb9f3..646d15cdb 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 5dd661a20..7e869d926 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 6eef65292..02dda5151 100644
--- a/numpy/core/tests/test_arrayprint.py
+++ b/numpy/core/tests/test_arrayprint.py
@@ -254,8 +254,10 @@ class TestPrintOptions(object):
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='<U4')")
else:
diff --git a/numpy/ma/core.py b/numpy/ma/core.py
index b71e8fa06..0d02bb315 100644
--- a/numpy/ma/core.py
+++ b/numpy/ma/core.py
@@ -3867,6 +3867,10 @@ class MaskedArray(ndarray):
def __str__(self):
return str(self._insert_masked_print())
+ if sys.version_info.major < 3:
+ def __unicode__(self):
+ return unicode(self._insert_masked_print())
+
def __repr__(self):
"""
Literal string representation.
@@ -6238,6 +6242,10 @@ class MaskedConstant(MaskedArray):
def __str__(self):
return str(masked_print_option._display)
+ if sys.version_info.major < 3:
+ def __unicode__(self):
+ return unicode(masked_print_option._display)
+
def __repr__(self):
if self is MaskedConstant.__singleton:
return 'masked'
diff --git a/numpy/ma/tests/test_core.py b/numpy/ma/tests/test_core.py
index fd8d629f9..03de71f81 100644
--- a/numpy/ma/tests/test_core.py
+++ b/numpy/ma/tests/test_core.py
@@ -500,6 +500,16 @@ class TestMaskedArray(object):
' fill_value = 999999)\n'
)
+ def test_0d_unicode(self):
+ u = u'caf\xe9'
+ utype = type(u)
+
+ arr_nomask = np.ma.array(u)
+ arr_masked = np.ma.array(u, mask=True)
+
+ assert_equal(utype(arr_nomask), u)
+ assert_equal(utype(arr_masked), u'--')
+
def test_pickling(self):
# Tests pickling
for dtype in (int, float, str, object):