15
15
16
16
import pickle
17
17
from io import BytesIO
18
+ from packaging .version import Version
18
19
from ..tmpdirs import InTemporaryDirectory
19
20
20
21
import numpy as np
21
22
23
+ from .. import __version__
22
24
from ..arrayproxy import (ArrayProxy , is_proxy , reshape_dataobj , get_obj_dtype )
23
25
from ..openers import ImageOpener
24
26
from ..nifti1 import Nifti1Header
27
+ from ..deprecator import ExpiredDeprecationError
25
28
26
29
from unittest import mock
27
30
@@ -57,6 +60,11 @@ def copy(self):
57
60
58
61
class CArrayProxy (ArrayProxy ):
59
62
# C array memory layout
63
+ _default_order = 'C'
64
+
65
+
66
+ class DeprecatedCArrayProxy (ArrayProxy ):
67
+ # Used in test_deprecated_order_classvar. Remove when that test is removed (8.0)
60
68
order = 'C'
61
69
62
70
@@ -81,6 +89,9 @@ def test_init():
81
89
assert ap .shape != shape
82
90
# Data stays the same, also
83
91
assert_array_equal (np .asarray (ap ), arr )
92
+ # You wouldn't do this, but order=None explicitly requests the default order
93
+ ap2 = ArrayProxy (bio , FunkyHeader (arr .shape ), order = None )
94
+ assert_array_equal (np .asarray (ap2 ), arr )
84
95
# C order also possible
85
96
bio = BytesIO ()
86
97
bio .seek (16 )
@@ -90,6 +101,8 @@ def test_init():
90
101
# Illegal init
91
102
with pytest .raises (TypeError ):
92
103
ArrayProxy (bio , object ())
104
+ with pytest .raises (ValueError ):
105
+ ArrayProxy (bio , hdr , order = 'badval' )
93
106
94
107
95
108
def test_tuplespec ():
@@ -154,33 +167,87 @@ def test_nifti1_init():
154
167
assert_array_equal (np .asarray (ap ), arr * 2.0 + 10 )
155
168
156
169
157
- def test_proxy_slicing ():
158
- shapes = (15 , 16 , 17 )
159
- for n_dim in range (1 , len (shapes ) + 1 ):
160
- shape = shapes [:n_dim ]
161
- arr = np .arange (np .prod (shape )).reshape (shape )
162
- for offset in (0 , 20 ):
163
- hdr = Nifti1Header ()
164
- hdr .set_data_offset (offset )
165
- hdr .set_data_dtype (arr .dtype )
166
- hdr .set_data_shape (shape )
167
- for order , klass in ('F' , ArrayProxy ), ('C' , CArrayProxy ):
168
- fobj = BytesIO ()
169
- fobj .write (b'\0 ' * offset )
170
- fobj .write (arr .tobytes (order = order ))
171
- prox = klass (fobj , hdr )
172
- for sliceobj in slicer_samples (shape ):
173
- assert_array_equal (arr [sliceobj ], prox [sliceobj ])
174
- # Check slicing works with scaling
170
+ @pytest .mark .parametrize ("n_dim" , (1 , 2 , 3 ))
171
+ @pytest .mark .parametrize ("offset" , (0 , 20 ))
172
+ def test_proxy_slicing (n_dim , offset ):
173
+ shape = (15 , 16 , 17 )[:n_dim ]
174
+ arr = np .arange (np .prod (shape )).reshape (shape )
175
+ hdr = Nifti1Header ()
176
+ hdr .set_data_offset (offset )
177
+ hdr .set_data_dtype (arr .dtype )
178
+ hdr .set_data_shape (shape )
179
+ for order , klass in ('F' , ArrayProxy ), ('C' , CArrayProxy ):
180
+ fobj = BytesIO ()
181
+ fobj .write (b'\0 ' * offset )
182
+ fobj .write (arr .tobytes (order = order ))
183
+ prox = klass (fobj , hdr )
184
+ assert prox .order == order
185
+ for sliceobj in slicer_samples (shape ):
186
+ assert_array_equal (arr [sliceobj ], prox [sliceobj ])
187
+
188
+
189
+ def test_proxy_slicing_with_scaling ():
190
+ shape = (15 , 16 , 17 )
191
+ offset = 20
192
+ arr = np .arange (np .prod (shape )).reshape (shape )
193
+ hdr = Nifti1Header ()
194
+ hdr .set_data_offset (offset )
195
+ hdr .set_data_dtype (arr .dtype )
196
+ hdr .set_data_shape (shape )
175
197
hdr .set_slope_inter (2.0 , 1.0 )
176
198
fobj = BytesIO ()
177
- fobj .write (b' \0 ' * offset )
199
+ fobj .write (bytes ( offset ) )
178
200
fobj .write (arr .tobytes (order = 'F' ))
179
201
prox = ArrayProxy (fobj , hdr )
180
202
sliceobj = (None , slice (None ), 1 , - 1 )
181
203
assert_array_equal (arr [sliceobj ] * 2.0 + 1.0 , prox [sliceobj ])
182
204
183
205
206
+ @pytest .mark .parametrize ("order" , ("C" , "F" ))
207
+ def test_order_override (order ):
208
+ shape = (15 , 16 , 17 )
209
+ arr = np .arange (np .prod (shape )).reshape (shape )
210
+ fobj = BytesIO ()
211
+ fobj .write (arr .tobytes (order = order ))
212
+ for klass in (ArrayProxy , CArrayProxy ):
213
+ prox = klass (fobj , (shape , arr .dtype ), order = order )
214
+ assert prox .order == order
215
+ sliceobj = (None , slice (None ), 1 , - 1 )
216
+ assert_array_equal (arr [sliceobj ], prox [sliceobj ])
217
+
218
+
219
+ def test_deprecated_order_classvar ():
220
+ shape = (15 , 16 , 17 )
221
+ arr = np .arange (np .prod (shape )).reshape (shape )
222
+ fobj = BytesIO ()
223
+ fobj .write (arr .tobytes (order = 'C' ))
224
+ sliceobj = (None , slice (None ), 1 , - 1 )
225
+
226
+ # We don't really care about the original order, just that the behavior
227
+ # of the deprecated mode matches the new behavior
228
+ fprox = ArrayProxy (fobj , (shape , arr .dtype ), order = 'F' )
229
+ cprox = ArrayProxy (fobj , (shape , arr .dtype ), order = 'C' )
230
+
231
+ # Start raising errors when we crank the dev version
232
+ if Version (__version__ ) >= Version ('7.0.0.dev0' ):
233
+ cm = pytest .raises (ExpiredDeprecationError )
234
+ else :
235
+ cm = pytest .deprecated_call ()
236
+
237
+ with cm :
238
+ prox = DeprecatedCArrayProxy (fobj , (shape , arr .dtype ))
239
+ assert prox .order == 'C'
240
+ assert_array_equal (prox [sliceobj ], cprox [sliceobj ])
241
+ with cm :
242
+ prox = DeprecatedCArrayProxy (fobj , (shape , arr .dtype ), order = 'C' )
243
+ assert prox .order == 'C'
244
+ assert_array_equal (prox [sliceobj ], cprox [sliceobj ])
245
+ with cm :
246
+ prox = DeprecatedCArrayProxy (fobj , (shape , arr .dtype ), order = 'F' )
247
+ assert prox .order == 'F'
248
+ assert_array_equal (prox [sliceobj ], fprox [sliceobj ])
249
+
250
+
184
251
def test_is_proxy ():
185
252
# Test is_proxy function
186
253
hdr = FunkyHeader ((2 , 3 , 4 ))
0 commit comments