summaryrefslogtreecommitdiff
path: root/numpy
diff options
context:
space:
mode:
Diffstat (limited to 'numpy')
-rw-r--r--numpy/core/src/multiarray/arraytypes.c.src8
-rw-r--r--numpy/core/tests/test_api.py28
2 files changed, 36 insertions, 0 deletions
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index 5e07f0df4..024dcab8c 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -1489,6 +1489,7 @@ OBJECT_to_@TOTYPE@(void *input, void *output, npy_intp n,
*
* #from = STRING*23, UNICODE*23, VOID*23#
* #fromtyp = npy_char*69#
+ * #is_string_to_bool = 1, 0*22, 1, 0*22, 0*23#
* #to = (BOOL,
* BYTE, UBYTE, SHORT, USHORT, INT, UINT,
* LONG, ULONG, LONGLONG, ULONGLONG,
@@ -1525,6 +1526,13 @@ static void
if (temp == NULL) {
return;
}
+#if @is_string_to_bool@
+ /* Legacy behaviour converts strings to integers before going to bool */
+ Py_SETREF(temp, PyNumber_Long(temp));
+ if (temp == NULL) {
+ return;
+ }
+#endif
if (@to@_setitem(temp, op, aop)) {
Py_DECREF(temp);
return;
diff --git a/numpy/core/tests/test_api.py b/numpy/core/tests/test_api.py
index 71b46e551..b3f7cc88a 100644
--- a/numpy/core/tests/test_api.py
+++ b/numpy/core/tests/test_api.py
@@ -278,6 +278,34 @@ def test_array_astype_warning(t):
a = np.array(10, dtype=np.complex_)
assert_warns(np.ComplexWarning, a.astype, t)
+@pytest.mark.parametrize(["dtype", "out_dtype"],
+ [(np.bytes_, np.bool_),
+ (np.unicode, np.bool_),
+ (np.dtype("S10,S9"), np.dtype("?,?"))])
+def test_string_to_boolean_cast(dtype, out_dtype):
+ """
+ Currently, for `astype` strings are cast to booleans effectively by
+ calling `bool(int(string)`. This is not consistent (see gh-9875) and
+ will eventually be deprecated.
+ """
+ arr = np.array(["10", "10\0\0\0", "0\0\0", "0"], dtype=dtype)
+ expected = np.array([True, True, False, False], dtype=out_dtype)
+ assert_array_equal(arr.astype(out_dtype), expected)
+
+@pytest.mark.parametrize(["dtype", "out_dtype"],
+ [(np.bytes_, np.bool_),
+ (np.unicode, np.bool_),
+ (np.dtype("S10,S9"), np.dtype("?,?"))])
+def test_string_to_boolean_cast_errors(dtype, out_dtype):
+ """
+ These currently error out, since cast to integers fails, but should not
+ error out in the future.
+ """
+ for invalid in ["False", "True", "", "\0", "non-empty"]:
+ arr = np.array([invalid], dtype=dtype)
+ with assert_raises(ValueError):
+ arr.astype(out_dtype)
+
def test_copyto_fromscalar():
a = np.arange(6, dtype='f4').reshape(2, 3)