{"record":{"id":"f908adbff5b9a2f2","repo":"pandas-dev/pandas","slug":"can-only-use-the-list-accessor-with-list-pyarr","errorCode":null,"errorMessage":"Can only use the '.list' accessor with 'list[pyarrow]' dtype, not {dtype}.","messagePattern":"Can only use the '\\.list' accessor with 'list\\[pyarrow\\]' dtype, not (.+?)\\.","errorType":"exception","errorClass":"AttributeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/arrow/accessors.py","lineNumber":48,"sourceCode":"    )\n\n\nclass ArrowAccessor(metaclass=ABCMeta):\n    @abstractmethod\n    def __init__(self, data, validation_msg: str) -> None:\n        self._data = data\n        self._validation_msg = validation_msg\n        self._validate(data)\n\n    @abstractmethod\n    def _is_valid_pyarrow_dtype(self, pyarrow_dtype) -> bool:\n        pass\n\n    def _validate(self, data) -> None:\n        dtype = data.dtype\n        if not HAS_PYARROW or not isinstance(dtype, ArrowDtype):\n            # Raise AttributeError so that inspect can handle non-struct Series.\n            raise AttributeError(self._validation_msg.format(dtype=dtype))\n\n        if not self._is_valid_pyarrow_dtype(dtype.pyarrow_dtype):\n            # Raise AttributeError so that inspect can handle invalid Series.\n            raise AttributeError(self._validation_msg.format(dtype=dtype))\n\n    @property\n    def _pa_array(self):\n        return self._data.array._pa_array\n\n\nclass ListAccessor(ArrowAccessor):\n    \"\"\"\n    Accessor object for list data properties of the Series values.\n\n    Parameters\n    ----------\n    data : Series\n        Series containing Arrow list data.","sourceCodeStart":30,"sourceCodeEnd":66,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/arrow/accessors.py#L30-L66","documentation":"`AttributeError` from `ArrowAccessor._validate` for the `.list` accessor. It fires when the Series dtype is not an `ArrowDtype` over a pyarrow list type (list / fixed_size_list / large_list). pandas deliberately raises `AttributeError` (not `TypeError`) so that `inspect`/dir()/autocomplete and `hasattr(s, 'list')` behave naturally on non-list Series — the accessor simply appears absent.","triggerScenarios":"`s.list` where `s.dtype` is object, `string`, numpy list-of-lists, an `ArrowDtype` that is not a list type (e.g. `int64[pyarrow]`, `string[pyarrow]`), or a `large_list`/`fixed_size_list` is fine but a struct/decimal is not.","commonSituations":"Calling `.list.flatten()` / `.list.len()` on a Series that was not constructed with `pd.ArrowDtype(pa.list_(...))`; dtype silently downcast to object by a previous op; user assumes pyarrow storage but the Series is plain object dtype.","solutions":["Construct the Series with an explicit Arrow list dtype: `pd.Series(data, dtype=pd.ArrowDtype(pa.list_(pa.int64())))`.","Convert an existing Series: `s = s.astype(pd.ArrowDtype(pa.list_(pa.int64())))` before using `.list`.","Guard with `if isinstance(s.dtype, pd.ArrowDtype) and pa.types.is_list(s.dtype.pyarrow_dtype): ...`."],"exampleFix":"// before\ns = pd.Series([[1,2],[3]])\ns.list.len()   # object dtype -> AttributeError\n\n// after\nimport pyarrow as pa\ns = pd.Series([[1,2],[3]], dtype=pd.ArrowDtype(pa.list_(pa.int64())))\ns.list.len()","handlingStrategy":"type-guard","validationCode":"import pyarrow as pa\nfrom pandas.core.dtypes.dtypes import ArrowDtype\nif not (isinstance(s.dtype, ArrowDtype) and pa.types.is_list(s.dtype.pyarrow_dtype)):\n    s = s.astype(pd.ArrowDtype(pa.list_(pa.int64())))\ns.list.len()","typeGuard":"def is_arrow_list_series(s) -> bool:\n    import pyarrow as pa\n    from pandas.core.dtypes.dtypes import ArrowDtype\n    return (isinstance(s.dtype, ArrowDtype)\n            and (pa.types.is_list(s.dtype.pyarrow_dtype)\n                 or pa.types.is_large_list(s.dtype.pyarrow_dtype)\n                 or pa.types.is_fixed_size_list(s.dtype.pyarrow_dtype)))","tryCatchPattern":"try:\n    out = s.list.len()\nexcept AttributeError as e:\n    if '.list' in str(e):\n        s = s.astype(pd.ArrowDtype(pa.list_(pa.int64())))\n        out = s.list.len()\n    else:\n        raise","preventionTips":["Construct Series with explicit pd.ArrowDtype(pa.list_(...))","Guard accessor use with hasattr(s, 'list') once dtype is confirmed"],"tags":["accessor","pyarrow","list","dtype-mismatch"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}