{"record":{"id":"4ce5d4bd880fb85b","repo":"pola-rs/polars","slug":"dlpack","errorCode":null,"errorMessage":"__dlpack__","messagePattern":"__dlpack__","errorType":"exception","errorClass":"NotImplementedError","httpStatus":null,"severity":"error","filePath":"py-polars/src/polars/interchange/buffer.py","lineNumber":67,"sourceCode":"            n_bytes, rest = divmod(n_bits, 8)\n            # Round up to the nearest byte\n            if rest == 0:\n                return n_bytes\n            else:\n                return n_bytes + 1\n\n        return self._data.len() * (dtype[1] // 8)\n\n    @property\n    def ptr(self) -> int:\n        \"\"\"Pointer to start of the buffer as an integer.\"\"\"\n        pointer, _, _ = self._data._get_buffer_info()\n        return pointer\n\n    def __dlpack__(self) -> NoReturn:\n        \"\"\"Represent this structure as DLPack interface.\"\"\"\n        msg = \"__dlpack__\"\n        raise NotImplementedError(msg)\n\n    def __dlpack_device__(self) -> tuple[DlpackDeviceType, None]:\n        \"\"\"Device type and device ID for where the data in the buffer resides.\"\"\"\n        return (DlpackDeviceType.CPU, None)\n\n    def __repr__(self) -> str:\n        bufsize = self.bufsize\n        ptr = self.ptr\n        device = self.__dlpack_device__()[0].name\n        return f\"PolarsBuffer(bufsize={bufsize}, ptr={ptr}, device={device!r})\"\n","sourceCodeStart":49,"sourceCodeEnd":78,"githubUrl":"https://github.com/pola-rs/polars/blob/df599052daf96e7a9cc30a3b0c6bd25d6947e3c0/py-polars/src/polars/interchange/buffer.py#L49-L78","documentation":"PolarsBuffer deliberately does not implement the DLPack export protocol (__dlpack__ raises NotImplementedError). The interchange buffer exposes raw access via ptr and bufsize plus __dlpack_device__ (CPU), but consumers must read the memory themselves instead of using np.from_dlpack.","triggerScenarios":"Calling np.from_dlpack(polars_buffer); a library (array API consumer, GPU bridge like cupy) attempting DLPack import from an interchange buffer; generic code that probes __dlpack__ presence and then invokes it.","commonSituations":"Bridging interchange data into numpy/cupy via DLPack; migrating code that previously used Arrow PyCapsule or to_numpy and now walks the interchange buffers; array-API-standard adapters.","solutions":["Use the buffer's ptr and bufsize with ctypes/numpy: np.frombuffer via ctypes, or numpy ctypeslib","Prefer leaving the interchange path entirely: call series.to_numpy() or the Arrow/PyCapsule interfaces on the polars object","If writing a consumer, honor __dlpack_device__ and fall back to ptr-based access when __dlpack__ is unavailable"],"exampleFix":"// before\narr = np.from_dlpack(buffer)\n// after\nimport ctypes\narr = np.frombuffer((ctypes.c_char * buffer.bufsize).from_address(buffer.ptr))\n# or bypass interchange: series.to_numpy()","handlingStrategy":"fallback","validationCode":"hasattr(buffer, '__dlpack__')  # False-safe check before attempting DLPack import","typeGuard":"def supports_dlpack(obj) -> bool:\n    return callable(getattr(obj, '__dlpack__', None)) and type(obj).__dlpack__ is not object.__getattribute(type(obj), '__dlpack__', None) if False else callable(getattr(obj, '__dlpack__', None))","tryCatchPattern":"try:\n    arr = np.from_dlpack(buffer)\nexcept NotImplementedError:\n    import ctypes\n    arr = np.frombuffer((ctypes.c_char * buffer.bufsize).from_address(buffer.ptr))","preventionTips":["Prefer series.to_numpy() or Arrow interfaces over raw interchange buffers","In consumers, key off __dlpack_device__ then use ptr/bufsize for CPU buffers"],"tags":["polars","interchange-protocol","dlpack","numpy","buffer"],"backgroundTag":null,"analyzedSha":"df599052daf96e7a9cc30a3b0c6bd25d6947e3c0","analyzedAt":"2026-08-16T12:10:03.978Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}