diff --git a/doc/release/upcoming_changes/15773.compatibility.rst b/doc/release/upcoming_changes/15773.compatibility.rst new file mode 100644 index 000000000000..bc9d47153579 --- /dev/null +++ b/doc/release/upcoming_changes/15773.compatibility.rst @@ -0,0 +1,10 @@ +``issubdtype`` no longer interprets ``float`` as ``np.floating`` +---------------------------------------------------------------- + +`numpy.issubdtype` had a FutureWarning since NumPy 1.14 which +has expired now. This means that certain input where the second +argument was neither a datatype nor a NumPy scalar type +(such as a string or a python type like ``int`` or ``float``) +will now be consistent with passing in ``np.dtype(arg2).type``. +This makes the result consistent with expectations and leads to +a false result in some cases which previously returned true. diff --git a/numpy/core/numerictypes.py b/numpy/core/numerictypes.py index 215da110da8b..9d7bbde931dd 100644 --- a/numpy/core/numerictypes.py +++ b/numpy/core/numerictypes.py @@ -388,35 +388,7 @@ def issubdtype(arg1, arg2): if not issubclass_(arg1, generic): arg1 = dtype(arg1).type if not issubclass_(arg2, generic): - arg2_orig = arg2 arg2 = dtype(arg2).type - if not isinstance(arg2_orig, dtype): - # weird deprecated behaviour, that tried to infer np.floating from - # float, and similar less obvious things, such as np.generic from - # str. - mro = arg2.mro() - arg2 = mro[1] if len(mro) > 1 else mro[0] - - def type_repr(x): - """ Helper to produce clear error messages """ - if not isinstance(x, type): - return repr(x) - elif issubclass(x, generic): - return "np.{}".format(x.__name__) - else: - return x.__name__ - - # 1.14, 2017-08-01 - warnings.warn( - "Conversion of the second argument of issubdtype from `{raw}` " - "to `{abstract}` is deprecated. In future, it will be treated " - "as `{concrete} == np.dtype({raw}).type`.".format( - raw=type_repr(arg2_orig), - abstract=type_repr(arg2), - concrete=type_repr(dtype(arg2_orig).type) - ), - FutureWarning, stacklevel=2 - ) return issubclass(arg1, arg2) diff --git a/numpy/core/tests/test_numerictypes.py b/numpy/core/tests/test_numerictypes.py index c72d13947671..2bc1b8979d66 100644 --- a/numpy/core/tests/test_numerictypes.py +++ b/numpy/core/tests/test_numerictypes.py @@ -401,6 +401,35 @@ def test_sibling_class(self): assert_(not np.issubdtype(w1(np.float32), w2(np.float64))) assert_(not np.issubdtype(w1(np.float64), w2(np.float32))) + def test_nondtype_nonscalartype(self): + # See gh-14619 and gh-9505 which introduced the deprecation to fix + # this. These tests are directly taken from gh-9505 + assert not np.issubdtype(np.float32, 'float64') + assert not np.issubdtype(np.float32, 'f8') + assert not np.issubdtype(np.int32, str) + assert not np.issubdtype(np.int32, 'int64') + assert not np.issubdtype(np.str_, 'void') + # for the following the correct spellings are + # np.integer, np.floating, or np.complexfloating respectively: + assert not np.issubdtype(np.int8, int) # np.int8 is never np.int_ + assert not np.issubdtype(np.float32, float) + assert not np.issubdtype(np.complex64, complex) + assert not np.issubdtype(np.float32, "float") + assert not np.issubdtype(np.float64, "f") + + # Test the same for the correct first datatype and abstract one + # in the case of int, float, complex: + assert np.issubdtype(np.float64, 'float64') + assert np.issubdtype(np.float64, 'f8') + assert np.issubdtype(np.str_, str) + assert np.issubdtype(np.int64, 'int64') + assert np.issubdtype(np.void, 'void') + assert np.issubdtype(np.int8, np.integer) + assert np.issubdtype(np.float32, np.floating) + assert np.issubdtype(np.complex64, np.complexfloating) + assert np.issubdtype(np.float64, "float") + assert np.issubdtype(np.float32, "f") + class TestSctypeDict: def test_longdouble(self):