From 3f445e0424033d0e92ef140e72780b395cb2ee63 Mon Sep 17 00:00:00 2001 From: Nilanjan Chatterjee Date: Sun, 11 Oct 2026 14:45:42 -0500 Subject: [PATCH] GH-40319: [Python] Accept null list scalars in pa.array The list converter treated a pyarrow ListScalar as a Python sequence and called len() on it, which fails for a null scalar. Append Arrow scalars directly, as the other converters already do. Co-Authored-By: Claude Opus 5.5 --- python/pyarrow/src/arrow/python/python_to_arrow.cc | 6 +++++- python/pyarrow/tests/test_convert_builtin.py | 5 +++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/python/pyarrow/src/arrow/python/python_to_arrow.cc b/python/pyarrow/src/arrow/python/python_to_arrow.cc index 5b83875813a1..f6971bfccc0b 100644 --- a/python/pyarrow/src/arrow/python/python_to_arrow.cc +++ b/python/pyarrow/src/arrow/python/python_to_arrow.cc @@ -841,7 +841,11 @@ class PyListConverter : public ListConverter { if (PyValue::IsNull(this->options_, value)) { return this->list_builder_->AppendNull(); } - if (has_numpy() && PyArray_Check(value)) { + if (arrow::py::is_scalar(value)) { + ARROW_ASSIGN_OR_RAISE(std::shared_ptr scalar, + arrow::py::unwrap_scalar(value)); + RETURN_NOT_OK(this->list_builder_->AppendScalar(GetStorageScalar(*scalar))); + } else if (has_numpy() && PyArray_Check(value)) { RETURN_NOT_OK(AppendNdarray(value)); } else if (PySequence_Check(value)) { RETURN_NOT_OK(AppendSequence(value)); diff --git a/python/pyarrow/tests/test_convert_builtin.py b/python/pyarrow/tests/test_convert_builtin.py index 3ac7be88eaa0..d35ac1a77bbb 100644 --- a/python/pyarrow/tests/test_convert_builtin.py +++ b/python/pyarrow/tests/test_convert_builtin.py @@ -2552,6 +2552,11 @@ def test_array_from_pylist_offset_overflow(): pa.list_view(pa.int64())), ([["a", "b"]], [pa.scalar(["a", "b"], type=pa.list_view(pa.string()))], pa.list_view(pa.string())), + # GH-40319: null list scalars + ([None, [1]], [pa.scalar(None, pa.list_(pa.int64())), pa.scalar([1])], + pa.list_(pa.int64())), + ([None], [pa.scalar(None, pa.large_list(pa.int64()))], + pa.large_list(pa.int64())), ( [1, 2, None], [pa.scalar(1, type=pa.int8()), pa.scalar(2, type=pa.int8()), None],