{"record":{"id":"b1202cf32b5e6716","repo":"pola-rs/polars","slug":"copy-not-allowed-cast-from-arr-dtype-to-dtype","errorCode":null,"errorMessage":"copy not allowed: cast from {arr.dtype} to {dtype} prohibited","messagePattern":"copy not allowed: cast from (.+?) to (.+?) prohibited","errorType":"exception","errorClass":"RuntimeError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/series/series.py","lineNumber":1500,"sourceCode":"            dtype = np.dtype(\"U\")\n\n        if copy is None:\n            writable, allow_copy = False, True\n        elif copy is True:\n            writable, allow_copy = True, True\n        elif copy is False:\n            writable, allow_copy = False, False\n        else:\n            msg = f\"invalid input for `copy`: {copy!r}\"\n            raise TypeError(msg)\n\n        arr = self.to_numpy(writable=writable, allow_copy=allow_copy)\n\n        if dtype is not None and dtype != arr.dtype:\n            if copy is False:\n                # TODO: Only raise when data must be copied\n                msg = f\"copy not allowed: cast from {arr.dtype} to {dtype} prohibited\"\n                raise RuntimeError(msg)\n\n            arr = arr.__array__(dtype)\n\n        return arr\n\n    def __array_ufunc__(\n        self, ufunc: np.ufunc, method: str_, *inputs: Any, **kwargs: Any\n    ) -> Series:\n        \"\"\"Numpy universal functions.\"\"\"\n        if self._s.n_chunks() > 1:\n            self._s.rechunk(in_place=True)\n\n        s = self._s\n\n        if method == \"__call__\":\n            if ufunc.nout != 1:\n                msg = \"only ufuncs that return one 1D array are supported\"\n                raise NotImplementedError(msg)","sourceCodeStart":1482,"sourceCodeEnd":1518,"githubUrl":"https://github.com/pola-rs/polars/blob/fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e/py-polars/src/polars/series/series.py#L1482-L1518","documentation":"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.","triggerScenarios":"`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.","commonSituations":"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.","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"],"exampleFix":"// before\narr = s.__array__(dtype=np.int32, copy=False)  # RuntimeError\n// after\narr = s.cast(pl.Int32).to_numpy()  # or allow copy=True","handlingStrategy":"validation","validationCode":"target = np.dtype(dtype)\narr0 = series.to_numpy()\nif target != arr0.dtype and copy is False:\n    raise ValueError(\"requested dtype differs; copy=False would need a cast\")","typeGuard":"def is_zero_copy_cast(series: pl.Series, dtype: np.dtype) -> bool:\n    return dtype is None or np.dtype(dtype) == series.to_numpy().dtype","tryCatchPattern":"try:\n    arr = series.__array__(dtype=dtype, copy=False)\nexcept RuntimeError as e:\n    if \"copy not allowed\" in str(e):\n        arr = series.__array__(dtype=dtype, copy=True)\n    else:\n        raise","preventionTips":["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"],"tags":["polars","python","numpy","zero-copy","dtype-cast"],"backgroundTag":"unsupported-dtype","analyzedSha":"fe841f959ef4d2ceefc05a310d33ed7b1ab24e5e","analyzedAt":"2026-09-18T22:14:11.667Z","contentChangedAt":"2026-09-18T22:14:11.667Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}