diff --git a/python/pyarrow/src/arrow/python/python_to_arrow.cc b/python/pyarrow/src/arrow/python/python_to_arrow.cc index 5b83875813a..354b37246a5 100644 --- a/python/pyarrow/src/arrow/python/python_to_arrow.cc +++ b/python/pyarrow/src/arrow/python/python_to_arrow.cc @@ -879,6 +879,8 @@ class PyListConverter : public ListConverter { Status ValidateBuilder(const MapType*) { if (this->list_builder_->key_builder()->null_count() > 0) { return Status::Invalid("Invalid Map: key field cannot contain null values"); + } else if (this->list_builder_->value_builder()->null_count() > 0) { + return Status::Invalid("Invalid Map: entries cannot be null"); } else { return Status::OK(); } diff --git a/python/pyarrow/tests/test_convert_builtin.py b/python/pyarrow/tests/test_convert_builtin.py index 3ac7be88eaa..06a79f86ac3 100644 --- a/python/pyarrow/tests/test_convert_builtin.py +++ b/python/pyarrow/tests/test_convert_builtin.py @@ -2167,6 +2167,15 @@ def test_map_from_tuples(): pa.array([entry], type=pa.map_('i4', 'i4')) +def test_map_null_entry_raises(): + # GH-41283: a null map entry must raise instead of aborting + ty = pa.map_(pa.string(), pa.int32()) + with pytest.raises(pa.ArrowInvalid, match="entries cannot be null"): + pa.array([[{'key': 'a', 'value': 1}, None]], type=ty) + with pytest.raises(pa.ArrowInvalid, match="entries cannot be null"): + pa.array([[None]], type=pa.map_(pa.int32(), pa.int32())) + + def test_dictionary_from_boolean(): typ = pa.dictionary(pa.int8(), value_type=pa.bool_()) a = pa.array([False, False, True, False, True], type=typ)