-
Notifications
You must be signed in to change notification settings - Fork 60
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
added support for __asdf_traverse__ method to allow custom introspect… #1052
Conversation
…ion of tag classes
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, that turned out nice and tidy! Can you add a brief section to readthedocs too?
asdf/_display.py
Outdated
@@ -1,5 +1,11 @@ | |||
""" | |||
Utilities for displaying the content of an ASDF tree. | |||
|
|||
Normally these tools only will introspect dicts, lists, and primative values |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
primative
--> primitive
asdf/_display.py
Outdated
@@ -1,5 +1,11 @@ | |||
""" | |||
Utilities for displaying the content of an ASDF tree. | |||
|
|||
Normally these tools only will introspect dicts, lists, and primative values | |||
(with an exception for arrays). However, if the objecct that is generated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
objecct
--> object
asdf/_display.py
Outdated
@@ -114,6 +125,15 @@ def __init__( | |||
self.recursive = recursive | |||
self.visible = visible | |||
self.children = [] | |||
self.tag = tag | |||
|
|||
def supports_info(node): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is being called as a class method up above, but it's not decorated as such and doesn't have a cls
argument. On the other hand, it seems to be working...
asdf/_display.py
Outdated
@@ -105,7 +115,8 @@ def from_root_node(cls, root_identifier, root_node): | |||
return root_info | |||
|
|||
def __init__( | |||
self, parent, identifier, node, depth, recursive=False, visible=True | |||
self, parent, identifier, node, depth, recursive=False, visible=True, | |||
tag=None |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this new tag
argument?
I believe I addressed the comments |
this functionality is great, looking forward to giving it a try, thanks @perrygreenfield ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems good to me.
asdf/_display.py
Outdated
next_nodes.append((info, child_identifier, child_node)) | ||
if cls.supports_info(node): | ||
info.tag = node._tag | ||
for child_identifier, child_node in node.__asdf_traverse__(): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Something I missed before, if we call get_children
on the result of __asdf_traverse__
, that will allow __asdf_traverse__
to return a dict and have it processed correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure what you mean here, particularly with if we call get_children
on the result. Doesn't __asdf_traverse__
return the same kind of result that get_children
does? I may be slow this morning. It is Wednesday.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The way this is set up currently, the __asdf_traverse__
method must return dict.items() if it wants to provide dict items, and enumerate(list) if it wants to provide list items. If we instead call get_children(__asdf_traverse__())
here, then __asdf_traverse__
can return simple dict or list and have everything work correctly (get_children will take care of calling .items() on the dict and wrapping the list in enumerate).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
OK, now I understand. I didn't realize you wanted to change what __asdf_traverse__
should return, I'll make the corresponding changes. It would be a simpler requirement on the method.
asdf/tests/test_api.py
Outdated
self._tag = "foo" | ||
|
||
def __asdf_traverse__(self): | ||
return list({'the_meaning_of_life_the_universe_and_everything': 42, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we add get_children
above, we can return a dict here
docs/asdf/extending/extensions.rst
Outdated
|
||
If the object produced by the extension supports a class method | ||
`.__asdf_traverse__` then it can be used by those tools to expose the contents | ||
of the object. That method should accept no arguments and return a list. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mention dict here if you decide to support that
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
This PR allows the asdf info functionality to check tag classes for a method asdf_traverse. If that method exists, then it is called whereupon it should return information that the info method expects. This allows any tag class to present information about its contents to the
info
method.The original purpose was to allow Roman data files to be displayed just like JWST files, which previously wasn't possible since the Roman asdf tree uses tag classes unlike the JWST tree. Roman_datamodels has been correspondingly updated to take advantage of this new capability.