Skip to content

DEPR: flags #52153

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 24 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
7fc7c57
DEPR: flags
jbrockmendel Mar 24, 2023
ae203a0
Merge branch 'main' into depr-flags
jbrockmendel Mar 24, 2023
921cf01
Merge branch 'main' into depr-flags
jbrockmendel Apr 4, 2023
080e4a5
doctests, docbuild
jbrockmendel Apr 4, 2023
95186a5
mypy fixup
jbrockmendel Apr 5, 2023
1376aa8
Merge branch 'main' into depr-flags
jbrockmendel Apr 5, 2023
8e02b92
suppress doctest warnings
jbrockmendel Apr 5, 2023
5d34d68
Merge branch 'main' into depr-flags
jbrockmendel Apr 13, 2023
6dfbaf6
Merge branch 'main' into depr-flags
jbrockmendel Apr 19, 2023
1662321
Merge branch 'main' into depr-flags
jbrockmendel Apr 21, 2023
a170330
Merge branch 'main' into depr-flags
jbrockmendel Apr 29, 2023
8f82ef4
Merge branch 'main' into depr-flags
jbrockmendel May 5, 2023
5f91dfb
Merge branch 'main' into depr-flags
jbrockmendel May 16, 2023
d19ee09
Merge branch 'main' into depr-flags
jbrockmendel May 27, 2023
f5250e3
Merge branch 'main' into depr-flags
jbrockmendel Jun 30, 2023
797a761
Merge branch 'main' into depr-flags
jbrockmendel Jul 26, 2023
6613850
Merge branch 'main' into depr-flags
jbrockmendel Jul 27, 2023
f081865
Merge branch 'main' into depr-flags
jbrockmendel Aug 23, 2023
b0c910d
Merge branch 'main' into depr-flags
jbrockmendel Sep 14, 2023
9402b9e
Merge branch 'main' into depr-flags
jbrockmendel Oct 29, 2023
c4eb93d
Merge branch 'main' into depr-flags
jbrockmendel Dec 13, 2023
35d114b
Merge branch 'main' into depr-flags
jbrockmendel Dec 18, 2023
e67982c
update inspect.getmembers tests
jbrockmendel Dec 18, 2023
4e00ed9
Merge branch 'main' into depr-flags
jbrockmendel Dec 22, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions doc/source/user_guide/duplicates.rst
Original file line number Diff line number Diff line change
Expand Up @@ -121,13 +121,15 @@ will be raised.

.. ipython:: python
:okexcept:
:okwarning:

pd.Series([0, 1, 2], index=["a", "b", "b"]).set_flags(allows_duplicate_labels=False)

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
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -193,6 +198,7 @@ operations.

.. ipython:: python
:okexcept:
:okwarning:

s1 = pd.Series(0, index=["a", "b"]).set_flags(allows_duplicate_labels=False)
s1
Expand Down
1 change: 1 addition & 0 deletions doc/source/whatsnew/v2.2.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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`)
Expand Down
8 changes: 6 additions & 2 deletions pandas/_testing/asserters.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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(
Expand Down
24 changes: 24 additions & 0 deletions pandas/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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. "
Expand Down
2 changes: 1 addition & 1 deletion pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -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."
Expand Down
23 changes: 18 additions & 5 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
}

Expand Down Expand Up @@ -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."
Expand Down Expand Up @@ -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)
Expand All @@ -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

Expand Down
22 changes: 17 additions & 5 deletions pandas/tests/copy_view/test_methods.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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

Expand Down Expand Up @@ -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)
Expand All @@ -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

Expand Down Expand Up @@ -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)

Expand Down
8 changes: 6 additions & 2 deletions pandas/tests/frame/methods/test_reset_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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):
Expand Down
26 changes: 18 additions & 8 deletions pandas/tests/frame/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand All @@ -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

Expand All @@ -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)
Loading