From 3be1a5890a7e24d00d9ace294c08568f25a4473c Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 30 Oct 2025 18:00:12 -0700 Subject: [PATCH 1/2] DEPR: to_datetime call in Series.combine_first --- doc/source/whatsnew/v3.0.0.rst | 1 + pandas/core/series.py | 9 +++++++++ pandas/tests/series/methods/test_combine_first.py | 8 +++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 38755aef32b85..55d250749f435 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -739,6 +739,7 @@ Other Deprecations - Deprecated option "future.no_silent_downcasting", as it is no longer used. In a future version accessing this option will raise (:issue:`59502`) - Deprecated slicing on a :class:`Series` or :class:`DataFrame` with a :class:`DatetimeIndex` using a ``datetime.date`` object, explicitly cast to :class:`Timestamp` instead (:issue:`35830`) - Deprecated the 'inplace' keyword from :meth:`Resampler.interpolate`, as passing ``True`` raises ``AttributeError`` (:issue:`58690`) +- Deprecated silent casting of non-datetime 'other' to datetime in :meth:`Series.combine_first` (:issue:`??`) .. --------------------------------------------------------------------------- .. _whatsnew_300.prior_deprecations: diff --git a/pandas/core/series.py b/pandas/core/series.py index fe71a3ab91933..f7adb5869cf25 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3271,6 +3271,15 @@ def combine_first(self, other) -> Series: if this.dtype.kind == "M" and other.dtype.kind != "M": # TODO: try to match resos? other = to_datetime(other) + warnings.warn( + "Silently casting non-datetime 'other' to datetime in " + "Series.combine_first is deprecated and will be removed " + "in a future version. Explicitly cast before calling " + "combine_first instead.", + Pandas4Warning, + stacklevel=find_stack_level(), + ) + combined = concat([this, other]) combined = combined.reindex(new_index) return combined.__finalize__(self, method="combine_first") diff --git a/pandas/tests/series/methods/test_combine_first.py b/pandas/tests/series/methods/test_combine_first.py index 51d6704e1905b..10f83cd9fc909 100644 --- a/pandas/tests/series/methods/test_combine_first.py +++ b/pandas/tests/series/methods/test_combine_first.py @@ -2,6 +2,8 @@ import numpy as np +from pandas.errors import Pandas4Warning + import pandas as pd from pandas import ( Period, @@ -75,9 +77,13 @@ def test_combine_first_dt64(self, unit): xp = to_datetime(Series(["2010", "2011"])).dt.as_unit(unit) tm.assert_series_equal(rs, xp) + def test_combine_first_dt64_casting_deprecation(self, unit): s0 = to_datetime(Series(["2010", np.nan])).dt.as_unit(unit) s1 = Series([np.nan, "2011"]) - rs = s0.combine_first(s1) + + msg = "Silently casting non-datetime 'other' to datetime" + with tm.assert_produces_warning(Pandas4Warning, match=msg): + rs = s0.combine_first(s1) xp = Series([datetime(2010, 1, 1), "2011"], dtype=f"datetime64[{unit}]") From f79e684bf5a019bfbaf51792089088ce541c1b7d Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 30 Oct 2025 18:02:50 -0700 Subject: [PATCH 2/2] GH ref --- doc/source/whatsnew/v3.0.0.rst | 2 +- pandas/core/series.py | 1 + pandas/tests/series/methods/test_combine_first.py | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v3.0.0.rst b/doc/source/whatsnew/v3.0.0.rst index 55d250749f435..425d6d1c49774 100644 --- a/doc/source/whatsnew/v3.0.0.rst +++ b/doc/source/whatsnew/v3.0.0.rst @@ -737,9 +737,9 @@ Other Deprecations - Deprecated allowing ``fill_value`` that cannot be held in the original dtype (excepting NA values for integer and bool dtypes) in :meth:`Series.shift` and :meth:`DataFrame.shift` (:issue:`53802`) - Deprecated backward-compatibility behavior for :meth:`DataFrame.select_dtypes` matching "str" dtype when ``np.object_`` is specified (:issue:`61916`) - Deprecated option "future.no_silent_downcasting", as it is no longer used. In a future version accessing this option will raise (:issue:`59502`) +- Deprecated silent casting of non-datetime 'other' to datetime in :meth:`Series.combine_first` (:issue:`62931`) - Deprecated slicing on a :class:`Series` or :class:`DataFrame` with a :class:`DatetimeIndex` using a ``datetime.date`` object, explicitly cast to :class:`Timestamp` instead (:issue:`35830`) - Deprecated the 'inplace' keyword from :meth:`Resampler.interpolate`, as passing ``True`` raises ``AttributeError`` (:issue:`58690`) -- Deprecated silent casting of non-datetime 'other' to datetime in :meth:`Series.combine_first` (:issue:`??`) .. --------------------------------------------------------------------------- .. _whatsnew_300.prior_deprecations: diff --git a/pandas/core/series.py b/pandas/core/series.py index f7adb5869cf25..1f4a09fefa0ac 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -3272,6 +3272,7 @@ def combine_first(self, other) -> Series: # TODO: try to match resos? other = to_datetime(other) warnings.warn( + # GH#62931 "Silently casting non-datetime 'other' to datetime in " "Series.combine_first is deprecated and will be removed " "in a future version. Explicitly cast before calling " diff --git a/pandas/tests/series/methods/test_combine_first.py b/pandas/tests/series/methods/test_combine_first.py index 10f83cd9fc909..490a71a993611 100644 --- a/pandas/tests/series/methods/test_combine_first.py +++ b/pandas/tests/series/methods/test_combine_first.py @@ -78,6 +78,7 @@ def test_combine_first_dt64(self, unit): tm.assert_series_equal(rs, xp) def test_combine_first_dt64_casting_deprecation(self, unit): + # GH#62931 s0 = to_datetime(Series(["2010", np.nan])).dt.as_unit(unit) s1 = Series([np.nan, "2011"])