diff options
Diffstat (limited to 'numpy')
-rw-r--r-- | numpy/core/src/multiarray/arraytypes.c.src | 8 | ||||
-rw-r--r-- | numpy/core/tests/test_api.py | 28 |
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) |