Skip to content

Commit

Permalink
deprecate validation during AsdFile.__init__
Browse files Browse the repository at this point in the history
  • Loading branch information
braingram committed Dec 5, 2023
1 parent 72cd8d5 commit b8a80a5
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 39 deletions.
7 changes: 7 additions & 0 deletions asdf/_tests/test_deprecated.py
Original file line number Diff line number Diff line change
Expand Up @@ -59,3 +59,10 @@ def test_AsdfFile_resolve_references_kwargs_deprecation():
af = asdf.AsdfFile()
with pytest.warns(AsdfDeprecationWarning, match="Passing kwargs to resolve_references is deprecated"):
af.resolve_references(foo=42)


def test_AsdfFile_init_validation_deprecation():
with pytest.warns(AsdfDeprecationWarning, match="Validation during AsdfFile.__init__ is deprecated"), pytest.raises(
ValidationError
):
asdf.AsdfFile({"history": 42})
54 changes: 24 additions & 30 deletions asdf/_tests/test_schema.py
Original file line number Diff line number Diff line change
Expand Up @@ -844,26 +844,20 @@ def test_schema_resolved_via_entry_points():
def test_max_min_literals(num):
msg = r"Integer value .* is too large to safely represent as a literal in ASDF"

tree = {
"test_int": num,
}

af = asdf.AsdfFile()
af["test_int"] = num
with pytest.raises(ValidationError, match=msg):
asdf.AsdfFile(tree)

tree = {
"test_list": [num],
}
af.validate()

af = asdf.AsdfFile()
af["test_list"] = [num]
with pytest.raises(ValidationError, match=msg):
asdf.AsdfFile(tree)

tree = {
num: "test_key",
}
af.validate()

af = asdf.AsdfFile()
af[num] = "test_key"
with pytest.raises(ValidationError, match=msg):
asdf.AsdfFile(tree)
af.validate()


@pytest.mark.parametrize("num", [constants.MAX_NUMBER + 1, constants.MIN_NUMBER - 1])
Expand Down Expand Up @@ -930,8 +924,10 @@ def test_mapping_supported_key_types(keys, version):
)
def test_mapping_unsupported_key_types(keys, version):
for key in keys:
af = asdf.AsdfFile(version=version)
af[key] = "value"
with pytest.raises(ValidationError, match=r"Mapping key .* is not permitted"):
asdf.AsdfFile({key: "value"}, version=version)
af.validate()


def test_nested_array():
Expand Down Expand Up @@ -1022,10 +1018,10 @@ def test_custom_validation_bad(tmp_path):
ff.write_to(asdf_file)

# Creating file using custom schema should fail
with pytest.raises(ValidationError, match=r".* is a required property"), asdf.AsdfFile(
tree,
custom_schema=custom_schema_path,
):
af = asdf.AsdfFile(custom_schema=custom_schema_path)
af._tree = asdf.tags.core.AsdfObject(tree)
with pytest.raises(ValidationError, match=r".* is a required property"):
af.validate()
pass

# Opening file without custom schema should pass
Expand Down Expand Up @@ -1101,11 +1097,10 @@ def test_custom_validation_with_definitions_bad(tmp_path):
ff.write_to(asdf_file)

# Creating file with custom schema should fail
with pytest.raises(ValidationError, match=r".* is a required property"), asdf.AsdfFile(
tree,
custom_schema=custom_schema_path,
):
pass
af = asdf.AsdfFile(custom_schema=custom_schema_path)
af._tree = asdf.tags.core.AsdfObject(tree)
with pytest.raises(ValidationError, match=r".* is a required property"):
af.validate()

# Opening file without custom schema should pass
with asdf.open(asdf_file):
Expand Down Expand Up @@ -1145,11 +1140,10 @@ def test_custom_validation_with_external_ref_bad(tmp_path):
ff.write_to(asdf_file)

# Creating file with custom schema should fail
with pytest.raises(ValidationError, match=r"False is not valid under any of the given schemas"), asdf.AsdfFile(
tree,
custom_schema=custom_schema_path,
):
pass
af = asdf.AsdfFile(custom_schema=custom_schema_path)
af["foo"] = False
with pytest.raises(ValidationError, match=r"False is not valid under any of the given schemas"):
af.validate()

# Opening file without custom schema should pass
with asdf.open(asdf_file):
Expand Down
11 changes: 10 additions & 1 deletion asdf/asdf.py
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,16 @@ def __init__(
self.find_references()
else:
self._tree = AsdfObject(tree)
self.validate()
try:
self.validate()
except ValidationError:
warnings.warn(
"Validation during AsdfFile.__init__ is deprecated. "
"Please use AsdfFile.validate to validate the tree",
AsdfDeprecationWarning,
)
raise

self.find_references()

self._comments = []
Expand Down
18 changes: 10 additions & 8 deletions docs/asdf/deprecations.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ Deprecations
Version 3.1
===========

Automatic validation on assignment to the top-level ``AsdfFile.tree`` attribute is
deprecated and will be disabled in a future version of asdf. Please call
``AsdfFile.validate`` to validate the tree. As this is difficult to deprecate without
triggering warnings for every tree assignment the warning will only be shown
if the validation triggered by tree assignment fails.

Similarly, validation during ``AsdfFile.resolve_references`` is deprecated (with the
warning only appearing for a failed validation).
Several deprecations were added to ``AsdfFile`` methods that validate the
tree. In a future version of asdf these methods will not perform any tree
validation (please call ``AsdfFile.validate`` to validate the tree).
As this behavior is difficult to deprecate (without triggering warnings
for every call of the method) an ``AsdfDeprecationWarning`` will only
be issued on a failed validation during the following methods:

* ``AsdfFile.tree`` assignment
* ``AsdfFile.resolve_references``
* ``AsdfFile.__init__`` (when the ``tree`` argument is provided)

Providing ``kwargs`` to ``AsdfFile.resolve_references`` does nothing and is deprecated.

Expand Down

0 comments on commit b8a80a5

Please sign in to comment.