Spaces:
Sleeping
Sleeping
# This file is part of h5py, a Python interface to the HDF5 library. | |
# | |
# http://www.h5py.org | |
# | |
# Copyright 2008-2013 Andrew Collette and contributors | |
# | |
# License: Standard 3-clause BSD; see "license.txt" for full license terms | |
# and contributor agreement. | |
""" | |
Tests the h5py.File object. | |
""" | |
import h5py | |
from h5py._hl.files import _drivers | |
from h5py import File | |
from .common import ut, TestCase | |
import pytest | |
import io | |
import tempfile | |
import os | |
def nfiles(): | |
return h5py.h5f.get_obj_count(h5py.h5f.OBJ_ALL, h5py.h5f.OBJ_FILE) | |
def ngroups(): | |
return h5py.h5f.get_obj_count(h5py.h5f.OBJ_ALL, h5py.h5f.OBJ_GROUP) | |
class TestDealloc(TestCase): | |
""" | |
Behavior on object deallocation. Note most of this behavior is | |
delegated to FileID. | |
""" | |
def test_autoclose(self): | |
""" File objects close automatically when out of scope, but | |
other objects remain open. """ | |
start_nfiles = nfiles() | |
start_ngroups = ngroups() | |
fname = self.mktemp() | |
f = h5py.File(fname, 'w') | |
g = f['/'] | |
self.assertEqual(nfiles(), start_nfiles+1) | |
self.assertEqual(ngroups(), start_ngroups+1) | |
del f | |
self.assertTrue(g) | |
self.assertEqual(nfiles(), start_nfiles) | |
self.assertEqual(ngroups(), start_ngroups+1) | |
f = g.file | |
self.assertTrue(f) | |
self.assertEqual(nfiles(), start_nfiles+1) | |
self.assertEqual(ngroups(), start_ngroups+1) | |
del g | |
self.assertEqual(nfiles(), start_nfiles+1) | |
self.assertEqual(ngroups(), start_ngroups) | |
del f | |
self.assertEqual(nfiles(), start_nfiles) | |
self.assertEqual(ngroups(), start_ngroups) | |
class TestDriverRegistration(TestCase): | |
def test_register_driver(self): | |
called_with = [None] | |
def set_fapl(plist, *args, **kwargs): | |
called_with[0] = args, kwargs | |
return _drivers['sec2'](plist) | |
h5py.register_driver('new-driver', set_fapl) | |
self.assertIn('new-driver', h5py.registered_drivers()) | |
fname = self.mktemp() | |
h5py.File(fname, driver='new-driver', driver_arg_0=0, driver_arg_1=1, | |
mode='w') | |
self.assertEqual( | |
called_with, | |
[((), {'driver_arg_0': 0, 'driver_arg_1': 1})], | |
) | |
def test_unregister_driver(self): | |
h5py.register_driver('new-driver', lambda plist: None) | |
self.assertIn('new-driver', h5py.registered_drivers()) | |
h5py.unregister_driver('new-driver') | |
self.assertNotIn('new-driver', h5py.registered_drivers()) | |
with self.assertRaises(ValueError) as e: | |
fname = self.mktemp() | |
h5py.File(fname, driver='new-driver', mode='w') | |
self.assertEqual(str(e.exception), 'Unknown driver type "new-driver"') | |
class TestCache(TestCase): | |
def test_defaults(self): | |
fname = self.mktemp() | |
f = h5py.File(fname, 'w') | |
self.assertEqual(list(f.id.get_access_plist().get_cache()), | |
[0, 521, 1048576, 0.75]) | |
def test_nbytes(self): | |
fname = self.mktemp() | |
f = h5py.File(fname, 'w', rdcc_nbytes=1024) | |
self.assertEqual(list(f.id.get_access_plist().get_cache()), | |
[0, 521, 1024, 0.75]) | |
def test_nslots(self): | |
fname = self.mktemp() | |
f = h5py.File(fname, 'w', rdcc_nslots=125) | |
self.assertEqual(list(f.id.get_access_plist().get_cache()), | |
[0, 125, 1048576, 0.75]) | |
def test_w0(self): | |
fname = self.mktemp() | |
f = h5py.File(fname, 'w', rdcc_w0=0.25) | |
self.assertEqual(list(f.id.get_access_plist().get_cache()), | |
[0, 521, 1048576, 0.25]) | |
class TestFileObj(TestCase): | |
def check_write(self, fileobj): | |
f = h5py.File(fileobj, 'w') | |
self.assertEqual(f.driver, 'fileobj') | |
self.assertEqual(f.filename, repr(fileobj)) | |
f.create_dataset('test', data=list(range(12))) | |
self.assertEqual(list(f), ['test']) | |
self.assertEqual(list(f['test'][:]), list(range(12))) | |
f.close() | |
def check_read(self, fileobj): | |
f = h5py.File(fileobj, 'r') | |
self.assertEqual(list(f), ['test']) | |
self.assertEqual(list(f['test'][:]), list(range(12))) | |
self.assertRaises(Exception, f.create_dataset, 'another.test', data=list(range(3))) | |
f.close() | |
def test_BytesIO(self): | |
with io.BytesIO() as fileobj: | |
self.assertEqual(len(fileobj.getvalue()), 0) | |
self.check_write(fileobj) | |
self.assertGreater(len(fileobj.getvalue()), 0) | |
self.check_read(fileobj) | |
def test_file(self): | |
fname = self.mktemp() | |
try: | |
with open(fname, 'wb+') as fileobj: | |
self.assertEqual(os.path.getsize(fname), 0) | |
self.check_write(fileobj) | |
self.assertGreater(os.path.getsize(fname), 0) | |
self.check_read(fileobj) | |
with open(fname, 'rb') as fileobj: | |
self.check_read(fileobj) | |
finally: | |
os.remove(fname) | |
def test_TemporaryFile(self): | |
# in this test, we check explicitly that temp file gets | |
# automatically deleted upon h5py.File.close()... | |
fileobj = tempfile.NamedTemporaryFile() | |
fname = fileobj.name | |
f = h5py.File(fileobj, 'w') | |
del fileobj | |
# ... but in your code feel free to simply | |
# f = h5py.File(tempfile.TemporaryFile()) | |
f.create_dataset('test', data=list(range(12))) | |
self.assertEqual(list(f), ['test']) | |
self.assertEqual(list(f['test'][:]), list(range(12))) | |
self.assertTrue(os.path.isfile(fname)) | |
f.close() | |
self.assertFalse(os.path.isfile(fname)) | |
def test_exception_open(self): | |
self.assertRaises(Exception, h5py.File, None, | |
driver='fileobj', mode='x') | |
self.assertRaises(Exception, h5py.File, 'rogue', | |
driver='fileobj', mode='x') | |
self.assertRaises(Exception, h5py.File, self, | |
driver='fileobj', mode='x') | |
def test_exception_read(self): | |
class BrokenBytesIO(io.BytesIO): | |
def readinto(self, b): | |
raise Exception('I am broken') | |
f = h5py.File(BrokenBytesIO(), 'w') | |
f.create_dataset('test', data=list(range(12))) | |
self.assertRaises(Exception, list, f['test']) | |
def test_exception_write(self): | |
class BrokenBytesIO(io.BytesIO): | |
allow_write = False | |
def write(self, b): | |
if self.allow_write: | |
return super().write(b) | |
else: | |
raise Exception('I am broken') | |
bio = BrokenBytesIO() | |
f = h5py.File(bio, 'w') | |
try: | |
self.assertRaises(Exception, f.create_dataset, 'test', | |
data=list(range(12))) | |
finally: | |
# Un-break writing so we can close: errors while closing get messy. | |
bio.allow_write = True | |
f.close() | |
def test_exception_close(self): | |
fileobj = io.BytesIO() | |
f = h5py.File(fileobj, 'w') | |
fileobj.close() | |
self.assertRaises(Exception, f.close) | |
def test_exception_writeonly(self): | |
# HDF5 expects read & write access to a file it's writing; | |
# check that we get the correct exception on a write-only file object. | |
fileobj = open(os.path.join(self.tempdir, 'a.h5'), 'wb') | |
with self.assertRaises(io.UnsupportedOperation): | |
f = h5py.File(fileobj, 'w') | |
group = f.create_group("group") | |
group.create_dataset("data", data='foo', dtype=h5py.string_dtype()) | |
def test_method_vanish(self): | |
fileobj = io.BytesIO() | |
f = h5py.File(fileobj, 'w') | |
f.create_dataset('test', data=list(range(12))) | |
self.assertEqual(list(f['test'][:]), list(range(12))) | |
fileobj.readinto = None | |
self.assertRaises(Exception, list, f['test']) | |
class TestTrackOrder(TestCase): | |
def populate(self, f): | |
for i in range(100): | |
# Mix group and dataset creation. | |
if i % 10 == 0: | |
f.create_group(str(i)) | |
else: | |
f[str(i)] = [i] | |
def test_track_order(self): | |
fname = self.mktemp() | |
f = h5py.File(fname, 'w', track_order=True) # creation order | |
self.populate(f) | |
self.assertEqual(list(f), | |
[str(i) for i in range(100)]) | |
def test_no_track_order(self): | |
fname = self.mktemp() | |
f = h5py.File(fname, 'w', track_order=False) # name alphanumeric | |
self.populate(f) | |
self.assertEqual(list(f), | |
sorted([str(i) for i in range(100)])) | |
class TestFileMetaBlockSize(TestCase): | |
""" | |
Feature: The meta block size can be manipulated, changing how metadata | |
is aggregated and the offset of the first dataset. | |
""" | |
def test_file_create_with_meta_block_size_4096(self): | |
# Test a large meta block size of 4 kibibytes | |
meta_block_size = 4096 | |
with File( | |
self.mktemp(), 'w', | |
meta_block_size=meta_block_size, | |
libver="latest" | |
) as f: | |
f["test"] = 5 | |
self.assertEqual(f.meta_block_size, meta_block_size) | |
# Equality is expected for HDF5 1.10 | |
self.assertGreaterEqual(f["test"].id.get_offset(), meta_block_size) | |
def test_file_create_with_meta_block_size_512(self): | |
# Test a small meta block size of 512 bytes | |
# The smallest verifiable meta_block_size is 463 | |
meta_block_size = 512 | |
libver = "latest" | |
with File( | |
self.mktemp(), 'w', | |
meta_block_size=meta_block_size, | |
libver=libver | |
) as f: | |
f["test"] = 3 | |
self.assertEqual(f.meta_block_size, meta_block_size) | |
# Equality is expected for HDF5 1.10 | |
self.assertGreaterEqual(f["test"].id.get_offset(), meta_block_size) | |
# Default meta_block_size is 2048. This should fail if meta_block_size is not set. | |
self.assertLess(f["test"].id.get_offset(), meta_block_size*2) | |