pola-rs/polars · error · RuntimeError
copy not allowed: cast from {arr.dtype} to {dtype} prohibite
Error message
copy not allowed: cast from {arr.dtype} to {dtype} prohibited What it means
In DataFrame.__array__, when a target dtype was requested that differs from the DataFrame's natural numpy dtype, a cast requires materializing a new array; if the caller set copy=False (allow_copy=False), that cast is prohibited and polars raises RuntimeError rather than silently violating the zero-copy contract. It is a data-integrity guarantee, not a polars bug.
Source
Thrown at py-polars/src/polars/dataframe/frame.py:1030
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,
nan_as_null: bool = False, # noqa: FBT001
allow_copy: bool = True, # noqa: FBT001
) -> PolarsDataFrame:
"""
Convert to a dataframe object implementing the dataframe interchange protocol.
.. deprecated:: 1.40.0
Support for the Dataframe Interchange Protocol is deprecated.View on GitHub (pinned to df599052da)
Solutions
- Drop the dtype argument and cast afterwards only if a copy is acceptable
- Relax the constraint: copy=None (default) or copy=True permits the cast
- Cast in polars first so the natural numpy dtype already matches: df = df.cast(pl.Float32) then np.array(df, copy=False)
- If zero-copy is mandatory, request exactly the DataFrame's native dtype (e.g. df.to_numpy().dtype)
Example fix
# before np.array(df, copy=False, dtype='float32') # after df = df.cast(pl.Float32) arr = np.array(df, copy=False)
Defensive patterns
Strategy: validation
Validate before calling
import numpy as np
def zero_copy_array(df, dtype=None):
if dtype is not None and np.dtype(dtype) != df.to_numpy().dtype:
raise ValueError('cast requested under copy=False; cast the frame first')
return np.array(df, copy=False) Try / catch
try:
arr = np.array(df, copy=False, dtype=dtype)
except RuntimeError as e:
if 'copy not allowed' in str(e):
arr = np.array(df, dtype=dtype) # accept one copy as fallback
else:
raise Prevention
- Cast in polars first (df.cast(...)) so the requested dtype matches natively
- Never pair copy=False with a dtype that differs from df.to_numpy().dtype
- Treat RuntimeError 'copy not allowed' as a contract violation to fix upstream, not to silence
When it happens
Trigger: np.array(df, copy=False, dtype='float32') on an integer or float64 DataFrame; np.array(df, copy=False, dtype=np.int32) against UInt64 data; df.__array__(dtype=..., copy=False) with any lossy or width-changing cast.
Common situations: Zero-copy pipelines (differential-evolution loops, shared-memory IPC) that request dtype normalization while pinning copy=False; consumers assuming NumPy casts are free; downcasting for memory limits with copy constraints carried over from another library.
Related errors
- invalid input for `copy`: {copy!r}
- copy not allowed: cast from {arr.dtype} to {dtype} prohibite
- copy not allowed: cannot create structured array without cop
- non-contiguous buffer must be made contiguous
- string buffers must be converted
AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16).
Data as JSON: /api/errors/42c4d355cff24533.
Report an issue: GitHub.