diff --git a/doc/source/whatsnew/v1.5.0.rst b/doc/source/whatsnew/v1.5.0.rst index a485aece76294..b2e39bad695af 100644 --- a/doc/source/whatsnew/v1.5.0.rst +++ b/doc/source/whatsnew/v1.5.0.rst @@ -138,6 +138,7 @@ Slicing on a :class:`DataFrame` will not be affected. Other Deprecations ^^^^^^^^^^^^^^^^^^ +- Deprecated the fallback behavior for :meth:`Series.where`, :meth:`Series.mask`, :meth:`DataFrame.where` and :meth:`DataFrame.mask` with ``PeriodDtype`` when an incompatible value is passed. In a future version, this will coerce to a common dtype instead of raising, matching other datetime-like dtypes (:issue:`45148`) - Deprecated the keyword ``line_terminator`` in :meth:`DataFrame.to_csv` and :meth:`Series.to_csv`, use ``lineterminator`` instead; this is for consistency with :func:`read_csv` and the standard library 'csv' module (:issue:`9568`) - Deprecated :meth:`DataFrame.iteritems`, :meth:`Series.iteritems`, :meth:`HDFStore.iteritems` in favor of :meth:`DataFrame.items`, :meth:`Series.items`, :meth:`HDFStore.items` (:issue:`45321`) - diff --git a/pandas/core/internals/blocks.py b/pandas/core/internals/blocks.py index d8543a15b1ea0..69f972c946741 100644 --- a/pandas/core/internals/blocks.py +++ b/pandas/core/internals/blocks.py @@ -1379,9 +1379,17 @@ def where(self, other, cond) -> list[Block]: # NB: not (yet) the same as # isinstance(values, NDArrayBackedExtensionArray) if isinstance(self.dtype, PeriodDtype): - # TODO: don't special-case - # Note: this is the main place where the fallback logic - # is different from EABackedBlock.putmask. + # TODO(2.0): once this deprecation is enforced, we can + # share fallback logic with EABackedBlock.putmask. + # GH#45148 + warnings.warn( + "The fallback behavior of .where and .mask with PeriodDtype is " + "deprecated. In a future version, when an incompatible " + "value is passed, the array will be upcast to a common dtype " + "(matching the behavior of other datetimelike dtypes).", + FutureWarning, + stacklevel=find_stack_level(), + ) raise blk = self.coerce_to_target_dtype(other) nbs = blk.where(other, cond) diff --git a/pandas/tests/frame/indexing/test_where.py b/pandas/tests/frame/indexing/test_where.py index 29605d0cfad3e..2f780c03bdfa7 100644 --- a/pandas/tests/frame/indexing/test_where.py +++ b/pandas/tests/frame/indexing/test_where.py @@ -893,11 +893,15 @@ def test_where_period_invalid_na(frame_or_series, as_cat, request): else: msg = "value should be a 'Period'" + warn = None if as_cat else FutureWarning + wmsg = "The fallback behavior of .where with PeriodDtype" with pytest.raises(TypeError, match=msg): - obj.where(mask, tdnat) + with tm.assert_produces_warning(warn, match=wmsg): + obj.where(mask, tdnat) with pytest.raises(TypeError, match=msg): - obj.mask(mask, tdnat) + with tm.assert_produces_warning(warn, match=wmsg): + obj.mask(mask, tdnat) def test_where_nullable_invalid_na(frame_or_series, any_numeric_ea_dtype):