Skip to content

when getting object by address do not fully instantiate when iterating#83

Merged
davidhassell merged 8 commits into
NCAS-CMS:mainfrom
kmuehlbauer:handle-not-implemented
Aug 21, 2025
Merged

when getting object by address do not fully instantiate when iterating#83
davidhassell merged 8 commits into
NCAS-CMS:mainfrom
kmuehlbauer:handle-not-implemented

Conversation

@kmuehlbauer

@kmuehlbauer kmuehlbauer commented Aug 15, 2025

Copy link
Copy Markdown
Collaborator

Description

The changes in this PR prevents instantiating objects fully when retrieving objects by address (eg. when dereferencing). This was reported in #70 (comment).

Checklist

  • This pull request has a descriptive title and labels
  • This pull request has a minimal description (most was discussed in the issue, but a two-liner description is still desirable)
  • Unit tests have been added (if codecov test fails)
  • Any changed dependencies have been added or removed correctly (if need be)
  • If you are working on the documentation, please ensure the current build passes
  • All tests pass

@valeriupredoi

Copy link
Copy Markdown
Collaborator

thanks a lot @kmuehlbauer - mind fixing the test too, please, mate? @bnlawrence you got a minute have a look at Kai's proposed change pls? 🍺

@kmuehlbauer

Copy link
Copy Markdown
Collaborator Author

@valeriupredoi I'm really sure there is a better solution to this here. I've only did this branch to let you know, what I'm about to. I've more details in #70 (comment).

The main problem is, that pyfive raises NotImplemented when a not implemented feature get's instanciated/requested. But, this also happens when dereferencing a Reference using visititems, which will instanciate all variables (including any not implemented) and raise. I can't do anything to prevent or work around from the h5netcdf-side. I hope @bnlawrence can spot the issue and maybe has already an idea to get around that.

@bnlawrence

Copy link
Copy Markdown
Collaborator

@valeriupredoi I'm really sure there is a better solution to this here. I've only did this branch to let you know, what I'm about to. I've more details in #70 (comment).

The main problem is, that pyfive raises NotImplemented when a not implemented feature get's instanciated/requested. But, this also happens when dereferencing a Reference using visititems, which will instanciate all variables (including any not implemented) and raise. I can't do anything to prevent or work around from the h5netcdf-side. I hope @bnlawrence can spot the issue and maybe has already an idea to get around that.

I know @davidhassell was thinking about this too. Before I dive in, @davidhassell, did you think any more about it? (As it happens, I am dead sick of proposal spreadsheets, so thinking about this for an hour or two would be a blessed relief.)

@valeriupredoi

Copy link
Copy Markdown
Collaborator

good man @kmuehlbauer - I usually open a Draft PR when it comes to these types, take your time, and am sure Bryan, David can help - this one's a bit out of my reach but I can help with fixing its tests etc, when time comes 🍺

@kmuehlbauer

Copy link
Copy Markdown
Collaborator Author

@valeriupredoi Ah, sorry, this should have been a draft.

@bnlawrence

bnlawrence commented Aug 19, 2025

Copy link
Copy Markdown
Collaborator

thanks a lot @kmuehlbauer - mind fixing the test too, please, mate? @bnlawrence you got a minute have a look at Kai's proposed change pls? 🍺

Actually, it would be really useful to have a test (or tests) that shows the behaviour that is wanted here, which is presumably to fail when you want it to and not before.

@bmaranville

bmaranville commented Aug 19, 2025

Copy link
Copy Markdown
Collaborator

I would agree that visititems is not needed (or appropriate?) for the dereference function.

Currently it's calling _get_obj_by_addr(self, obj_addr), which is then calling visititems, but I think you could just instantiate a new DataObjects with that offset and query it with is_dataset() to determine if it is a Group or Dataset, and then instantiate one of those to return, like is done here: https://github.com/NCAS-CMS/pyfive/blob/main/pyfive/high_level.py#L91

@kmuehlbauer

kmuehlbauer commented Aug 19, 2025

Copy link
Copy Markdown
Collaborator Author

@bmaranville Thanks for chiming in. This seems like a good way forward. I'll try to implement your suggestions here the next day. But, if someone has free cycles, feel free to add or override here.

@bnlawrence

Copy link
Copy Markdown
Collaborator

How about we start from deciding that the determine_dtype method of DataTypeMessageshould return something sensible for all dtypes, and we deal with the fact that pyfive doesn't implement them all elsewhere? Leaving aside whether or not we use visititems for dereferencing this would seem like a "good thing" (TM), wouldn't it? It kind of does now insofar as it tells you what it is as it raises itself in a heap ... but that's not as useful as saying, well, I can tell you what this is even if I can't read it?

Comment thread pyfive/datatype_msg.py Outdated
elif datatype_class == DATATYPE_ENUMERATED:
raise NotImplementedError(
"Enumerated datatype class not supported.")
return ("ENUMERATED", datatype_msg['size'])

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bnlawrence So, would this be something useful to return?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I think so. The higher-level API for dtype will need to return uint8, but what we do in between is the key and I think we will need that information. We could check for that in the higher-level API, return uint8, and implement check_enum_dtype to look for this. We could quite quickly then at least implement the ability to look at the enumeration integers, even if we can't immediately decode the dictionary stored in the Enumeration Property Description.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think DATATYPE_ENUMERATED can have a number of base types (any of the integer types?), not just uint8 - the base type is specified in the datatype message.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Quite right. Thanks for the reminder.

