Skip to content

Commit

Permalink
CoW: Fix warnings for eval
Browse files Browse the repository at this point in the history
  • Loading branch information
phofl committed Nov 25, 2023
1 parent 24fdde6 commit be587d5
Show file tree
Hide file tree
Showing 3 changed files with 12 additions and 20 deletions.
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
5 changes: 4 additions & 1 deletion pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -637,12 +637,15 @@ 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._values, copy=False, index=v.index)
for k, v in self.items()
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 @@ -1164,9 +1164,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 @@ -1220,8 +1218,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 @@ -1235,7 +1231,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 @@ -1908,8 +1904,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

0 comments on commit be587d5

Please sign in to comment.