diff options
author | Matti Picus <matti.picus@gmail.com> | 2020-08-28 23:44:54 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-08-28 23:44:54 +0300 |
commit | 53ea3a9dd802c13dc6930504d4a896bba8287cb0 (patch) | |
tree | 69fee9aa22001a638bc021ba53fc9d611940999f | |
parent | 4cd6e4b336fbc68d88c0e9bc45a435ce7b721f1f (diff) | |
parent | 9f29c08a5fcc097cd157be7be82f7114da60e23b (diff) | |
download | numpy-53ea3a9dd802c13dc6930504d4a896bba8287cb0.tar.gz |
Merge pull request #17161 from seberg/user_type_safe_casting
BUG: Remove Void special case for "safe casting"
-rw-r--r-- | numpy/core/src/multiarray/convert_datatype.c | 19 | ||||
-rw-r--r-- | numpy/core/tests/test_numeric.py | 25 |
2 files changed, 25 insertions, 19 deletions
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c index 1f5845eb7..d9121707b 100644 --- a/numpy/core/src/multiarray/convert_datatype.c +++ b/numpy/core/src/multiarray/convert_datatype.c @@ -343,25 +343,6 @@ PyArray_CanCastSafely(int fromtype, int totype) if (fromtype == totype) { return 1; } - /* Special-cases for some types */ - switch (fromtype) { - case NPY_DATETIME: - case NPY_TIMEDELTA: - case NPY_OBJECT: - case NPY_VOID: - return 0; - case NPY_BOOL: - return 1; - } - switch (totype) { - case NPY_BOOL: - case NPY_DATETIME: - case NPY_TIMEDELTA: - return 0; - case NPY_OBJECT: - case NPY_VOID: - return 1; - } from = PyArray_DescrFromType(fromtype); /* diff --git a/numpy/core/tests/test_numeric.py b/numpy/core/tests/test_numeric.py index badf48b33..0b27c54dd 100644 --- a/numpy/core/tests/test_numeric.py +++ b/numpy/core/tests/test_numeric.py @@ -14,6 +14,7 @@ from numpy.testing import ( assert_array_equal, assert_almost_equal, assert_array_almost_equal, assert_warns, assert_array_max_ulp, HAS_REFCOUNT ) +from numpy.core._rational_tests import rational from hypothesis import assume, given, strategies as st from hypothesis.extra import numpy as hynp @@ -863,6 +864,30 @@ class TestTypes: assert_equal(np.promote_types('<m8', '<m8'), np.dtype('m8')) assert_equal(np.promote_types('>m8', '>m8'), np.dtype('m8')) + def test_can_cast_and_promote_usertypes(self): + # The rational type defines safe casting for signed integers, + # boolean. Rational itself *does* cast safely to double. + # (rational does not actually cast to all signed integers, e.g. + # int64 can be both long and longlong and it registers only the first) + valid_types = ["int8", "int16", "int32", "int64", "bool"] + invalid_types = "BHILQP" + "FDG" + "mM" + "f" + "V" + + rational_dt = np.dtype(rational) + for numpy_dtype in valid_types: + numpy_dtype = np.dtype(numpy_dtype) + assert np.can_cast(numpy_dtype, rational_dt) + assert np.promote_types(numpy_dtype, rational_dt) is rational_dt + + for numpy_dtype in invalid_types: + numpy_dtype = np.dtype(numpy_dtype) + assert not np.can_cast(numpy_dtype, rational_dt) + with pytest.raises(TypeError): + np.promote_types(numpy_dtype, rational_dt) + + double_dt = np.dtype("double") + assert np.can_cast(rational_dt, double_dt) + assert np.promote_types(double_dt, rational_dt) is double_dt + def test_promote_types_strings(self): assert_equal(np.promote_types('bool', 'S'), np.dtype('S5')) assert_equal(np.promote_types('b', 'S'), np.dtype('S4')) |