From dc0376454cc35c5fd0961536917dd28fe4822e1a Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 13 Apr 2023 07:20:24 -0700 Subject: [PATCH 1/5] DEPR: is_datetime64_any_dtype --- doc/source/whatsnew/v2.1.0.rst | 1 + pandas/conftest.py | 1 + pandas/core/arrays/datetimelike.py | 12 +++++------- pandas/core/arrays/datetimes.py | 5 +++-- pandas/core/arrays/period.py | 8 +++++--- pandas/core/arrays/sparse/array.py | 3 +-- pandas/core/dtypes/common.py | 6 ++++++ pandas/core/generic.py | 5 ++--- pandas/core/methods/describe.py | 4 ++-- pandas/tests/dtypes/test_common.py | 25 ++++++++++++++----------- pandas/tests/dtypes/test_dtypes.py | 8 ++++++-- pandas/tests/dtypes/test_inference.py | 15 ++++++++++----- pandas/tests/scalar/test_nat.py | 4 +--- 13 files changed, 57 insertions(+), 40 deletions(-) diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index 9b5cba1e1ee05..95e8e6a4769b4 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -228,6 +228,7 @@ Deprecations - Deprecated making :meth:`Series.apply` return a :class:`DataFrame` when the passed-in callable returns a :class:`Series` object. In the future this will return a :class:`Series` whose values are themselves :class:`Series`. This pattern was very slow and it's recommended to use alternative methods to archive the same goal (:issue:`52116`) - Deprecated parameter ``convert_type`` in :meth:`Series.apply` (:issue:`52140`) - Deprecated ``freq`` parameter in :class:`PeriodArray` constructor, pass ``dtype`` instead (:issue:`52462`) +- Deprecated :func:`is_datetime64_any_dtype`, check for specific dtypes of interest instead (:issue:`??`) - Deprecated :func:`is_categorical_dtype`, use ``isinstance(obj.dtype, pd.CategoricalDtype)`` instead (:issue:`52527`) - Deprecated :func:`is_int64_dtype`, check ``dtype == np.dtype(np.int64)`` instead (:issue:`52564`) - Deprecated :func:`is_interval_dtype`, check ``isinstance(dtype, pd.IntervalDtype)`` instead (:issue:`52607`) diff --git a/pandas/conftest.py b/pandas/conftest.py index 7773d8de37705..bbd1e2a96c691 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -136,6 +136,7 @@ def pytest_collection_modifyitems(items, config) -> None: # Each entry specifies (path, message) - see the ignore_doctest_warning function ignored_doctest_warnings = [ ("is_int64_dtype", "is_int64_dtype is deprecated"), + ("is_datetime64_any_dtype", "is_datetime64_any_dtype is deprecated"), ("is_interval_dtype", "is_interval_dtype is deprecated"), ("is_datetime64tz_dtype", "is_datetime64tz_dtype is deprecated"), # Docstring divides by zero to show behavior difference diff --git a/pandas/core/arrays/datetimelike.py b/pandas/core/arrays/datetimelike.py index 658ffb4669c3c..d5ef1314b23e7 100644 --- a/pandas/core/arrays/datetimelike.py +++ b/pandas/core/arrays/datetimelike.py @@ -83,7 +83,6 @@ from pandas.core.dtypes.common import ( is_all_strings, - is_datetime64_any_dtype, is_datetime_or_timedelta_dtype, is_dtype_equal, is_float_dtype, @@ -1395,8 +1394,11 @@ def __sub__(self, other): def __rsub__(self, other): other_dtype = getattr(other, "dtype", None) + other_is_dt64 = lib.is_np_dtype(other_dtype, "M") or isinstance( + other_dtype, DatetimeTZDtype + ) - if is_datetime64_any_dtype(other_dtype) and lib.is_np_dtype(self.dtype, "m"): + if other_is_dt64 and lib.is_np_dtype(self.dtype, "m"): # ndarray[datetime64] cannot be subtracted from self, so # we need to wrap in DatetimeArray/Index and flip the operation if lib.is_scalar(other): @@ -1408,11 +1410,7 @@ def __rsub__(self, other): other = DatetimeArray(other) return other - self - elif ( - is_datetime64_any_dtype(self.dtype) - and hasattr(other, "dtype") - and not is_datetime64_any_dtype(other.dtype) - ): + elif self.dtype.kind == "M" and hasattr(other, "dtype") and not other_is_dt64: # GH#19959 datetime - datetime is well-defined as timedelta, # but any other type - datetime is not well-defined. raise TypeError( diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 12245a144ec2a..64fa9ec0080e5 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -50,7 +50,6 @@ DT64NS_DTYPE, INT64_DTYPE, is_bool_dtype, - is_datetime64_any_dtype, is_datetime64_dtype, is_dtype_equal, is_float_dtype, @@ -193,7 +192,9 @@ class DatetimeArray(dtl.TimelikeOps, dtl.DatelikeOps): # type: ignore[misc] _typ = "datetimearray" _internal_fill_value = np.datetime64("NaT", "ns") _recognized_scalars = (datetime, np.datetime64) - _is_recognized_dtype = is_datetime64_any_dtype + _is_recognized_dtype = lambda x: lib.is_np_dtype(x, "M") or isinstance( + x, DatetimeTZDtype + ) _infer_matches = ("datetime", "datetime64", "date") @property diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 89d02f7c1d444..4e2aa23e03a4f 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -55,7 +55,6 @@ from pandas.core.dtypes.common import ( ensure_object, - is_datetime64_any_dtype, is_datetime64_dtype, is_dtype_equal, is_float_dtype, @@ -63,7 +62,10 @@ is_period_dtype, pandas_dtype, ) -from pandas.core.dtypes.dtypes import PeriodDtype +from pandas.core.dtypes.dtypes import ( + DatetimeTZDtype, + PeriodDtype, +) from pandas.core.dtypes.generic import ( ABCIndex, ABCPeriodIndex, @@ -658,7 +660,7 @@ def astype(self, dtype, copy: bool = True): if isinstance(dtype, PeriodDtype): return self.asfreq(dtype.freq) - if is_datetime64_any_dtype(dtype): + if lib.is_np_dtype(dtype, "M") or isinstance(dtype, DatetimeTZDtype): # GH#45038 match PeriodIndex behavior. tz = getattr(dtype, "tz", None) return self.to_timestamp().tz_localize(tz) diff --git a/pandas/core/arrays/sparse/array.py b/pandas/core/arrays/sparse/array.py index f78486fa7d84f..18a1fc248f7b5 100644 --- a/pandas/core/arrays/sparse/array.py +++ b/pandas/core/arrays/sparse/array.py @@ -44,7 +44,6 @@ from pandas.core.dtypes.common import ( is_array_like, is_bool_dtype, - is_datetime64_any_dtype, is_dtype_equal, is_integer, is_list_like, @@ -559,7 +558,7 @@ def __array__(self, dtype: NpDtype | None = None) -> np.ndarray: # Can NumPy represent this type? # If not, `np.result_type` will raise. We catch that # and return object. - if is_datetime64_any_dtype(self.sp_values.dtype): + if self.sp_values.dtype.kind == "M": # However, we *do* special-case the common case of # a datetime64 with pandas NaT. if fill_value is NaT: diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 183fd5b2652b6..af4269bb920c5 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -862,6 +862,12 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: >>> is_datetime64_any_dtype(pd.DatetimeIndex([1, 2, 3], dtype="datetime64[ns]")) True """ + warnings.warn( + "is_datetime64_any_dtype is deprecated and will be removed in a future " + "version. Check for specific dtypes of interest instead.", + FutureWarning, + stacklevel=find_stack_level(), + ) if isinstance(arr_or_dtype, (np.dtype, ExtensionDtype)): # GH#33400 fastpath for dtype object return arr_or_dtype.kind == "M" diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 800aaf47e1631..3342c9d4ebc01 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -110,7 +110,6 @@ ensure_str, is_bool, is_bool_dtype, - is_datetime64_any_dtype, is_dict_like, is_dtype_equal, is_extension_array_dtype, @@ -7754,8 +7753,8 @@ def interpolate( methods = {"index", "values", "nearest", "time"} is_numeric_or_datetime = ( is_numeric_dtype(index.dtype) - or is_datetime64_any_dtype(index.dtype) - or lib.is_np_dtype(index.dtype, "m") + or isinstance(index.dtype, DatetimeTZDtype) + or lib.is_np_dtype(index.dtype, "mM") ) if method not in methods and not is_numeric_or_datetime: raise ValueError( diff --git a/pandas/core/methods/describe.py b/pandas/core/methods/describe.py index 2fcb0de6b5451..60a0fbe0537c7 100644 --- a/pandas/core/methods/describe.py +++ b/pandas/core/methods/describe.py @@ -31,10 +31,10 @@ from pandas.core.dtypes.common import ( is_bool_dtype, is_complex_dtype, - is_datetime64_any_dtype, is_extension_array_dtype, is_numeric_dtype, ) +from pandas.core.dtypes.dtypes import DatetimeTZDtype from pandas.core.arrays.arrow.dtype import ArrowDtype from pandas.core.arrays.floating import Float64Dtype @@ -361,7 +361,7 @@ def select_describe_func( return describe_categorical_1d elif is_numeric_dtype(data): return describe_numeric_1d - elif is_datetime64_any_dtype(data.dtype): + elif lib.is_np_dtype(data.dtype, "M") or isinstance(data.dtype, DatetimeTZDtype): return describe_timestamp_1d elif lib.is_np_dtype(data.dtype, "m"): return describe_numeric_1d diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 2c7651e0489d8..9f19798960f16 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -175,6 +175,7 @@ def test_get_dtype_error_catch(func): if ( func is com.is_int64_dtype or func is com.is_interval_dtype + or func is com.is_datetime64_any_dtype or func is com.is_datetime64tz_dtype or func is com.is_categorical_dtype ): @@ -471,17 +472,19 @@ def test_is_not_int64_dtype(dtype): def test_is_datetime64_any_dtype(): - assert not com.is_datetime64_any_dtype(int) - assert not com.is_datetime64_any_dtype(str) - assert not com.is_datetime64_any_dtype(np.array([1, 2])) - assert not com.is_datetime64_any_dtype(np.array(["a", "b"])) - - assert com.is_datetime64_any_dtype(np.datetime64) - assert com.is_datetime64_any_dtype(np.array([], dtype=np.datetime64)) - assert com.is_datetime64_any_dtype(DatetimeTZDtype("ns", "US/Eastern")) - assert com.is_datetime64_any_dtype( - pd.DatetimeIndex([1, 2, 3], dtype="datetime64[ns]") - ) + msg = "is_datetime64_any_dtype is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + assert not com.is_datetime64_any_dtype(int) + assert not com.is_datetime64_any_dtype(str) + assert not com.is_datetime64_any_dtype(np.array([1, 2])) + assert not com.is_datetime64_any_dtype(np.array(["a", "b"])) + + assert com.is_datetime64_any_dtype(np.datetime64) + assert com.is_datetime64_any_dtype(np.array([], dtype=np.datetime64)) + assert com.is_datetime64_any_dtype(DatetimeTZDtype("ns", "US/Eastern")) + assert com.is_datetime64_any_dtype( + pd.DatetimeIndex([1, 2, 3], dtype="datetime64[ns]") + ) def test_is_datetime64_ns_dtype(): diff --git a/pandas/tests/dtypes/test_dtypes.py b/pandas/tests/dtypes/test_dtypes.py index 09e100c660ddf..836ead45e1ed2 100644 --- a/pandas/tests/dtypes/test_dtypes.py +++ b/pandas/tests/dtypes/test_dtypes.py @@ -294,8 +294,11 @@ def test_compat(self, dtype): with tm.assert_produces_warning(FutureWarning, match=msg): assert is_datetime64tz_dtype(dtype) assert is_datetime64tz_dtype("datetime64[ns, US/Eastern]") - assert is_datetime64_any_dtype(dtype) - assert is_datetime64_any_dtype("datetime64[ns, US/Eastern]") + + msg = "is_datetime64_any_dtype is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + assert is_datetime64_any_dtype(dtype) + assert is_datetime64_any_dtype("datetime64[ns, US/Eastern]") assert is_datetime64_ns_dtype(dtype) assert is_datetime64_ns_dtype("datetime64[ns, US/Eastern]") assert not is_datetime64_dtype(dtype) @@ -1130,6 +1133,7 @@ def test_is_dtype_no_warning(check): if ( check is is_categorical_dtype or check is is_interval_dtype + or check is is_datetime64_any_dtype or check is is_datetime64tz_dtype ): warn = FutureWarning diff --git a/pandas/tests/dtypes/test_inference.py b/pandas/tests/dtypes/test_inference.py index 9358b44c243bc..b5319a88f80ed 100644 --- a/pandas/tests/dtypes/test_inference.py +++ b/pandas/tests/dtypes/test_inference.py @@ -1822,6 +1822,7 @@ def test_is_datetime_dtypes(self): tsa = pd.date_range("20130101", periods=3, tz="US/Eastern") msg = "is_datetime64tz_dtype is deprecated" + msg_any = "is_datetime64_any_dtype is deprecated" assert is_datetime64_dtype("datetime64") assert is_datetime64_dtype("datetime64[ns]") @@ -1833,10 +1834,11 @@ def test_is_datetime_dtypes(self): assert is_datetime64_ns_dtype(ts) assert is_datetime64_ns_dtype(tsa) - assert is_datetime64_any_dtype("datetime64") - assert is_datetime64_any_dtype("datetime64[ns]") - assert is_datetime64_any_dtype(ts) - assert is_datetime64_any_dtype(tsa) + with tm.assert_produces_warning(FutureWarning, match=msg_any): + assert is_datetime64_any_dtype("datetime64") + assert is_datetime64_any_dtype("datetime64[ns]") + assert is_datetime64_any_dtype(ts) + assert is_datetime64_any_dtype(tsa) with tm.assert_produces_warning(FutureWarning, match=msg): assert not is_datetime64tz_dtype("datetime64") @@ -1853,7 +1855,10 @@ def test_is_datetime_dtypes_with_tz(self, tz): with tm.assert_produces_warning(FutureWarning, match=msg): assert is_datetime64tz_dtype(dtype) assert is_datetime64_ns_dtype(dtype) - assert is_datetime64_any_dtype(dtype) + + msg_any = "is_datetime64_any_dtype is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg_any): + assert is_datetime64_any_dtype(dtype) def test_is_timedelta(self): assert is_timedelta64_dtype("timedelta64") diff --git a/pandas/tests/scalar/test_nat.py b/pandas/tests/scalar/test_nat.py index c13ea4eeb9e0d..0d85e37873a52 100644 --- a/pandas/tests/scalar/test_nat.py +++ b/pandas/tests/scalar/test_nat.py @@ -11,8 +11,6 @@ from pandas._libs.tslibs import iNaT from pandas.compat import is_numpy_dev -from pandas.core.dtypes.common import is_datetime64_any_dtype - from pandas import ( DatetimeIndex, DatetimeTZDtype, @@ -444,7 +442,7 @@ def test_nat_arithmetic_index(op_name, value): exp_name = "x" exp_data = [NaT] * 2 - if is_datetime64_any_dtype(value.dtype) and "plus" in op_name: + if value.dtype.kind == "M" and "plus" in op_name: expected = DatetimeIndex(exp_data, tz=value.tz, name=exp_name) else: expected = TimedeltaIndex(exp_data, name=exp_name) From 9dac868aebced44a7bf15a6fa1b4284132095ee4 Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 13 Apr 2023 07:22:02 -0700 Subject: [PATCH 2/5] GH ref --- doc/source/whatsnew/v2.1.0.rst | 2 +- pandas/core/dtypes/common.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index 95e8e6a4769b4..c17dc97f2bdb7 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -228,13 +228,13 @@ Deprecations - Deprecated making :meth:`Series.apply` return a :class:`DataFrame` when the passed-in callable returns a :class:`Series` object. In the future this will return a :class:`Series` whose values are themselves :class:`Series`. This pattern was very slow and it's recommended to use alternative methods to archive the same goal (:issue:`52116`) - Deprecated parameter ``convert_type`` in :meth:`Series.apply` (:issue:`52140`) - Deprecated ``freq`` parameter in :class:`PeriodArray` constructor, pass ``dtype`` instead (:issue:`52462`) -- Deprecated :func:`is_datetime64_any_dtype`, check for specific dtypes of interest instead (:issue:`??`) - Deprecated :func:`is_categorical_dtype`, use ``isinstance(obj.dtype, pd.CategoricalDtype)`` instead (:issue:`52527`) - Deprecated :func:`is_int64_dtype`, check ``dtype == np.dtype(np.int64)`` instead (:issue:`52564`) - Deprecated :func:`is_interval_dtype`, check ``isinstance(dtype, pd.IntervalDtype)`` instead (:issue:`52607`) - Deprecated :func:`is_datetime64tz_dtype`, check ``isinstance(dtype, pd.DatetimeTZDtype)`` instead (:issue:`52607`) - Deprecated unused "closed" and "normalize" keywords in the :class:`DatetimeIndex` constructor (:issue:`52628`) - Deprecated unused "closed" keyword in the :class:`TimedeltaIndex` constructor (:issue:`52628`) +- Deprecated :func:`is_datetime64_any_dtype`, check for specific dtypes of interest instead (:issue:`52651`) - .. --------------------------------------------------------------------------- diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index af4269bb920c5..8f2cfe5e5b273 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -862,6 +862,7 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: >>> is_datetime64_any_dtype(pd.DatetimeIndex([1, 2, 3], dtype="datetime64[ns]")) True """ + # GH#52651 warnings.warn( "is_datetime64_any_dtype is deprecated and will be removed in a future " "version. Check for specific dtypes of interest instead.", From 4cf85b8182c1376ab3b21bfd0469271489516808 Mon Sep 17 00:00:00 2001 From: Brock Date: Mon, 17 Apr 2023 15:17:21 -0700 Subject: [PATCH 3/5] Revert deprecation --- doc/source/whatsnew/v2.1.0.rst | 2 +- pandas/conftest.py | 1 - pandas/core/dtypes/common.py | 20 ++++++++++++-------- pandas/tests/dtypes/test_common.py | 25 +++++++++++-------------- pandas/tests/dtypes/test_dtypes.py | 8 ++------ pandas/tests/dtypes/test_inference.py | 15 +++++---------- 6 files changed, 31 insertions(+), 40 deletions(-) diff --git a/doc/source/whatsnew/v2.1.0.rst b/doc/source/whatsnew/v2.1.0.rst index 2f73ac873e64a..c537070533cd9 100644 --- a/doc/source/whatsnew/v2.1.0.rst +++ b/doc/source/whatsnew/v2.1.0.rst @@ -226,7 +226,6 @@ Deprecations - Deprecated the 'axis' keyword in :meth:`.GroupBy.idxmax`, :meth:`.GroupBy.idxmin`, :meth:`.GroupBy.fillna`, :meth:`.GroupBy.take`, :meth:`.GroupBy.skew`, :meth:`.GroupBy.rank`, :meth:`.GroupBy.cumprod`, :meth:`.GroupBy.cumsum`, :meth:`.GroupBy.cummax`, :meth:`.GroupBy.cummin`, :meth:`.GroupBy.pct_change`, :meth:`GroupBy.diff`, :meth:`.GroupBy.shift`, and :meth:`DataFrameGroupBy.corrwith`; for ``axis=1`` operate on the underlying :class:`DataFrame` instead (:issue:`50405`, :issue:`51046`) - Deprecated :class:`.DataFrameGroupBy` with ``as_index=False`` not including groupings in the result when they are not columns of the DataFrame (:issue:`49519`) - Deprecated :func:`is_categorical_dtype`, use ``isinstance(obj.dtype, pd.CategoricalDtype)`` instead (:issue:`52527`) -- Deprecated :func:`is_datetime64_any_dtype`, check for specific dtypes of interest instead (:issue:`52651`) - Deprecated :func:`is_datetime64tz_dtype`, check ``isinstance(dtype, pd.DatetimeTZDtype)`` instead (:issue:`52607`) - Deprecated :func:`is_int64_dtype`, check ``dtype == np.dtype(np.int64)`` instead (:issue:`52564`) - Deprecated :func:`is_interval_dtype`, check ``isinstance(dtype, pd.IntervalDtype)`` instead (:issue:`52607`) @@ -239,6 +238,7 @@ Deprecations - Deprecated parameter ``convert_type`` in :meth:`Series.apply` (:issue:`52140`) - Deprecated passing a dictionary to :meth:`.SeriesGroupBy.agg`; pass a list of aggregations instead (:issue:`50684`) - Deprecated the "fastpath" keyword in :class:`Categorical` constructor, use :meth:`Categorical.from_codes` instead (:issue:`20110`) +- Deprecated the behavior of :func:`is_bool_dtype` returning ``True`` for object-dtype :class:`Index` of bool objects (:issue:`52680`) - Deprecated the methods :meth:`Series.bool` and :meth:`DataFrame.bool` (:issue:`51749`) - Deprecated unused "closed" and "normalize" keywords in the :class:`DatetimeIndex` constructor (:issue:`52628`) - Deprecated unused "closed" keyword in the :class:`TimedeltaIndex` constructor (:issue:`52628`) diff --git a/pandas/conftest.py b/pandas/conftest.py index bbd1e2a96c691..7773d8de37705 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -136,7 +136,6 @@ def pytest_collection_modifyitems(items, config) -> None: # Each entry specifies (path, message) - see the ignore_doctest_warning function ignored_doctest_warnings = [ ("is_int64_dtype", "is_int64_dtype is deprecated"), - ("is_datetime64_any_dtype", "is_datetime64_any_dtype is deprecated"), ("is_interval_dtype", "is_interval_dtype is deprecated"), ("is_datetime64tz_dtype", "is_datetime64tz_dtype is deprecated"), # Docstring divides by zero to show behavior difference diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index a55461f61eeb7..dcf4c25f14e2f 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -862,13 +862,6 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool: >>> is_datetime64_any_dtype(pd.DatetimeIndex([1, 2, 3], dtype="datetime64[ns]")) True """ - # GH#52651 - warnings.warn( - "is_datetime64_any_dtype is deprecated and will be removed in a future " - "version. Check for specific dtypes of interest instead.", - FutureWarning, - stacklevel=find_stack_level(), - ) if isinstance(arr_or_dtype, (np.dtype, ExtensionDtype)): # GH#33400 fastpath for dtype object return arr_or_dtype.kind == "M" @@ -1226,7 +1219,18 @@ def is_bool_dtype(arr_or_dtype) -> bool: if isinstance(arr_or_dtype, ABCIndex): # Allow Index[object] that is all-bools or Index["boolean"] - return arr_or_dtype.inferred_type == "boolean" + if arr_or_dtype.inferred_type == "boolean": + if not is_bool_dtype(arr_or_dtype.dtype): + # GH#52680 + warnings.warn( + "The behavior of is_bool_dtype with an object-dtype Index " + "of bool objects is deprecated. In a future version, " + "this will return False. Cast the Index to a bool dtype instead.", + FutureWarning, + stacklevel=find_stack_level(), + ) + return True + return False elif isinstance(dtype, ExtensionDtype): return getattr(dtype, "_is_boolean", False) diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index b75d62d346dca..a28a5b62f4ad0 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -175,7 +175,6 @@ def test_get_dtype_error_catch(func): if ( func is com.is_int64_dtype or func is com.is_interval_dtype - or func is com.is_datetime64_any_dtype or func is com.is_datetime64tz_dtype or func is com.is_categorical_dtype ): @@ -472,19 +471,17 @@ def test_is_not_int64_dtype(dtype): def test_is_datetime64_any_dtype(): - msg = "is_datetime64_any_dtype is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - assert not com.is_datetime64_any_dtype(int) - assert not com.is_datetime64_any_dtype(str) - assert not com.is_datetime64_any_dtype(np.array([1, 2])) - assert not com.is_datetime64_any_dtype(np.array(["a", "b"])) - - assert com.is_datetime64_any_dtype(np.datetime64) - assert com.is_datetime64_any_dtype(np.array([], dtype=np.datetime64)) - assert com.is_datetime64_any_dtype(DatetimeTZDtype("ns", "US/Eastern")) - assert com.is_datetime64_any_dtype( - pd.DatetimeIndex([1, 2, 3], dtype="datetime64[ns]") - ) + assert not com.is_datetime64_any_dtype(int) + assert not com.is_datetime64_any_dtype(str) + assert not com.is_datetime64_any_dtype(np.array([1, 2])) + assert not com.is_datetime64_any_dtype(np.array(["a", "b"])) + + assert com.is_datetime64_any_dtype(np.datetime64) + assert com.is_datetime64_any_dtype(np.array([], dtype=np.datetime64)) + assert com.is_datetime64_any_dtype(DatetimeTZDtype("ns", "US/Eastern")) + assert com.is_datetime64_any_dtype( + pd.DatetimeIndex([1, 2, 3], dtype="datetime64[ns]") + ) def test_is_datetime64_ns_dtype(): diff --git a/pandas/tests/dtypes/test_dtypes.py b/pandas/tests/dtypes/test_dtypes.py index 836ead45e1ed2..09e100c660ddf 100644 --- a/pandas/tests/dtypes/test_dtypes.py +++ b/pandas/tests/dtypes/test_dtypes.py @@ -294,11 +294,8 @@ def test_compat(self, dtype): with tm.assert_produces_warning(FutureWarning, match=msg): assert is_datetime64tz_dtype(dtype) assert is_datetime64tz_dtype("datetime64[ns, US/Eastern]") - - msg = "is_datetime64_any_dtype is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg): - assert is_datetime64_any_dtype(dtype) - assert is_datetime64_any_dtype("datetime64[ns, US/Eastern]") + assert is_datetime64_any_dtype(dtype) + assert is_datetime64_any_dtype("datetime64[ns, US/Eastern]") assert is_datetime64_ns_dtype(dtype) assert is_datetime64_ns_dtype("datetime64[ns, US/Eastern]") assert not is_datetime64_dtype(dtype) @@ -1133,7 +1130,6 @@ def test_is_dtype_no_warning(check): if ( check is is_categorical_dtype or check is is_interval_dtype - or check is is_datetime64_any_dtype or check is is_datetime64tz_dtype ): warn = FutureWarning diff --git a/pandas/tests/dtypes/test_inference.py b/pandas/tests/dtypes/test_inference.py index b5319a88f80ed..9358b44c243bc 100644 --- a/pandas/tests/dtypes/test_inference.py +++ b/pandas/tests/dtypes/test_inference.py @@ -1822,7 +1822,6 @@ def test_is_datetime_dtypes(self): tsa = pd.date_range("20130101", periods=3, tz="US/Eastern") msg = "is_datetime64tz_dtype is deprecated" - msg_any = "is_datetime64_any_dtype is deprecated" assert is_datetime64_dtype("datetime64") assert is_datetime64_dtype("datetime64[ns]") @@ -1834,11 +1833,10 @@ def test_is_datetime_dtypes(self): assert is_datetime64_ns_dtype(ts) assert is_datetime64_ns_dtype(tsa) - with tm.assert_produces_warning(FutureWarning, match=msg_any): - assert is_datetime64_any_dtype("datetime64") - assert is_datetime64_any_dtype("datetime64[ns]") - assert is_datetime64_any_dtype(ts) - assert is_datetime64_any_dtype(tsa) + assert is_datetime64_any_dtype("datetime64") + assert is_datetime64_any_dtype("datetime64[ns]") + assert is_datetime64_any_dtype(ts) + assert is_datetime64_any_dtype(tsa) with tm.assert_produces_warning(FutureWarning, match=msg): assert not is_datetime64tz_dtype("datetime64") @@ -1855,10 +1853,7 @@ def test_is_datetime_dtypes_with_tz(self, tz): with tm.assert_produces_warning(FutureWarning, match=msg): assert is_datetime64tz_dtype(dtype) assert is_datetime64_ns_dtype(dtype) - - msg_any = "is_datetime64_any_dtype is deprecated" - with tm.assert_produces_warning(FutureWarning, match=msg_any): - assert is_datetime64_any_dtype(dtype) + assert is_datetime64_any_dtype(dtype) def test_is_timedelta(self): assert is_timedelta64_dtype("timedelta64") From 57631d01195a645f47f004893d05038bafecd22e Mon Sep 17 00:00:00 2001 From: Brock Date: Tue, 18 Apr 2023 11:04:16 -0700 Subject: [PATCH 4/5] revert accidental --- pandas/core/dtypes/common.py | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index dcf4c25f14e2f..20d8cb4adc8b6 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -1219,18 +1219,7 @@ def is_bool_dtype(arr_or_dtype) -> bool: if isinstance(arr_or_dtype, ABCIndex): # Allow Index[object] that is all-bools or Index["boolean"] - if arr_or_dtype.inferred_type == "boolean": - if not is_bool_dtype(arr_or_dtype.dtype): - # GH#52680 - warnings.warn( - "The behavior of is_bool_dtype with an object-dtype Index " - "of bool objects is deprecated. In a future version, " - "this will return False. Cast the Index to a bool dtype instead.", - FutureWarning, - stacklevel=find_stack_level(), - ) - return True - return False + return arr_or_dtype.inferred_type == "boolean" elif isinstance(dtype, ExtensionDtype): return getattr(dtype, "_is_boolean", False) From 2caf8959bd3c58fc65fcd3b3ebea53d7cc38085e Mon Sep 17 00:00:00 2001 From: Brock Date: Wed, 19 Apr 2023 09:29:18 -0700 Subject: [PATCH 5/5] merge mixups --- pandas/core/dtypes/common.py | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 55ee8426f0b70..67fb5a81ecabe 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -1219,7 +1219,18 @@ def is_bool_dtype(arr_or_dtype) -> bool: if isinstance(arr_or_dtype, ABCIndex): # Allow Index[object] that is all-bools or Index["boolean"] - return arr_or_dtype.inferred_type == "boolean" + if arr_or_dtype.inferred_type == "boolean": + if not is_bool_dtype(arr_or_dtype.dtype): + # GH#52680 + warnings.warn( + "The behavior of is_bool_dtype with an object-dtype Index " + "of bool objects is deprecated. In a future version, " + "this will return False. Cast the Index to a bool dtype instead.", + FutureWarning, + stacklevel=find_stack_level(), + ) + return True + return False elif isinstance(dtype, ExtensionDtype): return getattr(dtype, "_is_boolean", False)