Skip to content

Fix DataFile spec ID binding - #3954

Draft
kevinjqliu wants to merge 2 commits into
mainfrom
kevinjqliu-investigate-datafile-spec-id
Draft

Fix DataFile spec ID binding#3954
kevinjqliu wants to merge 2 commits into
mainfrom
kevinjqliu-investigate-datafile-spec-id

Conversation

@kevinjqliu

@kevinjqliu kevinjqliu commented Sep 12, 2026

Copy link
Copy Markdown
Contributor

Motivation

DataFile.from_args(spec_id=...) passed spec_id through **arguments, but Record._bind only retained fields in the serialized data_file struct. Because spec_id belongs to the containing manifest rather than the data-file schema, it was silently discarded and later access could raise AttributeError.

Changes

  • Handle spec_id explicitly in DataFile.from_args and store it as transient runtime context, keeping it out of Avro serialization.
  • Make Record._bind reject unknown arguments instead of silently dropping them, preventing similar bugs.
  • Validate against the selected format-version schema so v1-only and v2-only fields are not mixed during construction.

This keeps cross-version compatibility in schema resolution while making construction and writing follow the target Iceberg format version.

Tests

  • make lint
  • Targeted record and manifest tests

Reject unknown record fields while retaining spec_id as transient DataFile context.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI lite review requested due to automatic review settings September 12, 2026 01:57

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Strict binding breaks an existing integration caller that passes format_version instead of the supported parameter.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Fixes transient DataFile.spec_id handling and enforces schema-based validation for record binding.

Changes:

  • Preserves transient spec_id values.
  • Rejects unknown fields during binding.
  • Adds regression tests for binding and format handling.
File summaries
File Summary
tests/test_typedef.py Adds tests for unknown-field rejection.
tests/avro/test_file.py Tests spec_id preservation and format handling.
pyiceberg/typedef.py Adds schema validation. Critical: an existing caller passes unsupported format_version, causing TypeError.
pyiceberg/manifest.py Preserves transient spec_id. Critical: the existing format_version caller must be updated or supported via an intentional alias.
Review details
  • Files reviewed: 4/4 changed files
  • Comments generated: 2
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread pyiceberg/manifest.py
Comment on lines +468 to +471
cls, _table_format_version: TableVersion = DEFAULT_READ_VERSION, *, spec_id: int | None = None, **arguments: Any
) -> DataFile:
struct = DATA_FILE_TYPE[_table_format_version]
return super()._bind(struct, **arguments)
data_file = super()._bind(struct, **arguments)
Comment thread pyiceberg/typedef.py
Comment on lines +182 to +184
field_names = {field.name for field in struct.fields}
if unknown_fields := arguments.keys() - field_names:
raise TypeError(f"Unexpected {cls.__name__} fields: {', '.join(sorted(unknown_fields))}")
@kevinjqliu
kevinjqliu marked this pull request as draft September 12, 2026 02:23
Use the internal table format selector now that unknown DataFile fields are rejected.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants