diff --git a/doc/source/user_guide/duplicates.rst b/doc/source/user_guide/duplicates.rst index 7894789846ce8..3475dd0cea3f8 100644 --- a/doc/source/user_guide/duplicates.rst +++ b/doc/source/user_guide/duplicates.rst @@ -121,6 +121,7 @@ will be raised. .. ipython:: python :okexcept: + :okwarning: pd.Series([0, 1, 2], index=["a", "b", "b"]).set_flags(allows_duplicate_labels=False) @@ -128,6 +129,7 @@ This applies to both row and column labels for a :class:`DataFrame` .. ipython:: python :okexcept: + :okwarning: pd.DataFrame([[0, 1, 2], [3, 4, 5]], columns=["A", "B", "C"],).set_flags( allows_duplicate_labels=False @@ -137,6 +139,7 @@ This attribute can be checked or set with :attr:`~DataFrame.flags.allows_duplica which indicates whether that object can have duplicate labels. .. ipython:: python + :okwarning: df = pd.DataFrame({"A": [0, 1, 2, 3]}, index=["x", "y", "X", "Y"]).set_flags( allows_duplicate_labels=False @@ -148,6 +151,7 @@ which indicates whether that object can have duplicate labels. like ``allows_duplicate_labels`` set to some value .. ipython:: python + :okwarning: df2 = df.set_flags(allows_duplicate_labels=True) df2.flags.allows_duplicate_labels @@ -157,6 +161,7 @@ Or the property can just be set directly on the same object .. ipython:: python + :okwarning: df2.flags.allows_duplicate_labels = False df2.flags.allows_duplicate_labels @@ -193,6 +198,7 @@ operations. .. ipython:: python :okexcept: + :okwarning: s1 = pd.Series(0, index=["a", "b"]).set_flags(allows_duplicate_labels=False) s1 diff --git a/doc/source/whatsnew/v2.2.0.rst b/doc/source/whatsnew/v2.2.0.rst index d1481639ca5a0..dbfdd4c85862e 100644 --- a/doc/source/whatsnew/v2.2.0.rst +++ b/doc/source/whatsnew/v2.2.0.rst @@ -597,6 +597,7 @@ Other Deprecations - Deprecated :func:`pd.core.internals.api.make_block`, use public APIs instead (:issue:`40226`) - Deprecated :func:`read_gbq` and :meth:`DataFrame.to_gbq`. Use ``pandas_gbq.read_gbq`` and ``pandas_gbq.to_gbq`` instead https://pandas-gbq.readthedocs.io/en/latest/api.html (:issue:`55525`) - Deprecated :meth:`.DataFrameGroupBy.fillna` and :meth:`.SeriesGroupBy.fillna`; use :meth:`.DataFrameGroupBy.ffill`, :meth:`.DataFrameGroupBy.bfill` for forward and backward filling or :meth:`.DataFrame.fillna` to fill with a single value (or the Series equivalents) (:issue:`55718`) +- Deprecated :meth:`DataFrame.flags`, :meth:`DataFrame.set_flags`, :meth:`Series.flags`, :meth:`Series.set_flags` (:issue:`51280`) - Deprecated :meth:`DatetimeArray.__init__` and :meth:`TimedeltaArray.__init__`, use :func:`array` instead (:issue:`55623`) - Deprecated :meth:`Index.format`, use ``index.astype(str)`` or ``index.map(formatter)`` instead (:issue:`55413`) - Deprecated :meth:`Series.ravel`, the underlying array is already 1D, so ravel is not necessary (:issue:`52511`) diff --git a/pandas/_testing/asserters.py b/pandas/_testing/asserters.py index e342f76dc724b..48c92afde12f8 100644 --- a/pandas/_testing/asserters.py +++ b/pandas/_testing/asserters.py @@ -893,7 +893,9 @@ def assert_series_equal( raise_assert_detail(obj, "Series length are different", msg1, msg2) if check_flags: - assert left.flags == right.flags, f"{repr(left.flags)} != {repr(right.flags)}" + assert ( + left._flags == right._flags + ), f"{repr(left._flags)} != {repr(right._flags)}" if check_index: # GH #38183 @@ -1166,7 +1168,9 @@ def assert_frame_equal( ) if check_flags: - assert left.flags == right.flags, f"{repr(left.flags)} != {repr(right.flags)}" + assert ( + left._flags == right._flags + ), f"{repr(left._flags)} != {repr(right._flags)}" # index comparison assert_index_equal( diff --git a/pandas/conftest.py b/pandas/conftest.py index 983272d79081e..ef2a54b15bb22 100644 --- a/pandas/conftest.py +++ b/pandas/conftest.py @@ -168,6 +168,30 @@ def pytest_collection_modifyitems(items, config) -> None: "(Series|DataFrame).bool is now deprecated and will be removed " "in future version of pandas", ), + ( + "Flags", + "DataFrame.flags is deprecated and will be removed in a future version", + ), + ( + "flags", + "DataFrame.flags is deprecated and will be removed in a future version", + ), + ( + "allows_duplicate_labels", + "DataFrame.flags is deprecated and will be removed in a future version", + ), + ( + "set_flags", + "DataFrame.set_flags is deprecated and will be removed in a future version", + ), + ( + "DuplicateLabelError", + "Series.set_flags is deprecated and will be removed in a future version", + ), + ( + "DuplicateLabelError", + "Series.flags is deprecated and will be removed in a future version", + ), ( "pandas.core.generic.NDFrame.first", "first is deprecated and will be removed in a future version. " diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 3e2e589440bd9..ed9e09d42a509 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -5106,7 +5106,7 @@ def insert( """ if allow_duplicates is lib.no_default: allow_duplicates = False - if allow_duplicates and not self.flags.allows_duplicate_labels: + if allow_duplicates and not self._flags.allows_duplicate_labels: raise ValueError( "Cannot specify 'allow_duplicates=True' when " "'self.flags.allows_duplicate_labels' is False." diff --git a/pandas/core/generic.py b/pandas/core/generic.py index de25a02c6b37c..3d7afb541095f 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -440,6 +440,12 @@ def flags(self) -> Flags: False >>> df.flags["allows_duplicate_labels"] = True """ + warnings.warn( + f"{type(self).__name__}.flags is deprecated and will be removed " + "in a future version", + FutureWarning, + stacklevel=find_stack_level(), + ) return self._flags @final @@ -502,6 +508,13 @@ def set_flags( >>> df2.flags.allows_duplicate_labels False """ + warnings.warn( + f"{type(self).__name__}.set_flags is deprecated and will be removed " + "in a future version", + FutureWarning, + stacklevel=find_stack_level(), + ) + df = self.copy(deep=copy and not using_copy_on_write()) if allows_duplicate_labels is not None: df.flags["allows_duplicate_labels"] = allows_duplicate_labels @@ -2178,7 +2191,7 @@ def __getstate__(self) -> dict[str, Any]: "_typ": self._typ, "_metadata": self._metadata, "attrs": self.attrs, - "_flags": {k: self.flags[k] for k in self.flags._keys}, + "_flags": {k: self._flags[k] for k in self._flags._keys}, **meta, } @@ -4511,7 +4524,7 @@ def __delitem__(self, key) -> None: @final def _check_inplace_and_allows_duplicate_labels(self, inplace: bool_t): - if inplace and not self.flags.allows_duplicate_labels: + if inplace and not self._flags.allows_duplicate_labels: raise ValueError( "Cannot specify 'inplace=True' when " "'self.flags.allows_duplicate_labels' is False." @@ -6253,7 +6266,7 @@ def __finalize__(self, other, method: str | None = None, **kwargs) -> Self: # of an empty dict is 50x more expensive than the empty check. self.attrs = deepcopy(other.attrs) - self.flags.allows_duplicate_labels = other.flags.allows_duplicate_labels + self._flags.allows_duplicate_labels = other._flags.allows_duplicate_labels # For subclasses using _metadata. for name in set(self._metadata) & set(other._metadata): assert isinstance(name, str) @@ -6269,9 +6282,9 @@ def __finalize__(self, other, method: str | None = None, **kwargs) -> Self: self.attrs = deepcopy(attrs) allows_duplicate_labels = all( - x.flags.allows_duplicate_labels for x in other.objs + x._flags.allows_duplicate_labels for x in other.objs ) - self.flags.allows_duplicate_labels = allows_duplicate_labels + self._flags.allows_duplicate_labels = allows_duplicate_labels return self diff --git a/pandas/tests/copy_view/test_methods.py b/pandas/tests/copy_view/test_methods.py index 862aebdc70a9d..5dfb789932f7e 100644 --- a/pandas/tests/copy_view/test_methods.py +++ b/pandas/tests/copy_view/test_methods.py @@ -122,8 +122,12 @@ def test_copy_shallow(using_copy_on_write, warn_copy_on_write): def test_methods_copy_keyword( request, method, copy, using_copy_on_write, using_array_manager ): + warn = None + msg = "(DataFrame|Series).set_flags is deprecated" index = None - if "to_timestamp" in request.node.callspec.id: + if "set_flags" in request.node.callspec.id: + warn = FutureWarning + elif "to_timestamp" in request.node.callspec.id: index = period_range("2012-01-01", freq="D", periods=3) elif "to_period" in request.node.callspec.id: index = date_range("2012-01-01", freq="D", periods=3) @@ -139,7 +143,8 @@ def test_methods_copy_keyword( with tm.assert_produces_warning(FutureWarning, match=msg): df2 = method(df, copy=copy) else: - df2 = method(df, copy=copy) + with tm.assert_produces_warning(warn, match=msg): + df2 = method(df, copy=copy) share_memory = using_copy_on_write or copy is False @@ -197,8 +202,12 @@ def test_methods_copy_keyword( ], ) def test_methods_series_copy_keyword(request, method, copy, using_copy_on_write): + warn = None + msg = "(DataFrame|Series).set_flags is deprecated" index = None - if "to_timestamp" in request.node.callspec.id: + if "set_flags" in request.node.callspec.id: + warn = FutureWarning + elif "to_timestamp" in request.node.callspec.id: index = period_range("2012-01-01", freq="D", periods=3) elif "to_period" in request.node.callspec.id: index = date_range("2012-01-01", freq="D", periods=3) @@ -216,7 +225,8 @@ def test_methods_series_copy_keyword(request, method, copy, using_copy_on_write) with tm.assert_produces_warning(FutureWarning, match=msg): ser2 = method(ser, copy=copy) else: - ser2 = method(ser, copy=copy) + with tm.assert_produces_warning(warn, match=msg): + ser2 = method(ser, copy=copy) share_memory = using_copy_on_write or copy is False @@ -1285,7 +1295,9 @@ def test_series_set_axis(using_copy_on_write): def test_set_flags(using_copy_on_write, warn_copy_on_write): ser = Series([1, 2, 3]) ser_orig = ser.copy() - ser2 = ser.set_flags(allows_duplicate_labels=False) + msg = "Series.set_flags is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + ser2 = ser.set_flags(allows_duplicate_labels=False) assert np.shares_memory(ser, ser2) diff --git a/pandas/tests/frame/methods/test_reset_index.py b/pandas/tests/frame/methods/test_reset_index.py index fbf36dbc4fb02..010a1bfc4866a 100644 --- a/pandas/tests/frame/methods/test_reset_index.py +++ b/pandas/tests/frame/methods/test_reset_index.py @@ -441,7 +441,9 @@ def test_reset_index_duplicate_columns_allow( ): # GH#44755 reset_index with duplicate column labels df = multiindex_df.rename_axis("A") - df = df.set_flags(allows_duplicate_labels=flag) + msg = "DataFrame.set_flags is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + df = df.set_flags(allows_duplicate_labels=flag) if flag and allow_duplicates: result = df.reset_index(allow_duplicates=allow_duplicates) @@ -464,7 +466,9 @@ def test_reset_index_duplicate_columns_allow( @pytest.mark.parametrize("flag", [False, True]) def test_reset_index_duplicate_columns_default(self, multiindex_df, flag): df = multiindex_df.rename_axis("A") - df = df.set_flags(allows_duplicate_labels=flag) + msg = "DataFrame.set_flags is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + df = df.set_flags(allows_duplicate_labels=flag) msg = r"cannot insert \('A', ''\), already exists" with pytest.raises(ValueError, match=msg): diff --git a/pandas/tests/frame/test_api.py b/pandas/tests/frame/test_api.py index c7b444045a0f2..0e536ffa8cf3a 100644 --- a/pandas/tests/frame/test_api.py +++ b/pandas/tests/frame/test_api.py @@ -334,19 +334,25 @@ def test_set_flags( obj = obj["A"] key = 0 - result = obj.set_flags(allows_duplicate_labels=allows_duplicate_labels) + set_msg = "(DataFrame|Series).set_flags is deprecated" + with tm.assert_produces_warning(FutureWarning, match=set_msg): + result = obj.set_flags(allows_duplicate_labels=allows_duplicate_labels) + get_msg = "(DataFrame|Series).flags is deprecated" if allows_duplicate_labels is None: # We don't update when it's not provided - assert result.flags.allows_duplicate_labels is True + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert result.flags.allows_duplicate_labels is True else: - assert result.flags.allows_duplicate_labels is allows_duplicate_labels + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert result.flags.allows_duplicate_labels is allows_duplicate_labels # We made a copy assert obj is not result # We didn't mutate obj - assert obj.flags.allows_duplicate_labels is True + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert obj.flags.allows_duplicate_labels is True # But we didn't copy data if frame_or_series is Series: @@ -365,9 +371,10 @@ def test_set_flags( result.iloc[key] = 1 # Now we do copy. - result = obj.set_flags( - copy=True, allows_duplicate_labels=allows_duplicate_labels - ) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + result = obj.set_flags( + copy=True, allows_duplicate_labels=allows_duplicate_labels + ) result.iloc[key] = 10 assert obj.iloc[key] == 1 @@ -387,6 +394,9 @@ def test_inspect_getmembers(self): df = DataFrame() msg = "DataFrame._data is deprecated" with tm.assert_produces_warning( - DeprecationWarning, match=msg, check_stacklevel=False + # FutureWarning is for DataFrame.flags + (FutureWarning, DeprecationWarning), + match=msg, + check_stacklevel=False, ): inspect.getmembers(df) diff --git a/pandas/tests/generic/test_duplicate_labels.py b/pandas/tests/generic/test_duplicate_labels.py index f54db07824daf..89b80a1e21f99 100644 --- a/pandas/tests/generic/test_duplicate_labels.py +++ b/pandas/tests/generic/test_duplicate_labels.py @@ -9,6 +9,9 @@ not_implemented = pytest.mark.xfail(reason="Not implemented.") +get_msg = "(DataFrame|Series).flags is deprecated" +set_msg = "(DataFrame|Series).set_flags is deprecated" + # ---------------------------------------------------------------------------- # Preservation @@ -25,10 +28,13 @@ class TestPreserves: ) def test_construction_ok(self, cls, data): result = cls(data) - assert result.flags.allows_duplicate_labels is True + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert result.flags.allows_duplicate_labels is True - result = cls(data).set_flags(allows_duplicate_labels=False) - assert result.flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=set_msg): + result = cls(data).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert result.flags.allows_duplicate_labels is False @pytest.mark.parametrize( "func", @@ -42,8 +48,12 @@ def test_construction_ok(self, cls, data): ], ) def test_preserved_series(self, func): - s = pd.Series([0, 1], index=["a", "b"]).set_flags(allows_duplicate_labels=False) - assert func(s).flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=set_msg): + s = pd.Series([0, 1], index=["a", "b"]).set_flags( + allows_duplicate_labels=False + ) + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert func(s).flags.allows_duplicate_labels is False @pytest.mark.parametrize( "other", [pd.Series(0, index=["a", "b", "c"]), pd.Series(0, index=["a", "b"])] @@ -51,44 +61,56 @@ def test_preserved_series(self, func): # TODO: frame @not_implemented def test_align(self, other): - s = pd.Series([0, 1], index=["a", "b"]).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + s = pd.Series([0, 1], index=["a", "b"]).set_flags( + allows_duplicate_labels=False + ) a, b = s.align(other) - assert a.flags.allows_duplicate_labels is False - assert b.flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert a.flags.allows_duplicate_labels is False + assert b.flags.allows_duplicate_labels is False def test_preserved_frame(self): - df = pd.DataFrame({"A": [1, 2], "B": [3, 4]}, index=["a", "b"]).set_flags( - allows_duplicate_labels=False - ) - assert df.loc[["a"]].flags.allows_duplicate_labels is False - assert df.loc[:, ["A", "B"]].flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=set_msg): + df = pd.DataFrame({"A": [1, 2], "B": [3, 4]}, index=["a", "b"]).set_flags( + allows_duplicate_labels=False + ) + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert df.loc[["a"]].flags.allows_duplicate_labels is False + assert df.loc[:, ["A", "B"]].flags.allows_duplicate_labels is False def test_to_frame(self): - ser = pd.Series(dtype=float).set_flags(allows_duplicate_labels=False) - assert ser.to_frame().flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=set_msg): + ser = pd.Series(dtype=float).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert ser.to_frame().flags.allows_duplicate_labels is False @pytest.mark.parametrize("func", ["add", "sub"]) @pytest.mark.parametrize("frame", [False, True]) @pytest.mark.parametrize("other", [1, pd.Series([1, 2], name="A")]) def test_binops(self, func, other, frame): - df = pd.Series([1, 2], name="A", index=["a", "b"]).set_flags( - allows_duplicate_labels=False - ) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + df = pd.Series([1, 2], name="A", index=["a", "b"]).set_flags( + allows_duplicate_labels=False + ) if frame: df = df.to_frame() if isinstance(other, pd.Series) and frame: other = other.to_frame() func = operator.methodcaller(func, other) - assert df.flags.allows_duplicate_labels is False - assert func(df).flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert df.flags.allows_duplicate_labels is False + assert func(df).flags.allows_duplicate_labels is False def test_preserve_getitem(self): - df = pd.DataFrame({"A": [1, 2]}).set_flags(allows_duplicate_labels=False) - assert df[["A"]].flags.allows_duplicate_labels is False - assert df["A"].flags.allows_duplicate_labels is False - assert df.loc[0].flags.allows_duplicate_labels is False - assert df.loc[[0]].flags.allows_duplicate_labels is False - assert df.loc[0, ["A"]].flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=set_msg): + df = pd.DataFrame({"A": [1, 2]}).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert df[["A"]].flags.allows_duplicate_labels is False + assert df["A"].flags.allows_duplicate_labels is False + assert df.loc[0].flags.allows_duplicate_labels is False + assert df.loc[[0]].flags.allows_duplicate_labels is False + assert df.loc[0, ["A"]].flags.allows_duplicate_labels is False def test_ndframe_getitem_caching_issue( self, request, using_copy_on_write, warn_copy_on_write @@ -97,10 +119,12 @@ def test_ndframe_getitem_caching_issue( request.applymarker(pytest.mark.xfail(reason="Unclear behavior.")) # NDFrame.__getitem__ will cache the first df['A']. May need to # invalidate that cache? Update the cached entries? - df = pd.DataFrame({"A": [0]}).set_flags(allows_duplicate_labels=False) - assert df["A"].flags.allows_duplicate_labels is False - df.flags.allows_duplicate_labels = True - assert df["A"].flags.allows_duplicate_labels is True + with tm.assert_produces_warning(FutureWarning, match=set_msg): + df = pd.DataFrame({"A": [0]}).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert df["A"].flags.allows_duplicate_labels is False + df.flags.allows_duplicate_labels = True + assert df["A"].flags.allows_duplicate_labels is True @pytest.mark.parametrize( "objs, kwargs", @@ -160,30 +184,28 @@ def test_ndframe_getitem_caching_issue( ], ) def test_concat(self, objs, kwargs): - objs = [x.set_flags(allows_duplicate_labels=False) for x in objs] + with tm.assert_produces_warning(FutureWarning, match=set_msg): + objs = [x.set_flags(allows_duplicate_labels=False) for x in objs] result = pd.concat(objs, **kwargs) - assert result.flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert result.flags.allows_duplicate_labels is False @pytest.mark.parametrize( - "left, right, expected", + "left, right, should_set, expected", [ # false false false pytest.param( - pd.DataFrame({"A": [0, 1]}, index=["a", "b"]).set_flags( - allows_duplicate_labels=False - ), - pd.DataFrame({"B": [0, 1]}, index=["a", "d"]).set_flags( - allows_duplicate_labels=False - ), + pd.DataFrame({"A": [0, 1]}, index=["a", "b"]), + pd.DataFrame({"B": [0, 1]}, index=["a", "d"]), + (True, True), False, marks=not_implemented, ), # false true false pytest.param( - pd.DataFrame({"A": [0, 1]}, index=["a", "b"]).set_flags( - allows_duplicate_labels=False - ), + pd.DataFrame({"A": [0, 1]}, index=["a", "b"]), pd.DataFrame({"B": [0, 1]}, index=["a", "d"]), + (True, False), False, marks=not_implemented, ), @@ -191,13 +213,22 @@ def test_concat(self, objs, kwargs): ( pd.DataFrame({"A": [0, 1]}, index=["a", "b"]), pd.DataFrame({"B": [0, 1]}, index=["a", "d"]), + (False, False), True, ), ], ) - def test_merge(self, left, right, expected): + def test_merge(self, left, right, should_set, expected): + should_set_left, should_set_right = should_set + if should_set_left: + with tm.assert_produces_warning(FutureWarning, match=set_msg): + left = left.set_flags(allows_duplicate_labels=False) + if should_set_right: + with tm.assert_produces_warning(FutureWarning, match=set_msg): + right = right.set_flags(allows_duplicate_labels=False) result = pd.merge(left, right, left_index=True, right_index=True) - assert result.flags.allows_duplicate_labels is expected + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert result.flags.allows_duplicate_labels is expected @not_implemented def test_groupby(self): @@ -206,9 +237,11 @@ def test_groupby(self): # - apply # - transform # - Should passing a grouper that disallows duplicates propagate? - df = pd.DataFrame({"A": [1, 2, 3]}).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + df = pd.DataFrame({"A": [1, 2, 3]}).set_flags(allows_duplicate_labels=False) result = df.groupby([0, 0, 1]).agg("count") - assert result.flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert result.flags.allows_duplicate_labels is False @pytest.mark.parametrize("frame", [True, False]) @not_implemented @@ -221,9 +254,10 @@ def test_window(self, frame): ) if frame: df = df.to_frame() - assert df.rolling(3).mean().flags.allows_duplicate_labels is False - assert df.ewm(3).mean().flags.allows_duplicate_labels is False - assert df.expanding(3).mean().flags.allows_duplicate_labels is False + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert df.rolling(3).mean().flags.allows_duplicate_labels is False + assert df.ewm(3).mean().flags.allows_duplicate_labels is False + assert df.expanding(3).mean().flags.allows_duplicate_labels is False # ---------------------------------------------------------------------------- @@ -242,11 +276,13 @@ class TestRaises: ) def test_set_flags_with_duplicates(self, cls, axes): result = cls(**axes) - assert result.flags.allows_duplicate_labels is True + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert result.flags.allows_duplicate_labels is True msg = "Index has duplicates." with pytest.raises(pd.errors.DuplicateLabelError, match=msg): - cls(**axes).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + cls(**axes).set_flags(allows_duplicate_labels=False) @pytest.mark.parametrize( "data", @@ -259,13 +295,18 @@ def test_set_flags_with_duplicates(self, cls, axes): def test_setting_allows_duplicate_labels_raises(self, data): msg = "Index has duplicates." with pytest.raises(pd.errors.DuplicateLabelError, match=msg): - data.flags.allows_duplicate_labels = False + with tm.assert_produces_warning(FutureWarning, match=get_msg): + data.flags.allows_duplicate_labels = False - assert data.flags.allows_duplicate_labels is True + with tm.assert_produces_warning(FutureWarning, match=get_msg): + assert data.flags.allows_duplicate_labels is True def test_series_raises(self): a = pd.Series(0, index=["a", "b"]) - b = pd.Series([0, 1], index=["a", "b"]).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + b = pd.Series([0, 1], index=["a", "b"]).set_flags( + allows_duplicate_labels=False + ) msg = "Index has duplicates." with pytest.raises(pd.errors.DuplicateLabelError, match=msg): pd.concat([a, b]) @@ -285,9 +326,10 @@ def test_series_raises(self): ], ) def test_getitem_raises(self, getter, target): - df = pd.DataFrame({"A": [1, 2], "B": [3, 4]}, index=["a", "b"]).set_flags( - allows_duplicate_labels=False - ) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + df = pd.DataFrame({"A": [1, 2], "B": [3, 4]}, index=["a", "b"]).set_flags( + allows_duplicate_labels=False + ) if target: # df, df.loc, or df.iloc target = getattr(df, target) @@ -311,16 +353,18 @@ def test_getitem_raises(self, getter, target): ], ) def test_concat_raises(self, objs, kwargs): - objs = [x.set_flags(allows_duplicate_labels=False) for x in objs] + with tm.assert_produces_warning(FutureWarning, match=set_msg): + objs = [x.set_flags(allows_duplicate_labels=False) for x in objs] msg = "Index has duplicates." with pytest.raises(pd.errors.DuplicateLabelError, match=msg): pd.concat(objs, **kwargs) @not_implemented def test_merge_raises(self): - a = pd.DataFrame({"A": [0, 1, 2]}, index=["a", "b", "c"]).set_flags( - allows_duplicate_labels=False - ) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + a = pd.DataFrame({"A": [0, 1, 2]}, index=["a", "b", "c"]).set_flags( + allows_duplicate_labels=False + ) b = pd.DataFrame({"B": [0, 1, 2]}, index=["a", "b", "b"]) msg = "Index has duplicates." with pytest.raises(pd.errors.DuplicateLabelError, match=msg): @@ -344,14 +388,20 @@ def test_merge_raises(self): ) def test_raises_basic(idx): msg = "Index has duplicates." + with pytest.raises(pd.errors.DuplicateLabelError, match=msg): - pd.Series(1, index=idx).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + pd.Series(1, index=idx).set_flags(allows_duplicate_labels=False) with pytest.raises(pd.errors.DuplicateLabelError, match=msg): - pd.DataFrame({"A": [1, 1]}, index=idx).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + pd.DataFrame({"A": [1, 1]}, index=idx).set_flags( + allows_duplicate_labels=False + ) with pytest.raises(pd.errors.DuplicateLabelError, match=msg): - pd.DataFrame([[1, 2]], columns=idx).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + pd.DataFrame([[1, 2]], columns=idx).set_flags(allows_duplicate_labels=False) def test_format_duplicate_labels_message(): @@ -374,7 +424,8 @@ def test_format_duplicate_labels_message_multi(): def test_dataframe_insert_raises(): - df = pd.DataFrame({"A": [1, 2]}).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + df = pd.DataFrame({"A": [1, 2]}).set_flags(allows_duplicate_labels=False) msg = "Cannot specify" with pytest.raises(ValueError, match=msg): df.insert(0, "A", [3, 4], allow_duplicates=True) @@ -389,11 +440,13 @@ def test_dataframe_insert_raises(): ], ) def test_inplace_raises(method, frame_only): - df = pd.DataFrame({"A": [0, 0], "B": [1, 2]}).set_flags( - allows_duplicate_labels=False - ) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + df = pd.DataFrame({"A": [0, 0], "B": [1, 2]}).set_flags( + allows_duplicate_labels=False + ) s = df["A"] - s.flags.allows_duplicate_labels = False + with tm.assert_produces_warning(FutureWarning, match=get_msg): + s.flags.allows_duplicate_labels = False msg = "Cannot specify" with pytest.raises(ValueError, match=msg): @@ -404,10 +457,12 @@ def test_inplace_raises(method, frame_only): def test_pickle(): - a = pd.Series([1, 2]).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + a = pd.Series([1, 2]).set_flags(allows_duplicate_labels=False) b = tm.round_trip_pickle(a) tm.assert_series_equal(a, b) - a = pd.DataFrame({"A": []}).set_flags(allows_duplicate_labels=False) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + a = pd.DataFrame({"A": []}).set_flags(allows_duplicate_labels=False) b = tm.round_trip_pickle(a) tm.assert_frame_equal(a, b) diff --git a/pandas/tests/generic/test_generic.py b/pandas/tests/generic/test_generic.py index 6564e381af0ea..547c60367fd42 100644 --- a/pandas/tests/generic/test_generic.py +++ b/pandas/tests/generic/test_generic.py @@ -490,9 +490,12 @@ def test_flags_identity(self, frame_or_series): if frame_or_series is DataFrame: obj = obj.to_frame() - assert obj.flags is obj.flags + msg = "(DataFrame|Series).flags is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + assert obj.flags is obj.flags obj2 = obj.copy() - assert obj2.flags is not obj.flags + with tm.assert_produces_warning(FutureWarning, match=msg): + assert obj2.flags is not obj.flags def test_bool_dep(self) -> None: # GH-51749 diff --git a/pandas/tests/series/test_api.py b/pandas/tests/series/test_api.py index 29d6e2036476e..60156302a03c5 100644 --- a/pandas/tests/series/test_api.py +++ b/pandas/tests/series/test_api.py @@ -173,7 +173,10 @@ def test_inspect_getmembers(self): ser = Series(dtype=object) msg = "Series._data is deprecated" with tm.assert_produces_warning( - DeprecationWarning, match=msg, check_stacklevel=False + # FutureWarning is for Series.flags + (FutureWarning, DeprecationWarning), + match=msg, + check_stacklevel=False, ): inspect.getmembers(ser) diff --git a/pandas/tests/test_flags.py b/pandas/tests/test_flags.py index 9294b3fc3319b..d5a7179c0e652 100644 --- a/pandas/tests/test_flags.py +++ b/pandas/tests/test_flags.py @@ -1,12 +1,17 @@ import pytest import pandas as pd +import pandas._testing as tm + +set_msg = "DataFrame.set_flags is deprecated" +get_msg = "DataFrame.flags is deprecated" class TestFlags: def test_equality(self): - a = pd.DataFrame().set_flags(allows_duplicate_labels=True).flags - b = pd.DataFrame().set_flags(allows_duplicate_labels=False).flags + with tm.assert_produces_warning(FutureWarning, match=set_msg): + a = pd.DataFrame().set_flags(allows_duplicate_labels=True).flags + b = pd.DataFrame().set_flags(allows_duplicate_labels=False).flags assert a == a assert b == b @@ -14,29 +19,35 @@ def test_equality(self): assert a != 2 def test_set(self): - df = pd.DataFrame().set_flags(allows_duplicate_labels=True) - a = df.flags + with tm.assert_produces_warning(FutureWarning, match=set_msg): + df = pd.DataFrame().set_flags(allows_duplicate_labels=True) + with tm.assert_produces_warning(FutureWarning, match=get_msg): + a = df.flags a.allows_duplicate_labels = False assert a.allows_duplicate_labels is False a["allows_duplicate_labels"] = True assert a.allows_duplicate_labels is True def test_repr(self): - a = repr(pd.DataFrame({"A"}).set_flags(allows_duplicate_labels=True).flags) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + a = repr(pd.DataFrame({"A"}).set_flags(allows_duplicate_labels=True).flags) assert a == "" - a = repr(pd.DataFrame({"A"}).set_flags(allows_duplicate_labels=False).flags) + with tm.assert_produces_warning(FutureWarning, match=set_msg): + a = repr(pd.DataFrame({"A"}).set_flags(allows_duplicate_labels=False).flags) assert a == "" def test_obj_ref(self): df = pd.DataFrame() - flags = df.flags + with tm.assert_produces_warning(FutureWarning, match=get_msg): + flags = df.flags del df with pytest.raises(ValueError, match="object has been deleted"): flags.allows_duplicate_labels = True def test_getitem(self): df = pd.DataFrame() - flags = df.flags + with tm.assert_produces_warning(FutureWarning, match=get_msg): + flags = df.flags assert flags["allows_duplicate_labels"] is True flags["allows_duplicate_labels"] = False assert flags["allows_duplicate_labels"] is False diff --git a/pandas/tests/util/test_assert_frame_equal.py b/pandas/tests/util/test_assert_frame_equal.py index a074898f6046d..2aa634cb30250 100644 --- a/pandas/tests/util/test_assert_frame_equal.py +++ b/pandas/tests/util/test_assert_frame_equal.py @@ -270,7 +270,9 @@ def test_assert_frame_equal_datetime_like_dtype_mismatch(dtype): def test_allows_duplicate_labels(): left = DataFrame() - right = DataFrame().set_flags(allows_duplicate_labels=False) + msg = "DataFrame.set_flags is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + right = DataFrame().set_flags(allows_duplicate_labels=False) tm.assert_frame_equal(left, left) tm.assert_frame_equal(right, right) tm.assert_frame_equal(left, right, check_flags=False) @@ -316,10 +318,13 @@ def test_assert_frame_equal_check_like_different_indexes(): def test_assert_frame_equal_checking_allow_dups_flag(): # GH#45554 left = DataFrame([[1, 2], [3, 4]]) - left.flags.allows_duplicate_labels = False + msg = "DataFrame.flags is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + left.flags.allows_duplicate_labels = False right = DataFrame([[1, 2], [3, 4]]) - right.flags.allows_duplicate_labels = True + with tm.assert_produces_warning(FutureWarning, match=msg): + right.flags.allows_duplicate_labels = True tm.assert_frame_equal(left, right, check_flags=False) with pytest.raises(AssertionError, match="allows_duplicate_labels"): diff --git a/pandas/tests/util/test_assert_series_equal.py b/pandas/tests/util/test_assert_series_equal.py index f722f619bc456..64d145e48d426 100644 --- a/pandas/tests/util/test_assert_series_equal.py +++ b/pandas/tests/util/test_assert_series_equal.py @@ -382,7 +382,9 @@ def test_assert_series_equal_ignore_extension_dtype_mismatch_cross_class(): def test_allows_duplicate_labels(): left = Series([1]) - right = Series([1]).set_flags(allows_duplicate_labels=False) + msg = "Series.set_flags is deprecated" + with tm.assert_produces_warning(FutureWarning, match=msg): + right = Series([1]).set_flags(allows_duplicate_labels=False) tm.assert_series_equal(left, left) tm.assert_series_equal(right, right) tm.assert_series_equal(left, right, check_flags=False)