fix(tools): h5rs diff compares every name of a hard-linked object

The path walk skipped the second hard link to an object, so a file that
shares one dataset between /x and /y differed from a file holding two
identical copies: "</y> exists only in <B>", exit 1, where h5diff exits 0.
For a hard-linked group every member was reported the same way.

diff now enumerates every path below the start object (a hard link back
to an ancestor is recorded but not descended into), so each name is
compared. A group whose links cannot be read is now an error instead of
an empty group.

Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-26 01:14:53 -05:00
co-authored by Claude Opus 5.5
parent 845a9d0125
commit 699ee9c447
5 changed files with 156 additions and 26 deletions
+17
View File
@@ -109,6 +109,23 @@ small("attr.h5", attr=True)
small("reshaped.h5", shape=(4, 3))
small("int.h5", dtype="i4")
# One object under two names (a hard link) against two separate copies.
with h5py.File(os.path.join(out, "hardlinked.h5"), "w") as f:
f["x"] = np.arange(5)
f["y"] = f["x"]
g = f.create_group("g")
g["d"] = np.arange(3)
g.create_group("s")["e"] = np.arange(2)
f["h"] = g
for name, last in (("copied.h5", 1), ("copied_changed.h5", 9)):
with h5py.File(os.path.join(out, name), "w") as f:
f["x"] = np.arange(5)
f["y"] = np.arange(5)
for gname in ("g", "h"):
g = f.create_group(gname)
g["d"] = np.arange(3)
g.create_group("s")["e"] = np.array([0, last if gname == "h" else 1])
with h5py.File(os.path.join(out, "userblock.h5"), "w", userblock_size=1024) as f:
f["d"] = np.arange(10)