Skip to content

Commit a912748

Browse files
committed
BUG-CoW: from_records not tracking references when called with df (pandas-dev#52029)
1 parent 1c5dd84 commit a912748

File tree

3 files changed

+21
-0
lines changed

3 files changed

+21
-0
lines changed

doc/source/whatsnew/v2.0.0.rst

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,6 +197,9 @@ Copy-on-Write improvements
197197
behavior when the NumPy array is modified after creation of the
198198
:class:`DataFrame`.
199199

200+
- The :meth:`DataFrame.from_records` will now respect Copy-on-Write when called
201+
with a :class:`DataFrame`.
202+
200203
- Trying to set values using chained assignment (for example, ``df["a"][1:3] = 0``)
201204
will now always raise an warning when Copy-on-Write is enabled. In this mode,
202205
chained assignment can never work because we are always setting into a temporary

pandas/core/frame.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2180,6 +2180,9 @@ def from_records(
21802180
2 1 c
21812181
3 0 d
21822182
"""
2183+
if isinstance(data, DataFrame):
2184+
data = data.copy(deep=False)
2185+
21832186
result_index = None
21842187

21852188
# Make a copy of the input columns so we can modify it

pandas/tests/copy_view/test_constructors.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,18 @@ def test_frame_from_numpy_array(using_copy_on_write, copy, using_array_manager):
231231
assert not np.shares_memory(get_array(df, 0), arr)
232232
else:
233233
assert np.shares_memory(get_array(df, 0), arr)
234+
235+
236+
def test_dataframe_from_records_with_dataframe(using_copy_on_write):
237+
df = DataFrame({"a": [1, 2, 3]})
238+
df_orig = df.copy()
239+
with tm.assert_produces_warning(FutureWarning):
240+
df2 = DataFrame.from_records(df)
241+
if using_copy_on_write:
242+
assert not df._mgr._has_no_reference(0)
243+
assert np.shares_memory(get_array(df, "a"), get_array(df2, "a"))
244+
df2.iloc[0, 0] = 100
245+
if using_copy_on_write:
246+
tm.assert_frame_equal(df, df_orig)
247+
else:
248+
tm.assert_frame_equal(df, df2)

0 commit comments

Comments
 (0)