summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
authorSebastian Berg <sebastian@sipsolutions.net>2020-03-16 18:32:19 -0500
committerSebastian Berg <sebastian@sipsolutions.net>2020-03-16 18:41:29 -0500
commit769c68b037972200da70cd3846992b47798466eb (patch)
treee6036d429a1e333e09d6b55e9d41715d16e3ba5c /numpy
parentff4cfe7ecd46ee15fd88297964f6a5cb5423c291 (diff)
downloadnumpy-769c68b037972200da70cd3846992b47798466eb.tar.gz
BUG,MAINT: Remove incorrect special case in string to number casts
The string to number casts fall back to using the scalars and the type setitem function to do the cast. However, before calling setitem, they sometimes already called the Python function for string coercion. This is unnecessary. Closes gh-15608
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src63
-rw-r--r--numpy/core/tests/test_longdouble.py34
2 files changed, 24 insertions, 73 deletions
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index c16e0f311..5e07f0df4 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -1506,70 +1506,8 @@ OBJECT_to_@TOTYPE@(void *input, void *output, npy_intp n,
* #oskip = 1*18,(PyArray_DESCR(aop)->elsize)*3,1*2,
* 1*18,(PyArray_DESCR(aop)->elsize)*3,1*2,
* 1*18,(PyArray_DESCR(aop)->elsize)*3,1*2#
- * #convert = 1*18, 0*3, 1*2,
- * 1*18, 0*3, 1*2,
- * 0*23#
- * #convstr = (Long*9, Long*2, Float*4, Complex*3, Tuple*3, Long*2)*3#
*/
-#if @convert@
-
-#define IS_@from@
-
-static void
-@from@_to_@to@(void *input, void *output, npy_intp n,
- void *vaip, void *aop)
-{
- @fromtyp@ *ip = input;
- @totyp@ *op = output;
- PyArrayObject *aip = vaip;
-
- npy_intp i;
- int skip = PyArray_DESCR(aip)->elsize;
- int oskip = @oskip@;
-
- for (i = 0; i < n; i++, ip+=skip, op+=oskip) {
- PyObject *new;
- PyObject *temp = PyArray_Scalar(ip, PyArray_DESCR(aip), (PyObject *)aip);
- if (temp == NULL) {
- return;
- }
-
-#if defined(IS_STRING)
- /* Work around some Python 3K */
- new = PyUnicode_FromEncodedObject(temp, "ascii", "strict");
- Py_DECREF(temp);
- temp = new;
- if (temp == NULL) {
- return;
- }
-#endif
- /* convert from Python object to needed one */
- {
- PyObject *args;
-
- /* call out to the Python builtin given by convstr */
- args = Py_BuildValue("(N)", temp);
- new = Py@convstr@_Type.tp_new(&Py@convstr@_Type, args, NULL);
- Py_DECREF(args);
- temp = new;
- if (temp == NULL) {
- return;
- }
- }
-
- if (@to@_setitem(temp, op, aop)) {
- Py_DECREF(temp);
- return;
- }
- Py_DECREF(temp);
- }
-}
-
-#undef IS_@from@
-
-#else
-
static void
@from@_to_@to@(void *input, void *output, npy_intp n,
void *vaip, void *aop)
@@ -1595,7 +1533,6 @@ static void
}
}
-#endif
/**end repeat**/
diff --git a/numpy/core/tests/test_longdouble.py b/numpy/core/tests/test_longdouble.py
index bf12f0e1b..acef995f3 100644
--- a/numpy/core/tests/test_longdouble.py
+++ b/numpy/core/tests/test_longdouble.py
@@ -37,22 +37,36 @@ def test_repr_roundtrip():
assert_equal(np.longdouble(repr(o)), o, "repr was %s" % repr(o))
-def test_unicode():
- np.longdouble(u"1.2")
+@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l")
+def test_repr_roundtrip_bytes():
+ o = 1 + LD_INFO.eps
+ assert_equal(np.longdouble(repr(o).encode("ascii")), o)
-def test_string():
- np.longdouble("1.2")
+@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l")
+@pytest.mark.parametrize("strtype", (np.str_, np.bytes_, str, bytes))
+def test_array_and_stringlike_roundtrip(strtype):
+ """
+ Test that string representations of long-double roundtrip both
+ for array casting and scalar coercion, see also gh-15608.
+ """
+ o = 1 + LD_INFO.eps
+ if strtype in (np.bytes_, bytes):
+ o_str = strtype(repr(o).encode("ascii"))
+ else:
+ o_str = strtype(repr(o))
-def test_bytes():
- np.longdouble(b"1.2")
+ # Test that `o` is correctly coerced from the string-like
+ assert o == np.longdouble(o_str)
+ # Test that arrays also roundtrip correctly:
+ o_strarr = np.asarray([o] * 3, dtype=strtype)
+ assert (o == o_strarr.astype(np.longdouble)).all()
-@pytest.mark.skipif(string_to_longdouble_inaccurate, reason="Need strtold_l")
-def test_repr_roundtrip_bytes():
- o = 1 + LD_INFO.eps
- assert_equal(np.longdouble(repr(o).encode("ascii")), o)
+ # And array coercion and casting to string give the same as scalar repr:
+ assert (o_strarr == o_str).all()
+ assert (np.asarray([o] * 3).astype(strtype) == o_str).all()
def test_bogus_string():