Skip to content

Commit

Permalink
DEP: Expire deprecation of dtype/signature allowing instances
Browse files Browse the repository at this point in the history
We never really allowed instances here and deprecated it since
NumPy 1.21 (it just failed completely in 1.21.0).
  • Loading branch information
seberg committed Nov 7, 2022
1 parent fcafb65 commit 4a7d70a
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 15 deletions.
23 changes: 8 additions & 15 deletions numpy/core/src/umath/ufunc_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -4361,23 +4361,16 @@ _get_dtype(PyObject *dtype_obj) {
}
else if (NPY_UNLIKELY(out->singleton != descr)) {
/* This does not warn about `metadata`, but units is important. */
if (!PyArray_EquivTypes(out->singleton, descr)) {
/* Deprecated NumPy 1.21.2 (was an accidental error in 1.21) */
if (DEPRECATE(
if (out->singleton == NULL
|| !PyArray_EquivTypes(out->singleton, descr)) {
PyErr_SetString(PyExc_TypeError,
"The `dtype` and `signature` arguments to "
"ufuncs only select the general DType and not details "
"such as the byte order or time unit (with rare "
"exceptions see release notes). To avoid this warning "
"please use the scalar types `np.float64`, or string "
"notation.\n"
"In rare cases where the time unit was preserved, "
"either cast the inputs or provide an output array. "
"In the future NumPy may transition to allow providing "
"`dtype=` to denote the outputs `dtype` as well. "
"(Deprecated NumPy 1.21)") < 0) {
Py_DECREF(descr);
return NULL;
}
"such as the byte order or time unit. "
"You can avoid this error by using the scalar types "
"`np.float64` or the dtype string notation.");
Py_DECREF(descr);
return NULL;
}
}
Py_INCREF(out);
Expand Down
29 changes: 29 additions & 0 deletions numpy/core/tests/test_ufunc.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import sys

import pytest
from pytest import param

import numpy as np
import numpy.core._umath_tests as umt
Expand Down Expand Up @@ -477,6 +478,34 @@ def test_signature_dtype_type(self):
float_dtype = type(np.dtype(np.float64))
np.add(3, 4, signature=(float_dtype, float_dtype, None))

@pytest.mark.parametrize("get_kwarg", [
lambda dt: dict(dtype=x),
lambda dt: dict(signature=(x, None, None))])
def test_signature_dtype_instances_allowed(self, get_kwarg):
# We allow certain dtype instances when there is a clear singleton
# and the given one is equivalent; mainly for backcompat.
int64 = np.dtype("int64")
int64_2 = pickle.loads(pickle.dumps(int64))
# Relies on pickling behavior, if assert fails just remove test...
assert int64 is not int64_2

assert np.add(1, 2, **get_kwarg(int64_2)).dtype == int64
td = np.timedelta(2, "s")
assert np.add(td, td, **get_kwarg("m8")).dtype == "m8[s]"

@pytest.mark.parametrize("get_kwarg", [
param(lambda x: dict(dtype=x), id="dtype"),
param(lambda x: dict(signature=(x, None, None)), id="signature")])
def test_signature_dtype_instances_allowed(self, get_kwarg):
msg = "The `dtype` and `signature` arguments to ufuncs"

with pytest.raises(TypeError, match=msg):
np.add(3, 5, **get_kwarg(np.dtype("int64").newbyteorder()))
with pytest.raises(TypeError, match=msg):
np.add(3, 5, **get_kwarg(np.dtype("m8[ns]")))
with pytest.raises(TypeError, match=msg):
np.add(3, 5, **get_kwarg("m8[ns]"))

@pytest.mark.parametrize("casting", ["unsafe", "same_kind", "safe"])
def test_partial_signature_mismatch(self, casting):
# If the second argument matches already, no need to specify it:
Expand Down

0 comments on commit 4a7d70a

Please sign in to comment.