Skip to content

Commit d67c7f2

Browse files
committed
RF: ArrayProxy.KEEP_FILE_OPEN default value changed to 'auto'. Opener
keep_open flag passed through to indexed gzip drop_handles flag. indexed_gzip versions > 0.6 all supported.
1 parent 2edca76 commit d67c7f2

File tree

2 files changed

+36
-23
lines changed

2 files changed

+36
-23
lines changed

nibabel/arrayproxy.py

Lines changed: 15 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252
specifying the ``keep_file_open`` flag will result in a ``ValueError`` being
5353
raised.
5454
"""
55-
KEEP_FILE_OPEN_DEFAULT = False
55+
KEEP_FILE_OPEN_DEFAULT = 'auto'
5656

5757

5858
class ArrayProxy(object):
@@ -186,10 +186,10 @@ def _should_keep_file_open(self, file_like, keep_file_open):
186186
The return value is derived from these rules:
187187
188188
- If ``file_like`` is a file(-like) object, ``False`` is returned.
189-
Otherwise, ``file_like`` is assumed to be a file name.
190-
- if ``file_like`` ends with ``'gz'``, and the ``indexed_gzip``
191-
library is available, ``True`` is returned.
192-
- Otherwise, ``False`` is returned.
189+
Otherwise, ``file_like`` is assumed to be a file name
190+
- If ``keep_file_open`` is ``auto``, and ``indexed_gzip`` is
191+
not available, ``False`` is returned.
192+
- Otherwise, the value of ``keep_file_open`` is returned unchanged.
193193
194194
Parameters
195195
----------
@@ -203,23 +203,20 @@ def _should_keep_file_open(self, file_like, keep_file_open):
203203
-------
204204
205205
The value of ``keep_file_open`` that will be used by this
206-
``ArrayProxy``.
206+
``ArrayProxy``, and passed through to ``ImageOpener`` instances.
207207
"""
208208
if keep_file_open is None:
209209
keep_file_open = KEEP_FILE_OPEN_DEFAULT
210-
# if keep_file_open is True/False, we do what the user wants us to do
211-
if isinstance(keep_file_open, bool):
212-
return keep_file_open
213-
if keep_file_open != 'auto':
210+
if keep_file_open not in ('auto', True, False):
214211
raise ValueError('keep_file_open should be one of {None, '
215212
'\'auto\', True, False}')
216-
217213
# file_like is a handle - keep_file_open is irrelevant
218214
if hasattr(file_like, 'read') and hasattr(file_like, 'seek'):
219215
return False
220-
# Otherwise, if file_like is gzipped, and we have_indexed_gzip, we set
221-
# keep_file_open to True, else we set it to False
222-
return HAVE_INDEXED_GZIP and file_like.endswith('gz')
216+
# don't have indexed_gzip - auto -> False
217+
if keep_file_open == 'auto' and not HAVE_INDEXED_GZIP:
218+
return False
219+
return keep_file_open
223220

224221
@property
225222
@deprecate_with_version('ArrayProxy.header deprecated', '2.2', '3.0')
@@ -263,12 +260,13 @@ def _get_fileobj(self):
263260
A newly created ``ImageOpener`` instance, or an existing one,
264261
which provides access to the file.
265262
"""
266-
if self._keep_file_open:
263+
if bool(self._keep_file_open):
267264
if not hasattr(self, '_opener'):
268-
self._opener = ImageOpener(self.file_like, keep_open=True)
265+
self._opener = ImageOpener(
266+
self.file_like, keep_open=self._keep_file_open)
269267
yield self._opener
270268
else:
271-
with ImageOpener(self.file_like, keep_open=False) as opener:
269+
with ImageOpener(self.file_like) as opener:
272270
yield opener
273271

274272
def get_unscaled(self):

nibabel/openers.py

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,28 @@
1818

1919
# is indexed_gzip present and modern?
2020
try:
21-
from indexed_gzip import SafeIndexedGzipFile, __version__ as version
21+
import indexed_gzip as igzip
22+
version = igzip.__version__
2223

2324
HAVE_INDEXED_GZIP = True
2425

26+
# < 0.6 - no good
2527
if StrictVersion(version) < StrictVersion('0.6.0'):
2628
warnings.warn('indexed_gzip is present, but too old '
2729
'(>= 0.6.0 required): {})'.format(version))
2830
HAVE_INDEXED_GZIP = False
29-
30-
del version
31+
# < 0.7 - does not support drop_handles
32+
elif StrictVersion(version) < StrictVersion('0.7.0'):
33+
class IndexedGzipFile(igzip.SafeIndexedGzipFile):
34+
def __init__(self, *args, **kwargs):
35+
kwargs.pop('drop_handles', None)
36+
super(IndexedGzipFile, self).__init__(*args, **kwargs)
37+
# >= 0.8 SafeIndexedGzipFile renamed to IndexedGzipFile
38+
elif StrictVersion(version) < StrictVersion('0.8.0'):
39+
IndexedGzipFile = igzip.SafeIndexedGzipFile
40+
else:
41+
IndexedGzipFile = igzip.IndexedGzipFile
42+
del igzip, version
3143

3244
except ImportError:
3345
HAVE_INDEXED_GZIP = False
@@ -80,9 +92,12 @@ def readinto(self, buf):
8092

8193
def _gzip_open(filename, mode='rb', compresslevel=9, keep_open=False):
8294

83-
# use indexed_gzip if possible for faster read access
84-
if keep_open and mode == 'rb' and HAVE_INDEXED_GZIP:
85-
gzip_file = SafeIndexedGzipFile(filename)
95+
# use indexed_gzip if possible for faster read access. If keep_open ==
96+
# True, we tell IndexedGzipFile to keep the file handle open. Otherwise
97+
# the IndexedGzipFile will close/open the file on each read.
98+
if HAVE_INDEXED_GZIP and keep_open in (True, 'auto') and mode == 'rb':
99+
gzip_file = IndexedGzipFile(
100+
filename, drop_handles=keep_open == 'auto')
86101

87102
# Fall-back to built-in GzipFile (wrapped with the BufferedGzipFile class
88103
# defined above)

0 commit comments

Comments
 (0)