pandas-dev/pandas · error · ValueError

Unable to avoid copy while creating an array as requested.

Error message

Unable to avoid copy while creating an array as requested.

What it means

Raised by PeriodArray.__array__ when called with copy=False on a non-int64/non-bool target dtype. PeriodArray stores ordinals as int64, so producing a different dtype (e.g. object array of Period boxes) necessarily requires a copy; passing copy=False forbids it and the request is rejected.

Source

Thrown at pandas/core/arrays/period.py:452

            return None  # type: ignore[return-value]

    def __array__(
        self, dtype: NpDtype | None = None, copy: bool | None = None
    ) -> np.ndarray:
        if dtype == "i8":
            # For NumPy 1.x compatibility we cannot use copy=None.  And
            # `copy=False` has the meaning of `copy=None` here:
            if not copy:
                result = np.asarray(self.asi8, dtype=dtype)
                if self._readonly:
                    result = result.view()
                    result.flags.writeable = False
                return result
            else:
                return np.array(self.asi8, dtype=dtype)

        if copy is False:
            raise ValueError(
                "Unable to avoid copy while creating an array as requested."
            )

        if dtype == bool:
            return ~self._isnan

        # This will raise TypeError for non-object dtypes
        return np.array(list(self), dtype=object)

    def __arrow_array__(self, type=None):
        """
        Convert myself into a pyarrow Array.
        """
        import pyarrow

        from pandas.core.arrays.arrow.extension_types import ArrowPeriodType

        if type is not None:

View on GitHub (pinned to 71959b8cb9)

Solutions

  1. Allow the copy: drop copy=False or pass copy=True.
  2. Request the int64 view: np.asarray(pa, dtype='i8', copy=False) which is zero-copy.
  3. Use pa.to_numpy() which manages copy semantics internally.

Example fix

# before
arr = np.asarray(pa, dtype=object, copy=False)
# after
arr = np.asarray(pa, dtype=object)  # copy allowed
# or for zero-copy ordinals
arr = np.asarray(pa, dtype='i8', copy=False)
Defensive patterns

Strategy: validation

Validate before calling

import numpy as np

def to_numpy_zerocopy_or_allow(pa):
    try:
        return np.asarray(pa, dtype='i8', copy=False)
    except (TypeError, ValueError):
        return np.asarray(pa)

Type guard

import numpy as np

def is_zerocopy_compatible(pa, dtype) -> bool:
    return dtype in (None, np.dtype('i8')) or dtype == bool

Try / catch

try:
    arr = np.asarray(pa, dtype=target_dtype, copy=False)
except ValueError:
    arr = np.asarray(pa, dtype=target_dtype)

Prevention

When it happens

Trigger: np.asarray(period_array, dtype=object, copy=False), or frameworks that forward copy=False through __array__ (newer NumPy NEP 50 protocol). Also np.array(pa, copy=False) on a PeriodArray.

Common situations: NumPy 2.x changed copy semantics (copy=True/False/None); libraries passing copy=False explicitly. Arrow/other integrations that try zero-copy conversion of period arrays to object dtype.

Related errors


AI-assisted analysis of pandas-dev/pandas@71959b8cb9 (2026-08-07). Data as JSON: /api/errors/8ce9e4350845bfbd. Report an issue: GitHub.