Skip to content

Commit c78f125

Browse files
phoflpmhatre1
authored andcommitted
BUG: ensure_string_array might modify read-only array inplace (pandas-dev#57212)
* BUG: ensure_string_array might modify read-only array inplace * BUG: ensure_string_array might modify read-only array inplace * Fix pyarrow installed error
1 parent f948c3b commit c78f125

File tree

3 files changed

+16
-1
lines changed

3 files changed

+16
-1
lines changed

doc/source/whatsnew/v3.0.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -159,7 +159,7 @@ Numeric
159159

160160
Conversion
161161
^^^^^^^^^^
162-
-
162+
- Bug in :meth:`Series.astype` might modify read-only array inplace when casting to a string dtype (:issue:`57212`)
163163
-
164164

165165
Strings

pandas/_libs/lib.pyx

+3
Original file line numberDiff line numberDiff line change
@@ -770,6 +770,9 @@ cpdef ndarray[object] ensure_string_array(
770770
result = result.copy()
771771
elif not copy and result is arr:
772772
already_copied = False
773+
elif not copy and not result.flags.writeable:
774+
# Weird edge case where result is a view
775+
already_copied = False
773776

774777
if issubclass(arr.dtype.type, np.str_):
775778
# short-circuit, all elements are str

pandas/tests/copy_view/test_astype.py

+12
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import pytest
55

66
from pandas.compat.pyarrow import pa_version_under12p0
7+
import pandas.util._test_decorators as td
78

89
import pandas as pd
910
from pandas import (
@@ -139,6 +140,17 @@ def test_astype_string_copy_on_pickle_roundrip():
139140
tm.assert_series_equal(base, base_copy)
140141

141142

143+
@td.skip_if_no("pyarrow")
144+
def test_astype_string_read_only_on_pickle_roundrip():
145+
# https://github.com/pandas-dev/pandas/issues/54654
146+
# ensure_string_array may alter read-only array inplace
147+
base = Series(np.array([(1, 2), None, 1], dtype="object"))
148+
base_copy = pickle.loads(pickle.dumps(base))
149+
base_copy._values.flags.writeable = False
150+
base_copy.astype("string[pyarrow]", copy=False)
151+
tm.assert_series_equal(base, base_copy)
152+
153+
142154
def test_astype_dict_dtypes(using_copy_on_write):
143155
df = DataFrame(
144156
{"a": [1, 2, 3], "b": [4, 5, 6], "c": Series([1.5, 1.5, 1.5], dtype="float64")}

0 commit comments

Comments
 (0)