diff --git a/nibabel/analyze.py b/nibabel/analyze.py index e69718171..34597319d 100644 --- a/nibabel/analyze.py +++ b/nibabel/analyze.py @@ -515,7 +515,9 @@ def data_to_fileobj(self, data, fileobj, rescale=True): data = np.asanyarray(data) shape = self.get_data_shape() if data.shape != shape: - raise HeaderDataError('Data should be shape (%s)' % ', '.join(str(s) for s in shape)) + raise HeaderDataError( + 'Data should be shape ({})'.format(', '.join(str(s) for s in shape)) + ) out_dtype = self.get_data_dtype() if rescale: try: diff --git a/nibabel/cmdline/dicomfs.py b/nibabel/cmdline/dicomfs.py index 552bb0931..afd994b15 100644 --- a/nibabel/cmdline/dicomfs.py +++ b/nibabel/cmdline/dicomfs.py @@ -193,9 +193,7 @@ def release(self, path, flags, fh): def get_opt_parser(): # use module docstring for help output p = OptionParser( - usage='{} [OPTIONS] '.format( - os.path.basename(sys.argv[0]) - ), + usage=f'{os.path.basename(sys.argv[0])} [OPTIONS] ', version='%prog ' + nib.__version__, ) diff --git a/nibabel/cmdline/diff.py b/nibabel/cmdline/diff.py index 1231a778f..36760f7eb 100755 --- a/nibabel/cmdline/diff.py +++ b/nibabel/cmdline/diff.py @@ -302,7 +302,7 @@ def display_diff(files, diff): for item in value: if isinstance(item, dict): - item_str = ', '.join('%s: %s' % i for i in item.items()) + item_str = ', '.join('{}: {}'.format(*i) for i in item.items()) elif item is None: item_str = '-' else: diff --git a/nibabel/cmdline/ls.py b/nibabel/cmdline/ls.py index ff41afbd0..f79c27f0c 100755 --- a/nibabel/cmdline/ls.py +++ b/nibabel/cmdline/ls.py @@ -112,7 +112,7 @@ def proc_file(f, opts): and (h.has_data_slope or h.has_data_intercept) and not h.get_slope_inter() in ((1.0, 0.0), (None, None)) ): - row += ['@l*%.3g+%.3g' % h.get_slope_inter()] + row += ['@l*{:.3g}+{:.3g}'.format(*h.get_slope_inter())] else: row += [''] diff --git a/nibabel/dft.py b/nibabel/dft.py index d9e335999..e63c9c479 100644 --- a/nibabel/dft.py +++ b/nibabel/dft.py @@ -231,7 +231,7 @@ def __getattribute__(self, name): WHERE storage_instance = ? ORDER BY directory, name""" c.execute(query, (self.uid,)) - val = ['%s/%s' % tuple(row) for row in c] + val = ['{}/{}'.format(*tuple(row)) for row in c] self.files = val return val diff --git a/nibabel/freesurfer/mghformat.py b/nibabel/freesurfer/mghformat.py index 533d23592..6efa67ffa 100644 --- a/nibabel/freesurfer/mghformat.py +++ b/nibabel/freesurfer/mghformat.py @@ -570,7 +570,9 @@ def _write_data(self, mghfile, data, header): """ shape = header.get_data_shape() if data.shape != shape: - raise HeaderDataError('Data should be shape (%s)' % ', '.join(str(s) for s in shape)) + raise HeaderDataError( + 'Data should be shape ({})'.format(', '.join(str(s) for s in shape)) + ) offset = header.get_data_offset() out_dtype = header.get_data_dtype() array_to_file(data, mghfile, out_dtype, offset) diff --git a/nibabel/gifti/gifti.py b/nibabel/gifti/gifti.py index 7c5c3c4fb..caee7c350 100644 --- a/nibabel/gifti/gifti.py +++ b/nibabel/gifti/gifti.py @@ -18,7 +18,7 @@ import sys import warnings from copy import copy -from typing import Type, cast +from typing import cast import numpy as np @@ -598,7 +598,7 @@ class GiftiImage(xml.XmlSerializable, SerializableImage): # The parser will in due course be a GiftiImageParser, but we can't set # that now, because it would result in a circular import. We set it after # the class has been defined, at the end of the class definition. - parser: Type[xml.XmlParser] + parser: type[xml.XmlParser] def __init__( self, diff --git a/nibabel/nifti1.py b/nibabel/nifti1.py index ecd94c10d..478894731 100644 --- a/nibabel/nifti1.py +++ b/nibabel/nifti1.py @@ -552,7 +552,7 @@ def get_sizeondisk(self): return np.sum([e.get_sizeondisk() for e in self]) def __repr__(self): - return 'Nifti1Extensions(%s)' % ', '.join(str(e) for e in self) + return 'Nifti1Extensions({})'.format(', '.join(str(e) for e in self)) def write_to(self, fileobj, byteswap): """Write header extensions to fileobj diff --git a/nibabel/spatialimages.py b/nibabel/spatialimages.py index 96f8115a2..f4d27791b 100644 --- a/nibabel/spatialimages.py +++ b/nibabel/spatialimages.py @@ -169,8 +169,8 @@ def set_data_dtype(self, dtype: npt.DTypeLike) -> None: ... @ty.runtime_checkable class SpatialProtocol(ty.Protocol): def get_data_dtype(self) -> np.dtype: ... - def get_data_shape(self) -> ty.Tuple[int, ...]: ... - def get_zooms(self) -> ty.Tuple[float, ...]: ... + def get_data_shape(self) -> tuple[int, ...]: ... + def get_zooms(self) -> tuple[float, ...]: ... class HeaderDataError(Exception): diff --git a/nibabel/tests/test_data.py b/nibabel/tests/test_data.py index 5697752ea..511fa7f85 100644 --- a/nibabel/tests/test_data.py +++ b/nibabel/tests/test_data.py @@ -160,7 +160,7 @@ def test_data_path(with_nimd_env): tmpfile = pjoin(tmpdir, 'another_example.ini') with open(tmpfile, 'w') as fobj: fobj.write('[DATA]\n') - fobj.write('path = %s\n' % '/path/two') + fobj.write('path = {}\n'.format('/path/two')) assert get_data_path() == tst_list + ['/path/two'] + old_pth diff --git a/nibabel/tests/test_nifti1.py b/nibabel/tests/test_nifti1.py index 5ee4fb3c1..5a0495858 100644 --- a/nibabel/tests/test_nifti1.py +++ b/nibabel/tests/test_nifti1.py @@ -538,7 +538,7 @@ def test_slice_times(self): hdr.set_slice_duration(0.1) # We need a function to print out the Nones and floating point # values in a predictable way, for the tests below. - _stringer = lambda val: val is not None and '%2.1f' % val or None + _stringer = lambda val: val is not None and f'{val:2.1f}' or None _print_me = lambda s: list(map(_stringer, s)) # The following examples are from the nifti1.h documentation. hdr['slice_code'] = slice_order_codes['sequential increasing'] diff --git a/pyproject.toml b/pyproject.toml index 047b6154d..ead2782b2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -120,6 +120,7 @@ select = [ "F", "I", "Q", + "UP", ] ignore = [ "B006", # TODO: enable