Repository navigation
Conversation
ParquetDatasetWriter._write only closed the pyarrow ParquetWriter on the successful completion path. If a batch query/write or metadata persistence raised, the writer (and its underlying file handles) leaked while the outer file handle was closed by the caller. Wrap the write loop and metadata persistence in try/finally so the writer is always closed. Add a regression test that injects a mid-batch failure and checks both that the original exception propagates and that close() is called.
The first version of the test did not actually prove anything: pyarrow's `ParquetWriter.__del__` calls `close()` during garbage collection, so the mock recorded a close even when the writer was never closed explicitly and the test passed with the fix reverted. Keep the created writers alive so `__del__` cannot run before the assertion, and cover both variants of `write()` (opened path and borrowed buffer). The test now fails on the unfixed code and passes with the fix.
|
I found a problem with the regression test I added in this PR and pushed a fix for it, so it's worth flagging.
The updated test keeps the created writer instances alive so
Verified both directions locally: with the fix the test passes, with
|
What does this PR do?
Fixes #8743:
ParquetDatasetWriter._writeonly closes thepyarrow.parquet.ParquetWriteron the successful completion path. If a batch query/write or metadata persistence raises, the writer is left unclosed while the outer file handle is closed bywrite()— leaking the writer and its underlying file handles.Change
Move the write loop and metadata persistence into a
try/finallyblock sowriter.close()always runs, then returnwritten. No behavior change on the success path.Tests
Added
test_parquet_writer_closes_writer_on_failure, which injects a mid-batchwrite_tablefailure and asserts both that:writer.close()is still called.Verified locally:
55 passedintests/io/test_parquet.py(the 2 remaining errors are pre-existing HF-token/network fixture requirements, unrelated to this change).