summaryrefslogtreecommitdiff
path: root/numpy/core
diff options
context:
space:
mode:
Diffstat (limited to 'numpy/core')
-rw-r--r--numpy/core/setup.py4
-rw-r--r--numpy/core/src/multiarray/convert_datatype.c23
-rw-r--r--numpy/core/tests/test_casting_unittests.py17
3 files changed, 30 insertions, 14 deletions
diff --git a/numpy/core/setup.py b/numpy/core/setup.py
index 08510fcc8..2b7566c0a 100644
--- a/numpy/core/setup.py
+++ b/numpy/core/setup.py
@@ -24,9 +24,9 @@ NPY_RELAXED_STRIDES_DEBUG = (os.environ.get('NPY_RELAXED_STRIDES_DEBUG', "0") !=
NPY_RELAXED_STRIDES_DEBUG = NPY_RELAXED_STRIDES_DEBUG and NPY_RELAXED_STRIDES_CHECKING
# Set to True to use the new casting implementation as much as implemented.
-# Allows running the full test suit to excercise the new machinery until
+# Allows running the full test suit to exercise the new machinery until
# it is used as default and the old version is eventually deleted.
-NPY_USE_NEW_CASTINGIMPL = os.environ.get('NPY_USE_NEW_CASTINGIMPL', "0") != 0
+NPY_USE_NEW_CASTINGIMPL = os.environ.get('NPY_USE_NEW_CASTINGIMPL', "1") != "0"
# XXX: ugly, we use a class to avoid calling twice some expensive functions in
# config.h/numpyconfig.h. I don't see a better way because distutils force
diff --git a/numpy/core/src/multiarray/convert_datatype.c b/numpy/core/src/multiarray/convert_datatype.c
index a9e9051af..4758302cf 100644
--- a/numpy/core/src/multiarray/convert_datatype.c
+++ b/numpy/core/src/multiarray/convert_datatype.c
@@ -420,12 +420,12 @@ PyArray_CanCastSafely(int fromtype, int totype)
#if NPY_USE_NEW_CASTINGIMPL
PyArray_DTypeMeta *from = PyArray_DTypeFromTypeNum(fromtype);
if (from == NULL) {
- PyErr_WriteUnraisable(Py_None);
+ PyErr_WriteUnraisable(NULL);
return 0;
}
PyArray_DTypeMeta *to = PyArray_DTypeFromTypeNum(totype);
if (to == NULL) {
- PyErr_WriteUnraisable(Py_None);
+ PyErr_WriteUnraisable(NULL);
return 0;
}
PyObject *castingimpl = PyArray_GetCastingImpl(from, to);
@@ -433,7 +433,7 @@ PyArray_CanCastSafely(int fromtype, int totype)
Py_DECREF(to);
if (castingimpl == NULL) {
- PyErr_WriteUnraisable(Py_None);
+ PyErr_WriteUnraisable(NULL);
return 0;
}
else if (castingimpl == Py_None) {
@@ -2489,9 +2489,9 @@ structured_to_nonstructured_resolve_descriptors(
if (given_descrs[1] == NULL) {
loop_descrs[1] = dtypes[1]->default_descr(dtypes[1]);
/*
- * Special case strings here, this is probably unnecessary and
- * should be useless (i.e. it is necessary to use empty arrays to
- * trigger this path.).
+ * Special case strings here, it should be useless (and only actually
+ * work for empty arrays). Possibly this should simply raise for
+ * all parametric DTypes.
*/
if (dtypes[1]->type_num == NPY_STRING) {
loop_descrs[1]->elsize = given_descrs[0]->elsize;
@@ -2744,7 +2744,7 @@ object_to_any_resolve_descriptors(
* here is that e.g. "M8" input is considered to be the DType class,
* and by allowing it here, we go back to the "M8" instance.
*/
- if (dtypes[1]->parametric && !dtypes[1]->legacy) {
+ if (dtypes[1]->parametric) {
PyErr_Format(PyExc_TypeError,
"casting from object to the parametric DType %S requires "
"the specified output dtype instance. "
@@ -2756,11 +2756,6 @@ object_to_any_resolve_descriptors(
if (loop_descrs[1] == NULL) {
return -1;
}
- if (dtypes[1]->type_num == NPY_VOID) {
- /* NOTE: This appears to be behaviour as of 1.19 (void is not
- * adjusted) */
- loop_descrs[1]->elsize = sizeof(PyObject *);
- }
}
else {
Py_INCREF(given_descrs[1]);
@@ -2791,6 +2786,8 @@ PyArray_GetObjectToGenericCastingImpl()
return PyErr_NoMemory();
}
+ method->nin = 1;
+ method->nout = 1;
method->name = "object_to_any_cast";
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
method->casting = NPY_UNSAFE_CASTING;
@@ -2845,6 +2842,8 @@ PyArray_GetGenericToObjectCastingImpl()
return PyErr_NoMemory();
}
+ method->nin = 1;
+ method->nout = 1;
method->name = "any_to_object_cast";
method->flags = NPY_METH_SUPPORTS_UNALIGNED | NPY_METH_REQUIRES_PYAPI;
method->casting = NPY_SAFE_CASTING;
diff --git a/numpy/core/tests/test_casting_unittests.py b/numpy/core/tests/test_casting_unittests.py
index 2f82d718b..fec0ae7c7 100644
--- a/numpy/core/tests/test_casting_unittests.py
+++ b/numpy/core/tests/test_casting_unittests.py
@@ -282,3 +282,20 @@ class TestCasting:
assert safety == expected_safety
elif change_length > 0:
assert safety == Casting.safe
+
+ def test_void_to_string_special_case(self):
+ # Cover a small special case in void to string casting that could
+ # probably just as well be turned into an error (compare
+ # `test_object_to_parametric_internal_error` below).
+ assert np.array([], dtype="V5").astype("S").dtype.itemsize == 5
+ assert np.array([], dtype="V5").astype("U").dtype.itemsize == 4 * 5
+
+ def test_object_to_parametric_internal_error(self):
+ # We reject casting from object to a parametric type, without
+ # figuring out the correct instance first.
+ object_dtype = type(np.dtype(object))
+ other_dtype = type(np.dtype(str))
+ cast = get_castingimpl(object_dtype, other_dtype)
+ with pytest.raises(TypeError,
+ match="casting from object to the parametric DType"):
+ cast._resolve_descriptors((np.dtype("O"), None))