clawhdf5: FileEditor reports filters it cannot run as Error::Unsupported

A dataset whose filter this build cannot encode (scale-offset, N-Bit, SZIP;
a plugin filter the build lacks) failed with Error::Format("unsupported
filter: 6"), although the editor documents every refused edit as
Error::Unsupported, and the Python bindings raised ValueError rather than
NotImplementedError. Every edit now maps FormatError::UnsupportedFilter to
Error::Unsupported; the file is left untouched as before.

Test: edit_interop unencodable_filters_are_unsupported — h5py scale-offset
datasets (integer with chunks, integer never written, float D-scale):
Error::Unsupported naming the filter, and the file byte for byte unchanged.
Fails on the previous editor (Format(UnsupportedFilter(6))).

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-26 14:13:45 -05:00
co-authored by Claude Opus 5.5
parent 485bea0f4f
commit b668878129
4 changed files with 58 additions and 4 deletions
@@ -1402,3 +1402,36 @@ fn attribute_count_in_version_2_headers() {
}
}
}
/// A dataset whose filters this build cannot encode (scale-offset)
/// is `Error::Unsupported`, as the editor documents, not a format error,
/// and the file is left byte for byte as it was.
#[test]
fn unencodable_filters_are_unsupported() {
if !tools_ok() {
return;
}
let dir = tmpdir();
let path = dir.path().join("unencodable.h5");
py(&format!(
"import h5py, numpy as np\n\
with h5py.File({p:?}, 'w') as f:\n\
\x20 f.create_dataset('so', data=np.arange(16, dtype='<i4'), chunks=(8,), maxshape=(None,), scaleoffset=0)\n\
\x20 f.create_dataset('so_new', shape=(16,), dtype='<i4', chunks=(8,), maxshape=(None,), scaleoffset=0)\n\
\x20 f.create_dataset('sof', data=np.arange(16, dtype='<f8'), chunks=(8,), scaleoffset=2)\n",
p = path.to_str().unwrap()
));
let before = std::fs::read(&path).unwrap();
let mut ed = FileEditor::open(&path).unwrap();
for (ds, es) in [("so", 4), ("so_new", 4), ("sof", 8)] {
match ed.write_all(ds, &vec![0u8; 16 * es]) {
Err(Error::Unsupported(msg)) => assert!(msg.contains("filter"), "{ds}: {msg}"),
other => panic!("{ds}: {other:?}"),
}
}
drop(ed);
assert!(
std::fs::read(&path).unwrap() == before,
"a refused edit changed the file"
);
}