Repository: pandas-dev/pandas
Pull request #56377 (2023-12-07 13:15:49)

Backport PR #55703 on branch 2.1.x (Use DeprecationWarning instead of FutureWarning for is_.._dtype deprecations)
Backport of https://github.com/pandas-dev/pandas/pull/55703


Patch:
diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py
index 3db36fc50e..143dc46359 100644
--- a/pandas/core/dtypes/common.py
+++ b/pandas/core/dtypes/common.py
@@ -211,8 +211,8 @@ def is_sparse(arr) -> bool:
     warnings.warn(
         "is_sparse is deprecated and will be removed in a future "
         "version. Check `isinstance(dtype, pd.SparseDtype)` instead.",
-        FutureWarning,
-        stacklevel=find_stack_level(),
+        DeprecationWarning,
+        stacklevel=2,
     )
 
     dtype = getattr(arr, "dtype", arr)
@@ -329,8 +329,8 @@ def is_datetime64tz_dtype(arr_or_dtype) -> bool:
     warnings.warn(
         "is_datetime64tz_dtype is deprecated and will be removed in a future "
         "version. Check `isinstance(dtype, pd.DatetimeTZDtype)` instead.",
-        FutureWarning,
-        stacklevel=find_stack_level(),
+        DeprecationWarning,
+        stacklevel=2,
     )
     if isinstance(arr_or_dtype, DatetimeTZDtype):
         # GH#33400 fastpath for dtype object
@@ -408,8 +408,8 @@ def is_period_dtype(arr_or_dtype) -> bool:
     warnings.warn(
         "is_period_dtype is deprecated and will be removed in a future version. "
         "Use `isinstance(dtype, pd.PeriodDtype)` instead",
-        FutureWarning,
-        stacklevel=find_stack_level(),
+        DeprecationWarning,
+        stacklevel=2,
     )
     if isinstance(arr_or_dtype, ExtensionDtype):
         # GH#33400 fastpath for dtype object
@@ -454,8 +454,8 @@ def is_interval_dtype(arr_or_dtype) -> bool:
     warnings.warn(
         "is_interval_dtype is deprecated and will be removed in a future version. "
         "Use `isinstance(dtype, pd.IntervalDtype)` instead",
-        FutureWarning,
-        stacklevel=find_stack_level(),
+        DeprecationWarning,
+        stacklevel=2,
     )
     if isinstance(arr_or_dtype, ExtensionDtype):
         # GH#33400 fastpath for dtype object
@@ -498,9 +498,9 @@ def is_categorical_dtype(arr_or_dtype) -> bool:
     # GH#52527
     warnings.warn(
         "is_categorical_dtype is deprecated and will be removed in a future "
-        "version. Use isinstance(dtype, CategoricalDtype) instead",
-        FutureWarning,
-        stacklevel=find_stack_level(),
+        "version. Use isinstance(dtype, pd.CategoricalDtype) instead",
+        DeprecationWarning,
+        stacklevel=2,
     )
     if isinstance(arr_or_dtype, ExtensionDtype):
         # GH#33400 fastpath for dtype object
@@ -838,8 +838,8 @@ def is_int64_dtype(arr_or_dtype) -> bool:
     warnings.warn(
         "is_int64_dtype is deprecated and will be removed in a future "
         "version. Use dtype == np.int64 instead.",
-        FutureWarning,
-        stacklevel=find_stack_level(),
+        DeprecationWarning,
+        stacklevel=2,
     )
     return _is_dtype_type(arr_or_dtype, classes(np.int64))
 
@@ -1241,8 +1241,8 @@ def is_bool_dtype(arr_or_dtype) -> bool:
                     "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(),
+                    DeprecationWarning,
+                    stacklevel=2,
                 )
             return True
         return False


Test patch:
diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py
index 165bf61302..9419cb693d 100644
--- a/pandas/tests/dtypes/test_common.py
+++ b/pandas/tests/dtypes/test_common.py
@@ -164,7 +164,9 @@ def get_is_dtype_funcs():
     return [getattr(com, fname) for fname in fnames]
 
 
-@pytest.mark.filterwarnings("ignore:is_categorical_dtype is deprecated:FutureWarning")
+@pytest.mark.filterwarnings(
+    "ignore:is_categorical_dtype is deprecated:DeprecationWarning"
+)
 @pytest.mark.parametrize("func", get_is_dtype_funcs(), ids=lambda x: x.__name__)
 def test_get_dtype_error_catch(func):
     # see gh-15941
@@ -180,7 +182,7 @@ def test_get_dtype_error_catch(func):
         or func is com.is_categorical_dtype
         or func is com.is_period_dtype
     ):
-        warn = FutureWarning
+        warn = DeprecationWarning
 
     with tm.assert_produces_warning(warn, match=msg):
         assert not func(None)
