BUG: Series.str.pad/center/ljust/rjust with a negative width raises ArrowInvalid on PyArrow-backed strings
What happened:
Series.str.pad, Series.str.center, Series.str.ljust and Series.str.rjust raise pyarrow.lib.ArrowInvalid: Negative buffer resize when width is negative and the dtype is a PyArrow-backed string dtype.
Reproduction (reproduced on 3.0.6 with pyarrow 25.0.1):
import pandas as pd
s = pd.Series([ab, +ab, , café], dtype=pd.StringDtype(pyarrow))
s.str.ljust(-5)
# pyarrow.lib.ArrowInvalid: Negative buffer resize: -70center, rjust and pad raise the same error. The equivalent calls on object dtype, str dtype with python storage, and Python's own str.ljust/str.center all return the strings unchanged, since a non-positive width is a no-op in Python.
Expected behavior:
Negative (and zero) widths should return the values unchanged, matching object dtype and Python string semantics.
Root cause (from reading the code):
ArrowStringArrayMixin._str_pad in pandas/core/arrays/_arrow_string_mixins.py passes width straight to pc.utf8_lpad/pc.utf8_rpad/pc.utf8_center for pyarrow >= 17/21. These kernels size their output buffer from width and raise ArrowInvalid for negative values. Unlike the elementwise fallback paths (which call the Python str methods), the kernel path has no guard.
Notes:
- This is pre-existing and present in released 3.0.x (unlike the
str.zfillregression on main from #66339, tracked in #69486). - The same family of kernels is used for
Index.stras well.
Installed versions:
pandas 3.0.6, pyarrow 25.0.1, Python 3.13
Source: pandas-dev/pandas