From b92fc39b31d512ed7014421e83f6af6b2535e242 Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Mon, 2 Oct 2017 14:23:38 +0100 Subject: [PATCH 01/10] RF: ArrayProxy tells Opener whether it intends to keep the file open for multiple accesses, so Opener knows whether it should use indexed_gzip or not. --- nibabel/arrayproxy.py | 4 ++-- nibabel/openers.py | 21 +++++++++++++++++---- 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/nibabel/arrayproxy.py b/nibabel/arrayproxy.py index 18d7f67e3b..e95f519e02 100644 --- a/nibabel/arrayproxy.py +++ b/nibabel/arrayproxy.py @@ -265,10 +265,10 @@ def _get_fileobj(self): """ if self._keep_file_open: if not hasattr(self, '_opener'): - self._opener = ImageOpener(self.file_like) + self._opener = ImageOpener(self.file_like, keep_open=True) yield self._opener else: - with ImageOpener(self.file_like) as opener: + with ImageOpener(self.file_like, keep_open=False) as opener: yield opener def get_unscaled(self): diff --git a/nibabel/openers.py b/nibabel/openers.py index 04382f66bc..36bc208850 100644 --- a/nibabel/openers.py +++ b/nibabel/openers.py @@ -67,10 +67,10 @@ def readinto(self, buf): return n_read -def _gzip_open(filename, mode='rb', compresslevel=9): +def _gzip_open(filename, mode='rb', compresslevel=9, keep_open=False): # use indexed_gzip if possible for faster read access - if mode == 'rb' and HAVE_INDEXED_GZIP: + if keep_open and mode == 'rb' and HAVE_INDEXED_GZIP: gzip_file = SafeIndexedGzipFile(filename) # Fall-back to built-in GzipFile (wrapped with the BufferedGzipFile class @@ -101,12 +101,14 @@ class Opener(object): \*args : positional arguments passed to opening method when `fileish` is str. ``mode``, if not specified, is `rb`. ``compresslevel``, if relevant, and not specified, - is set from class variable ``default_compresslevel`` + is set from class variable ``default_compresslevel``. ``keep_open``, if + relevant, and not specified, is set from class variable + ``default_keep_open``. \*\*kwargs : keyword arguments passed to opening method when `fileish` is str. Change of defaults as for \*args """ - gz_def = (_gzip_open, ('mode', 'compresslevel')) + gz_def = (_gzip_open, ('mode', 'compresslevel', 'keep_open')) bz2_def = (bz2.BZ2File, ('mode', 'buffering', 'compresslevel')) compress_ext_map = { '.gz': gz_def, @@ -117,6 +119,9 @@ class Opener(object): default_compresslevel = 1 #: whether to ignore case looking for compression extensions compress_ext_icase = True + #: hint which tells us whether the file handle will be kept open for + # multiple reads/writes, or just for one-time access. + default_keep_open = False def __init__(self, fileish, *args, **kwargs): if self._is_fileobj(fileish): @@ -132,8 +137,16 @@ def __init__(self, fileish, *args, **kwargs): # Set default mode if 'mode' not in full_kwargs: kwargs['mode'] = 'rb' + # Default compression level if 'compresslevel' in arg_names and 'compresslevel' not in kwargs: kwargs['compresslevel'] = self.default_compresslevel + # Default keep_open hint + if 'keep_open' in arg_names: + if 'keep_open' not in kwargs: + kwargs['keep_open'] = self.default_keep_open + # Clear keep_open hint if it is not relevant for the file type + else: + kwargs.pop('keep_open', None) self.fobj = opener(fileish, *args, **kwargs) self._name = fileish self.me_opened = True From 73971bbc7aa6faf71e7058d13a8fef20985688d6 Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Mon, 2 Oct 2017 14:55:34 +0100 Subject: [PATCH 02/10] TEST: Adjusted tests which make sure that Opener uses GzipFile/IndexedGzipFile classes as appropriate --- nibabel/tests/test_arrayproxy.py | 16 +-------- nibabel/tests/test_openers.py | 58 +++++++++++++++++++++----------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/nibabel/tests/test_arrayproxy.py b/nibabel/tests/test_arrayproxy.py index 61492f6038..70265a5860 100644 --- a/nibabel/tests/test_arrayproxy.py +++ b/nibabel/tests/test_arrayproxy.py @@ -33,6 +33,7 @@ from nibabel.testing import VIRAL_MEMMAP from .test_fileslice import slicer_samples +from .test_openers import patch_indexed_gzip class FunkyHeader(object): @@ -412,21 +413,6 @@ def test_keep_file_open_true_false_invalid(): ArrayProxy(fname, ((10, 10, 10), dtype), keep_file_open='cauto') -@contextlib.contextmanager -def patch_indexed_gzip(state): - # Make it look like we do (state==True) or do not (state==False) have - # the indexed gzip module. - if state: - values = (True, True, gzip.GzipFile) - else: - values = (False, False, None) - with mock.patch('nibabel.openers.HAVE_INDEXED_GZIP', values[0]), \ - mock.patch('nibabel.arrayproxy.HAVE_INDEXED_GZIP', values[1]), \ - mock.patch('nibabel.openers.SafeIndexedGzipFile', values[2], - create=True): - yield - - @contextlib.contextmanager def patch_keep_file_open_default(value): # Patch arrayproxy.KEEP_FILE_OPEN_DEFAULT with the given value diff --git a/nibabel/tests/test_openers.py b/nibabel/tests/test_openers.py index 92c74f42e9..463ca6aa50 100644 --- a/nibabel/tests/test_openers.py +++ b/nibabel/tests/test_openers.py @@ -8,6 +8,7 @@ ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ### ## ''' Test for openers module ''' import os +import contextlib from gzip import GzipFile from bz2 import BZ2File from io import BytesIO, UnsupportedOperation @@ -96,16 +97,31 @@ def test_BinOpener(): BinOpener, 'test.txt', 'r') +class MockIndexedGzipFile(object): + def __init__(self, *args, **kwargs): + pass + + +@contextlib.contextmanager +def patch_indexed_gzip(state): + # Make it look like we do (state==True) or do not (state==False) have + # the indexed gzip module. + if state: + values = (True, True, MockIndexedGzipFile) + else: + values = (False, False, GzipFile) + with mock.patch('nibabel.openers.HAVE_INDEXED_GZIP', values[0]), \ + mock.patch('nibabel.arrayproxy.HAVE_INDEXED_GZIP', values[1]), \ + mock.patch('nibabel.openers.SafeIndexedGzipFile', values[2], + create=True): + yield + + def test_Opener_gzip_type(): # Test that BufferedGzipFile or IndexedGzipFile are used as appropriate data = 'this is some test data' fname = 'test.gz' - mockmod = mock.MagicMock() - - class MockIGZFile(object): - def __init__(self, *args, **kwargs): - pass with InTemporaryDirectory(): @@ -113,21 +129,23 @@ def __init__(self, *args, **kwargs): with GzipFile(fname, mode='wb') as f: f.write(data.encode()) - # test with indexd_gzip not present - with mock.patch('nibabel.openers.HAVE_INDEXED_GZIP', False), \ - mock.patch('nibabel.arrayproxy.HAVE_INDEXED_GZIP', False), \ - mock.patch('nibabel.openers.SafeIndexedGzipFile', None, - create=True): - assert isinstance(Opener(fname, mode='rb').fobj, GzipFile) - assert isinstance(Opener(fname, mode='wb').fobj, GzipFile) - - # test with indexd_gzip present - with mock.patch('nibabel.openers.HAVE_INDEXED_GZIP', True), \ - mock.patch('nibabel.arrayproxy.HAVE_INDEXED_GZIP', True), \ - mock.patch('nibabel.openers.SafeIndexedGzipFile', MockIGZFile, - create=True): - assert isinstance(Opener(fname, mode='rb').fobj, MockIGZFile) - assert isinstance(Opener(fname, mode='wb').fobj, GzipFile) + # Each test is specified by a tuple containing: + # (indexed_gzip present, Opener kwargs, expected file type) + tests = [ + (False, {'mode' : 'rb', 'keep_open' : True}, GzipFile), + (False, {'mode' : 'rb', 'keep_open' : False}, GzipFile), + (False, {'mode' : 'wb', 'keep_open' : True}, GzipFile), + (False, {'mode' : 'wb', 'keep_open' : False}, GzipFile), + (True, {'mode' : 'rb', 'keep_open' : True}, MockIndexedGzipFile), + (True, {'mode' : 'rb', 'keep_open' : False}, GzipFile), + (True, {'mode' : 'wb', 'keep_open' : True}, GzipFile), + (True, {'mode' : 'wb', 'keep_open' : False}, GzipFile), + ] + + for test in tests: + igzip_present, kwargs, expected = test + with patch_indexed_gzip(igzip_present): + assert isinstance(Opener(fname, **kwargs).fobj, expected) class TestImageOpener: From 83f5c8e8f0d9792a33589af16da03b3fa12c0141 Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Mon, 2 Oct 2017 16:36:54 +0100 Subject: [PATCH 03/10] RF: Restrict the use of indexed_gzip to versions >= 0.6.0 --- nibabel/openers.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/nibabel/openers.py b/nibabel/openers.py index 36bc208850..babd8881fd 100644 --- a/nibabel/openers.py +++ b/nibabel/openers.py @@ -13,11 +13,19 @@ import gzip import sys from os.path import splitext +from distutils.version import StrictVersion -# is indexed_gzip present? +# is indexed_gzip present and modern? try: - from indexed_gzip import SafeIndexedGzipFile + from indexed_gzip import SafeIndexedGzipFile, __version__ as version + + if StrictVersion(version) < StrictVersion("0.6.0"): + raise ImportError('indexed_gzip is present, but too old ' + '(>= 0.6.0 required): {})'.format(version)) + + del version HAVE_INDEXED_GZIP = True + except ImportError: HAVE_INDEXED_GZIP = False From 2e1a046c66e3f17680818cc8015c153952e1fc0c Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Mon, 2 Oct 2017 17:34:52 +0100 Subject: [PATCH 04/10] RF: Changed internally raised and eaten indexed_gzip version ImportError to a warning, so it will be shown to users. --- nibabel/openers.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/nibabel/openers.py b/nibabel/openers.py index babd8881fd..afd9d0fd6a 100644 --- a/nibabel/openers.py +++ b/nibabel/openers.py @@ -12,6 +12,7 @@ import bz2 import gzip import sys +import warnings from os.path import splitext from distutils.version import StrictVersion @@ -19,12 +20,14 @@ try: from indexed_gzip import SafeIndexedGzipFile, __version__ as version - if StrictVersion(version) < StrictVersion("0.6.0"): - raise ImportError('indexed_gzip is present, but too old ' - '(>= 0.6.0 required): {})'.format(version)) + HAVE_INDEXED_GZIP = True + + if StrictVersion(version) < StrictVersion('0.6.0'): + warnings.warn('indexed_gzip is present, but too old ' + '(>= 0.6.0 required): {})'.format(version)) + HAVE_INDEXED_GZIP = False del version - HAVE_INDEXED_GZIP = True except ImportError: HAVE_INDEXED_GZIP = False From 1e80412b67b5bb599ec45ccccb71612cfc8b68f4 Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Tue, 3 Oct 2017 21:44:23 +0100 Subject: [PATCH 05/10] RF: Removed Opener default_keep_open class attribute - default value is hard coded in __init__ --- nibabel/openers.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/nibabel/openers.py b/nibabel/openers.py index afd9d0fd6a..0f57fa406a 100644 --- a/nibabel/openers.py +++ b/nibabel/openers.py @@ -113,8 +113,7 @@ class Opener(object): passed to opening method when `fileish` is str. ``mode``, if not specified, is `rb`. ``compresslevel``, if relevant, and not specified, is set from class variable ``default_compresslevel``. ``keep_open``, if - relevant, and not specified, is set from class variable - ``default_keep_open``. + relevant, and not specified, is ``False``. \*\*kwargs : keyword arguments passed to opening method when `fileish` is str. Change of defaults as for \*args @@ -130,9 +129,6 @@ class Opener(object): default_compresslevel = 1 #: whether to ignore case looking for compression extensions compress_ext_icase = True - #: hint which tells us whether the file handle will be kept open for - # multiple reads/writes, or just for one-time access. - default_keep_open = False def __init__(self, fileish, *args, **kwargs): if self._is_fileobj(fileish): @@ -153,8 +149,7 @@ def __init__(self, fileish, *args, **kwargs): kwargs['compresslevel'] = self.default_compresslevel # Default keep_open hint if 'keep_open' in arg_names: - if 'keep_open' not in kwargs: - kwargs['keep_open'] = self.default_keep_open + kwargs.setdefault('keep_open', False) # Clear keep_open hint if it is not relevant for the file type else: kwargs.pop('keep_open', None) From e2c7809152a1c41f1385643a9dbe67020302929d Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Thu, 5 Oct 2017 09:29:13 +0100 Subject: [PATCH 06/10] TEST: Use SafeIndexedGzipFile instead of IndexedGzipFile --- nibabel/tests/test_openers.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/nibabel/tests/test_openers.py b/nibabel/tests/test_openers.py index 463ca6aa50..8bd05f49a9 100644 --- a/nibabel/tests/test_openers.py +++ b/nibabel/tests/test_openers.py @@ -256,10 +256,11 @@ class StrictOpener(Opener): assert_true(isinstance(fobj.fobj, file_class)) elif lext == 'gz': try: - from indexed_gzip import IndexedGzipFile + from indexed_gzip import SafeIndexedGzipFile except ImportError: - IndexedGzipFile = GzipFile - assert_true(isinstance(fobj.fobj, (GzipFile, IndexedGzipFile))) + SafeIndexedGzipFile = GzipFile + assert_true(isinstance(fobj.fobj, (GzipFile, + SafeIndexedGzipFile)) else: assert_true(isinstance(fobj.fobj, BZ2File)) From 92e4b9094504a9702dfc8628df0fc9e255378f53 Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Thu, 5 Oct 2017 13:37:56 +0100 Subject: [PATCH 07/10] TEST: Benchmark script for slicing gzipped files using ArrayProxy --- .../benchmarks/bench_arrayproxy_slicing.py | 199 ++++++++++++++++++ 1 file changed, 199 insertions(+) create mode 100644 nibabel/benchmarks/bench_arrayproxy_slicing.py diff --git a/nibabel/benchmarks/bench_arrayproxy_slicing.py b/nibabel/benchmarks/bench_arrayproxy_slicing.py new file mode 100644 index 0000000000..86eaf60922 --- /dev/null +++ b/nibabel/benchmarks/bench_arrayproxy_slicing.py @@ -0,0 +1,199 @@ +"""Benchmarks for ArrayProxy slicing of gzipped and non-gzipped files + +Run benchmarks with:: + + import nibabel as nib + nib.bench() + +If you have doctests enabled by default in nose (with a noserc file or +environment variable), and you have a numpy version <= 1.6.1, this will also +run the doctests, let's hope they pass. + +Run this benchmark with: + + nosetests -s --match '(?:^|[\\b_\\.//-])[Bb]ench' /path/to/bench_arrayproxy_slicing.py +""" + +from timeit import timeit +import contextlib +import gc +import itertools as it +import numpy as np +import mock + +import nibabel as nib +from nibabel.tmpdirs import InTemporaryDirectory +from nibabel.openers import HAVE_INDEXED_GZIP + +from .butils import print_git_title +from ..rstutils import rst_table + +# if memory_profiler is installed, we get memory usage results +try: + from memory_profiler import memory_usage +except ImportError: + memory_usage = None + + +# Each test involves loading an image of shape SHAPE, and then slicing it +# NITERS times +NITERS = 50 +SHAPE = (100, 100, 100, 100) + +# One test is run for each combination of SLICEOBJS, KEEP_OPENS, and HAVE_IGZIP + +# ':' gets replaced with slice(None) +# '?' gets replaced with a random index into the relevant axis +# numbers (assumed to be between 0 and 1) get scaled to the axis shape +SLICEOBJS = [ + ('?', ':', ':', ':'), + (':', ':', ':', '?'), + ('?', '?', '?', ':'), +] + +KEEP_OPENS = [False, True] + +if HAVE_INDEXED_GZIP: + HAVE_IGZIP = [False, True] +else: + HAVE_IGZIP = [False] + + +@contextlib.contextmanager +def patch_indexed_gzip(have_igzip): + with mock.patch('nibabel.openers.HAVE_INDEXED_GZIP', have_igzip), \ + mock.patch('nibabel.arrayproxy.HAVE_INDEXED_GZIP', have_igzip): + yield + + +def bench_arrayproxy_slicing(): + + print_git_title('\nArrayProxy gzip slicing') + + # each test is a tuple containing + # (HAVE_INDEXED_GZIP, keep_file_open, sliceobj) + tests = list(it.product(HAVE_IGZIP, KEEP_OPENS, SLICEOBJS)) + + # remove tests where HAVE_INDEXED_GZIP is True and keep_file_open is False, + # because if keep_file_open is False, HAVE_INDEXED_GZIP has no effect + tests = [t for t in tests if not (t[0] and not t[1])] + + testfile = 'testfile.nii' + testfilegz = 'test.nii.gz' + + def get_test_label(test): + have_igzip = test[0] + keep_open = test[1] + + if not (have_igzip and keep_open): + return 'gzip' + else: + return 'indexed_gzip' + + def fix_sliceobj(sliceobj): + new_sliceobj = [] + for i, s in enumerate(sliceobj): + if s == ':': + new_sliceobj.append(slice(None)) + elif s == '?': + new_sliceobj.append(np.random.randint(0, SHAPE[i])) + else: + new_sliceobj.append(int(s * SHAPE[i])) + return tuple(new_sliceobj) + + def fmt_sliceobj(sliceobj): + slcstr = [] + for i, s in enumerate(sliceobj): + if s in ':?': + slcstr.append(s) + else: + slcstr.append(str(int(s * SHAPE[i]))) + return '[{}]'.format(', '.join(slcstr)) + + with InTemporaryDirectory(): + + print('Generating test data... ({} MB)'.format( + int(round(np.prod(SHAPE) * 4 / 1048576.)))) + + data = np.array(np.random.random(SHAPE), dtype=np.float32) + + # zero out 10% of voxels so gzip has something to compress + mask = np.random.random(SHAPE[:3]) > 0.1 + if len(SHAPE) > 3: + data[mask, :] = 0 + else: + data[mask] = 0 + + # save uncompressed and compressed versions of the image + img = nib.nifti1.Nifti1Image(data, np.eye(4)) + nib.save(img, testfilegz) + nib.save(img, testfile) + + # each result is a tuple containing + # (label, keep_open, sliceobj, testtime, basetime, testmem, basemem) + # + # where "basetime" is the time taken to load and slice a memmapped + # (uncompressed)image, and "basemem" is memory usage for the same + results = [] + + # We use the same random seed for each slice object, + seeds = [np.random.randint(0, 2 ** 32) for s in SLICEOBJS] + + for ti, test in enumerate(tests): + + label = get_test_label(test) + have_igzip, keep_open, sliceobj = test + seed = seeds[SLICEOBJS.index(sliceobj)] + + print('Running test {} of {} ({})...'.format( + ti + 1, len(tests), label)) + + # load uncompressed and compressed versions of the image + img = nib.load(testfile, keep_file_open=keep_open) + + with patch_indexed_gzip(have_igzip): + imggz = nib.load(testfilegz, keep_file_open=keep_open) + + def basefunc(): + img.dataobj[fix_sliceobj(sliceobj)] + + def testfunc(): + with patch_indexed_gzip(have_igzip): + imggz.dataobj[fix_sliceobj(sliceobj)] + + # make sure nothing is floating around from the previous test + # iteration, so memory profiling is (hopefully) more accurate + gc.collect() + + if memory_usage is not None: + membaseline = max(memory_usage(lambda : None)) + testmem = max(memory_usage(testfunc)) - membaseline + basemem = max(memory_usage(basefunc)) - membaseline + else: + testmem = np.nan + basemem = np.nan + + # reset the random number generator, so test and baseline use the + # same slices + np.random.seed(seed) + testtime = float(timeit(testfunc, number=NITERS)) / float(NITERS) + np.random.seed(seed) + basetime = float(timeit(basefunc, number=NITERS)) / float(NITERS) + + results.append((label, keep_open, sliceobj, testtime, basetime, + testmem, basemem)) + + data = np.zeros((len(results), 4)) + data[:, 0] = [r[3] for r in results] + data[:, 1] = [r[4] for r in results] + try: + data[:, 2] = [r[3] / r[4] for r in results] + except: + data[:, 2] = np.nan + data[:, 3] = [r[5] - r[6] for r in results] + + rowlbls = ['Type {}, keep_open {}, slice {}'.format( + r[0], r[1], fmt_sliceobj(r[2])) for r in results] + collbls = ['Time', 'Baseline time', 'Time ratio', 'Memory deviation'] + + print(rst_table(data, rowlbls, collbls)) From e2c560ad184c69906fd1b0d2dfc058893d06ced1 Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Thu, 5 Oct 2017 15:51:17 +0100 Subject: [PATCH 08/10] BF: Fixes to get benchmarking scripts running --- nibabel/benchmarks/bench_array_to_file.py | 3 +++ nibabel/benchmarks/bench_finite_range.py | 2 ++ nibabel/pkg_info.py | 4 ++-- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/nibabel/benchmarks/bench_array_to_file.py b/nibabel/benchmarks/bench_array_to_file.py index e627485bb9..070f1a80a2 100644 --- a/nibabel/benchmarks/bench_array_to_file.py +++ b/nibabel/benchmarks/bench_array_to_file.py @@ -19,11 +19,14 @@ import numpy as np +from six import BytesIO from .butils import print_git_title from numpy.testing import measure +from nibabel.volumeutils import array_to_file + def bench_array_to_file(): rng = np.random.RandomState(20111001) diff --git a/nibabel/benchmarks/bench_finite_range.py b/nibabel/benchmarks/bench_finite_range.py index 1d442ed379..02a4e98856 100644 --- a/nibabel/benchmarks/bench_finite_range.py +++ b/nibabel/benchmarks/bench_finite_range.py @@ -24,6 +24,8 @@ from numpy.testing import measure +from nibabel.volumeutils import finite_range + def bench_finite_range(): rng = np.random.RandomState(20111001) diff --git a/nibabel/pkg_info.py b/nibabel/pkg_info.py index 11e22c8bdb..090cd24c24 100644 --- a/nibabel/pkg_info.py +++ b/nibabel/pkg_info.py @@ -2,9 +2,9 @@ import sys import subprocess try: - from ConfigParser import ConfigParser + from ConfigParser import RawConfigParser as ConfigParser except ImportError: - from configparser import ConfigParser # python 3 + from configparser import RawConfigParser as ConfigParser # python 3 COMMIT_INFO_FNAME = 'COMMIT_INFO.txt' From cc724ef89beb4d9eac7241445942d703da9c04e4 Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Thu, 5 Oct 2017 16:56:41 +0100 Subject: [PATCH 09/10] BF: Syntax error in test case --- nibabel/tests/test_openers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nibabel/tests/test_openers.py b/nibabel/tests/test_openers.py index 8bd05f49a9..ebde721732 100644 --- a/nibabel/tests/test_openers.py +++ b/nibabel/tests/test_openers.py @@ -260,7 +260,7 @@ class StrictOpener(Opener): except ImportError: SafeIndexedGzipFile = GzipFile assert_true(isinstance(fobj.fobj, (GzipFile, - SafeIndexedGzipFile)) + SafeIndexedGzipFile))) else: assert_true(isinstance(fobj.fobj, BZ2File)) From 39a296327edb3b59ff91d19bb8a0c2f73bc62bca Mon Sep 17 00:00:00 2001 From: Paul McCarthy Date: Fri, 6 Oct 2017 16:22:03 +0100 Subject: [PATCH 10/10] PL: Bowing to the style gods --- nibabel/benchmarks/bench_array_to_file.py | 4 +--- .../benchmarks/bench_arrayproxy_slicing.py | 19 +++++++++++-------- nibabel/benchmarks/bench_finite_range.py | 2 +- nibabel/pkg_info.py | 2 +- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/nibabel/benchmarks/bench_array_to_file.py b/nibabel/benchmarks/bench_array_to_file.py index 070f1a80a2..f55b8a2583 100644 --- a/nibabel/benchmarks/bench_array_to_file.py +++ b/nibabel/benchmarks/bench_array_to_file.py @@ -19,13 +19,11 @@ import numpy as np -from six import BytesIO - from .butils import print_git_title from numpy.testing import measure -from nibabel.volumeutils import array_to_file +from nibabel.volumeutils import array_to_file # NOQA def bench_array_to_file(): diff --git a/nibabel/benchmarks/bench_arrayproxy_slicing.py b/nibabel/benchmarks/bench_arrayproxy_slicing.py index 86eaf60922..a824822d3c 100644 --- a/nibabel/benchmarks/bench_arrayproxy_slicing.py +++ b/nibabel/benchmarks/bench_arrayproxy_slicing.py @@ -38,7 +38,7 @@ # Each test involves loading an image of shape SHAPE, and then slicing it # NITERS times NITERS = 50 -SHAPE = (100, 100, 100, 100) +SHAPE = (100, 100, 100, 100) # One test is run for each combination of SLICEOBJS, KEEP_OPENS, and HAVE_IGZIP @@ -61,8 +61,11 @@ @contextlib.contextmanager def patch_indexed_gzip(have_igzip): - with mock.patch('nibabel.openers.HAVE_INDEXED_GZIP', have_igzip), \ - mock.patch('nibabel.arrayproxy.HAVE_INDEXED_GZIP', have_igzip): + + atts = ['nibabel.openers.HAVE_INDEXED_GZIP', + 'nibabel.arrayproxy.HAVE_INDEXED_GZIP'] + + with mock.patch(atts[0], have_igzip), mock.patch(atts[1], have_igzip): yield @@ -78,12 +81,12 @@ def bench_arrayproxy_slicing(): # because if keep_file_open is False, HAVE_INDEXED_GZIP has no effect tests = [t for t in tests if not (t[0] and not t[1])] - testfile = 'testfile.nii' + testfile = 'testfile.nii' testfilegz = 'test.nii.gz' def get_test_label(test): have_igzip = test[0] - keep_open = test[1] + keep_open = test[1] if not (have_igzip and keep_open): return 'gzip' @@ -166,9 +169,9 @@ def testfunc(): gc.collect() if memory_usage is not None: - membaseline = max(memory_usage(lambda : None)) - testmem = max(memory_usage(testfunc)) - membaseline - basemem = max(memory_usage(basefunc)) - membaseline + membaseline = max(memory_usage(lambda: None)) + testmem = max(memory_usage(testfunc)) - membaseline + basemem = max(memory_usage(basefunc)) - membaseline else: testmem = np.nan basemem = np.nan diff --git a/nibabel/benchmarks/bench_finite_range.py b/nibabel/benchmarks/bench_finite_range.py index 02a4e98856..5f268eb285 100644 --- a/nibabel/benchmarks/bench_finite_range.py +++ b/nibabel/benchmarks/bench_finite_range.py @@ -24,7 +24,7 @@ from numpy.testing import measure -from nibabel.volumeutils import finite_range +from nibabel.volumeutils import finite_range # NOQA def bench_finite_range(): diff --git a/nibabel/pkg_info.py b/nibabel/pkg_info.py index 090cd24c24..bc58c3bdc9 100644 --- a/nibabel/pkg_info.py +++ b/nibabel/pkg_info.py @@ -4,7 +4,7 @@ try: from ConfigParser import RawConfigParser as ConfigParser except ImportError: - from configparser import RawConfigParser as ConfigParser # python 3 + from configparser import RawConfigParser as ConfigParser # python 3 COMMIT_INFO_FNAME = 'COMMIT_INFO.txt'