Skip to content

Commit 2e5862f

Browse files
phoflmeeseeksmachine
authored andcommitted
Backport PR pandas-dev#52017: BUG: Series constructor not respecting CoW when called with BlockManager
1 parent f74e0d2 commit 2e5862f

File tree

2 files changed

+35
-0
lines changed

2 files changed

+35
-0
lines changed

pandas/core/series.py

+7
Original file line numberDiff line numberDiff line change
@@ -379,6 +379,8 @@ def __init__(
379379
and dtype is None
380380
and copy is False
381381
):
382+
if using_copy_on_write():
383+
data = data.copy(deep=False)
382384
# GH#33357 called with just the SingleBlockManager
383385
NDFrame.__init__(self, data)
384386
if fastpath:
@@ -397,13 +399,18 @@ def __init__(
397399
data = SingleBlockManager.from_array(data, index)
398400
elif manager == "array":
399401
data = SingleArrayManager.from_array(data, index)
402+
elif using_copy_on_write() and not copy:
403+
data = data.copy(deep=False)
400404
if copy:
401405
data = data.copy()
402406
# skips validation of the name
403407
object.__setattr__(self, "_name", name)
404408
NDFrame.__init__(self, data)
405409
return
406410

411+
if isinstance(data, SingleBlockManager) and using_copy_on_write() and not copy:
412+
data = data.copy(deep=False)
413+
407414
name = ibase.maybe_extract_name(name, data, type(self))
408415

409416
if index is not None:

pandas/tests/copy_view/test_constructors.py

+28
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import numpy as np
22
import pytest
33

4+
import pandas as pd
45
from pandas import (
56
DataFrame,
67
DatetimeIndex,
@@ -118,6 +119,33 @@ def test_series_from_index_different_dtypes(using_copy_on_write):
118119
assert ser._mgr._has_no_reference(0)
119120

120121

122+
@pytest.mark.parametrize("fastpath", [False, True])
123+
@pytest.mark.parametrize("dtype", [None, "int64"])
124+
@pytest.mark.parametrize("idx", [None, pd.RangeIndex(start=0, stop=3, step=1)])
125+
def test_series_from_block_manager(using_copy_on_write, idx, dtype, fastpath):
126+
ser = Series([1, 2, 3], dtype="int64")
127+
ser_orig = ser.copy()
128+
ser2 = Series(ser._mgr, dtype=dtype, fastpath=fastpath, index=idx)
129+
assert np.shares_memory(get_array(ser), get_array(ser2))
130+
if using_copy_on_write:
131+
assert not ser2._mgr._has_no_reference(0)
132+
133+
ser2.iloc[0] = 100
134+
if using_copy_on_write:
135+
tm.assert_series_equal(ser, ser_orig)
136+
else:
137+
expected = Series([100, 2, 3])
138+
tm.assert_series_equal(ser, expected)
139+
140+
141+
def test_series_from_block_manager_different_dtype(using_copy_on_write):
142+
ser = Series([1, 2, 3], dtype="int64")
143+
ser2 = Series(ser._mgr, dtype="int32")
144+
assert not np.shares_memory(get_array(ser), get_array(ser2))
145+
if using_copy_on_write:
146+
assert ser2._mgr._has_no_reference(0)
147+
148+
121149
@pytest.mark.parametrize("func", [lambda x: x, lambda x: x._mgr])
122150
@pytest.mark.parametrize("columns", [None, ["a"]])
123151
def test_dataframe_constructor_mgr_or_df(using_copy_on_write, columns, func):

0 commit comments

Comments
 (0)