Skip to content

Commit

Permalink
DEPR: is_all_dates (#36697)
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrockmendel committed Sep 30, 2020
1 parent 78bca00 commit 90a6135
Show file tree
Hide file tree
Showing 20 changed files with 87 additions and 41 deletions.
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v1.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,8 @@ Deprecations
- :meth:`DataFrame.lookup` is deprecated and will be removed in a future version, use :meth:`DataFrame.melt` and :meth:`DataFrame.loc` instead (:issue:`18682`)
- The :meth:`Index.to_native_types` is deprecated. Use ``.astype(str)`` instead (:issue:`28867`)
- Deprecated indexing :class:`DataFrame` rows with datetime-like strings ``df[string]``, use ``df.loc[string]`` instead (:issue:`36179`)
- Deprecated casting an object-dtype index of ``datetime`` objects to :class:`DatetimeIndex` in the :class:`Series` constructor (:issue:`23598`)
- Deprecated :meth:`Index.is_all_dates` (:issue:`27744`)

.. ---------------------------------------------------------------------------
Expand Down
8 changes: 7 additions & 1 deletion pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -9528,7 +9528,13 @@ def truncate(

# if we have a date index, convert to dates, otherwise
# treat like a slice
if ax.is_all_dates:
if ax._is_all_dates:
if is_object_dtype(ax.dtype):
warnings.warn(
"Treating object-dtype Index of date objects as DatetimeIndex "
"is deprecated, will be removed in a future version.",
FutureWarning,
)
from pandas.core.tools.datetimes import to_datetime

before = to_datetime(before)
Expand Down
15 changes: 14 additions & 1 deletion pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -2086,12 +2086,25 @@ def inferred_type(self) -> str_t:
return lib.infer_dtype(self._values, skipna=False)

@cache_readonly
def is_all_dates(self) -> bool:
def _is_all_dates(self) -> bool:
"""
Whether or not the index values only consist of dates.
"""
return is_datetime_array(ensure_object(self._values))

@cache_readonly
def is_all_dates(self):
"""
Whether or not the index values only consist of dates.
"""
warnings.warn(
"Index.is_all_dates is deprecated, will be removed in a future version. "
"check index.inferred_type instead",
FutureWarning,
stacklevel=2,
)
return self._is_all_dates

# --------------------------------------------------------------------
# Pickle Methods

Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/datetimelike.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ class DatetimeIndexOpsMixin(ExtensionIndex):
_hasnans = hasnans # for index / array -agnostic code

@property
def is_all_dates(self) -> bool:
def _is_all_dates(self) -> bool:
return True

# ------------------------------------------------------------------------
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -1092,7 +1092,7 @@ def func(self, other, sort=sort):
# --------------------------------------------------------------------

@property
def is_all_dates(self) -> bool:
def _is_all_dates(self) -> bool:
"""
This is False even when left/right contain datetime-like objects,
as the check is done on the Interval itself
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/multi.py
Original file line number Diff line number Diff line change
Expand Up @@ -1733,7 +1733,7 @@ def to_flat_index(self):
return Index(self._values, tupleize_cols=False)

@property
def is_all_dates(self) -> bool:
def _is_all_dates(self) -> bool:
return False

def is_lexsorted(self) -> bool:
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/indexes/numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ def _assert_safe_casting(cls, data, subarr):
pass

@property
def is_all_dates(self) -> bool:
def _is_all_dates(self) -> bool:
"""
Checks that all the labels are datetime objects.
"""
Expand Down
4 changes: 2 additions & 2 deletions pandas/core/missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ def interpolate_1d(
return yvalues

if method == "time":
if not getattr(xvalues, "is_all_dates", None):
if not getattr(xvalues, "_is_all_dates", None):
# if not issubclass(xvalues.dtype.type, np.datetime64):
raise ValueError(
"time-weighted interpolation only works "
Expand Down Expand Up @@ -327,7 +327,7 @@ def _interpolate_scipy_wrapper(
"piecewise_polynomial": _from_derivatives,
}

if getattr(x, "is_all_dates", False):
if getattr(x, "_is_all_dates", False):
# GH 5975, scipy.interp1d can't handle datetime64s
x, new_x = x._values.astype("i8"), new_x.astype("i8")

Expand Down
10 changes: 8 additions & 2 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -409,14 +409,20 @@ def _set_axis(self, axis: int, labels, fastpath: bool = False) -> None:
if not fastpath:
labels = ensure_index(labels)

is_all_dates = labels.is_all_dates
if is_all_dates:
if labels._is_all_dates:
if not isinstance(labels, (DatetimeIndex, PeriodIndex, TimedeltaIndex)):
try:
labels = DatetimeIndex(labels)
# need to set here because we changed the index
if fastpath:
self._mgr.set_axis(axis, labels)
warnings.warn(
"Automatically casting object-dtype Index of datetimes to "
"DatetimeIndex is deprecated and will be removed in a "
"future version. Explicitly cast to DatetimeIndex instead.",
FutureWarning,
stacklevel=3,
)
except (tslibs.OutOfBoundsDatetime, ValueError):
# labels may exceeds datetime bounds,
# or not be a DatetimeIndex
Expand Down
2 changes: 1 addition & 1 deletion pandas/plotting/_matplotlib/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -1238,7 +1238,7 @@ def get_label(i):
# would be too close together.
condition = (
not self._use_dynamic_x()
and (data.index.is_all_dates and self.use_index)
and (data.index._is_all_dates and self.use_index)
and (not self.subplots or (self.subplots and self.sharex))
)

Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/interval/test_interval.py
Original file line number Diff line number Diff line change
Expand Up @@ -871,7 +871,7 @@ def test_is_all_dates(self):
pd.Timestamp("2017-01-01 00:00:00"), pd.Timestamp("2018-01-01 00:00:00")
)
year_2017_index = pd.IntervalIndex([year_2017])
assert not year_2017_index.is_all_dates
assert not year_2017_index._is_all_dates

@pytest.mark.parametrize("key", [[5], (2, 3)])
def test_get_value_non_scalar_errors(self, key):
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/indexes/multi/test_equivalence.py
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ def test_is_():


def test_is_all_dates(idx):
assert not idx.is_all_dates
assert not idx._is_all_dates


def test_is_numeric(idx):
Expand Down
3 changes: 2 additions & 1 deletion pandas/tests/indexes/test_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -1153,7 +1153,8 @@ def test_is_object(self, index, expected):
indirect=["index"],
)
def test_is_all_dates(self, index, expected):
assert index.is_all_dates is expected
with tm.assert_produces_warning(FutureWarning):
assert index.is_all_dates is expected

def test_summary(self, index):
self._check_method_works(Index._summary, index)
Expand Down
8 changes: 5 additions & 3 deletions pandas/tests/indexing/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -554,15 +554,17 @@ def test_string_slice(self):
# string indexing against datetimelike with object
# dtype should properly raises KeyError
df = DataFrame([1], Index([pd.Timestamp("2011-01-01")], dtype=object))
assert df.index.is_all_dates
assert df.index._is_all_dates
with pytest.raises(KeyError, match="'2011'"):
df["2011"]

with pytest.raises(KeyError, match="'2011'"):
df.loc["2011", 0]
with tm.assert_produces_warning(FutureWarning):
# This does an is_all_dates check
df.loc["2011", 0]

df = DataFrame()
assert not df.index.is_all_dates
assert not df.index._is_all_dates
with pytest.raises(KeyError, match="'2011'"):
df["2011"]

Expand Down
10 changes: 8 additions & 2 deletions pandas/tests/io/pytables/test_store.py
Original file line number Diff line number Diff line change
Expand Up @@ -2384,10 +2384,16 @@ def test_series(self, setup_path):
ts = tm.makeTimeSeries()
self._check_roundtrip(ts, tm.assert_series_equal, path=setup_path)

ts2 = Series(ts.index, Index(ts.index, dtype=object))
with tm.assert_produces_warning(FutureWarning):
# auto-casting object->DatetimeIndex deprecated
ts2 = Series(ts.index, Index(ts.index, dtype=object))
self._check_roundtrip(ts2, tm.assert_series_equal, path=setup_path)

ts3 = Series(ts.values, Index(np.asarray(ts.index, dtype=object), dtype=object))
with tm.assert_produces_warning(FutureWarning):
# auto-casting object->DatetimeIndex deprecated
ts3 = Series(
ts.values, Index(np.asarray(ts.index, dtype=object), dtype=object)
)
self._check_roundtrip(
ts3, tm.assert_series_equal, path=setup_path, check_index_type=False
)
Expand Down
2 changes: 1 addition & 1 deletion pandas/tests/series/test_alter_axes.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,4 @@ def test_set_index_makes_timeseries(self):

s = Series(range(10))
s.index = idx
assert s.index.is_all_dates
assert s.index._is_all_dates
8 changes: 4 additions & 4 deletions pandas/tests/series/test_constructors.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,11 +94,11 @@ def test_scalar_conversion(self):
def test_constructor(self, datetime_series):
with tm.assert_produces_warning(DeprecationWarning, check_stacklevel=False):
empty_series = Series()
assert datetime_series.index.is_all_dates
assert datetime_series.index._is_all_dates

# Pass in Series
derived = Series(datetime_series)
assert derived.index.is_all_dates
assert derived.index._is_all_dates

assert tm.equalContents(derived.index, datetime_series.index)
# Ensure new index is not created
Expand All @@ -109,9 +109,9 @@ def test_constructor(self, datetime_series):
assert mixed.dtype == np.object_
assert mixed[1] is np.NaN

assert not empty_series.index.is_all_dates
assert not empty_series.index._is_all_dates
with tm.assert_produces_warning(DeprecationWarning, check_stacklevel=False):
assert not Series().index.is_all_dates
assert not Series().index._is_all_dates

# exception raised is of type Exception
with pytest.raises(Exception, match="Data must be 1-dimensional"):
Expand Down
4 changes: 3 additions & 1 deletion pandas/tests/series/test_repr.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,9 @@ def test_timeseries_repr_object_dtype(self):
index = Index(
[datetime(2000, 1, 1) + timedelta(i) for i in range(1000)], dtype=object
)
ts = Series(np.random.randn(len(index)), index)
with tm.assert_produces_warning(FutureWarning):
# Index.is_all_dates deprecated
ts = Series(np.random.randn(len(index)), index)
repr(ts)

ts = tm.makeTimeSeries(1000)
Expand Down
6 changes: 4 additions & 2 deletions pandas/tests/series/test_timeseries.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@
class TestTimeSeries:
def test_timeseries_coercion(self):
idx = tm.makeDateIndex(10000)
ser = Series(np.random.randn(len(idx)), idx.astype(object))
assert ser.index.is_all_dates
with tm.assert_produces_warning(FutureWarning):
ser = Series(np.random.randn(len(idx)), idx.astype(object))
with tm.assert_produces_warning(FutureWarning):
assert ser.index.is_all_dates
assert isinstance(ser.index, DatetimeIndex)

def test_contiguous_boolean_preserve_freq(self):
Expand Down
34 changes: 20 additions & 14 deletions pandas/tests/window/moments/test_moments_rolling_apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,16 @@ def test_center_reindex_series(raw, series):
s = [f"x{x:d}" for x in range(12)]
minp = 10

series_xp = (
series.reindex(list(series.index) + s)
.rolling(window=25, min_periods=minp)
.apply(f, raw=raw)
.shift(-12)
.reindex(series.index)
)
warn = None if raw else FutureWarning
with tm.assert_produces_warning(warn, check_stacklevel=False):
# GH#36697 is_all_dates deprecated
series_xp = (
series.reindex(list(series.index) + s)
.rolling(window=25, min_periods=minp)
.apply(f, raw=raw)
.shift(-12)
.reindex(series.index)
)
series_rs = series.rolling(window=25, min_periods=minp, center=True).apply(
f, raw=raw
)
Expand All @@ -140,12 +143,15 @@ def test_center_reindex_frame(raw, frame):
s = [f"x{x:d}" for x in range(12)]
minp = 10

frame_xp = (
frame.reindex(list(frame.index) + s)
.rolling(window=25, min_periods=minp)
.apply(f, raw=raw)
.shift(-12)
.reindex(frame.index)
)
warn = None if raw else FutureWarning
with tm.assert_produces_warning(warn, check_stacklevel=False):
# GH#36697 is_all_dates deprecated
frame_xp = (
frame.reindex(list(frame.index) + s)
.rolling(window=25, min_periods=minp)
.apply(f, raw=raw)
.shift(-12)
.reindex(frame.index)
)
frame_rs = frame.rolling(window=25, min_periods=minp, center=True).apply(f, raw=raw)
tm.assert_frame_equal(frame_xp, frame_rs)

0 comments on commit 90a6135

Please sign in to comment.