Skip to content

Commit 0ab323f

Browse files
authored
DEPR: is_datetime64tz_dtype, is_interval_dtype (#52607)
* DEPR: is_datetime64tz_dtype, is_interval_dtype * GH ref * fix tests * typo fixup
1 parent 8d4cab5 commit 0ab323f

File tree

16 files changed

+149
-99
lines changed

16 files changed

+149
-99
lines changed

doc/source/whatsnew/v2.1.0.rst

+2
Original file line numberDiff line numberDiff line change
@@ -230,6 +230,8 @@ Deprecations
230230
- Deprecated ``freq`` parameter in :class:`PeriodArray` constructor, pass ``dtype`` instead (:issue:`52462`)
231231
- Deprecated :func:`is_categorical_dtype`, use ``isinstance(obj.dtype, pd.CategoricalDtype)`` instead (:issue:`52527`)
232232
- Deprecated :func:`is_int64_dtype`, check ``dtype == np.dtype(np.int64)`` instead (:issue:`52564`)
233+
- Deprecated :func:`is_interval_dtype`, check ``isinstance(dtype, pd.IntervalDtype)`` instead (:issue:`52607`)
234+
- Deprecated :func:`is_datetime64tz_dtype`, check ``isinstance(dtype, pd.DatetimeTZDtype)`` instead (:issue:`52607`)
233235
-
234236

235237
.. ---------------------------------------------------------------------------

pandas/conftest.py

+2
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,8 @@ def pytest_collection_modifyitems(items, config) -> None:
136136
# Each entry specifies (path, message) - see the ignore_doctest_warning function
137137
ignored_doctest_warnings = [
138138
("is_int64_dtype", "is_int64_dtype is deprecated"),
139+
("is_interval_dtype", "is_interval_dtype is deprecated"),
140+
("is_datetime64tz_dtype", "is_datetime64tz_dtype is deprecated"),
139141
# Docstring divides by zero to show behavior difference
140142
("missing.mask_zero_div_zero", "divide by zero encountered"),
141143
(

pandas/core/dtypes/common.py

+22-1
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,13 @@ def is_datetime64tz_dtype(arr_or_dtype) -> bool:
319319
>>> is_datetime64tz_dtype(s)
320320
True
321321
"""
322+
# GH#52607
323+
warnings.warn(
324+
"is_datetime64tz_dtype is deprecated and will be removed in a future "
325+
"version. Check `isinstance(dtype, pd.DatetimeTZDtype)` instead.",
326+
FutureWarning,
327+
stacklevel=find_stack_level(),
328+
)
322329
if isinstance(arr_or_dtype, DatetimeTZDtype):
323330
# GH#33400 fastpath for dtype object
324331
# GH 34986
@@ -431,6 +438,13 @@ def is_interval_dtype(arr_or_dtype) -> bool:
431438
>>> is_interval_dtype(pd.IntervalIndex([interval]))
432439
True
433440
"""
441+
# GH#52607
442+
warnings.warn(
443+
"is_interval_dtype is deprecated and will be removed in a future version. "
444+
"Use `isinstance(dtype, pd.IntervalDtype)` instead",
445+
FutureWarning,
446+
stacklevel=find_stack_level(),
447+
)
434448
if isinstance(arr_or_dtype, ExtensionDtype):
435449
# GH#33400 fastpath for dtype object
436450
return arr_or_dtype.type is Interval
@@ -854,7 +868,14 @@ def is_datetime64_any_dtype(arr_or_dtype) -> bool:
854868

855869
if arr_or_dtype is None:
856870
return False
857-
return is_datetime64_dtype(arr_or_dtype) or is_datetime64tz_dtype(arr_or_dtype)
871+
872+
try:
873+
tipo = get_dtype(arr_or_dtype)
874+
except TypeError:
875+
return False
876+
return (isinstance(tipo, np.dtype) and tipo.kind == "M") or isinstance(
877+
tipo, DatetimeTZDtype
878+
)
858879

859880

860881
def is_datetime64_ns_dtype(arr_or_dtype) -> bool:

pandas/core/indexes/interval.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
)
4444
from pandas.core.dtypes.common import (
4545
ensure_platform_int,
46-
is_datetime64tz_dtype,
4746
is_datetime_or_timedelta_dtype,
4847
is_dtype_equal,
4948
is_float,
@@ -55,7 +54,10 @@
5554
is_object_dtype,
5655
is_scalar,
5756
)
58-
from pandas.core.dtypes.dtypes import IntervalDtype
57+
from pandas.core.dtypes.dtypes import (
58+
DatetimeTZDtype,
59+
IntervalDtype,
60+
)
5961
from pandas.core.dtypes.missing import is_valid_na_for_dtype
6062

6163
from pandas.core.algorithms import unique
@@ -114,7 +116,7 @@ def _get_next_label(label):
114116
dtype = getattr(label, "dtype", type(label))
115117
if isinstance(label, (Timestamp, Timedelta)):
116118
dtype = "datetime64"
117-
if is_datetime_or_timedelta_dtype(dtype) or is_datetime64tz_dtype(dtype):
119+
if is_datetime_or_timedelta_dtype(dtype) or isinstance(dtype, DatetimeTZDtype):
118120
return label + np.timedelta64(1, "ns")
119121
elif is_integer_dtype(dtype):
120122
return label + 1
@@ -128,7 +130,7 @@ def _get_prev_label(label):
128130
dtype = getattr(label, "dtype", type(label))
129131
if isinstance(label, (Timestamp, Timedelta)):
130132
dtype = "datetime64"
131-
if is_datetime_or_timedelta_dtype(dtype) or is_datetime64tz_dtype(dtype):
133+
if is_datetime_or_timedelta_dtype(dtype) or isinstance(dtype, DatetimeTZDtype):
132134
return label - np.timedelta64(1, "ns")
133135
elif is_integer_dtype(dtype):
134136
return label - 1

pandas/core/reshape/tile.py

+1-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@
2323
ensure_platform_int,
2424
is_bool_dtype,
2525
is_datetime64_dtype,
26-
is_datetime64tz_dtype,
2726
is_datetime_or_timedelta_dtype,
2827
is_integer,
2928
is_list_like,
@@ -285,7 +284,7 @@ def cut(
285284
raise ValueError("Overlapping IntervalIndex is not accepted.")
286285

287286
else:
288-
if is_datetime64tz_dtype(bins):
287+
if isinstance(getattr(bins, "dtype", None), DatetimeTZDtype):
289288
bins = np.asarray(bins, dtype=DT64NS_DTYPE)
290289
else:
291290
bins = np.asarray(bins)

pandas/tests/base/test_unique.py

+2-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import numpy as np
22
import pytest
33

4-
from pandas.core.dtypes.common import is_datetime64tz_dtype
5-
64
import pandas as pd
75
import pandas._testing as tm
86
from pandas.tests.base.common import allow_na_ops
@@ -21,7 +19,7 @@ def test_unique(index_or_series_obj):
2119
tm.assert_index_equal(result, expected, exact=True)
2220
elif isinstance(obj, pd.Index):
2321
expected = pd.Index(unique_values, dtype=obj.dtype)
24-
if is_datetime64tz_dtype(obj.dtype):
22+
if isinstance(obj.dtype, pd.DatetimeTZDtype):
2523
expected = expected.normalize()
2624
tm.assert_index_equal(result, expected, exact=True)
2725
else:
@@ -56,7 +54,7 @@ def test_unique_null(null_obj, index_or_series_obj):
5654

5755
if isinstance(obj, pd.Index):
5856
expected = pd.Index(unique_values, dtype=obj.dtype)
59-
if is_datetime64tz_dtype(obj.dtype):
57+
if isinstance(obj.dtype, pd.DatetimeTZDtype):
6058
result = result.normalize()
6159
expected = expected.normalize()
6260
tm.assert_index_equal(result, expected, exact=True)

pandas/tests/dtypes/test_common.py

+24-13
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,12 @@ def test_get_dtype_error_catch(func):
172172

173173
msg = f"{func.__name__} is deprecated"
174174
warn = None
175-
if func is com.is_int64_dtype or func is com.is_categorical_dtype:
175+
if (
176+
func is com.is_int64_dtype
177+
or func is com.is_interval_dtype
178+
or func is com.is_datetime64tz_dtype
179+
or func is com.is_categorical_dtype
180+
):
176181
warn = FutureWarning
177182

178183
with tm.assert_produces_warning(warn, match=msg):
@@ -221,10 +226,12 @@ def test_is_datetime64_dtype():
221226

222227

223228
def test_is_datetime64tz_dtype():
224-
assert not com.is_datetime64tz_dtype(object)
225-
assert not com.is_datetime64tz_dtype([1, 2, 3])
226-
assert not com.is_datetime64tz_dtype(pd.DatetimeIndex([1, 2, 3]))
227-
assert com.is_datetime64tz_dtype(pd.DatetimeIndex(["2000"], tz="US/Eastern"))
229+
msg = "is_datetime64tz_dtype is deprecated"
230+
with tm.assert_produces_warning(FutureWarning, match=msg):
231+
assert not com.is_datetime64tz_dtype(object)
232+
assert not com.is_datetime64tz_dtype([1, 2, 3])
233+
assert not com.is_datetime64tz_dtype(pd.DatetimeIndex([1, 2, 3]))
234+
assert com.is_datetime64tz_dtype(pd.DatetimeIndex(["2000"], tz="US/Eastern"))
228235

229236

230237
def test_custom_ea_kind_M_not_datetime64tz():
@@ -235,8 +242,10 @@ def kind(self) -> str:
235242
return "M"
236243

237244
not_tz_dtype = NotTZDtype()
238-
assert not com.is_datetime64tz_dtype(not_tz_dtype)
239-
assert not com.needs_i8_conversion(not_tz_dtype)
245+
msg = "is_datetime64tz_dtype is deprecated"
246+
with tm.assert_produces_warning(FutureWarning, match=msg):
247+
assert not com.is_datetime64tz_dtype(not_tz_dtype)
248+
assert not com.needs_i8_conversion(not_tz_dtype)
240249

241250

242251
def test_is_timedelta64_dtype():
@@ -264,14 +273,16 @@ def test_is_period_dtype():
264273

265274

266275
def test_is_interval_dtype():
267-
assert not com.is_interval_dtype(object)
268-
assert not com.is_interval_dtype([1, 2, 3])
276+
msg = "is_interval_dtype is deprecated"
277+
with tm.assert_produces_warning(FutureWarning, match=msg):
278+
assert not com.is_interval_dtype(object)
279+
assert not com.is_interval_dtype([1, 2, 3])
269280

270-
assert com.is_interval_dtype(IntervalDtype())
281+
assert com.is_interval_dtype(IntervalDtype())
271282

272-
interval = pd.Interval(1, 2, closed="right")
273-
assert not com.is_interval_dtype(interval)
274-
assert com.is_interval_dtype(pd.IntervalIndex([interval]))
283+
interval = pd.Interval(1, 2, closed="right")
284+
assert not com.is_interval_dtype(interval)
285+
assert com.is_interval_dtype(pd.IntervalIndex([interval]))
275286

276287

277288
def test_is_categorical_dtype():

pandas/tests/dtypes/test_dtypes.py

+50-32
Original file line numberDiff line numberDiff line change
@@ -290,8 +290,10 @@ def test_subclass(self):
290290
assert issubclass(type(a), type(b))
291291

292292
def test_compat(self, dtype):
293-
assert is_datetime64tz_dtype(dtype)
294-
assert is_datetime64tz_dtype("datetime64[ns, US/Eastern]")
293+
msg = "is_datetime64tz_dtype is deprecated"
294+
with tm.assert_produces_warning(FutureWarning, match=msg):
295+
assert is_datetime64tz_dtype(dtype)
296+
assert is_datetime64tz_dtype("datetime64[ns, US/Eastern]")
295297
assert is_datetime64_any_dtype(dtype)
296298
assert is_datetime64_any_dtype("datetime64[ns, US/Eastern]")
297299
assert is_datetime64_ns_dtype(dtype)
@@ -349,25 +351,28 @@ def test_equality(self, dtype):
349351
assert dtype == "M8[ns, US/Eastern]"
350352

351353
def test_basic(self, dtype):
352-
assert is_datetime64tz_dtype(dtype)
354+
msg = "is_datetime64tz_dtype is deprecated"
355+
with tm.assert_produces_warning(FutureWarning, match=msg):
356+
assert is_datetime64tz_dtype(dtype)
353357

354358
dr = date_range("20130101", periods=3, tz="US/Eastern")
355359
s = Series(dr, name="A")
356360

357361
# dtypes
358-
assert is_datetime64tz_dtype(s.dtype)
359-
assert is_datetime64tz_dtype(s)
360-
assert not is_datetime64tz_dtype(np.dtype("float64"))
361-
assert not is_datetime64tz_dtype(1.0)
362+
with tm.assert_produces_warning(FutureWarning, match=msg):
363+
assert is_datetime64tz_dtype(s.dtype)
364+
assert is_datetime64tz_dtype(s)
365+
assert not is_datetime64tz_dtype(np.dtype("float64"))
366+
assert not is_datetime64tz_dtype(1.0)
362367

363368
def test_dst(self):
364369
dr1 = date_range("2013-01-01", periods=3, tz="US/Eastern")
365370
s1 = Series(dr1, name="A")
366-
assert is_datetime64tz_dtype(s1)
371+
assert isinstance(s1.dtype, DatetimeTZDtype)
367372

368373
dr2 = date_range("2013-08-01", periods=3, tz="US/Eastern")
369374
s2 = Series(dr2, name="A")
370-
assert is_datetime64tz_dtype(s2)
375+
assert isinstance(s2.dtype, DatetimeTZDtype)
371376
assert s1.dtype == s2.dtype
372377

373378
@pytest.mark.parametrize("tz", ["UTC", "US/Eastern"])
@@ -595,7 +600,9 @@ def test_hash_vs_equality(self, dtype):
595600
def test_construction(self, subtype):
596601
i = IntervalDtype(subtype, closed="right")
597602
assert i.subtype == np.dtype("int64")
598-
assert is_interval_dtype(i)
603+
msg = "is_interval_dtype is deprecated"
604+
with tm.assert_produces_warning(FutureWarning, match=msg):
605+
assert is_interval_dtype(i)
599606

600607
@pytest.mark.parametrize(
601608
"subtype", ["interval[int64]", "Interval[int64]", "int64", np.dtype("int64")]
@@ -616,7 +623,9 @@ def test_construction_generic(self, subtype):
616623
# generic
617624
i = IntervalDtype(subtype)
618625
assert i.subtype is None
619-
assert is_interval_dtype(i)
626+
msg = "is_interval_dtype is deprecated"
627+
with tm.assert_produces_warning(FutureWarning, match=msg):
628+
assert is_interval_dtype(i)
620629

621630
@pytest.mark.parametrize(
622631
"subtype",
@@ -787,31 +796,35 @@ def test_name_repr_generic(self, subtype):
787796
assert dtype.name == "interval"
788797

789798
def test_basic(self, dtype):
790-
assert is_interval_dtype(dtype)
799+
msg = "is_interval_dtype is deprecated"
800+
with tm.assert_produces_warning(FutureWarning, match=msg):
801+
assert is_interval_dtype(dtype)
791802

792-
ii = IntervalIndex.from_breaks(range(3))
803+
ii = IntervalIndex.from_breaks(range(3))
793804

794-
assert is_interval_dtype(ii.dtype)
795-
assert is_interval_dtype(ii)
805+
assert is_interval_dtype(ii.dtype)
806+
assert is_interval_dtype(ii)
796807

797-
s = Series(ii, name="A")
808+
s = Series(ii, name="A")
798809

799-
assert is_interval_dtype(s.dtype)
800-
assert is_interval_dtype(s)
810+
assert is_interval_dtype(s.dtype)
811+
assert is_interval_dtype(s)
801812

802813
def test_basic_dtype(self):
803-
assert is_interval_dtype("interval[int64, both]")
804-
assert is_interval_dtype(IntervalIndex.from_tuples([(0, 1)]))
805-
assert is_interval_dtype(IntervalIndex.from_breaks(np.arange(4)))
806-
assert is_interval_dtype(
807-
IntervalIndex.from_breaks(date_range("20130101", periods=3))
808-
)
809-
assert not is_interval_dtype("U")
810-
assert not is_interval_dtype("S")
811-
assert not is_interval_dtype("foo")
812-
assert not is_interval_dtype(np.object_)
813-
assert not is_interval_dtype(np.int64)
814-
assert not is_interval_dtype(np.float64)
814+
msg = "is_interval_dtype is deprecated"
815+
with tm.assert_produces_warning(FutureWarning, match=msg):
816+
assert is_interval_dtype("interval[int64, both]")
817+
assert is_interval_dtype(IntervalIndex.from_tuples([(0, 1)]))
818+
assert is_interval_dtype(IntervalIndex.from_breaks(np.arange(4)))
819+
assert is_interval_dtype(
820+
IntervalIndex.from_breaks(date_range("20130101", periods=3))
821+
)
822+
assert not is_interval_dtype("U")
823+
assert not is_interval_dtype("S")
824+
assert not is_interval_dtype("foo")
825+
assert not is_interval_dtype(np.object_)
826+
assert not is_interval_dtype(np.int64)
827+
assert not is_interval_dtype(np.float64)
815828

816829
def test_caching(self):
817830
IntervalDtype.reset_cache()
@@ -1113,9 +1126,14 @@ def test_is_dtype_no_warning(check):
11131126
data = pd.DataFrame({"A": [1, 2]})
11141127

11151128
warn = None
1116-
msg = "is_categorical_dtype is deprecated"
1117-
if check is is_categorical_dtype:
1129+
msg = f"{check.__name__} is deprecated"
1130+
if (
1131+
check is is_categorical_dtype
1132+
or check is is_interval_dtype
1133+
or check is is_datetime64tz_dtype
1134+
):
11181135
warn = FutureWarning
1136+
11191137
with tm.assert_produces_warning(warn, match=msg):
11201138
check(data)
11211139

pandas/tests/dtypes/test_inference.py

+11-5
Original file line numberDiff line numberDiff line change
@@ -1821,6 +1821,8 @@ def test_is_datetime_dtypes(self):
18211821
ts = pd.date_range("20130101", periods=3)
18221822
tsa = pd.date_range("20130101", periods=3, tz="US/Eastern")
18231823

1824+
msg = "is_datetime64tz_dtype is deprecated"
1825+
18241826
assert is_datetime64_dtype("datetime64")
18251827
assert is_datetime64_dtype("datetime64[ns]")
18261828
assert is_datetime64_dtype(ts)
@@ -1836,16 +1838,20 @@ def test_is_datetime_dtypes(self):
18361838
assert is_datetime64_any_dtype(ts)
18371839
assert is_datetime64_any_dtype(tsa)
18381840

1839-
assert not is_datetime64tz_dtype("datetime64")
1840-
assert not is_datetime64tz_dtype("datetime64[ns]")
1841-
assert not is_datetime64tz_dtype(ts)
1842-
assert is_datetime64tz_dtype(tsa)
1841+
with tm.assert_produces_warning(FutureWarning, match=msg):
1842+
assert not is_datetime64tz_dtype("datetime64")
1843+
assert not is_datetime64tz_dtype("datetime64[ns]")
1844+
assert not is_datetime64tz_dtype(ts)
1845+
assert is_datetime64tz_dtype(tsa)
18431846

18441847
@pytest.mark.parametrize("tz", ["US/Eastern", "UTC"])
18451848
def test_is_datetime_dtypes_with_tz(self, tz):
18461849
dtype = f"datetime64[ns, {tz}]"
18471850
assert not is_datetime64_dtype(dtype)
1848-
assert is_datetime64tz_dtype(dtype)
1851+
1852+
msg = "is_datetime64tz_dtype is deprecated"
1853+
with tm.assert_produces_warning(FutureWarning, match=msg):
1854+
assert is_datetime64tz_dtype(dtype)
18491855
assert is_datetime64_ns_dtype(dtype)
18501856
assert is_datetime64_any_dtype(dtype)
18511857

0 commit comments

Comments
 (0)