Skip to content

Commit

Permalink
Merge pull request #1739 from braingram/asdf_traverse
Browse files Browse the repository at this point in the history
fix __asdf_traverse__ for non-tagged object
  • Loading branch information
braingram committed May 7, 2024
2 parents 2a07337 + c012e70 commit bf9dbf3
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 1 deletion.
5 changes: 5 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
3.3.0 (unreleased)
------------------

- Fix ``__asdf_traverse__`` for non-tagged objects [#1739]

3.2.0 (2024-04-05)
------------------

Expand Down
10 changes: 9 additions & 1 deletion asdf/_node_info.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,7 +282,15 @@ def from_root_node(cls, key, root_identifier, root_node, schema=None, refresh_ex

if cls.traversable(node):
t_node = node.__asdf_traverse__()
info.set_schema_from_node(node, extension_manager)
if hasattr(node, "_tag") and isinstance(node._tag, str):
try:
info.set_schema_from_node(node, extension_manager)
except KeyError:
# if _tag is not a valid tag, no schema will be found
# and a KeyError will be raised. We don't raise the KeyError
# (or another exception) here as the node (object) might
# be using _tag for a non-ASDF purpose.
pass

else:
t_node = node
Expand Down
36 changes: 36 additions & 0 deletions asdf/_tests/_regtests/test_1738.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import asdf


def test_info_on_non_tagged_asdf_traverse_object():
"""
Calling info with a tree containing an object that implements
__asdf_traverse__ but does not have a _tag results in an
error
https://github.com/asdf-format/asdf/issues/1738
"""

class MyContainer:
def __init__(self, data):
self.data = data

def __asdf_traverse__(self):
return self.data

c = MyContainer([1, 2, 3])
af = asdf.AsdfFile()
af["c"] = c

# info should not error out
af.info()

# and search should work with the container
assert af.search(type_=int).paths == ["root['c'][0]", "root['c'][1]", "root['c'][2]"]

# this should work even if _tag exists (and is not a tag)
c._tag = {}
af.info()
assert af.search(type_=int).paths == ["root['c'][0]", "root['c'][1]", "root['c'][2]"]
c._tag = "a"
af.info()
assert af.search(type_=int).paths == ["root['c'][0]", "root['c'][1]", "root['c'][2]"]

0 comments on commit bf9dbf3

Please sign in to comment.