Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1e10542

Browse files
Merge pull request h5py#399 from andrewcollette/issue_367
Allow opening readonly files with mode==None
2 parents 5a37584 + ac18020 commit 1e10542

File tree

2 files changed

+49
-10
lines changed

2 files changed

+49
-10
lines changed

h5py/_hl/files.py

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -83,22 +83,37 @@ def make_fid(name, mode, userblock_size, fapl, fcpl=None):
8383
fid = h5f.create(name, h5f.ACC_EXCL, fapl=fapl, fcpl=fcpl)
8484
elif mode == 'w':
8585
fid = h5f.create(name, h5f.ACC_TRUNC, fapl=fapl, fcpl=fcpl)
86-
elif mode == 'a' or mode is None:
86+
elif mode == 'a':
87+
# Open in append mode (read/write).
88+
# If that fails, create a new file only if it won't clobber an
89+
# existing one (ACC_EXCL)
8790
try:
8891
fid = h5f.open(name, h5f.ACC_RDWR, fapl=fapl)
89-
try:
90-
existing_fcpl = fid.get_create_plist()
91-
if (userblock_size is not None and
92-
existing_fcpl.get_userblock() != userblock_size):
93-
raise ValueError("Requested userblock size (%d) does not match that of existing file (%d)" % (userblock_size, existing_fcpl.get_userblock()))
94-
except:
95-
fid.close()
96-
raise
9792
except IOError:
9893
fid = h5f.create(name, h5f.ACC_EXCL, fapl=fapl, fcpl=fcpl)
94+
elif mode is None:
95+
# Try to open in append mode (read/write).
96+
# If that fails, try readonly, and finally create a new file only
97+
# if it won't clobber an existing file (ACC_EXCL).
98+
try:
99+
fid = h5f.open(name, h5f.ACC_RDWR, fapl=fapl)
100+
except IOError:
101+
try:
102+
fid = h5f.open(name, h5f.ACC_RDONLY, fapl=fapl)
103+
except IOError:
104+
fid = h5f.create(name, h5f.ACC_EXCL, fapl=fapl, fcpl=fcpl)
99105
else:
100106
raise ValueError("Invalid mode; must be one of r, r+, w, w-, a")
101107

108+
try:
109+
if userblock_size is not None:
110+
existing_fcpl = fid.get_create_plist()
111+
if existing_fcpl.get_userblock() != userblock_size:
112+
raise ValueError("Requested userblock size (%d) does not match that of existing file (%d)" % (userblock_size, existing_fcpl.get_userblock()))
113+
except:
114+
fid.close()
115+
raise
116+
102117
return fid
103118

104119

h5py/tests/test_file.py

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515

1616
from __future__ import with_statement
1717

18-
import os
18+
import os, stat
1919

2020
from .common import ut, TestCase, unicode_filenames
2121
from h5py.highlevel import File
@@ -29,6 +29,30 @@ class TestFileOpen(TestCase):
2929
Feature: Opening files with Python-style modes.
3030
"""
3131

32+
def test_default(self):
33+
""" Default semantics in the presence or absence of a file """
34+
fname = self.mktemp()
35+
36+
# No existing file; create a new file and open RW
37+
with File(fname) as f:
38+
self.assertTrue(f)
39+
self.assertEqual(f.mode, 'r+')
40+
41+
# Existing readonly file; open read-only
42+
os.chmod(fname, stat.S_IREAD)
43+
try:
44+
with File(fname) as f:
45+
self.assertTrue(f)
46+
self.assertEqual(f.mode, 'r')
47+
finally:
48+
os.chmod(fname, stat.S_IWRITE)
49+
50+
# File exists but is not HDF5; raise IOError
51+
with open(fname, 'wb') as f:
52+
f.write(b'\x00')
53+
with self.assertRaises(IOError):
54+
File(fname)
55+
3256
def test_create(self):
3357
""" Mode 'w' opens file in overwrite mode """
3458
fname = self.mktemp()

0 commit comments

Comments
 (0)