Repository: pandas-dev/pandas
File: pandas/core/generic.py (Python)

Code before:
        # GH 19920: retain column metadata after concat
        result = concat(results, axis=1)
        # GH#40810 retain subclass
        # error: Incompatible types in assignment
        # (expression has type "Self", variable has type "DataFrame")
        result = self._constructor(result)  # type: ignore[assignment]
        result.columns = self.columns
        result = result.__finalize__(self, method="astype")
        # https://github.com/python/mypy/issues/8354
        return cast(Self, result)

    @final
    def copy(self, deep: bool = True) -> Self:
        """
        Make a copy of this object's indices and data.

        When ``deep=True`` (default), a new object will be created with a
        copy of the calling object's data and indices. Modifications to
        the data or indices of the copy will not be reflected in the
        original object (see notes below).

        When ``deep=False``, a new object will be created without copying
        the calling object's data or index (only references to the data
        and index are copied). With Copy-on-Write enabled by default,
        changes to the data of the original will *not* be reflected in the
        shallow copy (and vice versa). The shallow copy uses a lazy (deferred)
        copy mechanism that copies the data only when any changes to the
        original or shallow copy are made, ensuring memory efficiency while
        maintaining data integrity.

        .. note::
            In pandas versions prior to 3.0, the default behavior without
            Copy-on-Write was different: changes to the data of the original
            *were* reflected in the shallow copy (and vice versa). See the
            :ref:`Copy-on-Write user guide <copy_on_write>` for more information.

        Parameters
        ----------
        deep : bool, default True
            Make a deep copy, including a copy of the data and the indices.
            With ``deep=False`` neither the indices nor the data are copied.

        Returns
        -------
        Series or DataFrame
            Object type matches caller.

        See Also
        --------
        copy.copy : Return a shallow copy of an object.
        copy.deepcopy : Return a deep copy of an object.

Review comment (suggestion):
This is true in terms of mutations at the e.g. `Series` level, but not array.

```python
ser = pd.Series([1, 2, 3])
ser2 = ser.copy(deep=False)
ser.array[1] = 100
print(ser2)
# 0      1
# 1    100
# 2      3
# dtype: int64
```

I'm not sure if we want to highlight this, cc @jorisvandenbossche 

Code after:
        # GH 19920: retain column metadata after concat
        result = concat(results, axis=1)
        # GH#40810 retain subclass
        # error: Incompatible types in assignment
        # (expression has type "Self", variable has type "DataFrame")
        result = self._constructor(result)  # type: ignore[assignment]
        result.columns = self.columns
        result = result.__finalize__(self, method="astype")
        # https://github.com/python/mypy/issues/8354
        return cast(Self, result)

    @final
    def copy(self, deep: bool = True) -> Self:
        """
        Make a copy of this object's indices and data.

        When ``deep=True`` (default), a new object will be created with a
        copy of the calling object's data and indices. Modifications to
        the data or indices of the copy will not be reflected in the
        original object (see notes below).

        When ``deep=False``, a new object will be created without copying
        the calling object's data or index (only references to the data
        and index are copied). With Copy-on-Write, changes to the original
        will *not* be reflected in the shallow copy (and vice versa). The
        shallow copy uses a lazy (deferred) copy mechanism that copies the
        data only when any changes to the original or shallow copy are made,
        ensuring memory efficiency while maintaining data integrity.

        .. note::
            In pandas versions prior to 3.0, the default behavior without
            Copy-on-Write was different: changes to the original *were* reflected
            in the shallow copy (and vice versa). See the :ref:`Copy-on-Write
            user guide <copy_on_write>` for more information.

        Parameters
        ----------
        deep : bool, default True
            Make a deep copy, including a copy of the data and the indices.
            With ``deep=False`` neither the indices nor the data are copied.

        Returns
        -------
        Series or DataFrame
            Object type matches caller.

        See Also
        --------
        copy.copy : Return a shallow copy of an object.
        copy.deepcopy : Return a deep copy of an object.