Skip to content

Commit

Permalink
Backport PR #52017 on branch 2.0.x (BUG: Series constructor not respe…
Browse files Browse the repository at this point in the history
…cting CoW when called with BlockManager) (#52275)

Backport PR #52017: BUG: Series constructor not respecting CoW when called with BlockManager

Co-authored-by: Patrick Hoefler <61934744+phofl@users.noreply.github.com>
  • Loading branch information
meeseeksmachine and phofl committed Mar 29, 2023
1 parent f74e0d2 commit 4c2c3f8
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 0 deletions.
7 changes: 7 additions & 0 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -379,6 +379,8 @@ def __init__(
and dtype is None
and copy is False
):
if using_copy_on_write():
data = data.copy(deep=False)
# GH#33357 called with just the SingleBlockManager
NDFrame.__init__(self, data)
if fastpath:
Expand All @@ -397,13 +399,18 @@ def __init__(
data = SingleBlockManager.from_array(data, index)
elif manager == "array":
data = SingleArrayManager.from_array(data, index)
elif using_copy_on_write() and not copy:
data = data.copy(deep=False)
if copy:
data = data.copy()
# skips validation of the name
object.__setattr__(self, "_name", name)
NDFrame.__init__(self, data)
return

if isinstance(data, SingleBlockManager) and using_copy_on_write() and not copy:
data = data.copy(deep=False)

name = ibase.maybe_extract_name(name, data, type(self))

if index is not None:
Expand Down
28 changes: 28 additions & 0 deletions pandas/tests/copy_view/test_constructors.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import numpy as np
import pytest

import pandas as pd
from pandas import (
DataFrame,
DatetimeIndex,
Expand Down Expand Up @@ -118,6 +119,33 @@ def test_series_from_index_different_dtypes(using_copy_on_write):
assert ser._mgr._has_no_reference(0)


@pytest.mark.parametrize("fastpath", [False, True])
@pytest.mark.parametrize("dtype", [None, "int64"])
@pytest.mark.parametrize("idx", [None, pd.RangeIndex(start=0, stop=3, step=1)])
def test_series_from_block_manager(using_copy_on_write, idx, dtype, fastpath):
ser = Series([1, 2, 3], dtype="int64")
ser_orig = ser.copy()
ser2 = Series(ser._mgr, dtype=dtype, fastpath=fastpath, index=idx)
assert np.shares_memory(get_array(ser), get_array(ser2))
if using_copy_on_write:
assert not ser2._mgr._has_no_reference(0)

ser2.iloc[0] = 100
if using_copy_on_write:
tm.assert_series_equal(ser, ser_orig)
else:
expected = Series([100, 2, 3])
tm.assert_series_equal(ser, expected)


def test_series_from_block_manager_different_dtype(using_copy_on_write):
ser = Series([1, 2, 3], dtype="int64")
ser2 = Series(ser._mgr, dtype="int32")
assert not np.shares_memory(get_array(ser), get_array(ser2))
if using_copy_on_write:
assert ser2._mgr._has_no_reference(0)


@pytest.mark.parametrize("func", [lambda x: x, lambda x: x._mgr])
@pytest.mark.parametrize("columns", [None, ["a"]])
def test_dataframe_constructor_mgr_or_df(using_copy_on_write, columns, func):
Expand Down

0 comments on commit 4c2c3f8

Please sign in to comment.