From e7054461df9de7bba86c10658d4c19dfab82a4fd Mon Sep 17 00:00:00 2001 From: Nick Lee-Roller Date: Fri, 23 Oct 2026 16:42:38 -0700 Subject: [PATCH] GH-53500: [Python][Parquet] Prevent crashes when comparing metadata with None Require non-null typed arguments in Statistics, ColumnChunkMetaData, RowGroupMetaData, ParquetSchema and ColumnSchema equals(), following the existing FileMetaData.equals() pattern, and add a regression test. Co-Authored-By: Claude Sonnet 5.5 --- python/pyarrow/_parquet.pyx | 10 ++++---- python/pyarrow/tests/parquet/test_metadata.py | 24 +++++++++++++++++++ 2 files changed, 29 insertions(+), 5 deletions(-) diff --git a/python/pyarrow/_parquet.pyx b/python/pyarrow/_parquet.pyx index 2621c3bd6d61..a9b876d58286 100644 --- a/python/pyarrow/_parquet.pyx +++ b/python/pyarrow/_parquet.pyx @@ -108,7 +108,7 @@ cdef class Statistics(_Weakrefable): except TypeError: return NotImplemented - def equals(self, Statistics other): + def equals(self, Statistics other not None): """ Return whether the two column statistics objects are equal. @@ -521,7 +521,7 @@ cdef class ColumnChunkMetaData(_Weakrefable): except TypeError: return NotImplemented - def equals(self, ColumnChunkMetaData other): + def equals(self, ColumnChunkMetaData other not None): """ Return whether the two column chunk metadata objects are equal. @@ -919,7 +919,7 @@ cdef class RowGroupMetaData(_Weakrefable): except TypeError: return NotImplemented - def equals(self, RowGroupMetaData other): + def equals(self, RowGroupMetaData other not None): """ Return whether the two row group metadata objects are equal. @@ -1295,7 +1295,7 @@ cdef class ParquetSchema(_Weakrefable): except TypeError: return NotImplemented - def equals(self, ParquetSchema other): + def equals(self, ParquetSchema other not None): """ Return whether the two schemas are equal. @@ -1350,7 +1350,7 @@ cdef class ColumnSchema(_Weakrefable): def __reduce__(self): return ColumnSchema, (self.parent, self.index) - def equals(self, ColumnSchema other): + def equals(self, ColumnSchema other not None): """ Return whether the two column schemas are equal. diff --git a/python/pyarrow/tests/parquet/test_metadata.py b/python/pyarrow/tests/parquet/test_metadata.py index 9eee70b125e5..f83c3437e8ed 100644 --- a/python/pyarrow/tests/parquet/test_metadata.py +++ b/python/pyarrow/tests/parquet/test_metadata.py @@ -724,6 +724,30 @@ def test_metadata_equals(): original_metadata.equals(None) +def test_parquet_metadata_equals_none(tempdir): + table = pa.table({"a": [1, 2, 3]}) + path = tempdir / "metadata_equals_none.parquet" + pq.write_table(table, path) + + metadata = pq.read_metadata(path) + row_group = metadata.row_group(0) + column_chunk = row_group.column(0) + objects = [ + column_chunk.statistics, + column_chunk, + row_group, + metadata.schema, + metadata.schema[0], + ] + none_value = None + + for obj in objects: + assert (obj == none_value) is False + assert (obj != none_value) is True + with pytest.raises(TypeError): + obj.equals(none_value) + + @pytest.mark.parametrize("t1,t2,expected_error", ( ({'col1': range(10)}, {'col1': range(10)}, None), ({'col1': range(10)}, {'col2': range(10)},