Commit 02eef203 authored by Ole Streicher's avatar Ole Streicher

New upstream version 2.2.1

parent cf62d385
2.2.1 (2018-11-15)
------------------
- Fix an issue with the README that caused sporadic installation failures and
also prevented the long description from being rendered on pypi. [#607]
2.2.0 (2018-11-14)
------------------
- Add new parameter `lazy_load` to ``AsdfFile.open``. It is ``True`` by
default and preserves the default behavior. ``False`` detaches the
loaded tree from the underlying file: all blocks are fully read and
numpy arrays are materialized. Thus it becomes safe to close the file
and continue using ``AsdfFile.tree``. However, ``copy_arrays`` parameter
is still effective and the active memory maps may still require the file
to stay open in case ``copy_arrays`` is ``False``. [#573]
- Deprecate ``asdf.AsdfFile.open`` in favor of ``asdf.open``. [#579]
- Add readonly protection to memory mapped arrays when the underlying file
handle is readonly. [#579]
- Add ``AsdfConversionWarning`` for failures to convert ASDF tree into custom
types. This warning is converted to an error when using
``assert_roundtrip_tree`` for tests. [#583]
2.1.2 (2018-11-13)
------------------
- Make sure that all types corresponding to core tags are added to the type
index before any others. This fixes a bug that was related to the way that
subclass tags were overwritten by external extensions. [#598]
2.1.1 (2018-11-01)
------------------
- Make sure extension metadata is written even when constructing the ASDF tree
on-the-fly. [#549]
- Fix large integer validation when storing `numpy` integer literals in the
tree. [#553]
- Fix bug that caused subclass of external type to be serialized by the wrong
tag. [#560]
- 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)
------------------
......
Metadata-Version: 1.2
Name: asdf
Version: 2.1.0
Version: 2.2.1
Summary: Python tools to handle ASDF files
Home-page: http://github.com/spacetelescope/asdf
Author: Erik Bray, Dan D'Avella, Michael Droettboom
......@@ -9,12 +9,6 @@ License: BSD
Description: ASDF - Advanced Scientific Data Format
======================================
|Build Status| |Documentation Status| |Coverage Status| |stsci|
|astropy|
.. figure:: docs/_static/stsci_logo.png
:alt: STScI Logo
.. _begin-summary-text:
The **A**\ dvanced **S**\ cientific **D**\ ata **F**\ ormat (ASDF) is a
......@@ -320,16 +314,5 @@ Description: ASDF - Advanced Scientific Data Format
We strive to provide a welcoming community to all of our users by
abiding to the `Code of Conduct <CODE_OF_CONDUCT.md>`__.
.. |Build Status| image:: https://travis-ci.org/spacetelescope/asdf.svg?branch=master
:target: https://travis-ci.org/spacetelescope/asdf
.. |Documentation Status| image:: https://readthedocs.org/projects/asdf/badge/?version=latest
:target: http://asdf.readthedocs.io/en/latest/?badge=latest
.. |Coverage Status| image:: https://coveralls.io/repos/github/spacetelescope/asdf/badge.svg?branch=master
:target: https://coveralls.io/github/spacetelescope/asdf?branch=master
.. |stsci| image:: https://img.shields.io/badge/powered%20by-STScI-blue.svg?colorA=707170&colorB=3e8ddd&style=flat
:target: http://www.stsci.edu
.. |astropy| image:: http://img.shields.io/badge/powered%20by-AstroPy-orange.svg?style=flat
:target: http://www.astropy.org/
Platform: UNKNOWN
Requires-Python: >=3.3
ASDF - Advanced Scientific Data Format
======================================
|Build Status| |Documentation Status| |Coverage Status| |stsci|
|astropy|
.. figure:: docs/_static/stsci_logo.png
:alt: STScI Logo
..
ASDF - Advanced Scientific Data Format
======================================
.. raw:: html
<p align="center">
<img src="docs/_static/stsci_logo.png" alt="STScI Logo">
</p>
<h1 align="center">ASDF - Advanced Scientific Data Format</h1>
<p align="center">
<a href="https://travis-ci.org/spacetelescope/asdf"><img src="https://travis-ci.org/spacetelescope/asdf.svg?branch=master" alt="Build Status"></a>
<a href="http://asdf.readthedocs.io/en/latest/?badge=latest"><img src="https://readthedocs.org/projects/asdf/badge/?version=latest" alt="Documentation Status"></a>
<a href="https://coveralls.io/github/spacetelescope/asdf?branch=master"><img src="https://coveralls.io/repos/github/spacetelescope/asdf/badge.svg?branch=master" alt="Coverage Status"></a>
<img src="https://img.shields.io/pypi/l/asdf.svg" alt="license">
<a href="http://www.stsci.edu"><img src="https://img.shields.io/badge/powered%20by-STScI-blue.svg?colorA=707170&colorB=3e8ddd&style=flat" alt="stsci"></a>
<a href="http://www.astropy.org/"><img src="http://img.shields.io/badge/powered%20by-AstroPy-orange.svg?style=flat" alt="astropy"></a>
</p>
<p align="center">
<a href="#overview">Overview</a>
<a href="#installation">Installation</a>
<a href="#testing">Testing</a>
<a href="#documentation">Documentation</a>
<a href="#contributing">Contributing</a>
</p>
.. _begin-summary-text
......@@ -312,14 +329,3 @@ issue or a pull request.
We strive to provide a welcoming community to all of our users by
abiding to the `Code of Conduct <CODE_OF_CONDUCT.md>`__.
.. |Build Status| image:: https://travis-ci.org/spacetelescope/asdf.svg?branch=master
:target: https://travis-ci.org/spacetelescope/asdf
.. |Documentation Status| image:: https://readthedocs.org/projects/asdf/badge/?version=latest
:target: http://asdf.readthedocs.io/en/latest/?badge=latest
.. |Coverage Status| image:: https://coveralls.io/repos/github/spacetelescope/asdf/badge.svg?branch=master
:target: https://coveralls.io/github/spacetelescope/asdf?branch=master
.. |stsci| image:: https://img.shields.io/badge/powered%20by-STScI-blue.svg?colorA=707170&colorB=3e8ddd&style=flat
:target: http://www.stsci.edu
.. |astropy| image:: http://img.shields.io/badge/powered%20by-AstroPy-orange.svg?style=flat
:target: http://www.astropy.org/
......@@ -33,7 +33,7 @@ try:
except ImportError:
raise ImportError("asdf requires numpy")
from .asdf import AsdfFile
from .asdf import AsdfFile, open_asdf
from .asdftypes import CustomType
from .extension import AsdfExtension
from .stream import Stream
......@@ -42,4 +42,6 @@ from .tags.core.external_reference import ExternalArrayReference
from jsonschema import ValidationError
open = AsdfFile.open
open = open_asdf
# Avoid redundancy/confusion in the top-level namespace
del open_asdf
This diff is collapsed.
......@@ -95,7 +95,9 @@ class _AsdfWriteTypeIndex(object):
self._extensions_used = set()
try:
version_map = get_version_map(self._version)['tags']
version_map = get_version_map(self._version)
core_version_map = version_map['core']
standard_version_map = version_map['standard']
except ValueError:
raise ValueError(
"Don't know how to write out ASDF version {0}".format(
......@@ -126,7 +128,11 @@ class _AsdfWriteTypeIndex(object):
# hierarchy than the existing subclass.
if subclass in self._class_by_subclass:
if issubclass(self._class_by_subclass[subclass], typ):
continue
# Allow for cases where a subclass tag is being
# overridden by a tag from another extension.
if (self._extension_by_cls[subclass] ==
index._extension_by_type[asdftype]):
continue
self._class_by_subclass[subclass] = typ
self._type_by_subclasses[subclass] = asdftype
self._extension_by_cls[subclass] = index._extension_by_type[asdftype]
......@@ -148,8 +154,12 @@ class _AsdfWriteTypeIndex(object):
self._type_by_name[name] = asdftype
add_all_types(asdftype)
# Process all types defined in the ASDF version map
for name, _version in version_map.items():
# Process all types defined in the ASDF version map. It is important to
# make sure that tags that are associated with the core part of the
# standard are processed first in order to handle subclasses properly.
for name, _version in core_version_map.items():
add_by_tag(name, AsdfVersion(_version))
for name, _version in standard_version_map.items():
add_by_tag(name, AsdfVersion(_version))
# Now add any extension types that aren't known to the ASDF standard.
......
This diff is collapsed.
......@@ -8,6 +8,7 @@ Defragment command.
import os
import asdf
from .main import Command
from .. import AsdfFile
......@@ -65,7 +66,7 @@ def defragment(input, output=None, resolve_references=False, compress=None):
compress : str, optional
Compression to use.
"""
with AsdfFile.open(input) as ff:
with asdf.open(input) as ff:
ff2 = AsdfFile(ff)
if resolve_references:
ff2.resolve_references()
......
......@@ -28,6 +28,7 @@ except ImportError:
GREEN = ''
RESET = ''
import asdf
from .main import Command
from .. import AsdfFile
from .. import treeutil
......@@ -245,8 +246,8 @@ def compare_trees(diff_ctx, tree0, tree1, keys=[]):
def diff(filenames, minimal, iostream=sys.stdout):
"""Top-level implementation of diff algorithm"""
try:
with AsdfFile.open(filenames[0], _force_raw_types=True) as asdf0:
with AsdfFile.open(filenames[1], _force_raw_types=True) as asdf1:
with asdf.open(filenames[0], _force_raw_types=True) as asdf0:
with asdf.open(filenames[1], _force_raw_types=True) as asdf1:
diff_ctx = DiffContext(asdf0, asdf1, iostream, minimal=minimal)
compare_trees(diff_ctx, asdf0.tree, asdf1.tree)
except ValueError as error:
......
......@@ -8,6 +8,7 @@ Contains commands for dealing with exploded and imploded forms.
import os
import asdf
from .main import Command
from .. import AsdfFile
......@@ -65,7 +66,7 @@ def implode(input, output=None, resolve_references=False):
if output is None:
base, ext = os.path.splitext(input)
output = base + '_all' + '.asdf'
with AsdfFile.open(input) as ff:
with asdf.open(input) as ff:
ff2 = AsdfFile(ff)
if resolve_references:
ff2.resolve_references()
......@@ -115,5 +116,5 @@ def explode(input, output=None):
if output is None:
base, ext = os.path.splitext(input)
output = base + '_exploded' + '.asdf'
with AsdfFile.open(input) as ff:
with asdf.open(input) as ff:
ff.write_to(output, all_array_storage='external')
......@@ -8,6 +8,7 @@ import sys
import numpy as np
import pytest
import asdf
from ... import AsdfFile
from .. import main
from ...tests.helpers import get_file_sizes, assert_tree_match
......@@ -41,7 +42,7 @@ def _test_defragment(tmpdir, codec):
assert files['original.defragment.asdf'] < files['original.asdf']
with AsdfFile.open(os.path.join(str(tmpdir), 'original.defragment.asdf')) as ff:
with asdf.open(os.path.join(str(tmpdir), 'original.defragment.asdf')) as ff:
assert_tree_match(ff.tree, tree)
assert len(list(ff.blocks.internal_blocks)) == 2
......
......@@ -6,6 +6,7 @@ import os
import numpy as np
import asdf
from ... import AsdfFile
from .. import main
from ...tests.helpers import get_file_sizes, assert_tree_match
......@@ -35,6 +36,6 @@ def test_to_yaml(tmpdir):
assert 'original.asdf' in files
assert 'original.yaml' in files
with AsdfFile.open(os.path.join(str(tmpdir), 'original.yaml')) as ff:
with asdf.open(os.path.join(str(tmpdir), 'original.yaml')) as ff:
assert_tree_match(ff.tree, tree)
assert len(list(ff.blocks.internal_blocks)) == 0
......@@ -8,6 +8,7 @@ Contains commands for dealing with exploded and imploded forms.
import os
import asdf
from .main import Command
from .. import AsdfFile
......@@ -63,7 +64,7 @@ def to_yaml(input, output=None, resolve_references=False):
if output is None:
base, ext = os.path.splitext(input)
output = base + '.yaml'
with AsdfFile.open(input) as ff:
with asdf.open(input) as ff:
ff2 = AsdfFile(ff)
if resolve_references:
ff2.resolve_references()
......
......@@ -21,11 +21,6 @@ packagename = os.path.basename(os.path.dirname(__file__))
TESTED_VERSIONS[packagename] = version.version
pytest_plugins = [
'asdf.tests.schema_tester'
]
try:
PYTEST_HEADER_MODULES['Astropy'] = 'astropy'
PYTEST_HEADER_MODULES['jsonschema'] = 'jsonschema'
......
......@@ -11,3 +11,8 @@ class AsdfDeprecationWarning(AsdfWarning):
"""
A warning class to indicate a deprecated feature.
"""
class AsdfConversionWarning(AsdfWarning):
"""
Warning class used for failures to convert data into custom types.
"""
......@@ -231,4 +231,10 @@ class _DefaultExtensions:
def package_metadata(self):
return self._package_metadata
def reset(self):
"""This will be used primarily for testing purposes."""
self._extensions = []
self._extension_list = None
self._package_metadata = {}
default_extensions = _DefaultExtensions()
......@@ -73,7 +73,7 @@ if os.name == 'nt': # pragma: no cover
except OSError as e:
if e.errno != errno.EEXIST:
raise
old = "%s-%08x" % (dst, random.randint(0, sys.maxint))
old = "%s-%08x" % (dst, random.randint(0, sys.maxsize))
os.rename(dst, old)
os.rename(src, dst)
try:
......
......@@ -43,6 +43,10 @@ class _FitsBlock(object):
def data(self):
return self._hdu.data
@property
def readonly(self):
return False
@property
def array_storage(self):
return 'fits'
......@@ -178,7 +182,7 @@ class AsdfInFits(asdf.AsdfFile):
The URI for this ASDF file. Used to resolve relative
references against. If not provided, will be
automatically determined from the associated file object,
if possible and if created from `AsdfFile.open`.
if possible and if created from `asdf.open`.
validate_checksums : bool, optional
If `True`, validate the blocks against their checksums.
......
......@@ -1173,7 +1173,7 @@ def get_file(init, mode='r', uri=None, close=False):
elif isinstance(init, str):
parsed = urlparse.urlparse(init)
if parsed.scheme == 'http':
if parsed.scheme in ['http', 'https']:
if 'w' in mode:
raise ValueError(
"HTTP connections can not be opened for writing")
......
......@@ -4,8 +4,11 @@
import os
import json
import datetime
import warnings
from numbers import Integral
from functools import lru_cache
from collections import OrderedDict
from collections.abc import Mapping
from urllib import parse as urlparse
from jsonschema import validators as mvalidators
......@@ -217,7 +220,12 @@ def _create_validator(validators=YAML_VALIDATORS):
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):
......@@ -312,7 +320,6 @@ def load_custom_schema(url):
core = load_schema(AsdfObject.yaml_tag)
def update(d, u):
from collections import Mapping
for k, v in u.items():
# Respect the property ordering of the core schema
if k == 'propertyOrder' and k in d:
......@@ -457,7 +464,7 @@ def validate_large_literals(instance):
"""
# We can count on 52 bits of precision
for instance in treeutil.iter_tree(instance):
if (isinstance(instance, int) and (
if (isinstance(instance, (Integral)) and (
instance > ((1 << 51) - 1) or
instance < -((1 << 51) - 2))):
raise ValidationError(
......
......@@ -240,6 +240,8 @@ class NDArrayType(AsdfType):
self._offset = offset
self._strides = strides
self._order = order
if not asdffile.blocks.lazy_load:
self._make_array()
def _make_array(self):
if self._array is None:
......@@ -250,6 +252,8 @@ class NDArrayType(AsdfType):
shape, self._dtype, block.data,
self._offset, self._strides, self._order)
self._array = self._apply_mask(self._array, self._mask)
if block.readonly:
self._array.setflags(write=False)
return self._array
def _apply_mask(self, array, mask):
......@@ -342,6 +346,16 @@ class NDArrayType(AsdfType):
raise AttributeError()
return getattr(self._make_array(), attr)
def __setitem__(self, *args):
# This workaround appears to be necessary in order to avoid a segfault
# in the case that array assignment causes an exception. The segfault
# originates from the call to __repr__ inside the traceback report.
try:
self._make_array().__setitem__(*args)
except Exception as e:
self._array = None
raise e from None
@classmethod
def from_tree(cls, node, ctx):
if isinstance(node, list):
......@@ -507,7 +521,7 @@ for op in [
'__imul__', '__idiv__', '__itruediv__', '__ifloordiv__',
'__imod__', '__ipow__', '__ilshift__', '__irshift__',
'__iand__', '__ixor__', '__ior__', '__getitem__',
'__delitem__', '__contains__', '__setitem__']:
'__delitem__', '__contains__']:
setattr(NDArrayType, op, _make_operation(op))
......
......@@ -25,7 +25,7 @@ a: !core/complex-1.0.0
def test_invalid_complex(invalid):
with pytest.raises(asdf.ValidationError):
with asdf.AsdfFile.open(make_complex_asdf(invalid)):
with asdf.open(make_complex_asdf(invalid)):
pass
......@@ -36,7 +36,7 @@ def test_invalid_complex(invalid):
])
def test_valid_complex(valid):
with asdf.AsdfFile.open(make_complex_asdf(valid)) as af:
with asdf.open(make_complex_asdf(valid)) as af:
assert af.tree['a'] == complex(re.sub(r'[iI]$', r'j', valid))
......@@ -46,7 +46,7 @@ def test_valid_complex(valid):
])
def test_valid_nan_complex(valid):
with asdf.AsdfFile.open(make_complex_asdf(valid)) as af:
with asdf.open(make_complex_asdf(valid)) as af:
# Don't compare values since NANs are never equal
pass
......
......@@ -286,3 +286,12 @@ def test_metadata_with_custom_extension(tmpdir):
pass
assert len(warnings) == 0
# Make sure that this works even when constructing the tree on-the-fly
tmpfile3 = str(tmpdir.join('custom_extension2.asdf'))
with asdf.AsdfFile(extensions=FractionExtension()) as ff:
ff.tree['fraction'] = fractions.Fraction(4, 5)
ff.write_to(tmpfile3)
with asdf.open(tmpfile3, extensions=FractionExtension()) as af:
assert len(af['history']['extensions']) == 2
This diff is collapsed.
......@@ -141,10 +141,10 @@ frames:
""" % (declination, right_ascension, galcen_distance, roll, z_sun)
old_buff = helpers.yaml_to_asdf(old_frame_yaml)
old_asdf = AsdfFile.open(old_buff)
old_asdf = asdf.open(old_buff)
old_frame = old_asdf.tree['frames'][0]
new_buff = helpers.yaml_to_asdf(new_frame_yaml)
new_asdf = AsdfFile.open(new_buff)
new_asdf = asdf.open(new_buff)
new_frame = new_asdf.tree['frames'][0]
# Poor man's frame comparison since it's not implemented by astropy
......@@ -206,13 +206,13 @@ frames:
""" % (obsgeovel + obsgeoloc)
old_buff = helpers.yaml_to_asdf(old_frame_yaml)
old_asdf = AsdfFile.open(old_buff)
old_asdf = asdf.open(old_buff)
old_frame = old_asdf.tree['frames'][0]
old_loc = old_frame.reference_frame.obsgeoloc
old_vel = old_frame.reference_frame.obsgeovel
new_buff = helpers.yaml_to_asdf(new_frame_yaml)
new_asdf = AsdfFile.open(new_buff)
new_asdf = asdf.open(new_buff)
new_frame = new_asdf.tree['frames'][0]
new_loc = new_frame.reference_frame.obsgeoloc
new_vel = new_frame.reference_frame.obsgeovel
......
......@@ -3,6 +3,8 @@
This packages contains affiliated package tests.
"""
import numpy as np
from .. import CustomType
......@@ -20,3 +22,27 @@ class CustomTestType(CustomType):
@classmethod
def from_tree(cls, tree, ctx):
return tree
def create_small_tree():
x = np.arange(0, 10, dtype=np.float)
tree = {
'science_data': x,
'subset': x[3:-3],
'skipping': x[::2],
'not_shared': np.arange(10, 0, -1, dtype=np.uint8)
}
return tree
def create_large_tree():
# These are designed to be big enough so they don't fit in a
# single block, but not so big that RAM/disk space for the tests
# is enormous.
x = np.random.rand(256, 256)
y = np.random.rand(16, 16, 16)
tree = {
'science_data': x,
'more': y
}
return tree
......@@ -4,28 +4,14 @@
import pytest
import numpy as np
from . import create_small_tree, create_large_tree
@pytest.fixture
def small_tree():
x = np.arange(0, 10, dtype=np.float)
tree = {
'science_data': x,
'subset': x[3:-3],
'skipping': x[::2],
'not_shared': np.arange(10, 0, -1, dtype=np.uint8)
}
return tree
return create_small_tree()
@pytest.fixture
def large_tree():
# These are designed to be big enough so they don't fit in a
# single block, but not so big that RAM/disk space for the tests
# is enormous.
x = np.random.rand(256, 256)
y = np.random.rand(16, 16, 16)
tree = {
'science_data': x,
'more': y
}
return tree
return create_large_tree()
......@@ -3,6 +3,7 @@
import io
import os
import sys
import warnings
try:
from astropy.coordinates import ICRS
......@@ -19,10 +20,12 @@ try:
except ImportError:
CartesianDifferential = None
import asdf
from ..asdf import AsdfFile, get_asdf_library_info
from ..block import Block
from .httpserver import RangeHTTPServer
from ..extension import default_extensions
from .. import util
from ..exceptions import AsdfConversionWarning
from .. import versioning
from ..tags.core import AsdfObject
......@@ -143,10 +146,7 @@ def assert_tree_match(old_tree, new_tree, ctx=None,
recurse(old_tree, new_tree)
def assert_roundtrip_tree(tree, tmpdir, *, asdf_check_func=None,
raw_yaml_check_func=None, write_options={},
init_options={}, extensions=None,
tree_match_func='assert_equal'):
def assert_roundtrip_tree(*args, **kwargs):
"""
Assert that a given tree saves to ASDF and, when loaded back,
the tree matches the original tree.
......@@ -168,6 +168,16 @@ def assert_roundtrip_tree(tree, tmpdir, *, asdf_check_func=None,
Will be called with the reloaded ASDF file to perform any
additional checks.
"""
with warnings.catch_warnings():
warnings.filterwarnings("error", category=AsdfConversionWarning)
_assert_roundtrip_tree(*args, **kwargs)
def _assert_roundtrip_tree(tree, tmpdir, *, asdf_check_func=None,
raw_yaml_check_func=None, write_options={},
init_options={}, extensions=None,
tree_match_func='assert_equal'):
fname = str(tmpdir.join('test.asdf'))
# First, test writing/reading a BytesIO buffer
......@@ -175,7 +185,7 @@ def assert_roundtrip_tree(tree, tmpdir, *, asdf_check_func=None,
AsdfFile(tree, extensions=extensions, **init_options).write_to(buff, **write_options)
assert not buff.closed
buff.seek(0)
with AsdfFile.open(buff, mode='rw', extensions=extensions) as ff:
with asdf.open(buff, mode='rw', extensions=extensions) as ff:
assert not buff.closed
assert isinstance(ff.tree, AsdfObject)
assert 'asdf_library' in ff.tree
......@@ -186,7 +196,7 @@ def assert_roundtrip_tree(tree, tmpdir, *, asdf_check_func=None,
buff.seek(0)
ff = AsdfFile(extensions=extensions, **init_options)
content = AsdfFile._open_impl(ff, buff, _get_yaml_content=True)
content = AsdfFile._open_impl(ff, buff, mode='r', _get_yaml_content=True)
buff.close()
# We *never* want to get any raw python objects out
assert b'!!python' not in content
......@@ -198,7 +208,7 @@ def assert_roundtrip_tree(tree, tmpdir, *, asdf_check_func=None,
# Then, test writing/reading to a real file
ff = AsdfFile(tree, extensions=extensions, **init_options)
ff.write_to(fname, **write_options)
with AsdfFile.open(fname, mode='rw', extensions=extensions) as ff:
with asdf.open(fname, mode='rw', extensions=extensions) as ff:
assert_tree_match(tree, ff.tree, ff, funcname=tree_match_func)
if asdf_check_func:
asdf_check_func(ff)
......@@ -209,7 +219,7 @@ def assert_roundtrip_tree(tree, tmpdir, *, asdf_check_func=None,
AsdfFile(tree, extensions=extensions, **init_options).write_to(buff, **write_options)
assert not buff.closed
buff.seek(0)
with AsdfFile.open(buff, mode='rw', extensions=extensions) as ff:
with asdf.open(buff, mode='rw', extensions=extensions) as ff:
assert not buff.closed
assert isinstance(ff.tree, AsdfObject)
assert_tree_match(tree, ff.tree, ff, funcname=tree_match_func)
......@@ -222,7 +232,7 @@ def assert_roundtrip_tree(tree, tmpdir, *, asdf_check_func=None,
try:
ff = AsdfFile(tree, extensions=extensions, **init_options)
ff.write_to(os.path.join(server.tmpdir, 'test.asdf'), **write_options)
with AsdfFile.open(server.url + 'test.asdf', mode='r',
with asdf.open(server.url + 'test.asdf', mode='r',
extensions=extensions) as ff:
assert_tree_match(tree, ff.tree, ff, funcname=tree_match_func)
if asdf_check_func:
......@@ -230,6 +240,30 @@ def assert_roundtrip_tree(tree, tmpdir, *, asdf_check_func=None,
finally:
server.finalize()
# Now don't be lazy and check that nothing breaks
with io.BytesIO() as buff:
AsdfFile(tree, extensions=extensions, **init_options).write_to(buff, **write_options)
buff.seek(0)
ff = asdf.open(buff, extensions=extensions, copy_arrays=True, lazy_load=False)
# Ensure that all the blocks are loaded
for block in ff.blocks._internal_blocks:
assert isinstance(block, Block)