Skip to content

Commit 4127cfc

Browse files
committed
RF/TEST: Move h5py compatibility hacks into a private module
1 parent 0032049 commit 4127cfc

File tree

8 files changed

+63
-17
lines changed

8 files changed

+63
-17
lines changed

nibabel/_h5py_compat.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import sys
2+
import os
3+
from .optpkg import optional_package
4+
5+
# PY35: A bug affected Windows installations of h5py in Python3 versions <3.6
6+
# due to random dictionary ordering, causing float64 data arrays to sometimes be
7+
# loaded as longdouble (also 64 bit on Windows). This caused stochastic failures
8+
# to correctly handle data caches, and possibly other subtle bugs we never
9+
# caught. This was fixed in h5py 2.10.
10+
# Please see https://github.com/nipy/nibabel/issues/665 for details.
11+
min_h5py = '2.10' if os.name == 'nt' and (3,) <= sys.version_info < (3, 6) else None
12+
h5py, have_h5py, setup_module = optional_package('h5py', min_version=min_h5py)

nibabel/minc2.py

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,10 @@
2525
2626
mincstats my_funny.mnc
2727
"""
28-
import sys
29-
import os
3028
import numpy as np
3129

3230
from .keywordonly import kw_only_meth
33-
from .optpkg import optional_package
34-
35-
# PY35: A bug affected Windows installations of h5py in Python3 versions <3.6
36-
# due to random dictionary ordering, causing float64 data arrays to sometimes be
37-
# loaded as longdouble (also 64 bit on Windows). This caused stochastic failures
38-
# to correctly handle data caches, and possibly other subtle bugs we never
39-
# caught. This was fixed in h5py 2.10.
40-
# Please see https://github.com/nipy/nibabel/issues/665 for details.
41-
min_h5py = '2.10' if os.name == 'nt' and (3,) <= sys.version_info < (3, 6) else None
42-
h5py, have_h5py, setup_module = optional_package('h5py', min_version=min_h5py)
31+
from ._h5py_compat import h5py
4332

4433
from .minc1 import Minc1File, MincHeader, Minc1Image, MincError
4534

nibabel/tests/test_h5py_compat.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
"""
2+
These tests are almost certainly overkill, but serve to verify that
3+
the behavior of _h5py_compat is pass-through in all but a small set of
4+
well-defined cases
5+
"""
6+
import sys
7+
import os
8+
from distutils.version import LooseVersion
9+
import numpy as np
10+
11+
from ..optpkg import optional_package
12+
from .. import _h5py_compat as compat
13+
from ..testing import assert_equal, assert_true, assert_false, assert_not_equal
14+
15+
h5py, have_h5py, _ = optional_package('h5py')
16+
17+
18+
def test_optpkg_equivalence():
19+
# No effect on Linux/OSX
20+
if os.name == 'posix':
21+
assert_equal(have_h5py, compat.have_h5py)
22+
# No effect on Python 2.7 or 3.6+
23+
if sys.version_info >= (3, 6) or sys.version_info < (3,):
24+
assert_equal(have_h5py, compat.have_h5py)
25+
# Available in a strict subset of cases
26+
if not have_h5py:
27+
assert_false(compat.have_h5py)
28+
# Available when version is high enough
29+
elif LooseVersion(h5py.__version__) >= '2.10':
30+
assert_true(compat.have_h5py)
31+
32+
33+
def test_disabled_h5py_cases():
34+
# On mismatch
35+
if have_h5py and not compat.have_h5py:
36+
# Recapitulate min_h5py conditions from _h5py_compat
37+
assert_equal(os.name, 'nt')
38+
assert_true((3,) <= sys.version_info < (3, 6))
39+
assert_true(LooseVersion(h5py.__version__) < '2.10')
40+
# Verify that the root cause is present
41+
# If any tests fail, they will likely be these, so they may be
42+
# ill-advised...
43+
assert_equal(str(np.longdouble), str(np.float64))
44+
assert_not_equal(np.longdouble, np.float64)

nibabel/tests/test_image_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
from ..optpkg import optional_package
3636
_, have_scipy, _ = optional_package('scipy')
37-
from ..minc2 import have_h5py
37+
from .._h5py_compat import have_h5py
3838

3939
from .. import (AnalyzeImage, Spm99AnalyzeImage, Spm2AnalyzeImage,
4040
Nifti1Pair, Nifti1Image, Nifti2Pair, Nifti2Image,

nibabel/tests/test_imageclasses.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from nibabel.analyze import AnalyzeImage
1111
from nibabel.nifti1 import Nifti1Image
1212
from nibabel.nifti2 import Nifti2Image
13-
from ..minc2 import have_h5py
13+
from .._h5py_compat import have_h5py
1414

1515
from nibabel import imageclasses
1616
from nibabel.imageclasses import spatial_axes_first, class_map, ext_map

nibabel/tests/test_minc2.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,8 @@
1313
import numpy as np
1414

1515
from .. import minc2
16-
from ..minc2 import Minc2File, Minc2Image, h5py, have_h5py, setup_module
16+
from ..minc2 import Minc2File, Minc2Image
17+
from .._h5py_compat import h5py, have_h5py, setup_module
1718

1819
from nose.tools import (assert_true, assert_equal, assert_false, assert_raises)
1920

nibabel/tests/test_minc2_data.py

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

1616
import numpy as np
1717

18-
from ..minc2 import h5py, have_h5py, setup_module
18+
from .._h5py_compat import h5py, have_h5py, setup_module
1919

2020
from .nibabel_data import get_nibabel_data, needs_nibabel_data
2121
from .. import load as top_load, Nifti1Image

nibabel/tests/test_proxy_api.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
from .. import minc1
4747
from ..externals.netcdf import netcdf_file
4848
from .. import minc2
49-
from ..minc2 import h5py, have_h5py
49+
from .._h5py_compat import h5py, have_h5py
5050
from .. import ecat
5151
from .. import parrec
5252

0 commit comments

Comments
 (0)