fix(format): refuse to write datatypes the reader refuses

The reader now refuses a compound with a repeated field name or no
fields and an enum member with an empty name, as libhdf5 does, but the
writer still wrote them: CompoundTypeBuilder and EnumTypeBuilder build
them without complaint, so clawhdf5 wrote files it could not read back.
They were never valid HDF5; h5py refuses them.

Datatype::check_encodable, which FileWriter::finish runs on every
dataset and attribute type, now parses the type's own encoding back and
refuses one the reader refuses, with the reader's reason. That keeps the
writer in step with every reader check, not only these three.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-26 01:21:20 -05:00
co-authored by Claude Opus 5.5
parent a14ccc36bf
commit 17f09375ad
3 changed files with 83 additions and 4 deletions
+7
View File
@@ -333,6 +333,13 @@
a file shorter than the end of file its superblock records is refused
("truncated file"), and nothing past that end is read. `File`,
`LazyFile` and `MmapFile` do this.
- the writer: `FileWriter::finish()` / `FileBuilder::finish()` refuse a
datatype the reader would refuse (`FormatError::SerializationError`,
"datatype cannot be written: ..."), such as a compound with a repeated
field name or no fields, or an enum member with an empty name
(`CompoundTypeBuilder` and `EnumTypeBuilder` build them without
complaint). These were never valid HDF5 — h5py refuses them — and
clawhdf5 wrote them, which made files it could not read back.
Checks newer libhdf5 releases make but HDF5 2.0 does not (bit-field
offsets, the variable-length kind, array sizes) are left out, so files