fix(format): a dataset attribute set again replaces the earlier value
b0a1e4f fixed this for group and root attributes only. Setting a dataset
attribute twice still wrote two attribute messages with one name, and h5py
read back the first value: set_attr("a", 1) then set_attr("a", 2) read as
1, and list(attrs) was ["a", "a"]. DatasetBuilder::set_attr now replaces
the earlier value, compact or dense. Likewise, a hand-set attribute named
like a provenance attribute (_provenance_sha256, ...) is replaced by the
computed one instead of being written next to it and read first.
Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
@@ -1355,7 +1355,10 @@ fn flatten_ds(db: DatasetBuilder, refcount: u32) -> Result<DsFlat, FormatError>
|
||||
timestamp: prov.timestamp.clone(),
|
||||
source: prov.source.clone(),
|
||||
};
|
||||
attrs.extend(p.build_attrs(&raw));
|
||||
// The provenance attributes replace any the caller set by hand.
|
||||
let prov = p.build_attrs(&raw);
|
||||
attrs.retain(|a| prov.iter().all(|b| b.name != a.name));
|
||||
attrs.extend(prov);
|
||||
}
|
||||
let fill_message = fill_value_message(db.fill_time, db.fill_value.as_deref(), &dt)?;
|
||||
Ok(DsFlat {
|
||||
|
||||
@@ -695,8 +695,13 @@ impl DatasetBuilder {
|
||||
self
|
||||
}
|
||||
|
||||
/// Set attribute `name`. Setting it again replaces the earlier value,
|
||||
/// as `attrs[name] = v` does in h5py.
|
||||
pub fn set_attr(&mut self, name: &str, value: AttrValue) -> &mut Self {
|
||||
self.attrs.push((name.to_string(), value));
|
||||
match self.attrs.iter_mut().find(|(n, _)| n == name) {
|
||||
Some(slot) => slot.1 = value,
|
||||
None => self.attrs.push((name.to_string(), value)),
|
||||
}
|
||||
self
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user