Skip to content

Commit 81d4f0c

Browse files
authored
CoW: Ensure that iterrows does not allow mutating parent (#51271)
1 parent 58cc356 commit 81d4f0c

File tree

3 files changed

+17
-0
lines changed

3 files changed

+17
-0
lines changed

doc/source/whatsnew/v2.0.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ Copy-on-Write improvements
222222
- :meth:`DataFrame.to_timestamp` / :meth:`Series.to_timestamp`
223223
- :meth:`DataFrame.to_period` / :meth:`Series.to_period`
224224
- :meth:`DataFrame.truncate`
225+
- :meth:`DataFrame.iterrows`
225226
- :meth:`DataFrame.tz_convert` / :meth:`Series.tz_localize`
226227
- :meth:`DataFrame.fillna` / :meth:`Series.fillna`
227228
- :meth:`DataFrame.interpolate` / :meth:`Series.interpolate`

pandas/core/frame.py

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,8 +1392,14 @@ def iterrows(self) -> Iterable[tuple[Hashable, Series]]:
13921392
"""
13931393
columns = self.columns
13941394
klass = self._constructor_sliced
1395+
using_cow = using_copy_on_write()
13951396
for k, v in zip(self.index, self.values):
13961397
s = klass(v, index=columns, name=k).__finalize__(self)
1398+
if using_cow and self._mgr.is_single_block:
1399+
s._mgr.blocks[0].refs = self._mgr.blocks[0].refs # type: ignore[union-attr] # noqa
1400+
s._mgr.blocks[0].refs.add_reference( # type: ignore[union-attr]
1401+
s._mgr.blocks[0] # type: ignore[arg-type, union-attr]
1402+
)
13971403
yield k, s
13981404

13991405
def itertuples(

pandas/tests/copy_view/test_methods.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,16 @@ def test_asfreq_noop(using_copy_on_write):
13771377
tm.assert_frame_equal(df, df_orig)
13781378

13791379

1380+
def test_iterrows(using_copy_on_write):
1381+
df = DataFrame({"a": 0, "b": 1}, index=[1, 2, 3])
1382+
df_orig = df.copy()
1383+
1384+
for _, sub in df.iterrows():
1385+
sub.iloc[0] = 100
1386+
if using_copy_on_write:
1387+
tm.assert_frame_equal(df, df_orig)
1388+
1389+
13801390
def test_interpolate_creates_copy(using_copy_on_write):
13811391
# GH#51126
13821392
df = DataFrame({"a": [1.5, np.nan, 3]})

0 commit comments

Comments
 (0)