Skip to content

Commit 3686e03

Browse files
committed
RF: Cache supported_np_types by class
1 parent e96ecf7 commit 3686e03

File tree

1 file changed

+36
-7
lines changed

1 file changed

+36
-7
lines changed

nibabel/spatialimages.py

Lines changed: 36 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,11 @@
143143
from .viewers import OrthoSlicer3D
144144
from .volumeutils import shape_zoom_affine
145145

146+
try:
147+
from functools import cache
148+
except ImportError: # PY38
149+
from functools import lru_cache as cache
150+
146151

147152
class HeaderDataError(Exception):
148153
"""Class to indicate error in getting or setting header data"""
@@ -268,22 +273,29 @@ def data_from_fileobj(self, fileobj):
268273
return np.ndarray(shape, dtype, data_bytes, order=self.data_layout)
269274

270275

271-
def supported_np_types(obj):
272-
"""Numpy data types that instance `obj` supports
276+
@cache
277+
def _supported_np_types(klass):
278+
"""Numpy data types that instances of ``klass`` support
273279
274280
Parameters
275281
----------
276-
obj : object
277-
Object implementing `get_data_dtype` and `set_data_dtype`. The object
282+
klass : class
283+
Class implementing `get_data_dtype` and `set_data_dtype` methods. The object
278284
should raise ``HeaderDataError`` for setting unsupported dtypes. The
279285
object will likely be a header or a :class:`SpatialImage`
280286
281287
Returns
282288
-------
283289
np_types : set
284-
set of numpy types that `obj` supports
290+
set of numpy types that ``klass`` instances support
285291
"""
286-
dt = obj.get_data_dtype()
292+
try:
293+
obj = klass()
294+
except TypeError as e:
295+
if hasattr(klass, 'header_class'):
296+
obj = klass.header_class()
297+
else:
298+
raise e
287299
supported = set()
288300
for np_type in set(np.sctypeDict.values()):
289301
try:
@@ -293,10 +305,27 @@ def supported_np_types(obj):
293305
# Did set work?
294306
if np.dtype(obj.get_data_dtype()) == np.dtype(np_type):
295307
supported.add(np_type)
296-
obj.set_data_dtype(dt)
297308
return supported
298309

299310

311+
def supported_np_types(obj):
312+
"""Numpy data types that instance `obj` supports
313+
314+
Parameters
315+
----------
316+
obj : object
317+
Object implementing `get_data_dtype` and `set_data_dtype`. The object
318+
should raise ``HeaderDataError`` for setting unsupported dtypes. The
319+
object will likely be a header or a :class:`SpatialImage`
320+
321+
Returns
322+
-------
323+
np_types : set
324+
set of numpy types that `obj` supports
325+
"""
326+
return _supported_np_types(obj.__class__)
327+
328+
300329
class ImageDataError(Exception):
301330
pass
302331

0 commit comments

Comments
 (0)