Skip to content
22 changes: 17 additions & 5 deletions pandas/core/indexes/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -341,8 +341,13 @@ class Index(IndexOpsMixin, PandasObject):
Data type for the output Index. If not specified, this will be
inferred from `data`.
See the :ref:`user guide <basics.dtypes>` for more usages.
copy : bool, default False
Copy input data.
copy : bool, default None
Whether to copy input data, only relevant for array, Series, and Index
inputs (for other input, e.g. a list, a new array is created anyway).
Defaults to True for array input and False for Index/Series.
Set to False to avoid copying array input at your own risk (if you
know the input data won't be modified elsewhere).
Set to True to force copying Series/Index input up front.
name : object
Name to be stored in the index.
tupleize_cols : bool (default: True)
Expand Down Expand Up @@ -482,7 +487,7 @@ def __new__(
cls,
data=None,
dtype=None,
copy: bool = False,
copy: bool | None = None,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can also use the updated description in the Series docstring as a starting point to update the docstring here as well (as the end goal should be to make it similar)

name=None,
tupleize_cols: bool = True,
) -> Self:
Expand All @@ -499,9 +504,16 @@ def __new__(
if not copy and isinstance(data, (ABCSeries, Index)):
refs = data._references

if isinstance(data, (ExtensionArray, np.ndarray)):
# GH 63306
if copy is not False:
if dtype is None or astype_is_view(data.dtype, dtype):
data = data.copy()
copy = False

# range
if isinstance(data, (range, RangeIndex)):
result = RangeIndex(start=data, copy=copy, name=name)
result = RangeIndex(start=data, copy=bool(copy), name=name)
if dtype is not None:
return result.astype(dtype, copy=False)
# error: Incompatible return value type (got "MultiIndex",
Expand Down Expand Up @@ -569,7 +581,7 @@ def __new__(
data = com.asarray_tuplesafe(data, dtype=_dtype_obj)

try:
arr = sanitize_array(data, None, dtype=dtype, copy=copy)
arr = sanitize_array(data, None, dtype=dtype, copy=bool(copy))
except ValueError as err:
if "index must be specified when data is not list-like" in str(err):
raise cls._raise_scalar_data_error(data) from err
Expand Down
25 changes: 25 additions & 0 deletions pandas/tests/copy_view/index/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
DataFrame,
Index,
Series,
array,
)
import pandas._testing as tm
from pandas.tests.copy_view.util import get_array
Expand Down Expand Up @@ -150,3 +151,27 @@ def test_index_values():
idx = Index([1, 2, 3])
result = idx.values
assert result.flags.writeable is False


def test_constructor_copy_input_ndarray_default():
arr = np.array([0, 1])
idx = Index(arr)
assert not np.shares_memory(arr, get_array(idx))


def test_constructor_copy_input_ea_default():
arr = array([0, 1], dtype="Int64")
idx = Index(arr)
assert not tm.shares_memory(arr, idx.array)


def test_series_from_temporary_index_readonly_data():
# GH 63370
arr = np.array([0, 1], dtype=np.dtype(np.int8))
arr.flags.writeable = False
ser = Series(Index(arr))
assert not np.shares_memory(arr, get_array(ser))
assert ser._mgr._has_no_reference(0)
ser[[False, True]] = np.array([0, 2], dtype=np.dtype(np.int8))
expected = Series([0, 2], dtype=np.dtype(np.int8))
tm.assert_series_equal(ser, expected)
Loading