Merged
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
189 changes: 56 additions & 133 deletions zarr/tests/test_convenience.py
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import atexit
import os
import tempfile
import unittest
from numbers import Integral
Expand DownExpand Up@@ -456,67 +455,67 @@ def test_copy_all():
assert destination_group.subgroup.attrs["info"] == "sub attrs"


# noinspection PyAttributeOutsideInit
class TestCopy(unittest.TestCase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = False
self.new_source = group
self.new_dest = group

def setUp(self):
source = self.new_source()
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if self.source_h5py:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
class TestCopy:
@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def source(self, request, tmpdir):
def prep_source(source):
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if request.param:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42, filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
return source

if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('source.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield prep_source(h5f)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42,
filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
self.source = source

def test_copy_array(self):
source = self.source
dest = self.new_dest()
yield prep_source(group())

@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def dest(self, request, tmpdir):
if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('dest.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield h5f
else:
yield group()

def test_copy_array(self, source, dest):
# copy array with default options
copy(source['foo/bar/baz'], dest)
check_copied_array(source['foo/bar/baz'], dest['baz'])
copy(source['spam'], dest)
check_copied_array(source['spam'], dest['spam'])

def test_copy_bad_dest(self):
source = self.source

def test_copy_bad_dest(self, source, dest):
# try to copy to an array, dest must be a group
dest = self.new_dest().create_dataset('eggs', shape=(100,))
dest = dest.create_dataset('eggs', shape=(100,))
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest)

def test_copy_array_name(self):
source = self.source
dest = self.new_dest()

def test_copy_array_name(self, source, dest):
# copy array with name
copy(source['foo/bar/baz'], dest, name='qux')
assert 'baz' not in dest
check_copied_array(source['foo/bar/baz'], dest['qux'])

def test_copy_array_create_options(self):
source = self.source
dest = self.new_dest()
def test_copy_array_create_options(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

# copy array, provide creation options
compressor = Zlib(9)
create_kws = dict(chunks=(10,))
if self.dest_h5py:
if dest_h5py:
create_kws.update(compression='gzip', compression_opts=9,
shuffle=True, fletcher32=True, fillvalue=42)
else:
Expand All@@ -526,10 +525,7 @@ def test_copy_array_create_options(self):
check_copied_array(source['foo/bar/baz'], dest['baz'],
without_attrs=True, expect_props=create_kws)

def test_copy_array_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_array(self, source, dest):
# copy array, dest array in the way
dest.create_dataset('baz', shape=(10,))

Expand All@@ -554,10 +550,7 @@ def test_copy_array_exists_array(self):
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest, if_exists='foobar')

def test_copy_array_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_group(self, source, dest):
# copy array, dest group in the way
dest.create_group('baz')

Expand All@@ -577,13 +570,13 @@ def test_copy_array_exists_group(self):
copy(source['foo/bar/baz'], dest, if_exists='replace')
check_copied_array(source['foo/bar/baz'], dest['baz'])

def test_copy_array_skip_initialized(self):
source = self.source
dest = self.new_dest()
def test_copy_array_skip_initialized(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

dest.create_dataset('baz', shape=(100,), chunks=(10,), dtype='i8')
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

if self.dest_h5py:
if dest_h5py:
with pytest.raises(ValueError):
# not available with copy to h5py
copy(source['foo/bar/baz'], dest, if_exists='skip_initialized')
Expand All@@ -599,55 +592,37 @@ def test_copy_array_skip_initialized(self):
assert_array_equal(np.arange(100, 200), dest['baz'][:])
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

def test_copy_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group(self, source, dest):
# copy group, default options
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_no_name(self):
source = self.source
dest = self.new_dest()

def test_copy_group_no_name(self, source, dest):
with pytest.raises(TypeError):
# need a name if copy root
copy(source, dest)

copy(source, dest, name='root')
check_copied_group(source, dest['root'])

def test_copy_group_options(self):
source = self.source
dest = self.new_dest()

def test_copy_group_options(self, source, dest):
# copy group, non-default options
copy(source['foo'], dest, name='qux', without_attrs=True)
assert 'foo' not in dest
check_copied_group(source['foo'], dest['qux'], without_attrs=True)

def test_copy_group_shallow(self):
source = self.source
dest = self.new_dest()

def test_copy_group_shallow(self, source, dest):
# copy group, shallow
copy(source, dest, name='eggs', shallow=True)
check_copied_group(source, dest['eggs'], shallow=True)

def test_copy_group_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_group(self, source, dest):
# copy group, dest groups exist
dest.create_group('foo/bar')
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_array(self, source, dest):
# copy group, dest array in the way
dest.create_dataset('foo/bar', shape=(10,))

Expand All@@ -667,10 +642,7 @@ def test_copy_group_exists_array(self):
copy(source['foo'], dest, if_exists='replace')
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_dry_run(self):
source = self.source
dest = self.new_dest()

def test_copy_group_dry_run(self, source, dest):
# dry run, empty destination
n_copied, n_skipped, n_bytes_copied = \
copy(source['foo'], dest, dry_run=True, return_stats=True)
Expand DownExpand Up@@ -710,67 +682,18 @@ def test_copy_group_dry_run(self):
assert 0 == n_bytes_copied
assert_array_equal(baz, dest['foo/bar/baz'])

def test_logging(self):
source = self.source
dest = self.new_dest()

def test_logging(self, source, dest, tmpdir):
# callable log
copy(source['foo'], dest, dry_run=True, log=print)

# file name
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
fn = str(tmpdir.join('log_name'))
copy(source['foo'], dest, dry_run=True, log=fn)

# file
with tempfile.TemporaryFile(mode='w') as f:
with tmpdir.join('log_file').open(mode='w') as f:
copy(source['foo'], dest, dry_run=True, log=f)

# bad option
with pytest.raises(TypeError):
copy(source['foo'], dest, dry_run=True, log=True)


try:
import h5py
except ImportError: # pragma: no cover
h5py = None


def temp_h5f():
h5py = pytest.importorskip("h5py")
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
h5f = h5py.File(fn, mode='w')
atexit.register(lambda v: v.close(), h5f)
return h5f


class TestCopyHDF5ToZarr(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = False
self.new_source = temp_h5f
self.new_dest = group


class TestCopyZarrToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = True
self.new_source = group
self.new_dest = temp_h5f


class TestCopyHDF5ToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = True
self.new_source = temp_h5f
self.new_dest = temp_h5f
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
Merged
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
189 changes: 56 additions & 133 deletions zarr/tests/test_convenience.py
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import atexit
import os
import tempfile
import unittest
from numbers import Integral
Expand DownExpand Up@@ -456,67 +455,67 @@ def test_copy_all():
assert destination_group.subgroup.attrs["info"] == "sub attrs"


# noinspection PyAttributeOutsideInit
class TestCopy(unittest.TestCase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = False
self.new_source = group
self.new_dest = group

def setUp(self):
source = self.new_source()
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if self.source_h5py:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
class TestCopy:
@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def source(self, request, tmpdir):
def prep_source(source):
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if request.param:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42, filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
return source

if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('source.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield prep_source(h5f)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42,
filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
self.source = source

def test_copy_array(self):
source = self.source
dest = self.new_dest()
yield prep_source(group())

@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def dest(self, request, tmpdir):
if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('dest.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield h5f
else:
yield group()

def test_copy_array(self, source, dest):
# copy array with default options
copy(source['foo/bar/baz'], dest)
check_copied_array(source['foo/bar/baz'], dest['baz'])
copy(source['spam'], dest)
check_copied_array(source['spam'], dest['spam'])

def test_copy_bad_dest(self):
source = self.source

def test_copy_bad_dest(self, source, dest):
# try to copy to an array, dest must be a group
dest = self.new_dest().create_dataset('eggs', shape=(100,))
dest = dest.create_dataset('eggs', shape=(100,))
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest)

def test_copy_array_name(self):
source = self.source
dest = self.new_dest()

def test_copy_array_name(self, source, dest):
# copy array with name
copy(source['foo/bar/baz'], dest, name='qux')
assert 'baz' not in dest
check_copied_array(source['foo/bar/baz'], dest['qux'])

def test_copy_array_create_options(self):
source = self.source
dest = self.new_dest()
def test_copy_array_create_options(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

# copy array, provide creation options
compressor = Zlib(9)
create_kws = dict(chunks=(10,))
if self.dest_h5py:
if dest_h5py:
create_kws.update(compression='gzip', compression_opts=9,
shuffle=True, fletcher32=True, fillvalue=42)
else:
Expand All@@ -526,10 +525,7 @@ def test_copy_array_create_options(self):
check_copied_array(source['foo/bar/baz'], dest['baz'],
without_attrs=True, expect_props=create_kws)

def test_copy_array_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_array(self, source, dest):
# copy array, dest array in the way
dest.create_dataset('baz', shape=(10,))

Expand All@@ -554,10 +550,7 @@ def test_copy_array_exists_array(self):
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest, if_exists='foobar')

def test_copy_array_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_group(self, source, dest):
# copy array, dest group in the way
dest.create_group('baz')

Expand All@@ -577,13 +570,13 @@ def test_copy_array_exists_group(self):
copy(source['foo/bar/baz'], dest, if_exists='replace')
check_copied_array(source['foo/bar/baz'], dest['baz'])

def test_copy_array_skip_initialized(self):
source = self.source
dest = self.new_dest()
def test_copy_array_skip_initialized(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

dest.create_dataset('baz', shape=(100,), chunks=(10,), dtype='i8')
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

if self.dest_h5py:
if dest_h5py:
with pytest.raises(ValueError):
# not available with copy to h5py
copy(source['foo/bar/baz'], dest, if_exists='skip_initialized')
Expand All@@ -599,55 +592,37 @@ def test_copy_array_skip_initialized(self):
assert_array_equal(np.arange(100, 200), dest['baz'][:])
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

def test_copy_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group(self, source, dest):
# copy group, default options
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_no_name(self):
source = self.source
dest = self.new_dest()

def test_copy_group_no_name(self, source, dest):
with pytest.raises(TypeError):
# need a name if copy root
copy(source, dest)

copy(source, dest, name='root')
check_copied_group(source, dest['root'])

def test_copy_group_options(self):
source = self.source
dest = self.new_dest()

def test_copy_group_options(self, source, dest):
# copy group, non-default options
copy(source['foo'], dest, name='qux', without_attrs=True)
assert 'foo' not in dest
check_copied_group(source['foo'], dest['qux'], without_attrs=True)

def test_copy_group_shallow(self):
source = self.source
dest = self.new_dest()

def test_copy_group_shallow(self, source, dest):
# copy group, shallow
copy(source, dest, name='eggs', shallow=True)
check_copied_group(source, dest['eggs'], shallow=True)

def test_copy_group_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_group(self, source, dest):
# copy group, dest groups exist
dest.create_group('foo/bar')
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_array(self, source, dest):
# copy group, dest array in the way
dest.create_dataset('foo/bar', shape=(10,))

Expand All@@ -667,10 +642,7 @@ def test_copy_group_exists_array(self):
copy(source['foo'], dest, if_exists='replace')
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_dry_run(self):
source = self.source
dest = self.new_dest()

def test_copy_group_dry_run(self, source, dest):
# dry run, empty destination
n_copied, n_skipped, n_bytes_copied = \
copy(source['foo'], dest, dry_run=True, return_stats=True)
Expand DownExpand Up@@ -710,67 +682,18 @@ def test_copy_group_dry_run(self):
assert 0 == n_bytes_copied
assert_array_equal(baz, dest['foo/bar/baz'])

def test_logging(self):
source = self.source
dest = self.new_dest()

def test_logging(self, source, dest, tmpdir):
# callable log
copy(source['foo'], dest, dry_run=True, log=print)

# file name
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
fn = str(tmpdir.join('log_name'))
copy(source['foo'], dest, dry_run=True, log=fn)

# file
with tempfile.TemporaryFile(mode='w') as f:
with tmpdir.join('log_file').open(mode='w') as f:
copy(source['foo'], dest, dry_run=True, log=f)

# bad option
with pytest.raises(TypeError):
copy(source['foo'], dest, dry_run=True, log=True)


try:
import h5py
except ImportError: # pragma: no cover
h5py = None


def temp_h5f():
h5py = pytest.importorskip("h5py")
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
h5f = h5py.File(fn, mode='w')
atexit.register(lambda v: v.close(), h5f)
return h5f


class TestCopyHDF5ToZarr(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = False
self.new_source = temp_h5f
self.new_dest = group


class TestCopyZarrToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = True
self.new_source = group
self.new_dest = temp_h5f


class TestCopyHDF5ToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = True
self.new_source = temp_h5f
self.new_dest = temp_h5f
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
189 changes: 56 additions & 133 deletions zarr/tests/test_convenience.py
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import atexit
import os
import tempfile
import unittest
from numbers import Integral
Expand DownExpand Up@@ -456,67 +455,67 @@ def test_copy_all():
assert destination_group.subgroup.attrs["info"] == "sub attrs"


# noinspection PyAttributeOutsideInit
class TestCopy(unittest.TestCase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = False
self.new_source = group
self.new_dest = group

def setUp(self):
source = self.new_source()
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if self.source_h5py:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
class TestCopy:
@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def source(self, request, tmpdir):
def prep_source(source):
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if request.param:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42, filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
return source

if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('source.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield prep_source(h5f)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42,
filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
self.source = source

def test_copy_array(self):
source = self.source
dest = self.new_dest()
yield prep_source(group())

@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def dest(self, request, tmpdir):
if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('dest.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield h5f
else:
yield group()

def test_copy_array(self, source, dest):
# copy array with default options
copy(source['foo/bar/baz'], dest)
check_copied_array(source['foo/bar/baz'], dest['baz'])
copy(source['spam'], dest)
check_copied_array(source['spam'], dest['spam'])

def test_copy_bad_dest(self):
source = self.source

def test_copy_bad_dest(self, source, dest):
# try to copy to an array, dest must be a group
dest = self.new_dest().create_dataset('eggs', shape=(100,))
dest = dest.create_dataset('eggs', shape=(100,))
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest)

def test_copy_array_name(self):
source = self.source
dest = self.new_dest()

def test_copy_array_name(self, source, dest):
# copy array with name
copy(source['foo/bar/baz'], dest, name='qux')
assert 'baz' not in dest
check_copied_array(source['foo/bar/baz'], dest['qux'])

def test_copy_array_create_options(self):
source = self.source
dest = self.new_dest()
def test_copy_array_create_options(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

# copy array, provide creation options
compressor = Zlib(9)
create_kws = dict(chunks=(10,))
if self.dest_h5py:
if dest_h5py:
create_kws.update(compression='gzip', compression_opts=9,
shuffle=True, fletcher32=True, fillvalue=42)
else:
Expand All@@ -526,10 +525,7 @@ def test_copy_array_create_options(self):
check_copied_array(source['foo/bar/baz'], dest['baz'],
without_attrs=True, expect_props=create_kws)

def test_copy_array_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_array(self, source, dest):
# copy array, dest array in the way
dest.create_dataset('baz', shape=(10,))

Expand All@@ -554,10 +550,7 @@ def test_copy_array_exists_array(self):
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest, if_exists='foobar')

def test_copy_array_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_group(self, source, dest):
# copy array, dest group in the way
dest.create_group('baz')

Expand All@@ -577,13 +570,13 @@ def test_copy_array_exists_group(self):
copy(source['foo/bar/baz'], dest, if_exists='replace')
check_copied_array(source['foo/bar/baz'], dest['baz'])

def test_copy_array_skip_initialized(self):
source = self.source
dest = self.new_dest()
def test_copy_array_skip_initialized(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

dest.create_dataset('baz', shape=(100,), chunks=(10,), dtype='i8')
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

if self.dest_h5py:
if dest_h5py:
with pytest.raises(ValueError):
# not available with copy to h5py
copy(source['foo/bar/baz'], dest, if_exists='skip_initialized')
Expand All@@ -599,55 +592,37 @@ def test_copy_array_skip_initialized(self):
assert_array_equal(np.arange(100, 200), dest['baz'][:])
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

def test_copy_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group(self, source, dest):
# copy group, default options
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_no_name(self):
source = self.source
dest = self.new_dest()

def test_copy_group_no_name(self, source, dest):
with pytest.raises(TypeError):
# need a name if copy root
copy(source, dest)

copy(source, dest, name='root')
check_copied_group(source, dest['root'])

def test_copy_group_options(self):
source = self.source
dest = self.new_dest()

def test_copy_group_options(self, source, dest):
# copy group, non-default options
copy(source['foo'], dest, name='qux', without_attrs=True)
assert 'foo' not in dest
check_copied_group(source['foo'], dest['qux'], without_attrs=True)

def test_copy_group_shallow(self):
source = self.source
dest = self.new_dest()

def test_copy_group_shallow(self, source, dest):
# copy group, shallow
copy(source, dest, name='eggs', shallow=True)
check_copied_group(source, dest['eggs'], shallow=True)

def test_copy_group_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_group(self, source, dest):
# copy group, dest groups exist
dest.create_group('foo/bar')
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_array(self, source, dest):
# copy group, dest array in the way
dest.create_dataset('foo/bar', shape=(10,))

Expand All@@ -667,10 +642,7 @@ def test_copy_group_exists_array(self):
copy(source['foo'], dest, if_exists='replace')
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_dry_run(self):
source = self.source
dest = self.new_dest()

def test_copy_group_dry_run(self, source, dest):
# dry run, empty destination
n_copied, n_skipped, n_bytes_copied = \
copy(source['foo'], dest, dry_run=True, return_stats=True)
Expand DownExpand Up@@ -710,67 +682,18 @@ def test_copy_group_dry_run(self):
assert 0 == n_bytes_copied
assert_array_equal(baz, dest['foo/bar/baz'])

def test_logging(self):
source = self.source
dest = self.new_dest()

def test_logging(self, source, dest, tmpdir):
# callable log
copy(source['foo'], dest, dry_run=True, log=print)

# file name
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
fn = str(tmpdir.join('log_name'))
copy(source['foo'], dest, dry_run=True, log=fn)

# file
with tempfile.TemporaryFile(mode='w') as f:
with tmpdir.join('log_file').open(mode='w') as f:
copy(source['foo'], dest, dry_run=True, log=f)

# bad option
with pytest.raises(TypeError):
copy(source['foo'], dest, dry_run=True, log=True)


try:
import h5py
except ImportError: # pragma: no cover
h5py = None


def temp_h5f():
h5py = pytest.importorskip("h5py")
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
h5f = h5py.File(fn, mode='w')
atexit.register(lambda v: v.close(), h5f)
return h5f


class TestCopyHDF5ToZarr(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = False
self.new_source = temp_h5f
self.new_dest = group


class TestCopyZarrToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = True
self.new_source = group
self.new_dest = temp_h5f


class TestCopyHDF5ToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = True
self.new_source = temp_h5f
self.new_dest = temp_h5f
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
189 changes: 56 additions & 133 deletions zarr/tests/test_convenience.py
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import atexit
import os
import tempfile
import unittest
from numbers import Integral
Expand DownExpand Up@@ -456,67 +455,67 @@ def test_copy_all():
assert destination_group.subgroup.attrs["info"] == "sub attrs"


# noinspection PyAttributeOutsideInit
class TestCopy(unittest.TestCase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = False
self.new_source = group
self.new_dest = group

def setUp(self):
source = self.new_source()
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if self.source_h5py:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
class TestCopy:
@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def source(self, request, tmpdir):
def prep_source(source):
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if request.param:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42, filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
return source

if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('source.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield prep_source(h5f)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42,
filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
self.source = source

def test_copy_array(self):
source = self.source
dest = self.new_dest()
yield prep_source(group())

@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def dest(self, request, tmpdir):
if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('dest.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield h5f
else:
yield group()

def test_copy_array(self, source, dest):
# copy array with default options
copy(source['foo/bar/baz'], dest)
check_copied_array(source['foo/bar/baz'], dest['baz'])
copy(source['spam'], dest)
check_copied_array(source['spam'], dest['spam'])

def test_copy_bad_dest(self):
source = self.source

def test_copy_bad_dest(self, source, dest):
# try to copy to an array, dest must be a group
dest = self.new_dest().create_dataset('eggs', shape=(100,))
dest = dest.create_dataset('eggs', shape=(100,))
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest)

def test_copy_array_name(self):
source = self.source
dest = self.new_dest()

def test_copy_array_name(self, source, dest):
# copy array with name
copy(source['foo/bar/baz'], dest, name='qux')
assert 'baz' not in dest
check_copied_array(source['foo/bar/baz'], dest['qux'])

def test_copy_array_create_options(self):
source = self.source
dest = self.new_dest()
def test_copy_array_create_options(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

# copy array, provide creation options
compressor = Zlib(9)
create_kws = dict(chunks=(10,))
if self.dest_h5py:
if dest_h5py:
create_kws.update(compression='gzip', compression_opts=9,
shuffle=True, fletcher32=True, fillvalue=42)
else:
Expand All@@ -526,10 +525,7 @@ def test_copy_array_create_options(self):
check_copied_array(source['foo/bar/baz'], dest['baz'],
without_attrs=True, expect_props=create_kws)

def test_copy_array_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_array(self, source, dest):
# copy array, dest array in the way
dest.create_dataset('baz', shape=(10,))

Expand All@@ -554,10 +550,7 @@ def test_copy_array_exists_array(self):
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest, if_exists='foobar')

def test_copy_array_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_group(self, source, dest):
# copy array, dest group in the way
dest.create_group('baz')

Expand All@@ -577,13 +570,13 @@ def test_copy_array_exists_group(self):
copy(source['foo/bar/baz'], dest, if_exists='replace')
check_copied_array(source['foo/bar/baz'], dest['baz'])

def test_copy_array_skip_initialized(self):
source = self.source
dest = self.new_dest()
def test_copy_array_skip_initialized(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

dest.create_dataset('baz', shape=(100,), chunks=(10,), dtype='i8')
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

if self.dest_h5py:
if dest_h5py:
with pytest.raises(ValueError):
# not available with copy to h5py
copy(source['foo/bar/baz'], dest, if_exists='skip_initialized')
Expand All@@ -599,55 +592,37 @@ def test_copy_array_skip_initialized(self):
assert_array_equal(np.arange(100, 200), dest['baz'][:])
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

def test_copy_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group(self, source, dest):
# copy group, default options
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_no_name(self):
source = self.source
dest = self.new_dest()

def test_copy_group_no_name(self, source, dest):
with pytest.raises(TypeError):
# need a name if copy root
copy(source, dest)

copy(source, dest, name='root')
check_copied_group(source, dest['root'])

def test_copy_group_options(self):
source = self.source
dest = self.new_dest()

def test_copy_group_options(self, source, dest):
# copy group, non-default options
copy(source['foo'], dest, name='qux', without_attrs=True)
assert 'foo' not in dest
check_copied_group(source['foo'], dest['qux'], without_attrs=True)

def test_copy_group_shallow(self):
source = self.source
dest = self.new_dest()

def test_copy_group_shallow(self, source, dest):
# copy group, shallow
copy(source, dest, name='eggs', shallow=True)
check_copied_group(source, dest['eggs'], shallow=True)

def test_copy_group_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_group(self, source, dest):
# copy group, dest groups exist
dest.create_group('foo/bar')
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_array(self, source, dest):
# copy group, dest array in the way
dest.create_dataset('foo/bar', shape=(10,))

Expand All@@ -667,10 +642,7 @@ def test_copy_group_exists_array(self):
copy(source['foo'], dest, if_exists='replace')
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_dry_run(self):
source = self.source
dest = self.new_dest()

def test_copy_group_dry_run(self, source, dest):
# dry run, empty destination
n_copied, n_skipped, n_bytes_copied = \
copy(source['foo'], dest, dry_run=True, return_stats=True)
Expand DownExpand Up@@ -710,67 +682,18 @@ def test_copy_group_dry_run(self):
assert 0 == n_bytes_copied
assert_array_equal(baz, dest['foo/bar/baz'])

def test_logging(self):
source = self.source
dest = self.new_dest()

def test_logging(self, source, dest, tmpdir):
# callable log
copy(source['foo'], dest, dry_run=True, log=print)

# file name
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
fn = str(tmpdir.join('log_name'))
copy(source['foo'], dest, dry_run=True, log=fn)

# file
with tempfile.TemporaryFile(mode='w') as f:
with tmpdir.join('log_file').open(mode='w') as f:
copy(source['foo'], dest, dry_run=True, log=f)

# bad option
with pytest.raises(TypeError):
copy(source['foo'], dest, dry_run=True, log=True)


try:
import h5py
except ImportError: # pragma: no cover
h5py = None


def temp_h5f():
h5py = pytest.importorskip("h5py")
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
h5f = h5py.File(fn, mode='w')
atexit.register(lambda v: v.close(), h5f)
return h5f


class TestCopyHDF5ToZarr(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = False
self.new_source = temp_h5f
self.new_dest = group


class TestCopyZarrToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = True
self.new_source = group
self.new_dest = temp_h5f


class TestCopyHDF5ToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = True
self.new_source = temp_h5f
self.new_dest = temp_h5f
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
Merged
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
189 changes: 56 additions & 133 deletions zarr/tests/test_convenience.py
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import atexit
import os
import tempfile
import unittest
from numbers import Integral
Expand DownExpand Up@@ -456,67 +455,67 @@ def test_copy_all():
assert destination_group.subgroup.attrs["info"] == "sub attrs"


# noinspection PyAttributeOutsideInit
class TestCopy(unittest.TestCase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = False
self.new_source = group
self.new_dest = group

def setUp(self):
source = self.new_source()
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if self.source_h5py:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
class TestCopy:
@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def source(self, request, tmpdir):
def prep_source(source):
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if request.param:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42, filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
return source

if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('source.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield prep_source(h5f)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42,
filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
self.source = source

def test_copy_array(self):
source = self.source
dest = self.new_dest()
yield prep_source(group())

@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def dest(self, request, tmpdir):
if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('dest.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield h5f
else:
yield group()

def test_copy_array(self, source, dest):
# copy array with default options
copy(source['foo/bar/baz'], dest)
check_copied_array(source['foo/bar/baz'], dest['baz'])
copy(source['spam'], dest)
check_copied_array(source['spam'], dest['spam'])

def test_copy_bad_dest(self):
source = self.source

def test_copy_bad_dest(self, source, dest):
# try to copy to an array, dest must be a group
dest = self.new_dest().create_dataset('eggs', shape=(100,))
dest = dest.create_dataset('eggs', shape=(100,))
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest)

def test_copy_array_name(self):
source = self.source
dest = self.new_dest()

def test_copy_array_name(self, source, dest):
# copy array with name
copy(source['foo/bar/baz'], dest, name='qux')
assert 'baz' not in dest
check_copied_array(source['foo/bar/baz'], dest['qux'])

def test_copy_array_create_options(self):
source = self.source
dest = self.new_dest()
def test_copy_array_create_options(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

# copy array, provide creation options
compressor = Zlib(9)
create_kws = dict(chunks=(10,))
if self.dest_h5py:
if dest_h5py:
create_kws.update(compression='gzip', compression_opts=9,
shuffle=True, fletcher32=True, fillvalue=42)
else:
Expand All@@ -526,10 +525,7 @@ def test_copy_array_create_options(self):
check_copied_array(source['foo/bar/baz'], dest['baz'],
without_attrs=True, expect_props=create_kws)

def test_copy_array_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_array(self, source, dest):
# copy array, dest array in the way
dest.create_dataset('baz', shape=(10,))

Expand All@@ -554,10 +550,7 @@ def test_copy_array_exists_array(self):
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest, if_exists='foobar')

def test_copy_array_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_group(self, source, dest):
# copy array, dest group in the way
dest.create_group('baz')

Expand All@@ -577,13 +570,13 @@ def test_copy_array_exists_group(self):
copy(source['foo/bar/baz'], dest, if_exists='replace')
check_copied_array(source['foo/bar/baz'], dest['baz'])

def test_copy_array_skip_initialized(self):
source = self.source
dest = self.new_dest()
def test_copy_array_skip_initialized(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

dest.create_dataset('baz', shape=(100,), chunks=(10,), dtype='i8')
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

if self.dest_h5py:
if dest_h5py:
with pytest.raises(ValueError):
# not available with copy to h5py
copy(source['foo/bar/baz'], dest, if_exists='skip_initialized')
Expand All@@ -599,55 +592,37 @@ def test_copy_array_skip_initialized(self):
assert_array_equal(np.arange(100, 200), dest['baz'][:])
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

def test_copy_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group(self, source, dest):
# copy group, default options
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_no_name(self):
source = self.source
dest = self.new_dest()

def test_copy_group_no_name(self, source, dest):
with pytest.raises(TypeError):
# need a name if copy root
copy(source, dest)

copy(source, dest, name='root')
check_copied_group(source, dest['root'])

def test_copy_group_options(self):
source = self.source
dest = self.new_dest()

def test_copy_group_options(self, source, dest):
# copy group, non-default options
copy(source['foo'], dest, name='qux', without_attrs=True)
assert 'foo' not in dest
check_copied_group(source['foo'], dest['qux'], without_attrs=True)

def test_copy_group_shallow(self):
source = self.source
dest = self.new_dest()

def test_copy_group_shallow(self, source, dest):
# copy group, shallow
copy(source, dest, name='eggs', shallow=True)
check_copied_group(source, dest['eggs'], shallow=True)

def test_copy_group_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_group(self, source, dest):
# copy group, dest groups exist
dest.create_group('foo/bar')
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_array(self, source, dest):
# copy group, dest array in the way
dest.create_dataset('foo/bar', shape=(10,))

Expand All@@ -667,10 +642,7 @@ def test_copy_group_exists_array(self):
copy(source['foo'], dest, if_exists='replace')
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_dry_run(self):
source = self.source
dest = self.new_dest()

def test_copy_group_dry_run(self, source, dest):
# dry run, empty destination
n_copied, n_skipped, n_bytes_copied = \
copy(source['foo'], dest, dry_run=True, return_stats=True)
Expand DownExpand Up@@ -710,67 +682,18 @@ def test_copy_group_dry_run(self):
assert 0 == n_bytes_copied
assert_array_equal(baz, dest['foo/bar/baz'])

def test_logging(self):
source = self.source
dest = self.new_dest()

def test_logging(self, source, dest, tmpdir):
# callable log
copy(source['foo'], dest, dry_run=True, log=print)

# file name
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
fn = str(tmpdir.join('log_name'))
copy(source['foo'], dest, dry_run=True, log=fn)

# file
with tempfile.TemporaryFile(mode='w') as f:
with tmpdir.join('log_file').open(mode='w') as f:
copy(source['foo'], dest, dry_run=True, log=f)

# bad option
with pytest.raises(TypeError):
copy(source['foo'], dest, dry_run=True, log=True)


try:
import h5py
except ImportError: # pragma: no cover
h5py = None


def temp_h5f():
h5py = pytest.importorskip("h5py")
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
h5f = h5py.File(fn, mode='w')
atexit.register(lambda v: v.close(), h5f)
return h5f


class TestCopyHDF5ToZarr(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = False
self.new_source = temp_h5f
self.new_dest = group


class TestCopyZarrToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = True
self.new_source = group
self.new_dest = temp_h5f


class TestCopyHDF5ToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = True
self.new_source = temp_h5f
self.new_dest = temp_h5f
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
189 changes: 56 additions & 133 deletions zarr/tests/test_convenience.py
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import atexit
import os
import tempfile
import unittest
from numbers import Integral
Expand DownExpand Up@@ -456,67 +455,67 @@ def test_copy_all():
assert destination_group.subgroup.attrs["info"] == "sub attrs"


# noinspection PyAttributeOutsideInit
class TestCopy(unittest.TestCase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = False
self.new_source = group
self.new_dest = group

def setUp(self):
source = self.new_source()
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if self.source_h5py:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
class TestCopy:
@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def source(self, request, tmpdir):
def prep_source(source):
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if request.param:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42, filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
return source

if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('source.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield prep_source(h5f)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42,
filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
self.source = source

def test_copy_array(self):
source = self.source
dest = self.new_dest()
yield prep_source(group())

@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def dest(self, request, tmpdir):
if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('dest.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield h5f
else:
yield group()

def test_copy_array(self, source, dest):
# copy array with default options
copy(source['foo/bar/baz'], dest)
check_copied_array(source['foo/bar/baz'], dest['baz'])
copy(source['spam'], dest)
check_copied_array(source['spam'], dest['spam'])

def test_copy_bad_dest(self):
source = self.source

def test_copy_bad_dest(self, source, dest):
# try to copy to an array, dest must be a group
dest = self.new_dest().create_dataset('eggs', shape=(100,))
dest = dest.create_dataset('eggs', shape=(100,))
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest)

def test_copy_array_name(self):
source = self.source
dest = self.new_dest()

def test_copy_array_name(self, source, dest):
# copy array with name
copy(source['foo/bar/baz'], dest, name='qux')
assert 'baz' not in dest
check_copied_array(source['foo/bar/baz'], dest['qux'])

def test_copy_array_create_options(self):
source = self.source
dest = self.new_dest()
def test_copy_array_create_options(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

# copy array, provide creation options
compressor = Zlib(9)
create_kws = dict(chunks=(10,))
if self.dest_h5py:
if dest_h5py:
create_kws.update(compression='gzip', compression_opts=9,
shuffle=True, fletcher32=True, fillvalue=42)
else:
Expand All@@ -526,10 +525,7 @@ def test_copy_array_create_options(self):
check_copied_array(source['foo/bar/baz'], dest['baz'],
without_attrs=True, expect_props=create_kws)

def test_copy_array_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_array(self, source, dest):
# copy array, dest array in the way
dest.create_dataset('baz', shape=(10,))

Expand All@@ -554,10 +550,7 @@ def test_copy_array_exists_array(self):
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest, if_exists='foobar')

def test_copy_array_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_group(self, source, dest):
# copy array, dest group in the way
dest.create_group('baz')

Expand All@@ -577,13 +570,13 @@ def test_copy_array_exists_group(self):
copy(source['foo/bar/baz'], dest, if_exists='replace')
check_copied_array(source['foo/bar/baz'], dest['baz'])

def test_copy_array_skip_initialized(self):
source = self.source
dest = self.new_dest()
def test_copy_array_skip_initialized(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

dest.create_dataset('baz', shape=(100,), chunks=(10,), dtype='i8')
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

if self.dest_h5py:
if dest_h5py:
with pytest.raises(ValueError):
# not available with copy to h5py
copy(source['foo/bar/baz'], dest, if_exists='skip_initialized')
Expand All@@ -599,55 +592,37 @@ def test_copy_array_skip_initialized(self):
assert_array_equal(np.arange(100, 200), dest['baz'][:])
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

def test_copy_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group(self, source, dest):
# copy group, default options
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_no_name(self):
source = self.source
dest = self.new_dest()

def test_copy_group_no_name(self, source, dest):
with pytest.raises(TypeError):
# need a name if copy root
copy(source, dest)

copy(source, dest, name='root')
check_copied_group(source, dest['root'])

def test_copy_group_options(self):
source = self.source
dest = self.new_dest()

def test_copy_group_options(self, source, dest):
# copy group, non-default options
copy(source['foo'], dest, name='qux', without_attrs=True)
assert 'foo' not in dest
check_copied_group(source['foo'], dest['qux'], without_attrs=True)

def test_copy_group_shallow(self):
source = self.source
dest = self.new_dest()

def test_copy_group_shallow(self, source, dest):
# copy group, shallow
copy(source, dest, name='eggs', shallow=True)
check_copied_group(source, dest['eggs'], shallow=True)

def test_copy_group_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_group(self, source, dest):
# copy group, dest groups exist
dest.create_group('foo/bar')
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_array(self, source, dest):
# copy group, dest array in the way
dest.create_dataset('foo/bar', shape=(10,))

Expand All@@ -667,10 +642,7 @@ def test_copy_group_exists_array(self):
copy(source['foo'], dest, if_exists='replace')
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_dry_run(self):
source = self.source
dest = self.new_dest()

def test_copy_group_dry_run(self, source, dest):
# dry run, empty destination
n_copied, n_skipped, n_bytes_copied = \
copy(source['foo'], dest, dry_run=True, return_stats=True)
Expand DownExpand Up@@ -710,67 +682,18 @@ def test_copy_group_dry_run(self):
assert 0 == n_bytes_copied
assert_array_equal(baz, dest['foo/bar/baz'])

def test_logging(self):
source = self.source
dest = self.new_dest()

def test_logging(self, source, dest, tmpdir):
# callable log
copy(source['foo'], dest, dry_run=True, log=print)

# file name
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
fn = str(tmpdir.join('log_name'))
copy(source['foo'], dest, dry_run=True, log=fn)

# file
with tempfile.TemporaryFile(mode='w') as f:
with tmpdir.join('log_file').open(mode='w') as f:
copy(source['foo'], dest, dry_run=True, log=f)

# bad option
with pytest.raises(TypeError):
copy(source['foo'], dest, dry_run=True, log=True)


try:
import h5py
except ImportError: # pragma: no cover
h5py = None


def temp_h5f():
h5py = pytest.importorskip("h5py")
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
h5f = h5py.File(fn, mode='w')
atexit.register(lambda v: v.close(), h5f)
return h5f


class TestCopyHDF5ToZarr(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = False
self.new_source = temp_h5f
self.new_dest = group


class TestCopyZarrToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = True
self.new_source = group
self.new_dest = temp_h5f


class TestCopyHDF5ToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = True
self.new_source = temp_h5f
self.new_dest = temp_h5f
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
Merged
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
189 changes: 56 additions & 133 deletions zarr/tests/test_convenience.py
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import atexit
import os
import tempfile
import unittest
from numbers import Integral
Expand DownExpand Up@@ -456,67 +455,67 @@ def test_copy_all():
assert destination_group.subgroup.attrs["info"] == "sub attrs"


# noinspection PyAttributeOutsideInit
class TestCopy(unittest.TestCase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = False
self.new_source = group
self.new_dest = group

def setUp(self):
source = self.new_source()
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if self.source_h5py:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
class TestCopy:
@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def source(self, request, tmpdir):
def prep_source(source):
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if request.param:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42, filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
return source

if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('source.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield prep_source(h5f)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42,
filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
self.source = source

def test_copy_array(self):
source = self.source
dest = self.new_dest()
yield prep_source(group())

@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def dest(self, request, tmpdir):
if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('dest.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield h5f
else:
yield group()

def test_copy_array(self, source, dest):
# copy array with default options
copy(source['foo/bar/baz'], dest)
check_copied_array(source['foo/bar/baz'], dest['baz'])
copy(source['spam'], dest)
check_copied_array(source['spam'], dest['spam'])

def test_copy_bad_dest(self):
source = self.source

def test_copy_bad_dest(self, source, dest):
# try to copy to an array, dest must be a group
dest = self.new_dest().create_dataset('eggs', shape=(100,))
dest = dest.create_dataset('eggs', shape=(100,))
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest)

def test_copy_array_name(self):
source = self.source
dest = self.new_dest()

def test_copy_array_name(self, source, dest):
# copy array with name
copy(source['foo/bar/baz'], dest, name='qux')
assert 'baz' not in dest
check_copied_array(source['foo/bar/baz'], dest['qux'])

def test_copy_array_create_options(self):
source = self.source
dest = self.new_dest()
def test_copy_array_create_options(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

# copy array, provide creation options
compressor = Zlib(9)
create_kws = dict(chunks=(10,))
if self.dest_h5py:
if dest_h5py:
create_kws.update(compression='gzip', compression_opts=9,
shuffle=True, fletcher32=True, fillvalue=42)
else:
Expand All@@ -526,10 +525,7 @@ def test_copy_array_create_options(self):
check_copied_array(source['foo/bar/baz'], dest['baz'],
without_attrs=True, expect_props=create_kws)

def test_copy_array_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_array(self, source, dest):
# copy array, dest array in the way
dest.create_dataset('baz', shape=(10,))

Expand All@@ -554,10 +550,7 @@ def test_copy_array_exists_array(self):
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest, if_exists='foobar')

def test_copy_array_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_group(self, source, dest):
# copy array, dest group in the way
dest.create_group('baz')

Expand All@@ -577,13 +570,13 @@ def test_copy_array_exists_group(self):
copy(source['foo/bar/baz'], dest, if_exists='replace')
check_copied_array(source['foo/bar/baz'], dest['baz'])

def test_copy_array_skip_initialized(self):
source = self.source
dest = self.new_dest()
def test_copy_array_skip_initialized(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

dest.create_dataset('baz', shape=(100,), chunks=(10,), dtype='i8')
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

if self.dest_h5py:
if dest_h5py:
with pytest.raises(ValueError):
# not available with copy to h5py
copy(source['foo/bar/baz'], dest, if_exists='skip_initialized')
Expand All@@ -599,55 +592,37 @@ def test_copy_array_skip_initialized(self):
assert_array_equal(np.arange(100, 200), dest['baz'][:])
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

def test_copy_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group(self, source, dest):
# copy group, default options
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_no_name(self):
source = self.source
dest = self.new_dest()

def test_copy_group_no_name(self, source, dest):
with pytest.raises(TypeError):
# need a name if copy root
copy(source, dest)

copy(source, dest, name='root')
check_copied_group(source, dest['root'])

def test_copy_group_options(self):
source = self.source
dest = self.new_dest()

def test_copy_group_options(self, source, dest):
# copy group, non-default options
copy(source['foo'], dest, name='qux', without_attrs=True)
assert 'foo' not in dest
check_copied_group(source['foo'], dest['qux'], without_attrs=True)

def test_copy_group_shallow(self):
source = self.source
dest = self.new_dest()

def test_copy_group_shallow(self, source, dest):
# copy group, shallow
copy(source, dest, name='eggs', shallow=True)
check_copied_group(source, dest['eggs'], shallow=True)

def test_copy_group_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_group(self, source, dest):
# copy group, dest groups exist
dest.create_group('foo/bar')
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_array(self, source, dest):
# copy group, dest array in the way
dest.create_dataset('foo/bar', shape=(10,))

Expand All@@ -667,10 +642,7 @@ def test_copy_group_exists_array(self):
copy(source['foo'], dest, if_exists='replace')
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_dry_run(self):
source = self.source
dest = self.new_dest()

def test_copy_group_dry_run(self, source, dest):
# dry run, empty destination
n_copied, n_skipped, n_bytes_copied = \
copy(source['foo'], dest, dry_run=True, return_stats=True)
Expand DownExpand Up@@ -710,67 +682,18 @@ def test_copy_group_dry_run(self):
assert 0 == n_bytes_copied
assert_array_equal(baz, dest['foo/bar/baz'])

def test_logging(self):
source = self.source
dest = self.new_dest()

def test_logging(self, source, dest, tmpdir):
# callable log
copy(source['foo'], dest, dry_run=True, log=print)

# file name
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
fn = str(tmpdir.join('log_name'))
copy(source['foo'], dest, dry_run=True, log=fn)

# file
with tempfile.TemporaryFile(mode='w') as f:
with tmpdir.join('log_file').open(mode='w') as f:
copy(source['foo'], dest, dry_run=True, log=f)

# bad option
with pytest.raises(TypeError):
copy(source['foo'], dest, dry_run=True, log=True)


try:
import h5py
except ImportError: # pragma: no cover
h5py = None


def temp_h5f():
h5py = pytest.importorskip("h5py")
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
h5f = h5py.File(fn, mode='w')
atexit.register(lambda v: v.close(), h5f)
return h5f


class TestCopyHDF5ToZarr(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = False
self.new_source = temp_h5f
self.new_dest = group


class TestCopyZarrToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = True
self.new_source = group
self.new_dest = temp_h5f


class TestCopyHDF5ToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = True
self.new_source = temp_h5f
self.new_dest = temp_h5f
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
Merged
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
189 changes: 56 additions & 133 deletions zarr/tests/test_convenience.py
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
import atexit
import os
import tempfile
import unittest
from numbers import Integral
Expand DownExpand Up@@ -456,67 +455,67 @@ def test_copy_all():
assert destination_group.subgroup.attrs["info"] == "sub attrs"


# noinspection PyAttributeOutsideInit
class TestCopy(unittest.TestCase):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = False
self.new_source = group
self.new_dest = group

def setUp(self):
source = self.new_source()
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if self.source_h5py:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
class TestCopy:
@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def source(self, request, tmpdir):
def prep_source(source):
foo = source.create_group('foo')
foo.attrs['experiment'] = 'weird science'
baz = foo.create_dataset('bar/baz', data=np.arange(100), chunks=(50,))
baz.attrs['units'] = 'metres'
if request.param:
extra_kws = dict(compression='gzip', compression_opts=3, fillvalue=84,
shuffle=True, fletcher32=True)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42, filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
return source

if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('source.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield prep_source(h5f)
else:
extra_kws = dict(compressor=Zlib(3), order='F', fill_value=42,
filters=[Adler32()])
source.create_dataset('spam', data=np.arange(100, 200).reshape(20, 5),
chunks=(10, 2), dtype='i2', **extra_kws)
self.source = source

def test_copy_array(self):
source = self.source
dest = self.new_dest()
yield prep_source(group())

@pytest.fixture(params=[False, True], ids=['zarr', 'hdf5'])
def dest(self, request, tmpdir):
if request.param:
h5py = pytest.importorskip('h5py')
fn = tmpdir.join('dest.h5')
with h5py.File(str(fn), mode='w') as h5f:
yield h5f
else:
yield group()

def test_copy_array(self, source, dest):
# copy array with default options
copy(source['foo/bar/baz'], dest)
check_copied_array(source['foo/bar/baz'], dest['baz'])
copy(source['spam'], dest)
check_copied_array(source['spam'], dest['spam'])

def test_copy_bad_dest(self):
source = self.source

def test_copy_bad_dest(self, source, dest):
# try to copy to an array, dest must be a group
dest = self.new_dest().create_dataset('eggs', shape=(100,))
dest = dest.create_dataset('eggs', shape=(100,))
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest)

def test_copy_array_name(self):
source = self.source
dest = self.new_dest()

def test_copy_array_name(self, source, dest):
# copy array with name
copy(source['foo/bar/baz'], dest, name='qux')
assert 'baz' not in dest
check_copied_array(source['foo/bar/baz'], dest['qux'])

def test_copy_array_create_options(self):
source = self.source
dest = self.new_dest()
def test_copy_array_create_options(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

# copy array, provide creation options
compressor = Zlib(9)
create_kws = dict(chunks=(10,))
if self.dest_h5py:
if dest_h5py:
create_kws.update(compression='gzip', compression_opts=9,
shuffle=True, fletcher32=True, fillvalue=42)
else:
Expand All@@ -526,10 +525,7 @@ def test_copy_array_create_options(self):
check_copied_array(source['foo/bar/baz'], dest['baz'],
without_attrs=True, expect_props=create_kws)

def test_copy_array_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_array(self, source, dest):
# copy array, dest array in the way
dest.create_dataset('baz', shape=(10,))

Expand All@@ -554,10 +550,7 @@ def test_copy_array_exists_array(self):
with pytest.raises(ValueError):
copy(source['foo/bar/baz'], dest, if_exists='foobar')

def test_copy_array_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_array_exists_group(self, source, dest):
# copy array, dest group in the way
dest.create_group('baz')

Expand All@@ -577,13 +570,13 @@ def test_copy_array_exists_group(self):
copy(source['foo/bar/baz'], dest, if_exists='replace')
check_copied_array(source['foo/bar/baz'], dest['baz'])

def test_copy_array_skip_initialized(self):
source = self.source
dest = self.new_dest()
def test_copy_array_skip_initialized(self, source, dest):
dest_h5py = dest.__module__.startswith('h5py.')

dest.create_dataset('baz', shape=(100,), chunks=(10,), dtype='i8')
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

if self.dest_h5py:
if dest_h5py:
with pytest.raises(ValueError):
# not available with copy to h5py
copy(source['foo/bar/baz'], dest, if_exists='skip_initialized')
Expand All@@ -599,55 +592,37 @@ def test_copy_array_skip_initialized(self):
assert_array_equal(np.arange(100, 200), dest['baz'][:])
assert not np.all(source['foo/bar/baz'][:] == dest['baz'][:])

def test_copy_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group(self, source, dest):
# copy group, default options
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_no_name(self):
source = self.source
dest = self.new_dest()

def test_copy_group_no_name(self, source, dest):
with pytest.raises(TypeError):
# need a name if copy root
copy(source, dest)

copy(source, dest, name='root')
check_copied_group(source, dest['root'])

def test_copy_group_options(self):
source = self.source
dest = self.new_dest()

def test_copy_group_options(self, source, dest):
# copy group, non-default options
copy(source['foo'], dest, name='qux', without_attrs=True)
assert 'foo' not in dest
check_copied_group(source['foo'], dest['qux'], without_attrs=True)

def test_copy_group_shallow(self):
source = self.source
dest = self.new_dest()

def test_copy_group_shallow(self, source, dest):
# copy group, shallow
copy(source, dest, name='eggs', shallow=True)
check_copied_group(source, dest['eggs'], shallow=True)

def test_copy_group_exists_group(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_group(self, source, dest):
# copy group, dest groups exist
dest.create_group('foo/bar')
copy(source['foo'], dest)
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_exists_array(self):
source = self.source
dest = self.new_dest()

def test_copy_group_exists_array(self, source, dest):
# copy group, dest array in the way
dest.create_dataset('foo/bar', shape=(10,))

Expand All@@ -667,10 +642,7 @@ def test_copy_group_exists_array(self):
copy(source['foo'], dest, if_exists='replace')
check_copied_group(source['foo'], dest['foo'])

def test_copy_group_dry_run(self):
source = self.source
dest = self.new_dest()

def test_copy_group_dry_run(self, source, dest):
# dry run, empty destination
n_copied, n_skipped, n_bytes_copied = \
copy(source['foo'], dest, dry_run=True, return_stats=True)
Expand DownExpand Up@@ -710,67 +682,18 @@ def test_copy_group_dry_run(self):
assert 0 == n_bytes_copied
assert_array_equal(baz, dest['foo/bar/baz'])

def test_logging(self):
source = self.source
dest = self.new_dest()

def test_logging(self, source, dest, tmpdir):
# callable log
copy(source['foo'], dest, dry_run=True, log=print)

# file name
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
fn = str(tmpdir.join('log_name'))
copy(source['foo'], dest, dry_run=True, log=fn)

# file
with tempfile.TemporaryFile(mode='w') as f:
with tmpdir.join('log_file').open(mode='w') as f:
copy(source['foo'], dest, dry_run=True, log=f)

# bad option
with pytest.raises(TypeError):
copy(source['foo'], dest, dry_run=True, log=True)


try:
import h5py
except ImportError: # pragma: no cover
h5py = None


def temp_h5f():
h5py = pytest.importorskip("h5py")
fn = tempfile.mktemp()
atexit.register(os.remove, fn)
h5f = h5py.File(fn, mode='w')
atexit.register(lambda v: v.close(), h5f)
return h5f


class TestCopyHDF5ToZarr(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = False
self.new_source = temp_h5f
self.new_dest = group


class TestCopyZarrToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = False
self.dest_h5py = True
self.new_source = group
self.new_dest = temp_h5f


class TestCopyHDF5ToHDF5(TestCopy):

def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.source_h5py = True
self.dest_h5py = True
self.new_source = temp_h5f
self.new_dest = temp_h5f