@@ -200,7 +202,7 @@ def test_is_object():
 )
 def test_is_sparse(check_scipy):
     msg = "is_sparse is deprecated"
-    with tm.assert_produces_warning(FutureWarning, match=msg):
+    with tm.assert_produces_warning(DeprecationWarning, match=msg):
         assert com.is_sparse(SparseArray([1, 2, 3]))
 
         assert not com.is_sparse(np.array([1, 2, 3]))
@@ -230,7 +232,7 @@ def test_is_datetime64_dtype():
 
 def test_is_datetime64tz_dtype():
     msg = "is_datetime64tz_dtype is deprecated"
-    with tm.assert_produces_warning(FutureWarning, match=msg):
+    with tm.assert_produces_warning(DeprecationWarning, match=msg):
         assert not com.is_datetime64tz_dtype(object)
         assert not com.is_datetime64tz_dtype([1, 2, 3])
         assert not com.is_datetime64tz_dtype(pd.DatetimeIndex([1, 2, 3]))
@@ -246,7 +248,7 @@ def test_custom_ea_kind_M_not_datetime64tz():
 
     not_tz_dtype = NotTZDtype()
     msg = "is_datetime64tz_dtype is deprecated"
-    with tm.assert_produces_warning(FutureWarning, match=msg):
+    with tm.assert_produces_warning(DeprecationWarning, match=msg):
         assert not com.is_datetime64tz_dtype(not_tz_dtype)
         assert not com.needs_i8_conversion(not_tz_dtype)
 
@@ -268,7 +270,7 @@ def test_is_timedelta64_dtype():
 
 def test_is_period_dtype():
     msg = "is_period_dtype is deprecated"
-    with tm.assert_produces_warning(FutureWarning, match=msg):
+    with tm.assert_produces_warning(DeprecationWarning, match=msg):
         assert not com.is_period_dtype(object)
         assert not com.is_period_dtype([1, 2, 3])
         assert not com.is_period_dtype(pd.Period("2017-01-01"))
@@ -279,7 +281,7 @@ def test_is_period_dtype():
 
 def test_is_interval_dtype():
     msg = "is_interval_dtype is deprecated"
-    with tm.assert_produces_warning(FutureWarning, match=msg):
+    with tm.assert_produces_warning(DeprecationWarning, match=msg):
         assert not com.is_interval_dtype(object)
         assert not com.is_interval_dtype([1, 2, 3])
 
@@ -292,7 +294,7 @@ def test_is_interval_dtype():
 
 def test_is_categorical_dtype():
     msg = "is_categorical_dtype is deprecated"
-    with tm.assert_produces_warning(FutureWarning, match=msg):
+    with tm.assert_produces_warning(DeprecationWarning, match=msg):
         assert not com.is_categorical_dtype(object)
         assert not com.is_categorical_dtype([1, 2, 3])
 
@@ -433,7 +435,7 @@ def test_is_not_unsigned_integer_dtype(dtype):
 )
 def test_is_int64_dtype(dtype):
     msg = "is_int64_dtype is deprecated"
-    with tm.assert_produces_warning(FutureWarning, match=msg):
+    with tm.assert_produces_warning(DeprecationWarning, match=msg):
         assert com.is_int64_dtype(dtype)
 
 
@@ -471,7 +473,7 @@ def test_type_comparison_with_signed_int_ea_dtype_and_signed_int_numpy_dtype(
 )
 def test_is_not_int64_dtype(dtype):
     msg = "is_int64_dtype is deprecated"
-    with tm.assert_produces_warning(FutureWarning, match=msg):
+    with tm.assert_produces_warning(DeprecationWarning, match=msg):
         assert not com.is_int64_dtype(dtype)
 
 
diff --git a/pandas/tests/dtypes/test_dtypes.py b/pandas/tests/dtypes/test_dtypes.py
index f57093c29b..d5286d3fad 100644
--- a/pandas/tests/dtypes/test_dtypes.py
+++ b/pandas/tests/dtypes/test_dtypes.py
@@ -166,7 +166,7 @@ class TestCategoricalDtype(Base):
 
     def test_basic(self, dtype):
         msg = "is_categorical_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_categorical_dtype(dtype)
 
             factor = Categorical(["a", "b", "b", "a", "a", "c", "c", "c"])
@@ -291,7 +291,7 @@ class TestDatetimeTZDtype(Base):
 
     def test_compat(self, dtype):
         msg = "is_datetime64tz_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_datetime64tz_dtype(dtype)
             assert is_datetime64tz_dtype("datetime64[ns, US/Eastern]")
         assert is_datetime64_any_dtype(dtype)
