From f0d32a01deaa28d649d6baca68a770f648aceef8 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 18 Sep 2025 16:48:04 -0400 Subject: [PATCH 1/2] sty: Apply ruff fix for looped file.write file.writelines() does not add newlines. I have also checked the source code and it iterates over whatever is passed, so there should be no impact on memory usage. --- nibabel/cmdline/parrec2nii.py | 9 +++------ nibabel/volumeutils.py | 3 +-- pyproject.toml | 1 - 3 files changed, 4 insertions(+), 9 deletions(-) diff --git a/nibabel/cmdline/parrec2nii.py b/nibabel/cmdline/parrec2nii.py index 0ae6b3fb4..a64d0fa1c 100644 --- a/nibabel/cmdline/parrec2nii.py +++ b/nibabel/cmdline/parrec2nii.py @@ -358,8 +358,7 @@ def proc_file(infile, opts): ) with open(basefilename + '.bvals', 'w') as fid: # np.savetxt could do this, but it's just a loop anyway - for val in bvals: - fid.write(f'{val} ') + fid.writelines(f'{val} ' for val in bvals) fid.write('\n') else: verbose('Writing .bvals and .bvecs files') @@ -369,13 +368,11 @@ def proc_file(infile, opts): bvecs = apply_affine(bv_reorient, bvecs) with open(basefilename + '.bvals', 'w') as fid: # np.savetxt could do this, but it's just a loop anyway - for val in bvals: - fid.write(f'{val} ') + fid.writelines(f'{val} ' for val in bvals) fid.write('\n') with open(basefilename + '.bvecs', 'w') as fid: for row in bvecs.T: - for val in row: - fid.write(f'{val} ') + fid.writelines(f'{val} ' for val in row) fid.write('\n') # export data labels varying along the 4th dimensions if requested diff --git a/nibabel/volumeutils.py b/nibabel/volumeutils.py index 41bff7275..24b3b935e 100644 --- a/nibabel/volumeutils.py +++ b/nibabel/volumeutils.py @@ -830,8 +830,7 @@ def write_zeros(fileobj: io.IOBase, count: int, block_size: int = 8194) -> None: nblocks = int(count // block_size) rem = count % block_size blk = b'\x00' * block_size - for bno in range(nblocks): - fileobj.write(blk) + fileobj.writelines(blk for bno in range(nblocks)) fileobj.write(b'\x00' * rem) diff --git a/pyproject.toml b/pyproject.toml index c66902aef..5cd8fe9ba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -164,7 +164,6 @@ ignore = [ "RUF012", # TODO: enable "RUF015", "RUF017", # TODO: enable - "UP038", # https://github.com/astral-sh/ruff/issues/7871 # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules "W191", "E111", From f3ec45a59437f20f30fb063cc3aead0eba0f0f73 Mon Sep 17 00:00:00 2001 From: "Christopher J. Markiewicz" Date: Thu, 18 Sep 2025 21:47:21 -0400 Subject: [PATCH 2/2] fix: Add writelines proxy method --- nibabel/openers.py | 5 ++++- nibabel/volumeutils.py | 4 ++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/nibabel/openers.py b/nibabel/openers.py index 2d95d4813..3ad9b6c22 100644 --- a/nibabel/openers.py +++ b/nibabel/openers.py @@ -21,7 +21,7 @@ if ty.TYPE_CHECKING: from types import TracebackType - from _typeshed import WriteableBuffer + from _typeshed import ReadableBuffer, WriteableBuffer from ._typing import Self @@ -231,6 +231,9 @@ def readinto(self, buffer: WriteableBuffer, /) -> int | None: def write(self, b: bytes, /) -> int | None: return self.fobj.write(b) + def writelines(self, lines: ty.Iterable[ReadableBuffer], /) -> None: + self.fobj.writelines(lines) + def seek(self, pos: int, whence: int = 0, /) -> int: return self.fobj.seek(pos, whence) diff --git a/nibabel/volumeutils.py b/nibabel/volumeutils.py index 24b3b935e..10fb60ed0 100644 --- a/nibabel/volumeutils.py +++ b/nibabel/volumeutils.py @@ -1364,7 +1364,7 @@ def shape_zoom_affine( return aff -def rec2dict(rec: np.ndarray) -> dict[str, np.generic | np.ndarray]: +def rec2dict(rec: np.record) -> dict[str, np.generic | np.ndarray]: """Convert recarray to dictionary Also converts scalar values to scalars @@ -1387,7 +1387,7 @@ def rec2dict(rec: np.ndarray) -> dict[str, np.generic | np.ndarray]: True """ dct = {} - for key in rec.dtype.fields: + for key in rec.dtype.fields or (): val = rec[key] try: val = val.item()