123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848 |
- # 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.
- """
- File object test module.
- Tests all aspects of File objects, including their creation.
- """
- import pytest
- import os
- import stat
- import pickle
- import tempfile
- from sys import platform
- from .common import ut, TestCase, UNICODE_FILENAMES, closed_tempfile
- from h5py import File
- import h5py
- from .. import h5
- import pathlib
- class TestFileOpen(TestCase):
- """
- Feature: Opening files with Python-style modes.
- """
- def test_default(self):
- """ Default semantics in the presence or absence of a file """
- fname = self.mktemp()
- # No existing file; error
- with pytest.raises(FileNotFoundError):
- with File(fname):
- pass
- # Existing readonly file; open read-only
- with File(fname, 'w'):
- pass
- os.chmod(fname, stat.S_IREAD)
- try:
- with File(fname) as f:
- self.assertTrue(f)
- self.assertEqual(f.mode, 'r')
- finally:
- os.chmod(fname, stat.S_IWRITE)
- # File exists but is not HDF5; raise OSError
- with open(fname, 'wb') as f:
- f.write(b'\x00')
- with self.assertRaises(OSError):
- File(fname)
- def test_create(self):
- """ Mode 'w' opens file in overwrite mode """
- fname = self.mktemp()
- fid = File(fname, 'w')
- self.assertTrue(fid)
- fid.create_group('foo')
- fid.close()
- fid = File(fname, 'w')
- self.assertNotIn('foo', fid)
- fid.close()
- def test_create_exclusive(self):
- """ Mode 'w-' opens file in exclusive mode """
- fname = self.mktemp()
- fid = File(fname, 'w-')
- self.assertTrue(fid)
- fid.close()
- with self.assertRaises(FileExistsError):
- File(fname, 'w-')
- def test_append(self):
- """ Mode 'a' opens file in append/readwrite mode, creating if necessary """
- fname = self.mktemp()
- fid = File(fname, 'a')
- try:
- self.assertTrue(fid)
- fid.create_group('foo')
- assert 'foo' in fid
- finally:
- fid.close()
- fid = File(fname, 'a')
- try:
- assert 'foo' in fid
- fid.create_group('bar')
- assert 'bar' in fid
- finally:
- fid.close()
- os.chmod(fname, stat.S_IREAD) # Make file read-only
- try:
- with pytest.raises(PermissionError):
- File(fname, 'a')
- finally:
- # Make it writable again so it can be deleted on Windows
- os.chmod(fname, stat.S_IREAD | stat.S_IWRITE)
- def test_readonly(self):
- """ Mode 'r' opens file in readonly mode """
- fname = self.mktemp()
- fid = File(fname, 'w')
- fid.close()
- self.assertFalse(fid)
- fid = File(fname, 'r')
- self.assertTrue(fid)
- with self.assertRaises(ValueError):
- fid.create_group('foo')
- fid.close()
- def test_readwrite(self):
- """ Mode 'r+' opens existing file in readwrite mode """
- fname = self.mktemp()
- fid = File(fname, 'w')
- fid.create_group('foo')
- fid.close()
- fid = File(fname, 'r+')
- assert 'foo' in fid
- fid.create_group('bar')
- assert 'bar' in fid
- fid.close()
- def test_nonexistent_file(self):
- """ Modes 'r' and 'r+' do not create files """
- fname = self.mktemp()
- with self.assertRaises(FileNotFoundError):
- File(fname, 'r')
- with self.assertRaises(FileNotFoundError):
- File(fname, 'r+')
- def test_invalid_mode(self):
- """ Invalid modes raise ValueError """
- with self.assertRaises(ValueError):
- File(self.mktemp(), 'mongoose')
- @ut.skipIf(h5py.version.hdf5_version_tuple < (1, 10, 1),
- 'Requires HDF5 1.10.1 or later')
- class TestSpaceStrategy(TestCase):
- """
- Feature: Create file with specified file space strategy
- """
- def test_create_with_space_strategy(self):
- """ Create file with file space strategy """
- fname = self.mktemp()
- fid = File(fname, 'w', fs_strategy="page",
- fs_persist=True, fs_threshold=100)
- self.assertTrue(fid)
- # Unable to set file space strategy of an existing file
- with self.assertRaises(ValueError):
- File(fname, 'a', fs_strategy="page")
- # Invalid file space strategy type
- with self.assertRaises(ValueError):
- File(self.mktemp(), 'w', fs_strategy="invalid")
- dset = fid.create_dataset('foo', (100,), dtype='uint8')
- dset[...] = 1
- dset = fid.create_dataset('bar', (100,), dtype='uint8')
- dset[...] = 1
- del fid['foo']
- fid.close()
- fid = File(fname, 'a')
- plist = fid.id.get_create_plist()
- fs_strat = plist.get_file_space_strategy()
- assert(fs_strat[0] == 1)
- assert(fs_strat[1] == True)
- assert(fs_strat[2] == 100)
- dset = fid.create_dataset('foo2', (100,), dtype='uint8')
- dset[...] = 1
- fid.close()
- class TestModes(TestCase):
- """
- Feature: File mode can be retrieved via file.mode
- """
- def test_mode_attr(self):
- """ Mode equivalent can be retrieved via property """
- fname = self.mktemp()
- with File(fname, 'w') as f:
- self.assertEqual(f.mode, 'r+')
- with File(fname, 'r') as f:
- self.assertEqual(f.mode, 'r')
- def test_mode_external(self):
- """ Mode property works for files opened via external links
- Issue 190.
- """
- fname1 = self.mktemp()
- fname2 = self.mktemp()
- f1 = File(fname1, 'w')
- f1.close()
- f2 = File(fname2, 'w')
- try:
- f2['External'] = h5py.ExternalLink(fname1, '/')
- f3 = f2['External'].file
- self.assertEqual(f3.mode, 'r+')
- finally:
- f2.close()
- f3.close()
- f2 = File(fname2, 'r')
- try:
- f3 = f2['External'].file
- self.assertEqual(f3.mode, 'r')
- finally:
- f2.close()
- f3.close()
- class TestDrivers(TestCase):
- """
- Feature: Files can be opened with low-level HDF5 drivers. Does not
- include MPI drivers (see bottom).
- """
- @ut.skipUnless(os.name == 'posix', "Stdio driver is supported on posix")
- def test_stdio(self):
- """ Stdio driver is supported on posix """
- fid = File(self.mktemp(), 'w', driver='stdio')
- self.assertTrue(fid)
- self.assertEqual(fid.driver, 'stdio')
- fid.close()
- @ut.skipUnless(os.name == 'posix', "Sec2 driver is supported on posix")
- def test_sec2(self):
- """ Sec2 driver is supported on posix """
- fid = File(self.mktemp(), 'w', driver='sec2')
- self.assertTrue(fid)
- self.assertEqual(fid.driver, 'sec2')
- fid.close()
- def test_core(self):
- """ Core driver is supported (no backing store) """
- fname = self.mktemp()
- fid = File(fname, 'w', driver='core', backing_store=False)
- self.assertTrue(fid)
- self.assertEqual(fid.driver, 'core')
- fid.close()
- self.assertFalse(os.path.exists(fname))
- def test_backing(self):
- """ Core driver saves to file when backing store used """
- fname = self.mktemp()
- fid = File(fname, 'w', driver='core', backing_store=True)
- fid.create_group('foo')
- fid.close()
- fid = File(fname, 'r')
- assert 'foo' in fid
- fid.close()
- # keywords for other drivers are invalid when using the default driver
- with self.assertRaises(TypeError):
- File(fname, 'w', backing_store=True)
- def test_readonly(self):
- """ Core driver can be used to open existing files """
- fname = self.mktemp()
- fid = File(fname, 'w')
- fid.create_group('foo')
- fid.close()
- fid = File(fname, 'r', driver='core')
- self.assertTrue(fid)
- assert 'foo' in fid
- with self.assertRaises(ValueError):
- fid.create_group('bar')
- fid.close()
- def test_blocksize(self):
- """ Core driver supports variable block size """
- fname = self.mktemp()
- fid = File(fname, 'w', driver='core', block_size=1024,
- backing_store=False)
- self.assertTrue(fid)
- fid.close()
- def test_split(self):
- """ Split stores metadata in a separate file """
- fname = self.mktemp()
- fid = File(fname, 'w', driver='split')
- fid.close()
- self.assertTrue(os.path.exists(fname + '-m.h5'))
- fid = File(fname, 'r', driver='split')
- self.assertTrue(fid)
- fid.close()
- def test_fileobj(self):
- """ Python file object driver is supported """
- tf = tempfile.TemporaryFile()
- fid = File(tf, 'w', driver='fileobj')
- self.assertTrue(fid)
- self.assertEqual(fid.driver, 'fileobj')
- fid.close()
- # Driver must be 'fileobj' for file-like object if specified
- with self.assertRaises(ValueError):
- File(tf, 'w', driver='core')
- # TODO: family driver tests
- @ut.skipUnless(h5py.version.hdf5_version_tuple < (1, 10, 2),
- 'Requires HDF5 before 1.10.2')
- class TestLibver(TestCase):
- """
- Feature: File format compatibility bounds can be specified when
- opening a file.
- """
- def test_default(self):
- """ Opening with no libver arg """
- f = File(self.mktemp(), 'w')
- self.assertEqual(f.libver, ('earliest', 'latest'))
- f.close()
- def test_single(self):
- """ Opening with single libver arg """
- f = File(self.mktemp(), 'w', libver='latest')
- self.assertEqual(f.libver, ('latest', 'latest'))
- f.close()
- def test_multiple(self):
- """ Opening with two libver args """
- f = File(self.mktemp(), 'w', libver=('earliest', 'latest'))
- self.assertEqual(f.libver, ('earliest', 'latest'))
- f.close()
- def test_none(self):
- """ Omitting libver arg results in maximum compatibility """
- f = File(self.mktemp(), 'w')
- self.assertEqual(f.libver, ('earliest', 'latest'))
- f.close()
- @ut.skipIf(h5py.version.hdf5_version_tuple < (1, 10, 2),
- 'Requires HDF5 1.10.2 or later')
- class TestNewLibver(TestCase):
- """
- Feature: File format compatibility bounds can be specified when
- opening a file.
- Requirement: HDF5 1.10.2 or later
- """
- @classmethod
- def setUpClass(cls):
- super(TestNewLibver, cls).setUpClass()
- # Current latest library bound label
- if h5py.version.hdf5_version_tuple < (1, 11, 4):
- cls.latest = 'v110'
- elif h5py.version.hdf5_version_tuple < (1, 13, 0):
- cls.latest = 'v112'
- else:
- cls.latest = 'v114'
- def test_default(self):
- """ Opening with no libver arg """
- f = File(self.mktemp(), 'w')
- self.assertEqual(f.libver, ('earliest', self.latest))
- f.close()
- def test_single(self):
- """ Opening with single libver arg """
- f = File(self.mktemp(), 'w', libver='latest')
- self.assertEqual(f.libver, (self.latest, self.latest))
- f.close()
- def test_single_v108(self):
- """ Opening with "v108" libver arg """
- f = File(self.mktemp(), 'w', libver='v108')
- self.assertEqual(f.libver, ('v108', self.latest))
- f.close()
- def test_single_v110(self):
- """ Opening with "v110" libver arg """
- f = File(self.mktemp(), 'w', libver='v110')
- self.assertEqual(f.libver, ('v110', self.latest))
- f.close()
- @ut.skipIf(h5py.version.hdf5_version_tuple < (1, 11, 4),
- 'Requires HDF5 1.11.4 or later')
- def test_single_v112(self):
- """ Opening with "v112" libver arg """
- f = File(self.mktemp(), 'w', libver='v112')
- self.assertEqual(f.libver, ('v112', self.latest))
- f.close()
- def test_multiple(self):
- """ Opening with two libver args """
- f = File(self.mktemp(), 'w', libver=('earliest', 'v108'))
- self.assertEqual(f.libver, ('earliest', 'v108'))
- f.close()
- def test_none(self):
- """ Omitting libver arg results in maximum compatibility """
- f = File(self.mktemp(), 'w')
- self.assertEqual(f.libver, ('earliest', self.latest))
- f.close()
- class TestUserblock(TestCase):
- """
- Feature: Files can be create with user blocks
- """
- def test_create_blocksize(self):
- """ User blocks created with w, w-, x and properties work correctly """
- f = File(self.mktemp(), 'w-', userblock_size=512)
- try:
- self.assertEqual(f.userblock_size, 512)
- finally:
- f.close()
- f = File(self.mktemp(), 'x', userblock_size=512)
- try:
- self.assertEqual(f.userblock_size, 512)
- finally:
- f.close()
- f = File(self.mktemp(), 'w', userblock_size=512)
- try:
- self.assertEqual(f.userblock_size, 512)
- finally:
- f.close()
- # User block size must be an integer
- with self.assertRaises(ValueError):
- File(self.mktemp(), 'w', userblock_size='non')
- def test_write_only(self):
- """ User block only allowed for write """
- name = self.mktemp()
- f = File(name, 'w')
- f.close()
- with self.assertRaises(ValueError):
- f = h5py.File(name, 'r', userblock_size=512)
- with self.assertRaises(ValueError):
- f = h5py.File(name, 'r+', userblock_size=512)
- def test_match_existing(self):
- """ User block size must match that of file when opening for append """
- name = self.mktemp()
- f = File(name, 'w', userblock_size=512)
- f.close()
- with self.assertRaises(ValueError):
- f = File(name, 'a', userblock_size=1024)
- f = File(name, 'a', userblock_size=512)
- try:
- self.assertEqual(f.userblock_size, 512)
- finally:
- f.close()
- def test_power_of_two(self):
- """ User block size must be a power of 2 and at least 512 """
- name = self.mktemp()
- with self.assertRaises(ValueError):
- f = File(name, 'w', userblock_size=128)
- with self.assertRaises(ValueError):
- f = File(name, 'w', userblock_size=513)
- with self.assertRaises(ValueError):
- f = File(name, 'w', userblock_size=1023)
- def test_write_block(self):
- """ Test that writing to a user block does not destroy the file """
- name = self.mktemp()
- f = File(name, 'w', userblock_size=512)
- f.create_group("Foobar")
- f.close()
- pyfile = open(name, 'r+b')
- try:
- pyfile.write(b'X' * 512)
- finally:
- pyfile.close()
- f = h5py.File(name, 'r')
- try:
- assert "Foobar" in f
- finally:
- f.close()
- pyfile = open(name, 'rb')
- try:
- self.assertEqual(pyfile.read(512), b'X' * 512)
- finally:
- pyfile.close()
- class TestContextManager(TestCase):
- """
- Feature: File objects can be used as context managers
- """
- def test_context_manager(self):
- """ File objects can be used in with statements """
- with File(self.mktemp(), 'w') as fid:
- self.assertTrue(fid)
- self.assertTrue(not fid)
- @ut.skipIf(not UNICODE_FILENAMES, "Filesystem unicode support required")
- class TestUnicode(TestCase):
- """
- Feature: Unicode filenames are supported
- """
- def test_unicode(self):
- """ Unicode filenames can be used, and retrieved properly via .filename
- """
- fname = self.mktemp(prefix=chr(0x201a))
- fid = File(fname, 'w')
- try:
- self.assertEqual(fid.filename, fname)
- self.assertIsInstance(fid.filename, str)
- finally:
- fid.close()
- def test_unicode_hdf5_python_consistent(self):
- """ Unicode filenames can be used, and seen correctly from python
- """
- fname = self.mktemp(prefix=chr(0x201a))
- with File(fname, 'w') as f:
- self.assertTrue(os.path.exists(fname))
- def test_nonexistent_file_unicode(self):
- """
- Modes 'r' and 'r+' do not create files even when given unicode names
- """
- fname = self.mktemp(prefix=chr(0x201a))
- with self.assertRaises(IOError):
- File(fname, 'r')
- with self.assertRaises(IOError):
- File(fname, 'r+')
- class TestFileProperty(TestCase):
- """
- Feature: A File object can be retrieved from any child object,
- via the .file property
- """
- def test_property(self):
- """ File object can be retrieved from subgroup """
- fname = self.mktemp()
- hfile = File(fname, 'w')
- try:
- hfile2 = hfile['/'].file
- self.assertEqual(hfile, hfile2)
- finally:
- hfile.close()
- def test_close(self):
- """ All retrieved File objects are closed at the same time """
- fname = self.mktemp()
- hfile = File(fname, 'w')
- grp = hfile.create_group('foo')
- hfile2 = grp.file
- hfile3 = hfile['/'].file
- hfile2.close()
- self.assertFalse(hfile)
- self.assertFalse(hfile2)
- self.assertFalse(hfile3)
- def test_mode(self):
- """ Retrieved File objects have a meaningful mode attribute """
- hfile = File(self.mktemp(), 'w')
- try:
- grp = hfile.create_group('foo')
- self.assertEqual(grp.file.mode, hfile.mode)
- finally:
- hfile.close()
- class TestClose(TestCase):
- """
- Feature: Files can be closed
- """
- def test_close(self):
- """ Close file via .close method """
- fid = File(self.mktemp(), 'w')
- self.assertTrue(fid)
- fid.close()
- self.assertFalse(fid)
- def test_closed_file(self):
- """ Trying to modify closed file raises ValueError """
- fid = File(self.mktemp(), 'w')
- fid.close()
- with self.assertRaises(ValueError):
- fid.create_group('foo')
- def test_close_multiple_default_driver(self):
- fname = self.mktemp()
- f = h5py.File(fname, 'w')
- f.create_group("test")
- f.close()
- f.close()
- class TestFlush(TestCase):
- """
- Feature: Files can be flushed
- """
- def test_flush(self):
- """ Flush via .flush method """
- fid = File(self.mktemp(), 'w')
- fid.flush()
- fid.close()
- class TestRepr(TestCase):
- """
- Feature: File objects provide a helpful __repr__ string
- """
- def test_repr(self):
- """ __repr__ behaves itself when files are open and closed """
- fid = File(self.mktemp(), 'w')
- self.assertIsInstance(repr(fid), str)
- fid.close()
- self.assertIsInstance(repr(fid), str)
- class TestFilename(TestCase):
- """
- Feature: The name of a File object can be retrieved via .filename
- """
- def test_filename(self):
- """ .filename behaves properly for string data """
- fname = self.mktemp()
- fid = File(fname, 'w')
- try:
- self.assertEqual(fid.filename, fname)
- self.assertIsInstance(fid.filename, str)
- finally:
- fid.close()
- class TestCloseInvalidatesOpenObjectIDs(TestCase):
- """
- Ensure that closing a file invalidates object IDs, as appropriate
- """
- def test_close(self):
- """ Closing a file invalidates any of the file's open objects """
- with File(self.mktemp(), 'w') as f1:
- g1 = f1.create_group('foo')
- self.assertTrue(bool(f1.id))
- self.assertTrue(bool(g1.id))
- f1.close()
- self.assertFalse(bool(f1.id))
- self.assertFalse(bool(g1.id))
- with File(self.mktemp(), 'w') as f2:
- g2 = f2.create_group('foo')
- self.assertTrue(bool(f2.id))
- self.assertTrue(bool(g2.id))
- self.assertFalse(bool(f1.id))
- self.assertFalse(bool(g1.id))
- def test_close_one_handle(self):
- fname = self.mktemp()
- with File(fname, 'w') as f:
- f.create_group('foo')
- f1 = File(fname)
- f2 = File(fname)
- g1 = f1['foo']
- g2 = f2['foo']
- assert g1.id.valid
- assert g2.id.valid
- f1.close()
- assert not g1.id.valid
- # Closing f1 shouldn't close f2 or objects belonging to it
- assert f2.id.valid
- assert g2.id.valid
- f2.close()
- assert not f2.id.valid
- assert not g2.id.valid
- class TestPathlibSupport(TestCase):
- """
- Check that h5py doesn't break on pathlib
- """
- def test_pathlib_accepted_file(self):
- """ Check that pathlib is accepted by h5py.File """
- with closed_tempfile() as f:
- path = pathlib.Path(f)
- with File(path, 'w') as f2:
- self.assertTrue(True)
- def test_pathlib_name_match(self):
- """ Check that using pathlib does not affect naming """
- with closed_tempfile() as f:
- path = pathlib.Path(f)
- with File(path, 'w') as h5f1:
- pathlib_name = h5f1.filename
- with File(f, 'w') as h5f2:
- normal_name = h5f2.filename
- self.assertEqual(pathlib_name, normal_name)
- class TestPickle(TestCase):
- """Check that h5py.File can't be pickled"""
- def test_dump_error(self):
- with File(self.mktemp(), 'w') as f1:
- with self.assertRaises(TypeError):
- pickle.dumps(f1)
- # unittest doesn't work with pytest fixtures (and possibly other features),
- # hence no subclassing TestCase
- @pytest.mark.mpi
- class TestMPI(object):
- def test_mpio(self, mpi_file_name):
- """ MPIO driver and options """
- from mpi4py import MPI
- with File(mpi_file_name, 'w', driver='mpio', comm=MPI.COMM_WORLD) as f:
- assert f
- assert f.driver == 'mpio'
- @pytest.mark.skipif(h5py.version.hdf5_version_tuple < (1, 8, 9),
- reason="mpio atomic file operations were added in HDF5 1.8.9+")
- def test_mpi_atomic(self, mpi_file_name):
- """ Enable atomic mode for MPIO driver """
- from mpi4py import MPI
- with File(mpi_file_name, 'w', driver='mpio', comm=MPI.COMM_WORLD) as f:
- assert not f.atomic
- f.atomic = True
- assert f.atomic
- def test_close_multiple_mpio_driver(self, mpi_file_name):
- """ MPIO driver and options """
- from mpi4py import MPI
- f = File(mpi_file_name, 'w', driver='mpio', comm=MPI.COMM_WORLD)
- f.create_group("test")
- f.close()
- f.close()
- @ut.skipIf(h5py.version.hdf5_version_tuple < (1, 10, 1),
- 'Requires HDF5 1.10.1 or later')
- class TestSWMRMode(TestCase):
- """
- Feature: Create file that switches on SWMR mode
- """
- def test_file_mode_generalizes(self):
- fname = self.mktemp()
- fid = File(fname, 'w', libver='latest')
- g = fid.create_group('foo')
- # fid and group member file attribute should have the same mode
- assert fid.mode == g.file.mode == 'r+'
- fid.swmr_mode = True
- # fid and group member file attribute should still be 'r+'
- # even though file intent has changed
- assert fid.mode == g.file.mode == 'r+'
- fid.close()
- def test_swmr_mode_consistency(self):
- fname = self.mktemp()
- fid = File(fname, 'w', libver='latest')
- g = fid.create_group('foo')
- assert fid.swmr_mode == g.file.swmr_mode == False
- fid.swmr_mode = True
- # This setter should affect both fid and group member file attribute
- assert fid.swmr_mode == g.file.swmr_mode == True
- fid.close()
- # unittest doesn't work with pytest fixtures (and possibly other features),
- # hence no subclassing TestCase
- class TestROS3:
- @pytest.mark.skipif(h5py.version.hdf5_version_tuple < (1, 10, 6)
- or not h5.get_config().ros3,
- reason="ros3 file operations were added in HDF5 1.10.6+")
- def test_ros3(self):
- """ ROS3 driver and options """
- with File("https://dandiarchive.s3.amazonaws.com/ros3test.hdf5", 'r',
- driver='ros3') as f:
- assert f
- assert 'mydataset' in f.keys()
- assert f["mydataset"].shape == (100,)
- def test_close_gc(writable_file):
- # https://github.com/h5py/h5py/issues/1852
- for i in range(100):
- writable_file[str(i)] = []
- filename = writable_file.filename
- writable_file.close()
- # Ensure that Python's garbage collection doesn't interfere with closing
- # a file. Try a few times - the problem is not 100% consistent, but
- # normally showed up on the 1st or 2nd iteration for me. -TAK, 2021
- for i in range(10):
- with h5py.File(filename, 'r') as f:
- refs = [d.id for d in f.values()]
- refs.append(refs) # Make a reference cycle so GC is involved
- del refs # GC is likely to fire while closing the file
|