@@ -352,14 +352,14 @@ class TestDatetimeTZDtype(Base):
 
     def test_basic(self, dtype):
         msg = "is_datetime64tz_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_datetime64tz_dtype(dtype)
 
         dr = date_range("20130101", periods=3, tz="US/Eastern")
         s = Series(dr, name="A")
 
         # dtypes
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_datetime64tz_dtype(s.dtype)
             assert is_datetime64tz_dtype(s)
             assert not is_datetime64tz_dtype(np.dtype("float64"))
@@ -530,7 +530,7 @@ class TestPeriodDtype(Base):
 
     def test_basic(self, dtype):
         msg = "is_period_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_period_dtype(dtype)
 
             pidx = pd.period_range("2013-01-01 09:00", periods=5, freq="H")
@@ -618,7 +618,7 @@ class TestIntervalDtype(Base):
         i = IntervalDtype(subtype, closed="right")
         assert i.subtype == np.dtype("int64")
         msg = "is_interval_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_interval_dtype(i)
 
     @pytest.mark.parametrize(
@@ -641,7 +641,7 @@ class TestIntervalDtype(Base):
         i = IntervalDtype(subtype)
         assert i.subtype is None
         msg = "is_interval_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_interval_dtype(i)
 
     @pytest.mark.parametrize(
@@ -814,7 +814,7 @@ class TestIntervalDtype(Base):
 
     def test_basic(self, dtype):
         msg = "is_interval_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_interval_dtype(dtype)
 
             ii = IntervalIndex.from_breaks(range(3))
@@ -829,7 +829,7 @@ class TestIntervalDtype(Base):
 
     def test_basic_dtype(self):
         msg = "is_interval_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_interval_dtype("interval[int64, both]")
             assert is_interval_dtype(IntervalIndex.from_tuples([(0, 1)]))
             assert is_interval_dtype(IntervalIndex.from_breaks(np.arange(4)))
@@ -1158,7 +1158,7 @@ def test_is_dtype_no_warning(check):
         or check is is_datetime64tz_dtype
         or check is is_period_dtype
     ):
-        warn = FutureWarning
+        warn = DeprecationWarning
 
     with tm.assert_produces_warning(warn, match=msg):
         check(data)
diff --git a/pandas/tests/dtypes/test_inference.py b/pandas/tests/dtypes/test_inference.py
index df7c787d2b..2198ed0c6a 100644
--- a/pandas/tests/dtypes/test_inference.py
+++ b/pandas/tests/dtypes/test_inference.py
@@ -1821,7 +1821,7 @@ class TestNumberScalar:
         assert is_datetime64_any_dtype(ts)
         assert is_datetime64_any_dtype(tsa)
 
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert not is_datetime64tz_dtype("datetime64")
             assert not is_datetime64tz_dtype("datetime64[ns]")
             assert not is_datetime64tz_dtype(ts)
@@ -1833,7 +1833,7 @@ class TestNumberScalar:
         assert not is_datetime64_dtype(dtype)
 
         msg = "is_datetime64tz_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
+        with tm.assert_produces_warning(DeprecationWarning, match=msg):
             assert is_datetime64tz_dtype(dtype)
         assert is_datetime64_ns_dtype(dtype)
         assert is_datetime64_any_dtype(dtype)
diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py
index d585a56665..fb9e465238 100644
--- a/pandas/tests/series/test_constructors.py
+++ b/pandas/tests/series/test_constructors.py
@@ -17,7 +17,6 @@ from pandas._libs import (
 from pandas.errors import IntCastingNaNError
 import pandas.util._test_decorators as td
 
-from pandas.core.dtypes.common import is_categorical_dtype
 from pandas.core.dtypes.dtypes import CategoricalDtype
 
 import pandas as pd
@@ -393,18 +392,12 @@ class TestSeriesConstructors:
 
     def test_construct_from_categorical_with_dtype(self):
         # GH12574
-        cat = Series(Categorical([1, 2, 3]), dtype="category")
-        msg = "is_categorical_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
-            assert is_categorical_dtype(cat)
-            assert is_categorical_dtype(cat.dtype)
+        ser = Series(Categorical([1, 2, 3]), dtype="category")
+        assert isinstance(ser.dtype, CategoricalDtype)
 
     def test_construct_intlist_values_category_dtype(self):
         ser = Series([1, 2, 3], dtype="category")
-        msg = "is_categorical_dtype is deprecated"
-        with tm.assert_produces_warning(FutureWarning, match=msg):
-            assert is_categorical_dtype(ser)
-            assert is_categorical_dtype(ser.dtype)
+        assert isinstance(ser.dtype, CategoricalDtype)
 
     def test_constructor_categorical_with_coercion(self):
         factor = Categorical(["a", "b", "b", "a", "a", "c", "c", "c"])