Skip to content

pipe_file() rejects compression for small values and uploads an empty object when a compressed write fails #1037

Description

@laughingman7743

Problem

S3FileSystem.pipe_file() and AioS3FileSystem.pipe_file() handle fsspec's compression argument differently by path:

  • Single-request path (data up to the block size, outside a transaction): compression is passed to PutObject, which botocore rejects with ParamValidationError: Unknown parameter in input: "compression".
  • Buffered path (in a transaction, or data larger than the block size): compression is passed to open(), which returns a compression wrapper (e.g. GzipFile) around the S3File. A successful write uploads the compressed data. A failed write calls _close_without_commit() on the wrapper, which raises AttributeError: 'GzipFile' object has no attribute '_close_without_commit'. The original error is hidden, and a 10-byte object holding only the gzip header is still uploaded, in and outside a transaction, so the guarantee from Write pipe_file() data without committing a failed write #1003 (a failed write leaves the existing object unchanged) does not hold.

Checked offline on master fe21250 with mocked requests, and with botocore parameter validation for the single-request path.

This also blocks #1034: the write-and-close helper cannot move to S3File while open() may return a compression wrapper (found in review of PR #1035).

Proposed fix

When compression is given, pipe_file() compresses the value in memory with the codec that open() would use (fsspec.core.get_compression() + fsspec.compression.compr, including "infer" from the path), and uploads the compressed bytes through the usual paths without passing compression to open() or S3. The routing and the multipart size check then use the compressed size. The same applies to the transaction path of AioS3FileSystem.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions