summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatti Picus <matti.picus@gmail.com>2020-08-28 23:44:54 +0300
committerGitHub <noreply@github.com>2020-08-28 23:44:54 +0300
commit53ea3a9dd802c13dc6930504d4a896bba8287cb0 (patch)
tree69fee9aa22001a638bc021ba53fc9d611940999f
parent4cd6e4b336fbc68d88c0e9bc45a435ce7b721f1f (diff)
parent9f29c08a5fcc097cd157be7be82f7114da60e23b (diff)
downloadnumpy-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.c19
-rw-r--r--numpy/core/tests/test_numeric.py25
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'))