Skip to content

Commit 46bf959

Browse files
committed
ENH: Black-list int/"int" dtypes, add clarifying comment
1 parent b0b7ab8 commit 46bf959

File tree

1 file changed

+52
-0
lines changed

1 file changed

+52
-0
lines changed

nibabel/nifti1.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -881,6 +881,51 @@ def set_data_shape(self, shape):
881881
shape = (-1, 1, 1) + shape[3:]
882882
super(Nifti1Header, self).set_data_shape(shape)
883883

884+
def set_data_dtype(self, datatype):
885+
""" Set numpy dtype for data from code or dtype or type
886+
887+
Using :py:class:`int` or ``"int"`` is disallowed, as these types
888+
will be interpreted as ``np.int64``, which is almost never desired.
889+
``np.int64`` is permitted for those intent on making poor choices.
890+
891+
Examples
892+
--------
893+
>>> hdr = Nifti1Header()
894+
>>> hdr.set_data_dtype(np.uint8)
895+
>>> hdr.get_data_dtype()
896+
dtype('uint8')
897+
>>> hdr.set_data_dtype(np.dtype(np.uint8))
898+
>>> hdr.get_data_dtype()
899+
dtype('uint8')
900+
>>> hdr.set_data_dtype('implausible') #doctest: +IGNORE_EXCEPTION_DETAIL
901+
Traceback (most recent call last):
902+
...
903+
HeaderDataError: data dtype "implausible" not recognized
904+
>>> hdr.set_data_dtype('none') #doctest: +IGNORE_EXCEPTION_DETAIL
905+
Traceback (most recent call last):
906+
...
907+
HeaderDataError: data dtype "none" known but not supported
908+
>>> hdr.set_data_dtype(np.void) #doctest: +IGNORE_EXCEPTION_DETAIL
909+
Traceback (most recent call last):
910+
...
911+
HeaderDataError: data dtype "<type 'numpy.void'>" known but not supported
912+
>>> hdr.set_data_dtype('int')
913+
Traceback (most recent call last):
914+
...
915+
ValueError: Invalid data type 'int'. Specify a sized integer, e.g., 'uint8' or numpy.int16.
916+
>>> hdr.set_data_dtype(int)
917+
Traceback (most recent call last):
918+
...
919+
ValueError: Invalid data type 'int'. Specify a sized integer, e.g., 'uint8' or numpy.int16.
920+
>>> hdr.set_data_dtype('int64')
921+
>>> hdr.get_data_dtype()
922+
dtype('int64')
923+
"""
924+
if not isinstance(datatype, np.dtype) and datatype in (int, "int"):
925+
raise ValueError(f"Invalid data type {datatype!r}. Specify a sized integer, "
926+
"e.g., 'uint8' or numpy.int16.")
927+
super().set_data_dtype(datatype)
928+
884929
def get_qform_quaternion(self):
885930
""" Compute quaternion from b, c, d of quaternion
886931
@@ -1755,6 +1800,13 @@ class Nifti1Pair(analyze.AnalyzeImage):
17551800

17561801
def __init__(self, dataobj, affine, header=None,
17571802
extra=None, file_map=None, dtype=None):
1803+
# Special carve-out for 64 bit integers
1804+
# See GitHub issues
1805+
# * https://github.com/nipy/nibabel/issues/1046
1806+
# * https://github.com/nipy/nibabel/issues/1089
1807+
# This only applies to NIfTI because the parent Analyze formats did
1808+
# not support 64-bit integer data, so `set_data_dtype(int64)` would
1809+
# already fail.
17581810
danger_dts = (np.dtype("int64"), np.dtype("uint64"))
17591811
if header is None and dtype is None and dataobj.dtype in danger_dts:
17601812
msg = (f"Image data has type {dataobj.dtype}, which may cause "

0 commit comments

Comments
 (0)