Skip to content

Commit b7c179c

Browse files
committed
RF: Change ArrayProxy.order class var to _default_order, deprecate order
1 parent 34eda08 commit b7c179c

File tree

2 files changed

+55
-3
lines changed

2 files changed

+55
-3
lines changed

nibabel/arrayproxy.py

+16-3
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
"""
2828
from contextlib import contextmanager
2929
from threading import RLock
30+
import warnings
3031

3132
import numpy as np
3233

@@ -83,7 +84,7 @@ class ArrayProxy:
8384
See :mod:`nibabel.minc1`, :mod:`nibabel.ecat` and :mod:`nibabel.parrec` for
8485
examples.
8586
"""
86-
order = 'F'
87+
_default_order = 'F'
8788

8889
def __init__(self, file_like, spec, *, mmap=True, order=None, keep_file_open=None):
8990
"""Initialize array proxy instance
@@ -147,13 +148,25 @@ def __init__(self, file_like, spec, *, mmap=True, order=None, keep_file_open=Non
147148
else:
148149
raise TypeError('spec must be tuple of length 2-5 or header object')
149150

151+
# Warn downstream users that the class variable order is going away
152+
if hasattr(self.__class__, 'order'):
153+
warnings.warn(f'Class {self.__class__} has an `order` class variable. '
154+
'ArrayProxy subclasses should rename this variable to `_default_order` '
155+
'to avoid conflict with instance variables.\n'
156+
'* deprecated in version: 5.0\n'
157+
'* will raise error in version: 7.0\n',
158+
DeprecationWarning, stacklevel=2)
159+
# Override _default_order with order, to follow intent of subclasser
160+
self._default_order = self.order
161+
150162
# Copies of values needed to read array
151163
self._shape, self._dtype, self._offset, self._slope, self._inter = par
152164
# Permit any specifier that can be interpreted as a numpy dtype
153165
self._dtype = np.dtype(self._dtype)
154166
self._mmap = mmap
155-
if order is not None:
156-
self.order = order
167+
if order is None:
168+
order = self._default_order
169+
self.order = order
157170
# Flags to keep track of whether a single ImageOpener is created, and
158171
# whether a single underlying file handle is created.
159172
self._keep_file_open, self._persist_opener = \

nibabel/tests/test_arrayproxy.py

+39
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,16 @@
1515

1616
import pickle
1717
from io import BytesIO
18+
from packaging.version import Version
1819
from ..tmpdirs import InTemporaryDirectory
1920

2021
import numpy as np
2122

23+
from .. import __version__
2224
from ..arrayproxy import (ArrayProxy, is_proxy, reshape_dataobj, get_obj_dtype)
2325
from ..openers import ImageOpener
2426
from ..nifti1 import Nifti1Header
27+
from ..deprecator import ExpiredDeprecationError
2528

2629
from unittest import mock
2730

@@ -57,6 +60,10 @@ def copy(self):
5760

5861
class CArrayProxy(ArrayProxy):
5962
# C array memory layout
63+
_default_order = 'C'
64+
65+
66+
class DeprecatedCArrayProxy(ArrayProxy):
6067
order = 'C'
6168

6269

@@ -203,6 +210,38 @@ def test_order_override(order):
203210
assert_array_equal(arr[sliceobj], prox[sliceobj])
204211

205212

213+
def test_deprecated_order_classvar():
214+
shape = (15, 16, 17)
215+
arr = np.arange(np.prod(shape)).reshape(shape)
216+
fobj = BytesIO()
217+
fobj.write(arr.tobytes(order='C'))
218+
sliceobj = (None, slice(None), 1, -1)
219+
220+
# We don't really care about the original order, just that the behavior
221+
# of the deprecated mode matches the new behavior
222+
fprox = ArrayProxy(fobj, (shape, arr.dtype), order='F')
223+
cprox = ArrayProxy(fobj, (shape, arr.dtype), order='C')
224+
225+
# Start raising errors when we crank the dev version
226+
if Version(__version__) >= Version('7.0.0.dev0'):
227+
cm = pytest.raises(ExpiredDeprecationError)
228+
else:
229+
cm = pytest.deprecated_call()
230+
231+
with cm:
232+
prox = DeprecatedCArrayProxy(fobj, (shape, arr.dtype))
233+
assert prox.order == 'C'
234+
assert_array_equal(prox[sliceobj], cprox[sliceobj])
235+
with cm:
236+
prox = DeprecatedCArrayProxy(fobj, (shape, arr.dtype), order='C')
237+
assert prox.order == 'C'
238+
assert_array_equal(prox[sliceobj], cprox[sliceobj])
239+
with cm:
240+
prox = DeprecatedCArrayProxy(fobj, (shape, arr.dtype), order='F')
241+
assert prox.order == 'F'
242+
assert_array_equal(prox[sliceobj], fprox[sliceobj])
243+
244+
206245
def test_is_proxy():
207246
# Test is_proxy function
208247
hdr = FunkyHeader((2, 3, 4))

0 commit comments

Comments
 (0)