Skip to content
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

Allow tree to be created even when schema is missing #571

Merged
merged 2 commits into from
Oct 23, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@
- Fix bug that occurred when attempting to open invalid file but Astropy import
fails while checking for ASDF-in-FITS. [#562]

- Fix bug that caused tree creation to fail when unable to locate a schema file
for an unknown tag. This now simply causes a warning, and the offending node
is converted to basic Python data structures. [#571]

2.1.0 (2018-09-25)
------------------

Expand Down
8 changes: 7 additions & 1 deletion asdf/schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import os
import json
import datetime
import warnings
from numbers import Integral
from functools import lru_cache
from collections import OrderedDict
Expand Down Expand Up @@ -218,7 +219,12 @@ def iter_errors(self, instance, _schema=None, _seen=set()):
if tag is not None:
schema_path = self.ctx.resolver(tag)
if schema_path != tag:
s = load_schema(schema_path, self.ctx.resolver)
try:
s = load_schema(schema_path, self.ctx.resolver)
except FileNotFoundError:
msg = "Unable to locate schema file for '{}': '{}'"
warnings.warn(msg.format(tag, schema_path))
s = {}
if s:
with self.resolver.in_scope(schema_path):
for x in super(ASDFValidator, self).iter_errors(instance, s):
Expand Down
47 changes: 47 additions & 0 deletions asdf/tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -730,3 +730,50 @@ def test_custom_validation_with_definitions_bad(tmpdir):
with pytest.raises(ValidationError):
with asdf.open(asdf_file, custom_schema=custom_schema_path) as ff:
pass


def test_nonexistent_tag(tmpdir):
"""
This tests the case where a node is tagged with a type that apparently
comes from an extension that is known, but the type itself can't be found.

This could occur when a more recent version of an installed package
provides the new type, but an older version of the package is installed.
ASDF should still be able to open the file in this case, but it won't be
able to restore the type.

The bug that prompted this test results from attempting to load a schema
file that doesn't exist, which is why this test belongs in this file.
"""

# This shouldn't ever happen, but it's a useful test case
yaml = """
a: !core/doesnt_exist-1.0.0
hello
"""

buff = helpers.yaml_to_asdf(yaml)
with pytest.warns(None) as w:
with asdf.open(buff) as af:
assert str(af['a']) == 'hello'
# Currently there are 3 warnings since one occurs on each of the
# validation passes. It would be good to consolidate these eventually
assert len(w) == 3, helpers.display_warnings(w)
assert str(w[0].message).startswith("Unable to locate schema file")
assert str(w[1].message).startswith("Unable to locate schema file")
assert str(w[2].message).startswith(af['a']._tag)

# This is a more realistic case since we're using an external extension
yaml = """
a: !<tag:nowhere.org:custom/doesnt_exist-1.0.0>
hello
"""

buff = helpers.yaml_to_asdf(yaml)
with pytest.warns(None) as w:
with asdf.open(buff, extensions=CustomExtension()) as af:
assert str(af['a']) == 'hello'
assert len(w) == 3, helpers.display_warnings(w)
assert str(w[0].message).startswith("Unable to locate schema file")
assert str(w[1].message).startswith("Unable to locate schema file")
assert str(w[2].message).startswith(af['a']._tag)