{"record":{"id":"4aacd4bccce657dc","repo":"pandas-dev/pandas","slug":"sparsearray-does-not-support-item-assignment-via-s","errorCode":null,"errorMessage":"SparseArray does not support item assignment via setitem","messagePattern":"SparseArray does not support item assignment via setitem","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/sparse/array.py","lineNumber":621,"sourceCode":"                    unit = np.datetime_data(self.sp_values.dtype)[0]\n                    fill_value = np.datetime64(\"NaT\", unit)  # type: ignore[call-overload]\n            try:\n                dtype = np.result_type(self.sp_values.dtype, type(fill_value))\n            except TypeError:\n                dtype = object\n\n        out = np.full(self.shape, fill_value, dtype=dtype)\n        out[self.sp_index.indices] = self.sp_values\n        return out\n\n    def __setitem__(self, key, value) -> None:\n        if self._readonly:\n            raise ValueError(\"Cannot modify read-only array\")\n        # I suppose we could allow setting of non-fill_value elements.\n        # TODO(SparseArray.__setitem__): remove special cases in\n        # ExtensionBlock.where\n        msg = \"SparseArray does not support item assignment via setitem\"\n        raise TypeError(msg)\n\n    def sort(\n        self,\n        *,\n        ascending: bool = True,\n        kind: SortKind = \"quicksort\",\n        na_position: str = \"last\",\n    ) -> None:\n        raise NotImplementedError(\"SparseArray does not support in-place sort\")\n\n    @classmethod\n    def _from_sequence(\n        cls, scalars, *, dtype: Dtype | None = None, copy: bool = False\n    ) -> Self:\n        return cls(scalars, dtype=dtype)\n\n    @classmethod\n    def _from_factorized(cls, values, original) -> Self:","sourceCodeStart":603,"sourceCodeEnd":639,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/sparse/array.py#L603-L639","documentation":"Raised unconditionally by SparseArray.__setitem__. SparseArray is structurally immutable through item assignment because changing a stored value could require rebuilding the underlying sparse index. Although the method checks _readonly first, any setitem attempt that passes that guard is still rejected.","triggerScenarios":"Calling arr[i] = value, arr[mask] = value, or arr[slc] = value on a pandas SparseArray. Also triggered indirectly by ops that route through ExtensionArray.__setitem__ (e.g. some DataFrame.loc/iloc in-place writes on a sparse-backed column).","commonSituations":"Migrating dense ndarray/Series code to SparseArray expecting setitem to work; filling or updating a sparse column in place; using .where/inplace operations that delegate to __setitem__.","solutions":["Rebuild the SparseArray from modified dense data: arr = SparseArray(np.asarray(arr), ...); modify the dense view; reconstruct.","Operate via Series: wrap in pd.Series(arr), perform assignment, then .astype('Sparse') again.","Use arr = arr.fillna(value) or arr.shift/map to produce a new array rather than mutating.","If only fill_value elements need changing, rebuild with a new SparseDtype fill_value instead of setitem."],"exampleFix":"// before\narr = pd.arrays.SparseArray([1.0, np.nan, 3.0])\narr[1] = 2.0  # raises\n// after\nimport numpy as np\ndense = np.asarray(arr)\ndense[1] = 2.0\narr = pd.arrays.SparseArray(dense)","handlingStrategy":"validation","validationCode":"from pandas.core.arrays.sparse import SparseArray\n\ndef can_setitem(arr) -> bool:\n    return not isinstance(arr, SparseArray)","typeGuard":"from pandas.core.arrays.sparse import SparseArray\nimport pandas as pd\n\ndef is_sparse(arr) -> bool:\n    return isinstance(arr, (SparseArray, pd.arrays.SparseArray))","tryCatchPattern":"try:\n    arr[i] = value\nexcept TypeError as e:\n    if \"does not support item assignment\" in str(e):\n        arr = pd.arrays.SparseArray(np.asarray(arr))\n        # modify dense, rebuild\n    else:\n        raise","preventionTips":["Treat SparseArray as immutable; never call __setitem__.","Route mutations through Series or dense materialization.","Document sparse columns as rebuild-only in shared helpers."],"tags":["sparse","setitem","mutation","extension-array"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}