Describe the bug
On a boolean array with a non-zero offset (a slice), fill_null_forward, fill_null_backward and
replace_with_mask return values that belong to other positions of the parent array: the value
bitmap is read without the slice's offset. A materialised copy of the same slice gives the right
answer, and an int64 slice is handled correctly, so it is specific to the bit-packed boolean path.
pyarrow 25.0.1, Python 3.13.9, macOS 26.6 (arm64), wheel from PyPI.
import pyarrow as pa, pyarrow.compute as pc
full = pa.array([True, False, None, True, True, False, None, True], pa.bool_())
sliced = full.slice(3, 5) # [True, True, False, None, True]
copy = pa.array(sliced.to_pylist(), pa.bool_()) # same values, offset 0
print("forward sliced", pc.fill_null_forward(sliced).to_pylist())
print("forward copy ", pc.fill_null_forward(copy).to_pylist())
print("backward sliced", pc.fill_null_backward(sliced).to_pylist())
print("backward copy ", pc.fill_null_backward(copy).to_pylist())
mask = pa.array([True, False, False, False, False])
repl = pa.array([False], pa.bool_())
print("replace sliced", pc.replace_with_mask(sliced, mask, repl).to_pylist())
print("replace copy ", pc.replace_with_mask(copy, mask, repl).to_pylist())
print("int64 control ", pc.fill_null_forward(pa.array([1, None, 3, 4, None, 6, None, 8]).slice(3, 5)).to_pylist())
Output:
forward sliced [True, False, False, False, True]
forward copy [True, True, False, False, True]
backward sliced [True, False, False, True, True]
backward copy [True, True, False, True, True]
replace sliced [False, False, False, None, True]
replace copy [False, True, False, None, True]
int64 control [4, 4, 6, 6, 8]
In every "sliced" line the second element is False, which is full[1], not full[4] (True):
the untouched positions are copied from bit index i of the parent bitmap instead of offset + i.
Expected behavior
The "sliced" and "copy" lines agree, as they do for int64.
This looks distinct from #45086 (an allocation crash on a boolean ChunkedArray, fixed on main by #50843 and not in a release yet): the values here are wrong, not the allocation.
Component(s)
C++, Python
Describe the bug
On a boolean array with a non-zero offset (a slice),
fill_null_forward,fill_null_backwardandreplace_with_maskreturn values that belong to other positions of the parent array: the valuebitmap is read without the slice's offset. A materialised copy of the same slice gives the right
answer, and an int64 slice is handled correctly, so it is specific to the bit-packed boolean path.
pyarrow 25.0.1, Python 3.13.9, macOS 26.6 (arm64), wheel from PyPI.
Output:
In every "sliced" line the second element is
False, which isfull[1], notfull[4](True):the untouched positions are copied from bit index
iof the parent bitmap instead ofoffset + i.Expected behavior
The "sliced" and "copy" lines agree, as they do for int64.
This looks distinct from #45086 (an allocation crash on a boolean ChunkedArray, fixed on main by #50843 and not in a release yet): the values here are wrong, not the allocation.
Component(s)
C++, Python