diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 837429d2f..18254a7a0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,7 +12,7 @@ repos: - id: check-toml - id: check-added-large-files - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.12.2 + rev: v0.12.7 hooks: - id: ruff-check args: [ --fix ] 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/cli/tests/test_parser.py b/fmriprep/cli/tests/test_parser.py index c44221d1f..e6cf4d49e 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 c9f6efd49..3beb1b75c 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: @@ -780,9 +779,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 6f7e850c7..a3dbf198d 100644 --- a/fmriprep/interfaces/conftest.py +++ b/fmriprep/interfaces/conftest.py @@ -10,7 +10,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 49ac59054..f46843efc 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): @@ -261,20 +261,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) 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 57b75772b..3b7fb0076 100644 --- a/fmriprep/workflows/base.py +++ b/fmriprep/workflows/base.py @@ -876,8 +876,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 bcd282d50..89aa49746 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, jacobian: bool = False, ) -> pe.Workflow: diff --git a/fmriprep/workflows/bold/fit.py b/fmriprep/workflows/bold/fit.py index 0a6536250..5013dfe1d 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, jacobian: bool = False, omp_nthreads: int = 1, @@ -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 @@ -793,7 +793,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] @@ -841,7 +841,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/tests/test_base.py b/fmriprep/workflows/tests/test_base.py index df96afdd1..c7a73528c 100644 --- a/fmriprep/workflows/tests/test_base.py +++ b/fmriprep/workflows/tests/test_base.py @@ -115,9 +115,9 @@ def _make_params( skull_strip_t1w: str = 'auto', use_syn_sdc: str | bool = False, freesurfer: bool = True, - ignore: list[str] = None, - force: list[str] = None, - bids_filters: dict = None, + ignore: list[str] | None = None, + force: list[str] | None = None, + bids_filters: dict | None = None, ): if ignore is None: ignore = [] diff --git a/pyproject.toml b/pyproject.toml index 7a05d2f3d..d1403d6cf 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", + "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", + "PLC0415", + "PLW2901", + "RUF005", + "RUF012", ] [tool.ruff.lint.flake8-quotes] diff --git a/tox.ini b/tox.ini index ced8d6cda..2c97cad46 100644 --- a/tox.ini +++ b/tox.ini @@ -73,7 +73,6 @@ skip_install = true commands = ruff check --fix ruff format - ruff check --select ISC001 [testenv:spellcheck] description = Check spelling