Skip to content

CoW: Fix warnings for eval #56170

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

Merged
merged 5 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 4 additions & 11 deletions pandas/core/computation/eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -388,17 +388,10 @@ def eval(
# we will ignore numpy warnings here; e.g. if trying
# to use a non-numeric indexer
try:
with warnings.catch_warnings(record=True):
warnings.filterwarnings(
"always", "Setting a value on a view", FutureWarning
)
# TODO: Filter the warnings we actually care about here.
if inplace and isinstance(target, NDFrame):
target.loc[:, assigner] = ret
else:
target[ # pyright: ignore[reportGeneralTypeIssues]
assigner
] = ret
if inplace and isinstance(target, NDFrame):
target.loc[:, assigner] = ret
else:
target[assigner] = ret # pyright: ignore[reportGeneralTypeIssues]
except (TypeError, IndexError) as err:
raise ValueError("Cannot assign expression output to target") from err

Expand Down
7 changes: 6 additions & 1 deletion pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -650,12 +650,17 @@ def _get_cleaned_column_resolvers(self) -> dict[Hashable, Series]:
Used in :meth:`DataFrame.eval`.
"""
from pandas.core.computation.parsing import clean_column_name
from pandas.core.series import Series

if isinstance(self, ABCSeries):
return {clean_column_name(self.name): self}

return {
clean_column_name(k): v for k, v in self.items() if not isinstance(k, int)
clean_column_name(k): Series(
v, copy=False, index=self.index, name=k
).__finalize__(self)
for k, v in zip(self.columns, self._iter_column_arrays())
if not isinstance(k, int)
}

@final
Expand Down
12 changes: 4 additions & 8 deletions pandas/tests/computation/test_eval.py
Original file line number Diff line number Diff line change
Expand Up @@ -1173,9 +1173,7 @@ def test_assignment_single_assign_new(self):
df.eval("c = a + b", inplace=True)
tm.assert_frame_equal(df, expected)

# TODO(CoW-warn) this should not warn (DataFrame.eval creates refs to self)
@pytest.mark.filterwarnings("ignore:Setting a value on a view:FutureWarning")
def test_assignment_single_assign_local_overlap(self, warn_copy_on_write):
def test_assignment_single_assign_local_overlap(self):
df = DataFrame(
np.random.default_rng(2).standard_normal((5, 2)), columns=list("ab")
)
Expand Down Expand Up @@ -1229,8 +1227,6 @@ def test_column_in(self):
tm.assert_series_equal(result, expected, check_names=False)

@pytest.mark.xfail(reason="Unknown: Omitted test_ in name prior.")
# TODO(CoW-warn) this should not warn (DataFrame.eval creates refs to self)
@pytest.mark.filterwarnings("ignore:Setting a value on a view:FutureWarning")
def test_assignment_not_inplace(self):
# see gh-9297
df = DataFrame(
Expand All @@ -1244,7 +1240,7 @@ def test_assignment_not_inplace(self):
expected["c"] = expected["a"] + expected["b"]
tm.assert_frame_equal(df, expected)

def test_multi_line_expression(self):
def test_multi_line_expression(self, warn_copy_on_write):
# GH 11149
df = DataFrame({"a": [1, 2, 3], "b": [4, 5, 6]})
expected = df.copy()
Expand Down Expand Up @@ -1917,8 +1913,8 @@ def test_set_inplace(using_copy_on_write, warn_copy_on_write):
df = DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]})
result_view = df[:]
ser = df["A"]
# with tm.assert_cow_warning(warn_copy_on_write):
df.eval("A = B + C", inplace=True)
with tm.assert_cow_warning(warn_copy_on_write):
df.eval("A = B + C", inplace=True)
expected = DataFrame({"A": [11, 13, 15], "B": [4, 5, 6], "C": [7, 8, 9]})
tm.assert_frame_equal(df, expected)
if not using_copy_on_write:
Expand Down