From 86700a7f048f3e8f837928155548cfcf142c7018 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Wed, 29 Nov 2023 23:25:04 +0100 Subject: [PATCH 01/12] DEPR: Deprecate dtype inference on pandas objects --- doc/source/whatsnew/v2.2.0.rst | 1 + pandas/core/frame.py | 15 +++++++++++++++ pandas/core/indexes/base.py | 15 ++++++++++++++- pandas/core/series.py | 15 +++++++++++++++ pandas/tests/copy_view/test_constructors.py | 3 ++- pandas/tests/frame/test_constructors.py | 17 +++++++++++++++++ .../indexes/base_class/test_constructors.py | 14 ++++++++++++++ pandas/tests/indexes/test_base.py | 3 ++- .../tests/series/accessors/test_dt_accessor.py | 7 ++++--- pandas/tests/series/methods/test_between.py | 2 +- pandas/tests/series/methods/test_equals.py | 6 ++++-- pandas/tests/series/test_constructors.py | 17 ++++++++++++++++- 12 files changed, 105 insertions(+), 10 deletions(-) diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst index 8cb4b3f24d435..ca380340b7d1d 100644 --- a/doc/source/whatsnew/v2.2.0.rst +++ b/doc/source/whatsnew/v2.2.0.rst @@ -384,6 +384,7 @@ Other Deprecations - Deprecated allowing passing :class:`BlockManager` objects to :class:`DataFrame` or :class:`SingleBlockManager` objects to :class:`Series` (:issue:`52419`) - Deprecated automatic downcasting of object-dtype results in :meth:`Series.replace` and :meth:`DataFrame.replace`, explicitly call ``result = result.infer_objects(copy=False)`` instead. To opt in to the future version, use ``pd.set_option("future.no_silent_downcasting", True)`` (:issue:`54710`) - Deprecated downcasting behavior in :meth:`Series.where`, :meth:`DataFrame.where`, :meth:`Series.mask`, :meth:`DataFrame.mask`, :meth:`Series.clip`, :meth:`DataFrame.clip`; in a future version these will not infer object-dtype columns to non-object dtype, or all-round floats to integer dtype. Call ``result.infer_objects(copy=False)`` on the result for object inference, or explicitly cast floats to ints. To opt in to the future version, use ``pd.set_option("future.no_silent_downcasting", True)`` (:issue:`53656`) +- Deprecated dtype inference in :class:`Index`, :class:`Series` and :class:`DataFrame` constructors when giving a pandas input, call ``.infer_objects`` on the input to keep the current behavior (:issue:`56012`) - Deprecated including the groups in computations when using :meth:`DataFrameGroupBy.apply` and :meth:`DataFrameGroupBy.resample`; pass ``include_groups=False`` to exclude the groups (:issue:`7155`) - Deprecated indexing an :class:`Index` with a boolean indexer of length zero (:issue:`55820`) - Deprecated not passing a tuple to :class:`DataFrameGroupBy.get_group` or :class:`SeriesGroupBy.get_group` when grouping by a length-1 list-like (:issue:`25971`) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index f6c44827d1662..bc15a340695d1 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -714,6 +714,10 @@ def __init__( manager = _get_option("mode.data_manager", silent=True) + is_pandas_object = isinstance(data, (Series, Index, ExtensionArray)) + data_dtype = getattr(data, "dtype", None) + original_dtype = dtype + # GH47215 if isinstance(index, set): raise ValueError("index cannot be a set") @@ -900,6 +904,17 @@ def __init__( NDFrame.__init__(self, mgr) + if original_dtype is None and is_pandas_object and data_dtype == np.object_: + if self.dtypes.iloc[0] != data_dtype: + warnings.warn( + "Dtype inference on a pandas object " + "(Series, Index, ExtensionArray) is deprecated. The Index " + "constructor will keep the original dtype in the future. " + "Call ``infer_objects on the result", + FutureWarning, + stacklevel=2, + ) + # ---------------------------------------------------------------------- def __dataframe__( diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index ac4d2976593a2..e508a6b1dd996 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -491,6 +491,8 @@ def __new__( if not copy and isinstance(data, (ABCSeries, Index)): refs = data._references + is_pandas_object = isinstance(data, (ABCSeries, Index, ExtensionArray)) + # range if isinstance(data, (range, RangeIndex)): result = RangeIndex(start=data, copy=copy, name=name) @@ -570,7 +572,18 @@ def __new__( klass = cls._dtype_to_subclass(arr.dtype) arr = klass._ensure_array(arr, arr.dtype, copy=False) - return klass._simple_new(arr, name, refs=refs) + result = klass._simple_new(arr, name, refs=refs) + if dtype is None and is_pandas_object and data_dtype == np.object_: + if result.dtype != data_dtype: + warnings.warn( + "Dtype inference on a pandas object " + "(Series, Index, ExtensionArray) is deprecated. The Index " + "constructor will keep the original dtype in the future. " + "Call ``infer_objects on the result", + FutureWarning, + stacklevel=2, + ) + return result @classmethod def _ensure_array(cls, data, dtype, copy: bool): diff --git a/pandas/core/series.py b/pandas/core/series.py index 888e8cc4e7d40..e4fbfd9ce6ce8 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -424,6 +424,10 @@ def __init__( self.name = name return + is_pandas_object = isinstance(data, (Series, Index, ExtensionArray)) + data_dtype = getattr(data, "dtype", None) + original_dtype = dtype + if isinstance(data, (ExtensionArray, np.ndarray)): if copy is not False and using_copy_on_write(): if dtype is None or astype_is_view(data.dtype, pandas_dtype(dtype)): @@ -581,6 +585,17 @@ def __init__( self.name = name self._set_axis(0, index) + if original_dtype is None and is_pandas_object and data_dtype == np.object_: + if self.dtype != data_dtype: + warnings.warn( + "Dtype inference on a pandas object " + "(Series, Index, ExtensionArray) is deprecated. The Index " + "constructor will keep the original dtype in the future. " + "Call ``infer_objects on the result", + FutureWarning, + stacklevel=2, + ) + def _init_dict( self, data, index: Index | None = None, dtype: DtypeObj | None = None ): diff --git a/pandas/tests/copy_view/test_constructors.py b/pandas/tests/copy_view/test_constructors.py index 7d5c485958039..1aa458a625028 100644 --- a/pandas/tests/copy_view/test_constructors.py +++ b/pandas/tests/copy_view/test_constructors.py @@ -314,7 +314,8 @@ def test_dataframe_from_series_or_index_different_dtype(using_copy_on_write, con def test_dataframe_from_series_infer_datetime(using_copy_on_write): ser = Series([Timestamp("2019-12-31"), Timestamp("2020-12-31")], dtype=object) - df = DataFrame(ser) + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + df = DataFrame(ser) assert not np.shares_memory(get_array(ser), get_array(df, 0)) if using_copy_on_write: assert df._mgr._has_no_reference(0) diff --git a/pandas/tests/frame/test_constructors.py b/pandas/tests/frame/test_constructors.py index 84189f8149d81..081d0ad15de67 100644 --- a/pandas/tests/frame/test_constructors.py +++ b/pandas/tests/frame/test_constructors.py @@ -2759,6 +2759,23 @@ def test_frame_string_inference_block_dim(self): df = DataFrame(np.array([["hello", "goodbye"], ["hello", "Hello"]])) assert df._mgr.blocks[0].ndim == 2 + def test_inference_on_pandas_objects(self): + # GH#56012 + idx = Index([Timestamp("2019-12-31")], dtype=object) + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + result = DataFrame(idx, columns=["a"]) + assert result.dtypes.iloc[0] != np.object_ + result = DataFrame({"a": idx}) + assert result.dtypes.iloc[0] == np.object_ + + ser = Series([Timestamp("2019-12-31")], dtype=object) + + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + result = DataFrame(ser, columns=["a"]) + assert result.dtypes.iloc[0] != np.object_ + result = DataFrame({"a": ser}) + assert result.dtypes.iloc[0] == np.object_ + class TestDataFrameConstructorIndexInference: def test_frame_from_dict_of_series_overlapping_monthly_period_indexes(self): diff --git a/pandas/tests/indexes/base_class/test_constructors.py b/pandas/tests/indexes/base_class/test_constructors.py index 60abbfc441e8e..fd5176a28565e 100644 --- a/pandas/tests/indexes/base_class/test_constructors.py +++ b/pandas/tests/indexes/base_class/test_constructors.py @@ -5,6 +5,7 @@ from pandas import ( Index, MultiIndex, + Series, ) import pandas._testing as tm @@ -57,3 +58,16 @@ def test_index_string_inference(self): with pd.option_context("future.infer_string", True): ser = Index(["a", 1]) tm.assert_index_equal(ser, expected) + + def test_inference_on_pandas_objects(self): + # GH#56012 + idx = Index([pd.Timestamp("2019-12-31")], dtype=object) + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + result = Index(idx) + assert result.dtype != np.object_ + + ser = Series([pd.Timestamp("2019-12-31")], dtype=object) + + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + result = Index(ser) + assert result.dtype != np.object_ diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index 3db81c0285bd2..421ae102b8b12 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -99,7 +99,8 @@ def test_constructor_copy(self, index): ) def test_constructor_from_index_dtlike(self, cast_as_obj, index): if cast_as_obj: - result = Index(index.astype(object)) + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + result = Index(index.astype(object)) else: result = Index(index) diff --git a/pandas/tests/series/accessors/test_dt_accessor.py b/pandas/tests/series/accessors/test_dt_accessor.py index 083a4c4b24adb..fa882cb9a61a0 100644 --- a/pandas/tests/series/accessors/test_dt_accessor.py +++ b/pandas/tests/series/accessors/test_dt_accessor.py @@ -259,9 +259,10 @@ def test_dt_accessor_limited_display_api(self): tm.assert_almost_equal(results, sorted(set(ok_for_dt + ok_for_dt_methods))) # Period - ser = Series( - period_range("20130101", periods=5, freq="D", name="xxx").astype(object) - ) + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + ser = Series( + period_range("20130101", periods=5, freq="D", name="xxx").astype(object) + ) results = get_dir(ser) tm.assert_almost_equal( results, sorted(set(ok_for_period + ok_for_period_methods)) diff --git a/pandas/tests/series/methods/test_between.py b/pandas/tests/series/methods/test_between.py index 8f4931beae589..005272b97e19a 100644 --- a/pandas/tests/series/methods/test_between.py +++ b/pandas/tests/series/methods/test_between.py @@ -20,7 +20,7 @@ def test_between(self): tm.assert_series_equal(result, expected) def test_between_datetime_object_dtype(self): - ser = Series(bdate_range("1/1/2000", periods=20).astype(object)) + ser = Series(bdate_range("1/1/2000", periods=20).astype(object), dtype=object) ser[::2] = np.nan result = ser[ser.between(ser[3], ser[17])] diff --git a/pandas/tests/series/methods/test_equals.py b/pandas/tests/series/methods/test_equals.py index b94723b7cbddf..875ffdd3fe851 100644 --- a/pandas/tests/series/methods/test_equals.py +++ b/pandas/tests/series/methods/test_equals.py @@ -82,13 +82,15 @@ def test_equals_matching_nas(): left = Series([np.datetime64("NaT")], dtype=object) right = Series([np.datetime64("NaT")], dtype=object) assert left.equals(right) - assert Index(left).equals(Index(right)) + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + assert Index(left).equals(Index(right)) assert left.array.equals(right.array) left = Series([np.timedelta64("NaT")], dtype=object) right = Series([np.timedelta64("NaT")], dtype=object) assert left.equals(right) - assert Index(left).equals(Index(right)) + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + assert Index(left).equals(Index(right)) assert left.array.equals(right.array) left = Series([np.float64("NaN")], dtype=object) diff --git a/pandas/tests/series/test_constructors.py b/pandas/tests/series/test_constructors.py index e08f8d0c15f39..69f62199d048e 100644 --- a/pandas/tests/series/test_constructors.py +++ b/pandas/tests/series/test_constructors.py @@ -1323,7 +1323,8 @@ def test_constructor_periodindex(self): pi = period_range("20130101", periods=5, freq="D") s = Series(pi) assert s.dtype == "Period[D]" - expected = Series(pi.astype(object)) + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + expected = Series(pi.astype(object)) tm.assert_series_equal(s, expected) def test_constructor_dict(self): @@ -2144,6 +2145,20 @@ def test_series_string_inference_na_first(self): result = Series([pd.NA, "b"]) tm.assert_series_equal(result, expected) + def test_inference_on_pandas_objects(self): + # GH#56012 + ser = Series([Timestamp("2019-12-31")], dtype=object) + with tm.assert_produces_warning(None): + # This doesn't do inference + result = Series(ser) + assert result.dtype == np.object_ + + idx = Index([Timestamp("2019-12-31")], dtype=object) + + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + result = Series(idx) + assert result.dtype != np.object_ + class TestSeriesConstructorIndexCoercion: def test_series_constructor_datetimelike_index_coercion(self): From 7daf53571cf6268dfd87e50d2dc64f08ce716fea Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Thu, 30 Nov 2023 00:17:58 +0100 Subject: [PATCH 02/12] Fixup tests --- pandas/_testing/__init__.py | 13 ++++++++++--- pandas/tests/tseries/frequencies/test_inference.py | 4 +++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/pandas/_testing/__init__.py b/pandas/_testing/__init__.py index b1918e1b1d7c2..3a1aae47c5eba 100644 --- a/pandas/_testing/__init__.py +++ b/pandas/_testing/__init__.py @@ -15,6 +15,7 @@ ContextManager, cast, ) +import warnings import numpy as np @@ -306,11 +307,17 @@ def box_expected(expected, box_cls, transpose: bool = True): else: expected = pd.array(expected, copy=False) elif box_cls is Index: - expected = Index(expected) + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", "Dtype inference", category=FutureWarning) + expected = Index(expected) elif box_cls is Series: - expected = Series(expected) + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", "Dtype inference", category=FutureWarning) + expected = Series(expected) elif box_cls is DataFrame: - expected = Series(expected).to_frame() + with warnings.catch_warnings(): + warnings.filterwarnings("ignore", "Dtype inference", category=FutureWarning) + expected = Series(expected).to_frame() if transpose: # for vector operations, we need a DataFrame to be a single-row, # not a single-column, in order to operate against non-DataFrame diff --git a/pandas/tests/tseries/frequencies/test_inference.py b/pandas/tests/tseries/frequencies/test_inference.py index 45741e852fef7..99a504f4188c1 100644 --- a/pandas/tests/tseries/frequencies/test_inference.py +++ b/pandas/tests/tseries/frequencies/test_inference.py @@ -23,6 +23,7 @@ date_range, period_range, ) +import pandas._testing as tm from pandas.core.arrays import ( DatetimeArray, TimedeltaArray, @@ -206,7 +207,8 @@ def test_infer_freq_custom(base_delta_code_pair, constructor): ) def test_infer_freq_index(freq, expected): rng = period_range("1959Q2", "2009Q3", freq=freq) - rng = Index(rng.to_timestamp("D", how="e").astype(object)) + with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): + rng = Index(rng.to_timestamp("D", how="e").astype(object)) assert rng.inferred_freq == expected From 2b28aa29605527f6531fc33002383427b2a8cb7c Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Thu, 30 Nov 2023 10:52:01 +0100 Subject: [PATCH 03/12] Update base.py --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index e508a6b1dd996..342cd9675f244 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -583,7 +583,7 @@ def __new__( FutureWarning, stacklevel=2, ) - return result + return result # type: ignore[return-value] @classmethod def _ensure_array(cls, data, dtype, copy: bool): From 1c6c3e3a930c0db92294445c25f213efb6ec1fe7 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Sat, 9 Dec 2023 23:55:10 +0100 Subject: [PATCH 04/12] Fixup --- pandas/core/strings/accessor.py | 11 +++++------ pandas/tests/strings/test_cat.py | 21 ++++++++++++++++----- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/pandas/core/strings/accessor.py b/pandas/core/strings/accessor.py index 75866c6f6013a..631030d637fae 100644 --- a/pandas/core/strings/accessor.py +++ b/pandas/core/strings/accessor.py @@ -689,19 +689,18 @@ def cat( result = cat_safe(all_cols, sep) out: Index | Series + if isinstance(self._orig.dtype, CategoricalDtype): + # We need to infer the new categories. + dtype = self._orig.dtype.categories.dtype # type: ignore[assignment] + else: + dtype = self._orig.dtype if isinstance(self._orig, ABCIndex): # add dtype for case that result is all-NA - dtype = None if isna(result).all(): dtype = object out = Index(result, dtype=dtype, name=self._orig.name) else: # Series - if isinstance(self._orig.dtype, CategoricalDtype): - # We need to infer the new categories. - dtype = self._orig.dtype.categories.dtype # type: ignore[assignment] - else: - dtype = self._orig.dtype res_ser = Series( result, dtype=dtype, index=data.index, name=self._orig.name, copy=False ) diff --git a/pandas/tests/strings/test_cat.py b/pandas/tests/strings/test_cat.py index 284932491a65e..c1e7ad6e02779 100644 --- a/pandas/tests/strings/test_cat.py +++ b/pandas/tests/strings/test_cat.py @@ -98,14 +98,18 @@ def test_str_cat_categorical( with option_context("future.infer_string", infer_string): s = Index(["a", "a", "b", "a"], dtype=dtype_caller) - s = s if box == Index else Series(s, index=s) + s = s if box == Index else Series(s, index=s, dtype=s.dtype) t = Index(["b", "a", "b", "c"], dtype=dtype_target) - expected = Index(["ab", "aa", "bb", "ac"]) + expected = Index( + ["ab", "aa", "bb", "ac"], dtype=object if dtype_caller == "object" else None + ) expected = ( expected if box == Index - else Series(expected, index=Index(s, dtype=dtype_caller)) + else Series( + expected, index=Index(s, dtype=dtype_caller), dtype=expected.dtype + ) ) # Series/Index with unaligned Index -> t.values @@ -123,12 +127,19 @@ def test_str_cat_categorical( # Series/Index with Series having different Index t = Series(t.values, index=t.values) - expected = Index(["aa", "aa", "bb", "bb", "aa"]) + expected = Index( + ["aa", "aa", "bb", "bb", "aa"], + dtype=object if dtype_caller == "object" else None, + ) dtype = object if dtype_caller == "object" else s.dtype.categories.dtype expected = ( expected if box == Index - else Series(expected, index=Index(expected.str[:1], dtype=dtype)) + else Series( + expected, + index=Index(expected.str[:1], dtype=dtype), + dtype=expected.dtype, + ) ) result = s.str.cat(t, sep=sep) From 5a6244c4ac77cc082f66785856186e971e894c0b Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Thu, 14 Dec 2023 22:39:16 +0100 Subject: [PATCH 05/12] Update accessor.py --- pandas/core/strings/accessor.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pandas/core/strings/accessor.py b/pandas/core/strings/accessor.py index 631030d637fae..1b7d632c0fa80 100644 --- a/pandas/core/strings/accessor.py +++ b/pandas/core/strings/accessor.py @@ -691,13 +691,13 @@ def cat( out: Index | Series if isinstance(self._orig.dtype, CategoricalDtype): # We need to infer the new categories. - dtype = self._orig.dtype.categories.dtype # type: ignore[assignment] + dtype = self._orig.dtype.categories.dtype else: dtype = self._orig.dtype if isinstance(self._orig, ABCIndex): # add dtype for case that result is all-NA if isna(result).all(): - dtype = object + dtype = object # type: ignore[assignment] out = Index(result, dtype=dtype, name=self._orig.name) else: # Series From 24eff8007fc2e8d2d9ac2c23c37741391623db8d Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Mon, 18 Dec 2023 20:30:43 +0100 Subject: [PATCH 06/12] Update pandas/core/indexes/base.py Co-authored-by: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> --- pandas/core/indexes/base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 50b0fcfd6dc21..f994b1057ee44 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -580,7 +580,7 @@ def __new__( "Dtype inference on a pandas object " "(Series, Index, ExtensionArray) is deprecated. The Index " "constructor will keep the original dtype in the future. " - "Call ``infer_objects on the result", + "Call `infer_objects` on the result", FutureWarning, stacklevel=2, ) From eef58ea3ad18f282521686e08f85a5345ad57e82 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Mon, 18 Dec 2023 20:30:48 +0100 Subject: [PATCH 07/12] Update pandas/core/frame.py Co-authored-by: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> --- pandas/core/frame.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 638662a690775..6dcbe10618d26 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -922,7 +922,7 @@ def __init__( "Dtype inference on a pandas object " "(Series, Index, ExtensionArray) is deprecated. The Index " "constructor will keep the original dtype in the future. " - "Call ``infer_objects on the result", + "Call `infer_objects` on the result", FutureWarning, stacklevel=2, ) From ab2a735558030e1d67e059951a58e789fc641697 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Mon, 18 Dec 2023 20:31:01 +0100 Subject: [PATCH 08/12] Update pandas/core/series.py Co-authored-by: Matthew Roeschke <10647082+mroeschke@users.noreply.github.com> --- pandas/core/series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index a322b02fc50c9..c79309867cb28 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -591,7 +591,7 @@ def __init__( "Dtype inference on a pandas object " "(Series, Index, ExtensionArray) is deprecated. The Index " "constructor will keep the original dtype in the future. " - "Call ``infer_objects on the result", + "Call `infer_objects` on the result", FutureWarning, stacklevel=2, ) From ab62a3196169899ccff239a978f22032dacea964 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Mon, 18 Dec 2023 21:02:35 +0100 Subject: [PATCH 09/12] Update series.py --- pandas/core/series.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/core/series.py b/pandas/core/series.py index c79309867cb28..9af3d63fa1081 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -593,7 +593,7 @@ def __init__( "constructor will keep the original dtype in the future. " "Call `infer_objects` on the result", FutureWarning, - stacklevel=2, + stacklevel=find_stack_level(), ) def _init_dict( From 0e828b72b891944447387ddc7215c8c35f37d41f Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Thu, 21 Dec 2023 19:47:11 +0100 Subject: [PATCH 10/12] Update --- pandas/core/frame.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 6dcbe10618d26..e1048a51089ac 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -920,9 +920,10 @@ def __init__( if self.dtypes.iloc[0] != data_dtype: warnings.warn( "Dtype inference on a pandas object " - "(Series, Index, ExtensionArray) is deprecated. The Index " + "(Series, Index, ExtensionArray) is deprecated. The DataFrame " "constructor will keep the original dtype in the future. " - "Call `infer_objects` on the result", + "Call `infer_objects` on the result to get the old " + "behavior.", FutureWarning, stacklevel=2, ) From 86f1a946001b0e09f088ce79d47743f718eac5a3 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Thu, 21 Dec 2023 19:51:21 +0100 Subject: [PATCH 11/12] Address comments --- pandas/core/indexes/base.py | 3 ++- pandas/core/series.py | 4 ++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index f994b1057ee44..e01c4e75e9f8a 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -580,7 +580,8 @@ def __new__( "Dtype inference on a pandas object " "(Series, Index, ExtensionArray) is deprecated. The Index " "constructor will keep the original dtype in the future. " - "Call `infer_objects` on the result", + "Call `infer_objects` on the result to get the old " + "behavior.", FutureWarning, stacklevel=2, ) diff --git a/pandas/core/series.py b/pandas/core/series.py index 9af3d63fa1081..d46068b6338c5 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -589,9 +589,9 @@ def __init__( if self.dtype != data_dtype: warnings.warn( "Dtype inference on a pandas object " - "(Series, Index, ExtensionArray) is deprecated. The Index " + "(Series, Index, ExtensionArray) is deprecated. The Series " "constructor will keep the original dtype in the future. " - "Call `infer_objects` on the result", + "Call `infer_objects` on the result to get the old behavior.", FutureWarning, stacklevel=find_stack_level(), ) From cd067cc8b6f9fa4424e9086459bad1b2f1560e7b Mon Sep 17 00:00:00 2001 From: Patrick Hoefler <61934744+phofl@users.noreply.github.com> Date: Thu, 21 Dec 2023 22:44:27 +0100 Subject: [PATCH 12/12] Address comments --- pandas/tests/series/accessors/test_dt_accessor.py | 5 ++--- pandas/tests/series/methods/test_between.py | 2 +- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/pandas/tests/series/accessors/test_dt_accessor.py b/pandas/tests/series/accessors/test_dt_accessor.py index fa882cb9a61a0..34465a7c12c18 100644 --- a/pandas/tests/series/accessors/test_dt_accessor.py +++ b/pandas/tests/series/accessors/test_dt_accessor.py @@ -259,10 +259,9 @@ def test_dt_accessor_limited_display_api(self): tm.assert_almost_equal(results, sorted(set(ok_for_dt + ok_for_dt_methods))) # Period + idx = period_range("20130101", periods=5, freq="D", name="xxx").astype(object) with tm.assert_produces_warning(FutureWarning, match="Dtype inference"): - ser = Series( - period_range("20130101", periods=5, freq="D", name="xxx").astype(object) - ) + ser = Series(idx) results = get_dir(ser) tm.assert_almost_equal( results, sorted(set(ok_for_period + ok_for_period_methods)) diff --git a/pandas/tests/series/methods/test_between.py b/pandas/tests/series/methods/test_between.py index 005272b97e19a..3913419038876 100644 --- a/pandas/tests/series/methods/test_between.py +++ b/pandas/tests/series/methods/test_between.py @@ -20,7 +20,7 @@ def test_between(self): tm.assert_series_equal(result, expected) def test_between_datetime_object_dtype(self): - ser = Series(bdate_range("1/1/2000", periods=20).astype(object), dtype=object) + ser = Series(bdate_range("1/1/2000", periods=20), dtype=object) ser[::2] = np.nan result = ser[ser.between(ser[3], ser[17])]