pola-rs/polars · error · TypeError

invalid input for `copy`: {copy!r}

Error message

invalid input for `copy`: {copy!r}

What it means

DataFrame.__array__ maps the NumPy copy protocol's copy parameter to (writable, allow_copy): None -> (False, True), True -> (True, True), False -> (False, False). Any other value (strings like 'if-needed', np._CopyMode enum members, non-bool objects) has no mapping and raises TypeError.

Source

Thrown at py-polars/src/polars/dataframe/frame.py:1022

    ) -> np.ndarray[Any, Any]:
        """
        Return a NumPy ndarray with the given data type.

        This method ensures a Polars DataFrame can be treated as a NumPy ndarray.
        It enables `np.asarray` and NumPy universal functions.

        See the NumPy documentation for more information:
        https://numpy.org/doc/stable/user/basics.interoperability.html#the-array-method
        """
        if copy is None:
            writable, allow_copy = False, True
        elif copy is True:
            writable, allow_copy = True, True
        elif copy is False:
            writable, allow_copy = False, False
        else:
            msg = f"invalid input for `copy`: {copy!r}"
            raise TypeError(msg)

        arr = self.to_numpy(writable=writable, allow_copy=allow_copy)

        if dtype is not None and dtype != arr.dtype:
            if copy is False:
                # TODO: Only raise when data must be copied
                msg = f"copy not allowed: cast from {arr.dtype} to {dtype} prohibited"
                raise RuntimeError(msg)

            arr = arr.__array__(dtype)

        return arr

    @deprecated(
        "Support for the dataframe interchange protocol is deprecated since version 1.40.0"
    )
    def __dataframe__(
        self,

View on GitHub (pinned to df599052da)

Solutions

  1. Pass only True, False, or None for copy when invoking df.__array__ / np.array on a DataFrame
  2. Translate np._CopyMode.ALWAYS->True, NEVER->False, IF_NEEDED->None before calling
  3. Prefer the public df.to_numpy(writable=..., allow_copy=...) which has explicit flags

Example fix

# before
np.array(df, copy=np._CopyMode.IF_NEEDED)  # TypeError

# after
np.array(df, copy=None)
Defensive patterns

Strategy: type-guard

Validate before calling

import numpy as np

COPY_MODE_MAP = {
    np._CopyMode.ALWAYS: True,
    np._CopyMode.NEVER: False,
    np._CopyMode.IF_NEEDED: None,
}
copy_arg = COPY_MODE_MAP.get(copy, copy)  # translate before calling
if copy_arg not in (True, False, None):
    raise TypeError(f'copy must be True/False/None, got {copy!r}')

Type guard

def is_valid_copy_flag(c: object) -> bool:
    return c is None or isinstance(c, bool)

Prevention

When it happens

Trigger: np.array(df, copy=np._CopyMode.IF_NEEDED) or copy='if-needed'; passing np.copy semantics strings from other array libraries; a custom wrapper calling df.__array__(copy=some_int) directly.

Common situations: Interoperability code targeting array-api copy modes; migrating from libraries that accept string copy modes (numpy accepts np._CopyMode enums in its own API but the level-1 __array__ protocol here only handles tri-state bool/None).

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/4ce0a3751d4485f4. Report an issue: GitHub.