diff --git a/docs/conf.py b/docs/conf.py index 754c88545..b5d1c036b 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ sys.path.append(os.path.abspath('sphinxext')) sys.path.insert(0, os.path.abspath('../wrapper')) -from github_link import make_linkcode_resolve # noqa: E402 +from github_link import make_linkcode_resolve # -- General configuration ------------------------------------------------ diff --git a/fmriprep/_warnings.py b/fmriprep/_warnings.py index 151b6ca0c..a744a8e9e 100644 --- a/fmriprep/_warnings.py +++ b/fmriprep/_warnings.py @@ -35,7 +35,7 @@ def _warn(message, category=None, stacklevel=1, source=None): category = type(category).__name__ category = category.replace('type', 'WARNING') - logging.getLogger('py.warnings').warning(f'{category or "WARNING"}: {message}') + logging.getLogger('py.warnings').warning('%s: %s', category or 'WARNING', message) def _showwarning(message, category, filename, lineno, file=None, line=None): diff --git a/fmriprep/cli/tests/test_parser.py b/fmriprep/cli/tests/test_parser.py index d68ea2bbd..c4044d74a 100644 --- a/fmriprep/cli/tests/test_parser.py +++ b/fmriprep/cli/tests/test_parser.py @@ -254,7 +254,7 @@ def test_derivatives(tmp_path): # Providing --derivatives with names should use them temp_args = args + [ '--derivatives', - f'anat={str(bids_path / "derivatives/smriprep")}', + f'anat={bids_path / "derivatives/smriprep"}', ] opts = parser.parse_args(temp_args) assert opts.derivatives == {'anat': bids_path / 'derivatives/smriprep'} diff --git a/fmriprep/cli/version.py b/fmriprep/cli/version.py index 0b6ae837c..1717cb808 100644 --- a/fmriprep/cli/version.py +++ b/fmriprep/cli/version.py @@ -72,7 +72,7 @@ def check_latest(): versions = [Version(rel) for rel in response.json()['releases'].keys()] versions = [rel for rel in versions if not rel.is_prerelease] if versions: - latest = sorted(versions)[-1] + latest = max(versions) else: latest = None diff --git a/fmriprep/config.py b/fmriprep/config.py index 3ecd4de67..d299e044a 100644 --- a/fmriprep/config.py +++ b/fmriprep/config.py @@ -530,8 +530,7 @@ def _process_value(value): 'raw': cls.bids_dir, 'templateflow': Path(TF_LAYOUT.root), } - for deriv_name, deriv_path in cls.derivatives.items(): - dataset_links[deriv_name] = deriv_path + dataset_links.update(cls.derivatives) cls.dataset_links = dataset_links if 'all' in cls.debug: @@ -775,9 +774,7 @@ def get(flat=False): return settings return { - '.'.join((section, k)): v - for section, configs in settings.items() - for k, v in configs.items() + f'{section}.{k}': v for section, configs in settings.items() for k, v in configs.items() } diff --git a/fmriprep/interfaces/confounds.py b/fmriprep/interfaces/confounds.py index 7be150bd9..106ce8082 100644 --- a/fmriprep/interfaces/confounds.py +++ b/fmriprep/interfaces/confounds.py @@ -429,8 +429,8 @@ def less_breakable(a_string): # Taken from https://stackoverflow.com/questions/1175208/ # If we end up using it more than just here, probably worth pulling in a well-tested package def camel_to_snake(name): - s1 = re.sub('(.)([A-Z][a-z]+)', r'\1_\2', name) - return re.sub('([a-z0-9])([A-Z])', r'\1_\2', s1).lower() + s1 = re.sub(r'(.)([A-Z][a-z]+)', r'\1_\2', name) + return re.sub(r'([a-z0-9])([A-Z])', r'\1_\2', s1).lower() def _adjust_indices(left_df, right_df): # This forces missing values to appear at the beginning of the DataFrame diff --git a/fmriprep/interfaces/conftest.py b/fmriprep/interfaces/conftest.py index a8511d04b..46ea82b54 100644 --- a/fmriprep/interfaces/conftest.py +++ b/fmriprep/interfaces/conftest.py @@ -9,7 +9,7 @@ import os from contextlib import contextmanager - @contextmanager # type: ignore + @contextmanager def _chdir(path): cwd = os.getcwd() os.chdir(path) diff --git a/fmriprep/interfaces/reports.py b/fmriprep/interfaces/reports.py index 6d199ccee..0c56f5845 100644 --- a/fmriprep/interfaces/reports.py +++ b/fmriprep/interfaces/reports.py @@ -131,12 +131,12 @@ def _run_interface(self, runtime): def _generate_segment(self): BIDS_NAME = re.compile( r'^(.*\/)?' - '(?Psub-[a-zA-Z0-9]+)' - '(_(?Pses-[a-zA-Z0-9]+))?' - '(_(?Ptask-[a-zA-Z0-9]+))?' - '(_(?Pacq-[a-zA-Z0-9]+))?' - '(_(?Prec-[a-zA-Z0-9]+))?' - '(_(?Prun-[a-zA-Z0-9]+))?' + r'(?Psub-[a-zA-Z0-9]+)' + r'(_(?Pses-[a-zA-Z0-9]+))?' + r'(_(?Ptask-[a-zA-Z0-9]+))?' + r'(_(?Pacq-[a-zA-Z0-9]+))?' + r'(_(?Prec-[a-zA-Z0-9]+))?' + r'(_(?Prun-[a-zA-Z0-9]+))?' ) if not isdefined(self.inputs.subjects_dir): @@ -254,20 +254,15 @@ def _generate_segment(self): pedir = get_world_pedir(self.inputs.orientation, self.inputs.pe_direction) - dummy_scan_tmp = '{n_dum}' if self.inputs.dummy_scans == self.inputs.algo_dummy_scans: - dummy_scan_msg = ' '.join( - [dummy_scan_tmp, '(Confirmed: {n_alg} automatically detected)'] - ).format(n_dum=self.inputs.dummy_scans, n_alg=self.inputs.algo_dummy_scans) + dummy_scan_msg = f'{self.inputs.dummy_scans} (Confirmed: {self.inputs.algo_dummy_scans} automatically detected)' # the number of dummy scans was specified by the user and # it is not equal to the number detected by the algorithm elif self.inputs.dummy_scans is not None: - dummy_scan_msg = ' '.join( - [dummy_scan_tmp, '(Warning: {n_alg} automatically detected)'] - ).format(n_dum=self.inputs.dummy_scans, n_alg=self.inputs.algo_dummy_scans) + dummy_scan_msg = f'{self.inputs.dummy_scans} (Warning: {self.inputs.algo_dummy_scans} automatically detected)' # the number of dummy scans was not specified by the user else: - dummy_scan_msg = dummy_scan_tmp.format(n_dum=self.inputs.algo_dummy_scans) + dummy_scan_msg = f'{self.inputs.algo_dummy_scans}' multiecho = 'Single-echo EPI sequence.' n_echos = len(self.inputs.echo_idx) @@ -365,7 +360,8 @@ def get_world_pedir(ornt, pe_direction): if flip[not inv].startswith(axcode): return '-'.join(flip) LOGGER.warning( - 'Cannot determine world direction of phase encoding. ' - f'Orientation: {ornt}; PE dir: {pe_direction}' + 'Cannot determine world direction of phase encoding. Orientation: %s; PE dir: %s', + ornt, + pe_direction, ) return 'Could not be determined - assuming Anterior-Posterior' diff --git a/fmriprep/interfaces/workbench.py b/fmriprep/interfaces/workbench.py index e666830c1..925dc0caa 100644 --- a/fmriprep/interfaces/workbench.py +++ b/fmriprep/interfaces/workbench.py @@ -292,7 +292,7 @@ def _format_arg(self, opt, spec, val): if opt == 'valid_roi_out' and val: # generate a filename and add it to argstr roi_out = self._gen_filename(self.inputs.in_file, suffix='_roi') - iflogger.info('Setting roi output file as', roi_out) + iflogger.info('Setting roi output file as %s', roi_out) spec.argstr += ' ' + roi_out return super()._format_arg(opt, spec, val) diff --git a/fmriprep/utils/telemetry.py b/fmriprep/utils/telemetry.py index 33116f760..7226025b7 100644 --- a/fmriprep/utils/telemetry.py +++ b/fmriprep/utils/telemetry.py @@ -156,7 +156,7 @@ def before_send(event, hints): return None if msg.startswith('Saving crash info to '): return None - if re.match('Node .+ failed to run on host .+', msg): + if re.match(r'Node .+ failed to run on host .+', msg): return None if 'breadcrumbs' in event and isinstance(event['breadcrumbs'], list): diff --git a/fmriprep/workflows/base.py b/fmriprep/workflows/base.py index c8a2fb8a7..f8b007b2d 100644 --- a/fmriprep/workflows/base.py +++ b/fmriprep/workflows/base.py @@ -792,8 +792,8 @@ def map_fieldmap_estimation( fmap_estimators = find_estimators( layout=layout, subject=subject_id, - fmapless=bool(use_syn) or ignore_fieldmaps and force_syn, - force_fmapless=force_syn or ignore_fieldmaps and use_syn, + fmapless=bool(use_syn) or (ignore_fieldmaps and force_syn), + force_fmapless=force_syn or (ignore_fieldmaps and use_syn), bids_filters=filters, ) diff --git a/fmriprep/workflows/bold/base.py b/fmriprep/workflows/bold/base.py index 0130ebf65..1af997ef2 100644 --- a/fmriprep/workflows/bold/base.py +++ b/fmriprep/workflows/bold/base.py @@ -55,7 +55,7 @@ def init_bold_wf( *, bold_series: list[str], - precomputed: dict = None, + precomputed: dict | None = None, fieldmap_id: str | None = None, ) -> pe.Workflow: """ diff --git a/fmriprep/workflows/bold/fit.py b/fmriprep/workflows/bold/fit.py index a585d5646..27783ec6f 100644 --- a/fmriprep/workflows/bold/fit.py +++ b/fmriprep/workflows/bold/fit.py @@ -95,7 +95,7 @@ def get_sbrefs( def init_bold_fit_wf( *, bold_series: list[str], - precomputed: dict = None, + precomputed: dict | None = None, fieldmap_id: str | None = None, omp_nthreads: int = 1, name: str = 'bold_fit_wf', @@ -231,7 +231,7 @@ def init_bold_fit_wf( metadata = layout.get_metadata(bold_file) orientation = ''.join(nb.aff2axcodes(nb.load(bold_file).affine)) - bold_tlen, mem_gb = estimate_bold_mem_usage(bold_file) + _bold_tlen, mem_gb = estimate_bold_mem_usage(bold_file) # Boolean used to update workflow self-descriptions multiecho = len(bold_series) > 1 @@ -746,7 +746,7 @@ def init_bold_native_wf( bold_file = bold_series[0] metadata = all_metadata[0] - bold_tlen, mem_gb = estimate_bold_mem_usage(bold_file) + _bold_tlen, mem_gb = estimate_bold_mem_usage(bold_file) if multiecho: shapes = [nb.load(echo).shape for echo in bold_series] @@ -794,7 +794,7 @@ def init_bold_native_wf( # Multiecho outputs 'bold_echos', # Individual corrected echos 't2star_map', # T2* map - ], # fmt:skip + ], ), name='outputnode', ) diff --git a/fmriprep/workflows/bold/stc.py b/fmriprep/workflows/bold/stc.py index 65e9e6fe9..bae48f704 100644 --- a/fmriprep/workflows/bold/stc.py +++ b/fmriprep/workflows/bold/stc.py @@ -115,7 +115,7 @@ def init_bold_stc_wf( inputnode = pe.Node(niu.IdentityInterface(fields=['bold_file', 'skip_vols']), name='inputnode') outputnode = pe.Node(niu.IdentityInterface(fields=['stc_file']), name='outputnode') - LOGGER.log(25, f'BOLD series will be slice-timing corrected to an offset of {tzero:.3g}s.') + LOGGER.log(25, 'BOLD series will be slice-timing corrected to an offset of %.3gs.', tzero) # It would be good to fingerprint memory use of afni.TShift slice_timing_correction = pe.Node( diff --git a/fmriprep/workflows/tests/test_base.py b/fmriprep/workflows/tests/test_base.py index 1af32eb18..2e58fc3e5 100644 --- a/fmriprep/workflows/tests/test_base.py +++ b/fmriprep/workflows/tests/test_base.py @@ -117,8 +117,8 @@ def _make_params( use_syn_sdc: str | bool = False, force_syn: bool = False, freesurfer: bool = True, - ignore: list[str] = None, - bids_filters: dict = None, + ignore: list[str] | None = None, + bids_filters: dict | None = None, ): if ignore is None: ignore = [] diff --git a/pyproject.toml b/pyproject.toml index 89e1f8e4e..93fcdff97 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -154,9 +154,6 @@ line-length = 99 [tool.ruff.lint] extend-select = [ - "F", - "E", - "W", "I", "UP", "YTT", @@ -164,8 +161,8 @@ extend-select = [ "BLE", "B", "A", - # "CPY", "C4", + # "CPY", "DTZ", "T10", # "EM", @@ -173,12 +170,33 @@ extend-select = [ "FA", "ISC", "ICN", + "LOG", + "G", + "PIE", + "PYI", "PT", "Q", + # "SIM", + # "TID", + "FLY", + # "PD", + "PERF", + "W", + "PGH", + "PLC", + "PLE", + "PLW", + "FURB", + "RUF", ] ignore = [ "S311", # We are not using random for cryptographic purposes "S603", + "PIE790", + "PERF203", + "PLW2901", + "RUF005", + "RUF012", ] [tool.ruff.lint.flake8-quotes]