Skip to content

Commit a2d8433

Browse files
authored
Merge pull request #83 from kmuehlbauer/handle-not-implemented
when getting object by address do not fully instantiate when iterating
2 parents 04f5199 + 6f1224c commit a2d8433

File tree

3 files changed

+38
-5
lines changed

3 files changed

+38
-5
lines changed

pyfive/dataobjects.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,12 @@ def get_id_storage_params(self):
675675
version, dims, layout_class, property_offset = (
676676
self._get_data_message_properties(msg_offset))
677677
return msg_offset, layout_class, property_offset
678-
678+
679+
@property
680+
def is_group(self):
681+
""" True when DataObjects points to a group, False for a dataset. """
682+
return len(self.find_msg_type(GROUP_INFO_MSG_TYPE)) > 0
683+
679684
@property
680685
def is_dataset(self):
681686
""" True when DataObjects points to a dataset, False for a group. """

pyfive/high_level.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def __len__(self):
5050
return len(self._links)
5151

5252
def _dereference(self, ref):
53-
""" Deference a Reference object. """
53+
""" Dereference a Reference object. """
5454
if not ref:
5555
raise ValueError('cannot deference null reference')
5656
obj = self.file._get_object_by_address(ref.address_of_reference)
@@ -217,8 +217,19 @@ def _get_object_by_address(self, obj_addr):
217217
""" Return the object pointed to by a given address. """
218218
if self._dataobjects.offset == obj_addr:
219219
return self
220-
return self.visititems(
221-
lambda x, y: y if y._dataobjects.offset == obj_addr else None)
220+
221+
queue = deque([(self.name.rstrip('/'), self)])
222+
while queue:
223+
base, grp = queue.popleft()
224+
for name, link_addr in grp._links.items():
225+
full_path = f"{base}/{name}" if base else f"/{name}"
226+
# check address without instantiating
227+
if link_addr == obj_addr:
228+
# return instantiated object
229+
return grp[name]
230+
# descend only if it's a subgroup (need to instantiate minimally)
231+
if DataObjects(self.file._fh, link_addr).is_group:
232+
queue.append((full_path, grp[name]))
222233

223234
def close(self):
224235
""" Close the file. """

tests/test_h5netcdf.py

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,4 +57,21 @@ def test_file_contents():
5757
print('Attempting to compare ',x)
5858
print(h5file[x])
5959
print(p5file[x])
60-
raise
60+
raise
61+
62+
# check dereferencing
63+
ref1 = p5file["foo"].attrs["DIMENSION_LIST"][0][-1]
64+
assert p5file["x"].id == p5file[ref1].id
65+
assert str(p5file["x"][:]) == str(p5file[ref1][:])
66+
67+
ref2 = p5file["subgroup/subvar"].attrs["DIMENSION_LIST"][0][-1]
68+
assert p5file["x"].id == p5file[ref2].id
69+
assert str(p5file["x"][:]) == str(p5file[ref2][:])
70+
71+
assert p5file[ref1].id == p5file[ref2].id
72+
assert str(p5file[ref1][:]) == str(p5file[ref2][:])
73+
74+
ref3 = p5file["subgroup/y_var"].attrs["DIMENSION_LIST"][0][-1]
75+
assert p5file["subgroup/y"].id == p5file[ref3].id
76+
assert str(p5file["subgroup/y"][:]) == str(p5file[ref3][:])
77+
assert p5file["y"].id != p5file[ref3].id

0 commit comments

Comments
 (0)