Convert `FileFormatModel` from `ABC` to `typing.Protocol` (#3692)

Closes #3100 

## Rationale for this change

`FileFormatModel` had only abstract methods (no shared implementation),
so an `ABC` was heavier than needed. This PR converts it to
`typing.Protocol`, which is the more Pythonic pattern for a pure
interface. `FileFormatWriter` remains an `ABC` since it has shared
`__enter__`/`__exit__`/`result` implementations that inheritance carries
for free. `FileFormatFactory` is unchanged - it matches the existing
`AuthManagerFactory` pattern.

## Changes

New format implementations can now conform structurally without
inheriting from `FileFormatModel`. Net: 2 `ABC`s → 1 `ABC` + 1
`Protocol`. No signature change for existing callers;
`ParquetFormatModel(FileFormatModel)` inheritance is retained
(`Protocol` supports explicit conformance).

## Are these changes tested?

Yes. `tests/io/test_fileformat.py` adds two tests using a shared
`_StructuralModel` helper:

- `test_file_format_model_is_protocol` - a structurally-conforming class
(no inheritance) passes `isinstance()` against `FileFormatModel`.
- `test_structural_model_works_with_factory` - a structurally-conforming
class can be registered and retrieved via `FileFormatFactory`
end-to-end.

## Are there any user-facing changes?

No. Default behavior is unchanged.
2 files changed
tree: 6cd879dba91892d05f672da669d90288008bc974
  1. .github/
  2. dev/
  3. mkdocs/
  4. notebooks/
  5. pyiceberg/
  6. tests/
  7. vendor/
  8. .asf.yaml
  9. .codespellrc
  10. .gitignore
  11. .markdownlint.yaml
  12. .pre-commit-config.yaml
  13. AGENTS.md
  14. LICENSE
  15. Makefile
  16. MANIFEST.in
  17. NOTICE
  18. pyproject.toml
  19. README.md
  20. ruff.toml
  21. SECURITY-THREAT-MODEL.md
  22. setup.py
  23. uv.lock
README.md

Iceberg Python

PyIceberg is a Python library for programmatic access to Iceberg table metadata as well as to table data in Iceberg format. It is a Python implementation of the Iceberg table spec.

The documentation is available at https://py.iceberg.apache.org/.

Get in Touch