fix(py): a panic in the library raises clawhdf5.InternalError, not PanicException
PanicException derives from BaseException, so `except Exception` let a library bug through. Every call from the bindings into the library now runs under catch_unwind and a panic becomes InternalError (RuntimeError) naming the object. Tests: a hidden hook panics inside the guard; and the v4 chunk indexes are compared with h5py from Python — with the library fix reverted, ds[0:30] of the implicit-index dataset now raises InternalError instead of aborting the test run. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -57,9 +57,9 @@ impl PyFile {
|
||||
let filename = path.to_string();
|
||||
match mode {
|
||||
"r" => {
|
||||
let file = py
|
||||
.detach(|| clawhdf5_rs::File::open(path))
|
||||
.map_err(to_py_err)?;
|
||||
let file = py.detach(|| {
|
||||
crate::no_panic(|| clawhdf5_rs::File::open(path).map_err(to_py_err))
|
||||
})?;
|
||||
Ok(Self {
|
||||
inner: Some(FileInner::Read(Arc::new(file))),
|
||||
filename,
|
||||
@@ -277,29 +277,31 @@ fn parse_compression(
|
||||
|
||||
/// Build and write the HDF5 file from accumulated write state.
|
||||
fn finalize_write(state: WriteState) -> PyResult<()> {
|
||||
let mut builder = clawhdf5_rs::FileBuilder::new();
|
||||
crate::no_panic(|| {
|
||||
let mut builder = clawhdf5_rs::FileBuilder::new();
|
||||
|
||||
// Root attributes
|
||||
let root_attrs = state.root_attrs.lock().unwrap_or_else(|e| e.into_inner());
|
||||
for (name, val) in root_attrs.iter() {
|
||||
builder.set_attr(name, val.clone().into());
|
||||
}
|
||||
drop(root_attrs);
|
||||
// Root attributes
|
||||
let root_attrs = state.root_attrs.lock().unwrap_or_else(|e| e.into_inner());
|
||||
for (name, val) in root_attrs.iter() {
|
||||
builder.set_attr(name, val.clone().into());
|
||||
}
|
||||
drop(root_attrs);
|
||||
|
||||
// Root datasets
|
||||
for spec in &state.root_datasets {
|
||||
let db = builder.create_dataset(&spec.name);
|
||||
apply_dataset_spec(db, spec);
|
||||
}
|
||||
// Root datasets
|
||||
for spec in &state.root_datasets {
|
||||
let db = builder.create_dataset(&spec.name);
|
||||
apply_dataset_spec(db, spec);
|
||||
}
|
||||
|
||||
// Groups
|
||||
for group_arc in &state.groups {
|
||||
let guard = group_arc.lock().unwrap();
|
||||
finalize_write_group(&mut builder, &guard);
|
||||
}
|
||||
// Groups
|
||||
for group_arc in &state.groups {
|
||||
let guard = group_arc.lock().unwrap();
|
||||
finalize_write_group(&mut builder, &guard);
|
||||
}
|
||||
|
||||
builder.write(&state.path).map_err(to_py_err)?;
|
||||
Ok(())
|
||||
builder.write(&state.path).map_err(to_py_err)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
Reference in New Issue
Block a user