@bnlawrence

Copy link
Copy Markdown
Collaborator

I have added a new branch (enum_and_friends) where we can work on enum support. For the moment it is very dysfunctional, but it's a framework to work from, and includes a test which should make sure we support the h5py interface. Unfortunately I need to put this down to work on some other things and will be unlikely to follow all the way through before early September - but you never know, depends on progress and boredom levels with the other stuff I have to do right now. Ideally this branch also sorts out the visititems issue properly, but it might be that proceeding with this hack for the h5netcdf application is the right temporary expedient - but someone else will need to write the test for that.

@bnlawrence

Copy link
Copy Markdown
Collaborator

I have added a new branch (enum_and_friends) where we can work on enum support. For the moment it is very dysfunctional, but it's a framework to work from, and includes a test which should make sure we support the h5py interface. Unfortunately I need to put this down to work on some other things and will be unlikely to follow all the way through before early September - but you never know, depends on progress and boredom levels with the other stuff I have to do right now. Ideally this branch also sorts out the visititems issue properly, but it might be that proceeding with this hack for the h5netcdf application is the right temporary expedient - but someone else will need to write the test for that.

(And yes, I should have done it with a fork and a draft pull request, sorry, but I'm time poor right now and that would have taken me a wee bit longer to set up in VSC.)

Comment thread pyfive/high_level.py
Comment on lines +228 to +241
queue = deque([(self.name.rstrip('/'), self)])
while queue:
base, grp = queue.popleft()
for name, link_addr in grp._links.items():
full_path = f"{base}/{name}" if base else f"/{name}"
# check address without instantiating
if link_addr == obj_addr:
# return instantiated object
return grp[name]
# descend only if it's a subgroup (need to instantiate minimally)
# would be neat to have .is_group
dataobjs = DataObjects(self.file._fh, link_addr)
if not dataobjs.is_dataset and not dataobjs.is_datatype:
queue.append((full_path, grp[name]))

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This gets the object by address without instantiating completely. The DataObject creation is needed, to check for group and step into groups. Not sure if this more performant, but it doesn't instantiate the complete Datasets.

@kmuehlbauer kmuehlbauer marked this pull request as draft August 20, 2025 15:59
@kmuehlbauer kmuehlbauer changed the title hack: return None for not implemented when getting object by address do not fully instantiate when iterating Aug 20, 2025
@codecov

codecov Bot commented Aug 20, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 72.06%. Comparing base (7772b9b) to head (6f1224c).
⚠️ Report is 247 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main      #83      +/-   ##
==========================================
+ Coverage   71.93%   72.06%   +0.12%     
==========================================
  Files          11       11              
  Lines        2423     2434      +11     
  Branches      364      368       +4     
==========================================
+ Hits         1743     1754      +11     
+ Misses        583      582       -1     
- Partials       97       98       +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@kmuehlbauer

Copy link
Copy Markdown
Collaborator Author

OK, great, this seems to work now. I'll have to add tests.

@kmuehlbauer

Copy link
Copy Markdown
Collaborator Author

JFTR, as enum type is now handled in another PR, I'm concentrating here in the dereferencing of REFERENCE. This was done by using visititems which instantiated all objects which have been iterated over.

This now just compares the addresses and do a minimal test for group, where I added a respective is_group-method.

@kmuehlbauer kmuehlbauer marked this pull request as ready for review August 20, 2025 20:50
@kmuehlbauer

Copy link
Copy Markdown
Collaborator Author

Ready for review from my side. Thanks for all the suggestions and details.

@kmuehlbauer

Copy link
Copy Markdown
Collaborator Author

I was able to gain full coverage by adding another test. I'll leave this be now, so reviewers can have a look.

@davidhassell

Copy link
Copy Markdown
Collaborator

Thanks, @kmuehlbauer - I'm paying attention again now :), and will have a look at this PR today ...

@davidhassell davidhassell left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @kmuehlbauer,

Thank you for this change. The tests uses cases look good, the tests pass for me too. The new code makes sense, and I always like a corrected spelling mistake :).

We'll get this merged and out in a new PyPi release (0.5.1) today or tomorrow, so that it can be immediately used in the h5netcdf pyfive backend PR (h5netcdf/h5netcdf#273).

Cheers,
David

@kmuehlbauer

Copy link
Copy Markdown
Collaborator Author

Great news @davidhassell, happy to contribute.

@davidhassell

Copy link
Copy Markdown
Collaborator

(I'll be including this in the new Change Log that I'm about to start ...)

@davidhassell davidhassell merged commit a2d8433 into NCAS-CMS:main Aug 21, 2025
6 checks passed
@kmuehlbauer kmuehlbauer deleted the handle-not-implemented branch August 21, 2025 14:18
@valeriupredoi

Copy link
Copy Markdown
Collaborator

indeed, great many thanks @kmuehlbauer and @davidhassell 🍺 x2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants