pola-rs/polars · error · RuntimeError
copy not allowed: cast from
Error message
copy not allowed: cast from {arr.dtype} to {dtype} prohibited What it means
When `copy=False` is requested in Series.__array__, polars promises a zero-copy numpy view. If the requested dtype differs from the produced array's dtype, the cast would require copying data, so a RuntimeError is raised instead of silently violating the no-copy contract.
Solutions
- Allow copying: call with `copy=True` (or omit copy)
- Request the dtype the Series naturally produces (match `arr.dtype`, e.g. cast the Series in polars first: `series.cast(pl.Int32)` then convert)
- Only pass a dtype when it equals the Series' numpy dtype; check `series.to_numpy().dtype` beforehand
Example fix
// before arr = s.__array__(dtype=np.int32, copy=False) # RuntimeError // after arr = s.cast(pl.Int32).to_numpy() # or allow copy=True
Defensive patterns
Strategy: validation
Validate before calling
target = np.dtype(dtype)
arr0 = series.to_numpy()
if target != arr0.dtype and copy is False:
raise ValueError("requested dtype differs; copy=False would need a cast") Type guard
def is_zero_copy_cast(series: pl.Series, dtype: np.dtype) -> bool:
return dtype is None or np.dtype(dtype) == series.to_numpy().dtype Try / catch
try:
arr = series.__array__(dtype=dtype, copy=False)
except RuntimeError as e:
if "copy not allowed" in str(e):
arr = series.__array__(dtype=dtype, copy=True)
else:
raise Prevention
- Match requested dtype to the Series' natural numpy dtype
- Cast in polars (.cast) before converting instead of casting in numpy
- Only use copy=False in genuinely zero-copy pipelines
When it happens
Trigger: `series.__array__(dtype=np.int32, copy=False)` or `np.asarray(series, dtype=..., copy=False)` where `dtype != arr.dtype` (e.g. requesting a cast from Int64 to Float64 or to a different width) at py-polars/src/polars/series/series.py:1500.
Common situations: Interop code forcing a dtype while also forbidding copies; date/datetime series converted to numpy with a different dtype requested; strict zero-copy pipelines that changed the target dtype.
Related errors
- arr.dot query vector must be one-dimensional
- cannot convert DataFrame to
- cannot convert List column
- cannot parse numpy data type
- incorrect NumPy datetime resolution 'D' (datetime only)…
AI-assisted analysis of pola-rs/polars@fe841f959e (2026-09-18).
Data as JSON: /api/errors/b1202cf32b5e6716.
Report an issue: GitHub.
Appendix: source
Thrown at py-polars/src/polars/series/series.py:1500
dtype = np.dtype("U")
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
def __array_ufunc__(
self, ufunc: np.ufunc, method: str_, *inputs: Any, **kwargs: Any
) -> Series:
"""Numpy universal functions."""
if self._s.n_chunks() > 1:
self._s.rechunk(in_place=True)
s = self._s
if method == "__call__":
if ufunc.nout != 1:
msg = "only ufuncs that return one 1D array are supported"
raise NotImplementedError(msg)View on GitHub (pinned to fe841f959e)