|
12 | 12 |
|
13 | 13 | import warnings
|
14 | 14 |
|
| 15 | +import pickle |
15 | 16 | from io import BytesIO
|
16 | 17 | from ..tmpdirs import InTemporaryDirectory
|
17 | 18 |
|
18 | 19 | import numpy as np
|
19 | 20 |
|
20 | 21 | from ..arrayproxy import ArrayProxy, is_proxy, reshape_dataobj
|
| 22 | +from ..openers import ImageOpener |
21 | 23 | from ..nifti1 import Nifti1Header
|
22 | 24 |
|
23 | 25 | from numpy.testing import assert_array_equal, assert_array_almost_equal
|
24 | 26 | from nose.tools import (assert_true, assert_false, assert_equal,
|
25 | 27 | assert_not_equal, assert_raises)
|
26 | 28 | from nibabel.testing import VIRAL_MEMMAP
|
| 29 | +import mock |
27 | 30 |
|
28 | 31 | from .test_fileslice import slicer_samples
|
29 | 32 |
|
@@ -327,3 +330,51 @@ def check_mmap(hdr, offset, proxy_class,
|
327 | 330 | # Check invalid values raise error
|
328 | 331 | assert_raises(ValueError, proxy_class, fname, hdr, mmap='rw')
|
329 | 332 | assert_raises(ValueError, proxy_class, fname, hdr, mmap='r+')
|
| 333 | + |
| 334 | + |
| 335 | +def test_keep_file_open(): |
| 336 | + # Test the behaviour of the keep_file_open __init__ flag. |
| 337 | + numopeners = [0] |
| 338 | + |
| 339 | + class CountingImageOpener(ImageOpener): |
| 340 | + |
| 341 | + def __init__(self, *args, **kwargs): |
| 342 | + |
| 343 | + super(CountingImageOpener, self).__init__(*args, **kwargs) |
| 344 | + numopeners[0] += 1 |
| 345 | + |
| 346 | + fname = 'testdata' |
| 347 | + dtype = np.float32 |
| 348 | + data = np.arange(1000, dtype=np.float32).reshape((10, 10, 10)) |
| 349 | + with InTemporaryDirectory(): |
| 350 | + with open(fname, 'wb') as fobj: |
| 351 | + fobj.write(data.tostring(order='F')) |
| 352 | + with mock.patch('nibabel.arrayproxy.ImageOpener', CountingImageOpener): |
| 353 | + proxy_no_kfp = ArrayProxy(fname, ((10, 10, 10), dtype)) |
| 354 | + proxy_kfp = ArrayProxy(fname, ((10, 10, 10), dtype), |
| 355 | + keep_file_open=True) |
| 356 | + voxels = np.random.randint(0, 10, (10, 3), dtype=np.uint32) |
| 357 | + for i in range(voxels.shape[0]): |
| 358 | + x , y, z = [int(c) for c in voxels[i, :]] |
| 359 | + assert proxy_no_kfp[x, y, z] == x * 100 + y * 10 + z |
| 360 | + assert numopeners[0] == i + 1 |
| 361 | + numopeners[0] = 0 |
| 362 | + for i in range(voxels.shape[0]): |
| 363 | + x , y, z = [int(c) for c in voxels[i, :]] |
| 364 | + assert proxy_kfp[x, y, z] == x * 100 + y * 10 + z |
| 365 | + assert numopeners[0] == 1 |
| 366 | + |
| 367 | + |
| 368 | +def test_pickle_lock(): |
| 369 | + # Test that ArrayProxy can be pickled, and that thread lock is created |
| 370 | + |
| 371 | + def islock(l): |
| 372 | + # isinstance doesn't work on threading.Lock? |
| 373 | + return hasattr(l, 'acquire') and hasattr(l, 'release') |
| 374 | + |
| 375 | + proxy = ArrayProxy('dummyfile', ((10, 10, 10), np.float32)) |
| 376 | + assert islock(proxy._lock) |
| 377 | + pickled = pickle.dumps(proxy) |
| 378 | + unpickled = pickle.loads(pickled) |
| 379 | + assert islock(unpickled._lock) |
| 380 | + assert proxy._lock is not unpickled._lock |
0 commit comments