From 014135cc5b5d6d6db02a005739faebd07d64e6b7 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 10:34:10 +0200 Subject: [PATCH 01/24] STY: Apply ruff/flake8-bugbear rule B007 B007 Loop control variable not used within loop body Co-authored-by: Chris Markiewicz --- nipype/algorithms/mesh.py | 2 +- nipype/algorithms/modelgen.py | 25 +++++---- nipype/interfaces/cmtk/nx.py | 10 ++-- nipype/interfaces/cmtk/parcellation.py | 2 +- nipype/interfaces/dcmstack.py | 2 +- nipype/interfaces/dipy/simulate.py | 4 +- nipype/interfaces/fsl/model.py | 24 ++++----- nipype/interfaces/fsl/preprocess.py | 59 +++++++++------------- nipype/interfaces/io.py | 4 +- nipype/interfaces/mrtrix/convert.py | 5 +- nipype/interfaces/nipy/model.py | 2 +- nipype/interfaces/spm/base.py | 2 +- nipype/interfaces/spm/preprocess.py | 30 +++++------ nipype/pipeline/engine/tests/test_nodes.py | 2 +- nipype/pipeline/engine/utils.py | 4 +- nipype/pipeline/engine/workflows.py | 8 +-- nipype/pipeline/plugins/sgegraph.py | 2 +- nipype/pipeline/plugins/slurmgraph.py | 2 +- nipype/sphinxext/plot_workflow.py | 4 +- nipype/testing/utils.py | 2 +- nipype/utils/draw_gantt_chart.py | 2 +- nipype/utils/matlabtools.py | 2 +- nipype/utils/provenance.py | 6 +-- 23 files changed, 94 insertions(+), 111 deletions(-) diff --git a/nipype/algorithms/mesh.py b/nipype/algorithms/mesh.py index 5ba00d2675..d578953e8e 100644 --- a/nipype/algorithms/mesh.py +++ b/nipype/algorithms/mesh.py @@ -244,7 +244,7 @@ def _run_interface(self, runtime): if self.inputs.weighting == "area": faces = vtk1.polys.to_array().reshape(-1, 4).astype(int)[:, 1:] - for i, p1 in enumerate(points2): + for i, _ in enumerate(points2): # compute surfaces, set in weight w = 0.0 point_faces = faces[(faces[:, :] == i).any(axis=1)] diff --git a/nipype/algorithms/modelgen.py b/nipype/algorithms/modelgen.py index 78083cb628..b7844e5b6b 100644 --- a/nipype/algorithms/modelgen.py +++ b/nipype/algorithms/modelgen.py @@ -389,7 +389,7 @@ def _generate_standard_design( if hasattr(info, "conditions") and info.conditions is not None: for cid, cond in enumerate(info.conditions): sessinfo[i]["cond"].insert(cid, dict()) - sessinfo[i]["cond"][cid]["name"] = info.conditions[cid] + sessinfo[i]["cond"][cid]["name"] = cond scaled_onset = scale_timings( info.onsets[cid], self.inputs.input_units, @@ -434,12 +434,11 @@ def _generate_standard_design( sessinfo[i]["regress"][j]["name"] = info.regressor_names[j] else: sessinfo[i]["regress"][j]["name"] = "UR%d" % (j + 1) - sessinfo[i]["regress"][j]["val"] = info.regressors[j] + sessinfo[i]["regress"][j]["val"] = r sessinfo[i]["scans"] = functional_runs[i] if realignment_parameters is not None: - for i, rp in enumerate(realignment_parameters): - mc = realignment_parameters[i] + for i, mc in enumerate(realignment_parameters): for col in range(mc.shape[1]): colidx = len(sessinfo[i]["regress"]) sessinfo[i]["regress"].insert(colidx, dict(name="", val=[])) @@ -597,14 +596,14 @@ def _concatenate_info(self, infolist): for i, info in enumerate(infolist[1:]): # info.[conditions, tmod] remain the same if info.onsets: - for j, val in enumerate(info.onsets): + for j, onsets in enumerate(info.onsets): if self.inputs.input_units == "secs": - onsets = np.array( - info.onsets[j] - ) + self.inputs.time_repetition * sum(nscans[0 : (i + 1)]) + onsets = np.array(onsets) + self.inputs.time_repetition * sum( + nscans[0 : (i + 1)] + ) infoout.onsets[j].extend(onsets.tolist()) else: - onsets = np.array(info.onsets[j]) + sum(nscans[0 : (i + 1)]) + onsets = np.array(onsets) + sum(nscans[0 : (i + 1)]) infoout.onsets[j].extend(onsets.tolist()) for j, val in enumerate(info.durations): @@ -621,8 +620,8 @@ def _concatenate_info(self, infolist): ) if hasattr(info, "amplitudes") and info.amplitudes: - for j, val in enumerate(info.amplitudes): - infoout.amplitudes[j].extend(info.amplitudes[j]) + for j, amplitudes in enumerate(info.amplitudes): + infoout.amplitudes[j].extend(amplitudes) if hasattr(info, "pmod") and info.pmod: for j, val in enumerate(info.pmod): @@ -633,8 +632,8 @@ def _concatenate_info(self, infolist): if hasattr(info, "regressors") and info.regressors: # assumes same ordering of regressors across different # runs and the same names for the regressors - for j, v in enumerate(info.regressors): - infoout.regressors[j].extend(info.regressors[j]) + for j, regressors in enumerate(info.regressors): + infoout.regressors[j].extend(regressors) # insert session regressors if not hasattr(infoout, "regressors") or not infoout.regressors: diff --git a/nipype/interfaces/cmtk/nx.py b/nipype/interfaces/cmtk/nx.py index ad72582f3d..d8d8314ba1 100644 --- a/nipype/interfaces/cmtk/nx.py +++ b/nipype/interfaces/cmtk/nx.py @@ -351,7 +351,7 @@ def add_node_data(node_array, ntwk): def add_edge_data(edge_array, ntwk, above=0, below=0): edge_ntwk = ntwk.copy() data = {} - for x, row in enumerate(edge_array): + for x, row in enumerate(edge_array): # noqa: B007 for y in range(np.max(np.shape(edge_array[x]))): if edge_array[x, y] != 0: data["value"] = edge_array[x, y] @@ -550,14 +550,14 @@ def _run_interface(self, runtime): # stacks them together, and saves them in a MATLAB .mat file via Scipy global dicts dicts = list() - for idx, key in enumerate(dict_measures.keys()): - for idxd, keyd in enumerate(dict_measures[key].keys()): + for key, value in dict_measures.items(): + for idxd, keyd in enumerate(value.keys()): if idxd == 0: nparraykeys = np.array(keyd) - nparrayvalues = np.array(dict_measures[key][keyd]) + nparrayvalues = np.array(value[keyd]) else: nparraykeys = np.append(nparraykeys, np.array(keyd)) - values = np.array(dict_measures[key][keyd]) + values = np.array(value[keyd]) nparrayvalues = np.append(nparrayvalues, values) nparray = np.vstack((nparraykeys, nparrayvalues)) out_file = op.abspath(self._gen_outfilename(key, "mat")) diff --git a/nipype/interfaces/cmtk/parcellation.py b/nipype/interfaces/cmtk/parcellation.py index 65062247d8..98e3166be0 100644 --- a/nipype/interfaces/cmtk/parcellation.py +++ b/nipype/interfaces/cmtk/parcellation.py @@ -598,7 +598,7 @@ def create_wm_mask(subject_id, subjects_dir, fs_dir, parcellation_name): roid = np.asanyarray(roi.dataobj) assert roid.shape[0] == wmmask.shape[0] pg = nx.read_graphml(pgpath) - for brk, brv in pg.nodes(data=True): + for brk, brv in pg.nodes(data=True): # noqa: B007 if brv["dn_region"] == "cortical": iflogger.info( "Subtracting region %s with intensity value %s", diff --git a/nipype/interfaces/dcmstack.py b/nipype/interfaces/dcmstack.py index 7664097c58..6150e2ffa3 100644 --- a/nipype/interfaces/dcmstack.py +++ b/nipype/interfaces/dcmstack.py @@ -186,7 +186,7 @@ def _run_interface(self, runtime): stacks = dcmstack.parse_and_stack(src_paths) self.out_list = [] - for key, stack in list(stacks.items()): + for stack in stacks.values(): nw = NiftiWrapper(stack.to_nifti(embed_meta=True)) const_meta = nw.meta_ext.get_class_dict(("global", "const")) out_path = self._get_out_path(const_meta) diff --git a/nipype/interfaces/dipy/simulate.py b/nipype/interfaces/dipy/simulate.py index 6959e0a31d..402cb596d0 100644 --- a/nipype/interfaces/dipy/simulate.py +++ b/nipype/interfaces/dipy/simulate.py @@ -208,7 +208,7 @@ def _run_interface(self, runtime): dirs = np.hstack((dirs, fd[msk > 0])) # Add random directions for isotropic components - for d in range(nballs): + for _ in range(nballs): fd = np.random.randn(nvox, 3) w = np.linalg.norm(fd, axis=1) fd[w < np.finfo(float).eps, ...] = np.array([1.0, 0.0, 0.0]) @@ -341,7 +341,7 @@ def _generate_gradients(ndirs=64, values=[1000, 3000], nb0s=1): bvecs = np.vstack((bvecs, vertices)) bvals = np.hstack((bvals, v * np.ones(vertices.shape[0]))) - for i in range(nb0s): + for _ in range(nb0s): bvals = bvals.tolist() bvals.insert(0, 0) diff --git a/nipype/interfaces/fsl/model.py b/nipype/interfaces/fsl/model.py index 2ada4ab969..989c785335 100644 --- a/nipype/interfaces/fsl/model.py +++ b/nipype/interfaces/fsl/model.py @@ -199,8 +199,8 @@ def _create_ev_files( # generate sections for conditions and other nuisance # regressors num_evs = [0, 0] - for field in ["cond", "regress"]: - for i, cond in enumerate(runinfo[field]): + for field in ("cond", "regress"): + for cond in runinfo[field]: name = cond["name"] evname.append(name) evfname = os.path.join( @@ -279,9 +279,7 @@ def _create_ev_files( contrastmask_element = load_template("feat_contrastmask_element.tcl") # add t/f contrast info ev_txt += contrast_header.substitute() - con_names = [] - for j, con in enumerate(contrasts): - con_names.append(con[0]) + con_names = [con[0] for con in contrasts] con_map = {} ftest_idx = [] ttest_idx = [] @@ -365,7 +363,7 @@ def _run_interface(self, runtime): n_tcon = 0 n_fcon = 0 if isdefined(self.inputs.contrasts): - for i, c in enumerate(self.inputs.contrasts): + for c in self.inputs.contrasts: if c[1] == "T": n_tcon += 1 elif c[1] == "F": @@ -422,7 +420,7 @@ def _list_outputs(self): outputs["ev_files"].insert(runno, []) evname = [] for field in ["cond", "regress"]: - for i, cond in enumerate(runinfo[field]): + for cond in runinfo[field]: name = cond["name"] evname.append(name) evfname = os.path.join( @@ -1389,8 +1387,7 @@ def _run_interface(self, runtime): "", "/Matrix", ] - for i in range(self.inputs.num_copes): - mat_txt += ["1"] + grp_txt.extend(["1"] * self.inputs.num_copes) mat_txt = "\n".join(mat_txt) con_txt = [ @@ -1412,16 +1409,15 @@ def _run_interface(self, runtime): "", "/Matrix", ] - for i in range(self.inputs.num_copes): - grp_txt += ["1"] + grp_txt.extend(["1"] * self.inputs.num_copes) grp_txt = "\n".join(grp_txt) txt = {"design.mat": mat_txt, "design.con": con_txt, "design.grp": grp_txt} # write design files - for i, name in enumerate(["design.mat", "design.con", "design.grp"]): + for name, name_txt in txt.items(): with open(os.path.join(cwd, name), "w") as f: - f.write(txt[name]) + f.write(name_txt) return runtime @@ -1560,7 +1556,7 @@ def _run_interface(self, runtime): "", "/Matrix", ] - for conidx, con in enumerate(self.inputs.contrasts): + for con in self.inputs.contrasts: if con[1] == "F": convals = np.zeros((ntcons, 1)) for tcon in con[2]: diff --git a/nipype/interfaces/fsl/preprocess.py b/nipype/interfaces/fsl/preprocess.py index e4abd5ce16..2c12a8368a 100644 --- a/nipype/interfaces/fsl/preprocess.py +++ b/nipype/interfaces/fsl/preprocess.py @@ -416,63 +416,52 @@ def _list_outputs(self): outputs["tissue_class_map"] = self._gen_fname(suffix="_seg", **_gen_fname_opts) if self.inputs.segments: - outputs["tissue_class_files"] = [] - for i in range(nclasses): - outputs["tissue_class_files"].append( - self._gen_fname(suffix="_seg_%d" % i, **_gen_fname_opts) - ) + outputs["tissue_class_files"] = [ + self._gen_fname(suffix=f"_seg_{i}", **_gen_fname_opts) + for i in range(nclasses) + ] if isdefined(self.inputs.output_biascorrected): - outputs["restored_image"] = [] if len(self.inputs.in_files) > 1: # for multi-image segmentation there is one corrected image # per input - for val, f in enumerate(self.inputs.in_files): - # image numbering is 1-based - outputs["restored_image"].append( - self._gen_fname( - suffix="_restore_%d" % (val + 1), **_gen_fname_opts - ) - ) + outputs["restored_image"] = [ + self._gen_fname(suffix=f"_restore_{i}", **_gen_fname_opts) + for i in range(1, len(self.inputs.in_files) + 1) + ] else: # single image segmentation has unnumbered output image - outputs["restored_image"].append( + outputs["restored_image"] = [ self._gen_fname(suffix="_restore", **_gen_fname_opts) - ) + ] outputs["mixeltype"] = self._gen_fname(suffix="_mixeltype", **_gen_fname_opts) if not self.inputs.no_pve: outputs["partial_volume_map"] = self._gen_fname( suffix="_pveseg", **_gen_fname_opts ) - outputs["partial_volume_files"] = [] - for i in range(nclasses): - outputs["partial_volume_files"].append( - self._gen_fname(suffix="_pve_%d" % i, **_gen_fname_opts) - ) + outputs["partial_volume_files"] = [ + self._gen_fname(suffix=f"_pve_{i}", **_gen_fname_opts) + for i in range(nclasses) + ] if self.inputs.output_biasfield: - outputs["bias_field"] = [] if len(self.inputs.in_files) > 1: # for multi-image segmentation there is one bias field image # per input - for val, f in enumerate(self.inputs.in_files): - # image numbering is 1-based - outputs["bias_field"].append( - self._gen_fname( - suffix="_bias_%d" % (val + 1), **_gen_fname_opts - ) - ) + outputs["bias_field"] = [ + self._gen_fname(suffix=f"_bias_{i}", **_gen_fname_opts) + for i in range(1, len(self.inputs.in_files) + 1) + ] else: # single image segmentation has unnumbered output image - outputs["bias_field"].append( + outputs["bias_field"] = [ self._gen_fname(suffix="_bias", **_gen_fname_opts) - ) + ] if self.inputs.probability_maps: - outputs["probability_maps"] = [] - for i in range(nclasses): - outputs["probability_maps"].append( - self._gen_fname(suffix="_prob_%d" % i, **_gen_fname_opts) - ) + outputs["probability_maps"] = [ + self._gen_fname(suffix="_prob_{i}", **_gen_fname_opts) + for i in range(nclasses) + ] return outputs diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 46cdfb44f2..3efb7d680e 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -609,7 +609,7 @@ def _upload_to_s3(self, bucket, src, dst): # If src is a directory, collect files (this assumes dst is a dir too) if os.path.isdir(src): src_files = [] - for root, dirs, files in os.walk(src): + for root, dirs, files in os.walk(src): # noqa: B007 src_files.extend([os.path.join(root, fil) for fil in files]) # Make the dst files have the dst folder as base dir dst_files = [os.path.join(dst, src_f.split(src)[1]) for src_f in src_files] @@ -1393,7 +1393,7 @@ def __init__(self, templates, **kwargs): # Infer the infields and outfields from the template infields = [] - for name, template in list(templates.items()): + for template in templates.values(): for _, field_name, _, _ in string.Formatter().parse(template): if field_name is not None: field_name = re.match(r"\w+", field_name).group() diff --git a/nipype/interfaces/mrtrix/convert.py b/nipype/interfaces/mrtrix/convert.py index 783974c667..6d016db879 100644 --- a/nipype/interfaces/mrtrix/convert.py +++ b/nipype/interfaces/mrtrix/convert.py @@ -100,9 +100,10 @@ def points_per_track(offset): ] # Converts numpy array to list, removes the last value for idx, value in enumerate(nonfinite_list): if idx == 0: - track_points.append(nonfinite_list[idx]) + track_points.append(value) else: - track_points.append(nonfinite_list[idx] - nonfinite_list[idx - 1] - 1) + track_points.append(value - last_value - 1) + last_value = value return track_points, nonfinite_list def track_gen(track_points): diff --git a/nipype/interfaces/nipy/model.py b/nipype/interfaces/nipy/model.py index c99a4acaea..380b0383e2 100644 --- a/nipype/interfaces/nipy/model.py +++ b/nipype/interfaces/nipy/model.py @@ -151,7 +151,7 @@ def _run_interface(self, runtime): onsets = [] duration = [] - for i, cond in enumerate(session_info[0]["cond"]): + for cond in session_info[0]["cond"]: onsets += cond["onset"] conditions += [cond["name"]] * len(cond["onset"]) if len(cond["duration"]) == 1: diff --git a/nipype/interfaces/spm/base.py b/nipype/interfaces/spm/base.py index 4998f0af34..28e7864794 100644 --- a/nipype/interfaces/spm/base.py +++ b/nipype/interfaces/spm/base.py @@ -489,7 +489,7 @@ def _generate_job(self, prefix="", contents=None): jobstring += "%s = {...\n" % (prefix) else: jobstring += "{...\n" - for i, val in enumerate(contents): + for val in contents: if isinstance(val, np.ndarray): jobstring += self._generate_job(prefix=None, contents=val) elif isinstance(val, list): diff --git a/nipype/interfaces/spm/preprocess.py b/nipype/interfaces/spm/preprocess.py index c7f69785ff..a0a81cf3a1 100644 --- a/nipype/interfaces/spm/preprocess.py +++ b/nipype/interfaces/spm/preprocess.py @@ -363,10 +363,10 @@ def _list_outputs(self): if resliced_all: outputs["out_files"] = [] - for idx, imgf in enumerate(ensure_list(self.inputs.in_files)): + for imgf in ensure_list(self.inputs.in_files): appliedvdm_run = [] if isinstance(imgf, list): - for i, inner_imgf in enumerate(ensure_list(imgf)): + for inner_imgf in ensure_list(imgf): newfile = fname_presuffix( inner_imgf, prefix=self.inputs.out_prefix ) @@ -656,10 +656,10 @@ def _list_outputs(self): if resliced_all: outputs["realigned_files"] = [] - for idx, imgf in enumerate(ensure_list(self.inputs.in_files)): + for imgf in ensure_list(self.inputs.in_files): realigned_run = [] if isinstance(imgf, list): - for i, inner_imgf in enumerate(ensure_list(imgf)): + for inner_imgf in ensure_list(imgf): newfile = fname_presuffix( inner_imgf, prefix=self.inputs.out_prefix ) @@ -927,10 +927,10 @@ def _list_outputs(self): if resliced_all: outputs["realigned_unwarped_files"] = [] - for idx, imgf in enumerate(ensure_list(self.inputs.in_files)): + for imgf in ensure_list(self.inputs.in_files): realigned_run = [] if isinstance(imgf, list): - for i, inner_imgf in enumerate(ensure_list(imgf)): + for inner_imgf in ensure_list(imgf): newfile = fname_presuffix( inner_imgf, prefix=self.inputs.out_prefix ) @@ -1916,11 +1916,10 @@ def _list_outputs(self): n_classes = 5 if isdefined(self.inputs.tissues): n_classes = len(self.inputs.tissues) - for i in range(n_classes): - outputs["native_class_images"].append([]) - outputs["dartel_input_images"].append([]) - outputs["normalized_class_images"].append([]) - outputs["modulated_class_images"].append([]) + outputs["native_class_images"].extend([] for _ in range(n_classes)) + outputs["dartel_input_images"].extend([] for _ in range(n_classes)) + outputs["normalized_class_images"].extend([] for _ in range(n_classes)) + outputs["modulated_class_images"].extend([] for _ in range(n_classes)) for filename in self.inputs.channel_files: pth, base, ext = split_filename(filename) @@ -2164,11 +2163,10 @@ def _list_outputs(self): n_classes = 5 if isdefined(self.inputs.tissues): n_classes = len(self.inputs.tissues) - for i in range(n_classes): - outputs["native_class_images"].append([]) - outputs["dartel_input_images"].append([]) - outputs["normalized_class_images"].append([]) - outputs["modulated_class_images"].append([]) + outputs["native_class_images"].extend([] for _ in range(n_classes)) + outputs["dartel_input_images"].extend([] for _ in range(n_classes)) + outputs["normalized_class_images"].extend([] for _ in range(n_classes)) + outputs["modulated_class_images"].extend([] for _ in range(n_classes)) # main outputs are generated for the first channel images only for filename in self.inputs.channels[0][0]: diff --git a/nipype/pipeline/engine/tests/test_nodes.py b/nipype/pipeline/engine/tests/test_nodes.py index 19ffd714c6..d5ce4134f9 100644 --- a/nipype/pipeline/engine/tests/test_nodes.py +++ b/nipype/pipeline/engine/tests/test_nodes.py @@ -181,7 +181,7 @@ def func1(in1): ) mapnode.inputs.in1 = [1, 2] - for idx, node in mapnode._make_nodes(): + for idx, node in mapnode._make_nodes(): # noqa: B007 for attr in ("overwrite", "run_without_submitting", "plugin_args"): assert getattr(node, attr) == getattr(mapnode, attr) for attr in ("_n_procs", "_mem_gb"): diff --git a/nipype/pipeline/engine/utils.py b/nipype/pipeline/engine/utils.py index 0f800aa02a..65c6c77888 100644 --- a/nipype/pipeline/engine/utils.py +++ b/nipype/pipeline/engine/utils.py @@ -537,7 +537,7 @@ def _write_detailed_dot(graph, dotfilename): + ["}"] ) outports = [] - for u, v, d in graph.out_edges(nbunch=n, data=True): + for u, v, d in graph.out_edges(nbunch=n, data=True): # noqa: B007 for cd in d["connect"]: if isinstance(cd[0], (str, bytes)): outport = cd[0] @@ -1599,7 +1599,7 @@ def write_workflow_prov(graph, filename=None, format="all"): # add dependencies (edges) # Process->Process - for idx, edgeinfo in enumerate(graph.in_edges()): + for edgeinfo in graph.in_edges(): ps.g.wasStartedBy( processes[list(nodes).index(edgeinfo[1])], starter=processes[list(nodes).index(edgeinfo[0])], diff --git a/nipype/pipeline/engine/workflows.py b/nipype/pipeline/engine/workflows.py index 54577f21b8..93758b0a13 100644 --- a/nipype/pipeline/engine/workflows.py +++ b/nipype/pipeline/engine/workflows.py @@ -232,7 +232,7 @@ def connect(self, *args, **kwargs): raise Exception("\n".join(["Some connections were not found"] + infostr)) # turn functions into strings - for srcnode, destnode, connects in connection_list: + for srcnode, destnode, connects in connection_list: # noqa: B007 for idx, (src, dest) in enumerate(connects): if isinstance(src, tuple) and not isinstance(src[1], (str, bytes)): function_source = getsource(src[1]) @@ -702,9 +702,9 @@ def getname(u, i): json_dict = [] for i, node in enumerate(nodes): - imports = [] - for u, v in graph.in_edges(nbunch=node): - imports.append(getname(u, nodes.index(u))) + imports = [ + getname(u, nodes.index(u)) for u, v in graph.in_edges(nbunch=node) + ] json_dict.append( dict(name=getname(node, i), size=1, group=groups[i], imports=imports) ) diff --git a/nipype/pipeline/plugins/sgegraph.py b/nipype/pipeline/plugins/sgegraph.py index 5cd1c7bfb7..3d9e8ac40d 100644 --- a/nipype/pipeline/plugins/sgegraph.py +++ b/nipype/pipeline/plugins/sgegraph.py @@ -80,7 +80,7 @@ def make_job_name(jobnumber, nodeslist): if ( self._dont_resubmit_completed_jobs ): # A future parameter for controlling this behavior could be added here - for idx, pyscript in enumerate(pyfiles): + for idx, pyscript in enumerate(pyfiles): # noqa: B007 node = nodes[idx] node_status_done = node_completed_status(node) diff --git a/nipype/pipeline/plugins/slurmgraph.py b/nipype/pipeline/plugins/slurmgraph.py index c74ab05a87..0999595f5d 100644 --- a/nipype/pipeline/plugins/slurmgraph.py +++ b/nipype/pipeline/plugins/slurmgraph.py @@ -80,7 +80,7 @@ def make_job_name(jobnumber, nodeslist): if ( self._dont_resubmit_completed_jobs ): # A future parameter for controlling this behavior could be added here - for idx, pyscript in enumerate(pyfiles): + for idx, pyscript in enumerate(pyfiles): # noqa: B007 node = nodes[idx] node_status_done = node_completed_status(node) diff --git a/nipype/sphinxext/plot_workflow.py b/nipype/sphinxext/plot_workflow.py index 74745f99cb..a7af0ee29c 100644 --- a/nipype/sphinxext/plot_workflow.py +++ b/nipype/sphinxext/plot_workflow.py @@ -427,7 +427,7 @@ def run(self): # copy image files to builder's output directory, if necessary os.makedirs(dest_dir, exist_ok=True) - for code_piece, images in results: + for code_piece, images in results: # noqa: B007 for img in images: for fn in img.filenames(): destimg = os.path.join(dest_dir, os.path.basename(fn)) @@ -731,7 +731,7 @@ def render_figures( run_code(code, code_path, ns, function_name) img = ImageFile(output_base, output_dir) - for fmt, dpi in formats: + for fmt, dpi in formats: # noqa: B007 try: img_path = img.filename(fmt) imgname, ext = os.path.splitext(os.path.basename(img_path)) diff --git a/nipype/testing/utils.py b/nipype/testing/utils.py index 71a75a41c7..00c45187ed 100644 --- a/nipype/testing/utils.py +++ b/nipype/testing/utils.py @@ -78,7 +78,7 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.fusefat.send_signal(signal.SIGINT) # Allow 1s to return without sending terminate - for count in range(10): + for _ in range(10): time.sleep(0.1) if self.fusefat.poll() is not None: break diff --git a/nipype/utils/draw_gantt_chart.py b/nipype/utils/draw_gantt_chart.py index 64a0d793db..bdd9ad28c9 100644 --- a/nipype/utils/draw_gantt_chart.py +++ b/nipype/utils/draw_gantt_chart.py @@ -222,7 +222,7 @@ def draw_lines(start, total_duration, minute_scale, scale): num_lines = int(((total_duration // 60) // minute_scale) + 2) # Iterate through the lines and create html line markers string - for line in range(num_lines): + for _ in range(num_lines): # Line object new_line = "
" % next_line result += new_line diff --git a/nipype/utils/matlabtools.py b/nipype/utils/matlabtools.py index ea06cd4126..e2b1966d47 100644 --- a/nipype/utils/matlabtools.py +++ b/nipype/utils/matlabtools.py @@ -54,7 +54,7 @@ def mlab_tempfile(dir=None): # return names that aren't valid matlab names, but we can't control that # directly, we just keep trying until we get a valid name. To avoid an # infinite loop for some strange reason, we only try 100 times. - for n in range(100): + for _ in range(100): f = tempfile.NamedTemporaryFile(suffix=".m", prefix="tmp_matlab_", dir=dir) # Check the file name for matlab compliance fname = os.path.splitext(os.path.basename(f.name))[0] diff --git a/nipype/utils/provenance.py b/nipype/utils/provenance.py index ba71ac6d6e..35f5d41e86 100644 --- a/nipype/utils/provenance.py +++ b/nipype/utils/provenance.py @@ -361,7 +361,7 @@ def add_results(self, results, keep_provenance=False): ) self.g.used(a0, id) # write environment entities - for idx, (key, val) in enumerate(sorted(runtime.environ.items())): + for key, val in sorted(runtime.environ.items()): if key not in PROV_ENVVARS: continue in_attr = { @@ -380,7 +380,7 @@ def add_results(self, results, keep_provenance=False): {pm.PROV["type"]: nipype_ns["Inputs"], pm.PROV["label"]: "Inputs"} ) # write input entities - for idx, (key, val) in enumerate(sorted(inputs.items())): + for key, val in sorted(inputs.items()): in_entity = prov_encode(self.g, val).identifier self.g.hadMember(input_collection, in_entity) used_attr = {pm.PROV["label"]: key, nipype_ns["inPort"]: key} @@ -396,7 +396,7 @@ def add_results(self, results, keep_provenance=False): ) self.g.wasGeneratedBy(output_collection, a0) # write output entities - for idx, (key, val) in enumerate(sorted(outputs.items())): + for key, val in sorted(outputs.items()): out_entity = prov_encode(self.g, val).identifier self.g.hadMember(output_collection, out_entity) gen_attr = {pm.PROV["label"]: key, nipype_ns["outPort"]: key} From 51f712df257eaa09ba47e75ad08e002c0efd472e Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 11:41:35 +0200 Subject: [PATCH 02/24] STY: Apply ruff/flake8-bugbear rule B015 B015 Pointless comparison at end of function scope. Did you mean to return the expression result? --- nipype/tests/test_nipype.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/tests/test_nipype.py b/nipype/tests/test_nipype.py index 3f103b5529..128adbfa3a 100644 --- a/nipype/tests/test_nipype.py +++ b/nipype/tests/test_nipype.py @@ -19,7 +19,7 @@ def test_nipype_info(): ) def test_git_hash(): # removing the first "g" from gitversion - get_nipype_gitversion()[1:] == get_info()["commit_hash"] + assert get_nipype_gitversion()[1:] == get_info()["commit_hash"] def _check_no_et(): From c17bc9fc026f3c044495e819b2e8d8dc81ee0155 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 11:39:31 +0200 Subject: [PATCH 03/24] STY: Apply ruff/flake8-bugbear rule B018 B018 Found useless expression. Either assign it to a variable or remove it. --- nipype/interfaces/ants/tests/test_resampling.py | 2 +- nipype/interfaces/ants/tests/test_segmentation.py | 8 ++++---- nipype/interfaces/base/tests/test_specs.py | 6 +++--- nipype/interfaces/freesurfer/tests/test_preprocess.py | 8 ++++---- nipype/interfaces/fsl/tests/test_preprocess.py | 6 +++--- tools/checkspecs.py | 2 +- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/nipype/interfaces/ants/tests/test_resampling.py b/nipype/interfaces/ants/tests/test_resampling.py index 3b1da9d3ee..abd1831a25 100644 --- a/nipype/interfaces/ants/tests/test_resampling.py +++ b/nipype/interfaces/ants/tests/test_resampling.py @@ -103,4 +103,4 @@ def test_WarpTimeSeriesImageMultiTransform_invaffine_wrong(change_dir, create_wt wtsimt = create_wtsimt wtsimt.inputs.invert_affine = [0] with pytest.raises(Exception): - wtsimt.cmdline + wtsimt.cmdline # noqa: B018 diff --git a/nipype/interfaces/ants/tests/test_segmentation.py b/nipype/interfaces/ants/tests/test_segmentation.py index 4fc22ee34a..b757afb923 100644 --- a/nipype/interfaces/ants/tests/test_segmentation.py +++ b/nipype/interfaces/ants/tests/test_segmentation.py @@ -46,20 +46,20 @@ def test_LaplacianThickness_wrongargs(change_dir, create_lt): with pytest.raises( ValueError, match=r".* requires a value for input 'sulcus_prior' .*" ): - lt.cmdline + lt.cmdline # noqa: B018 lt.inputs.sulcus_prior = 0.15 with pytest.raises(ValueError, match=r".* requires a value for input 'dT' .*"): - lt.cmdline + lt.cmdline # noqa: B018 lt.inputs.dT = 0.01 with pytest.raises( ValueError, match=r".* requires a value for input 'prior_thickness' .*" ): - lt.cmdline + lt.cmdline # noqa: B018 lt.inputs.prior_thickness = 5.9 with pytest.raises( ValueError, match=r".* requires a value for input 'smooth_param' .*" ): - lt.cmdline + lt.cmdline # noqa: B018 lt.inputs.smooth_param = 4.5 assert ( lt.cmdline == "LaplacianThickness functional.nii diffusion_weighted.nii " diff --git a/nipype/interfaces/base/tests/test_specs.py b/nipype/interfaces/base/tests/test_specs.py index 44a9c014c4..1d91ff593b 100644 --- a/nipype/interfaces/base/tests/test_specs.py +++ b/nipype/interfaces/base/tests/test_specs.py @@ -71,12 +71,12 @@ def test_TraitedSpec_dynamic(): a.foo = 1 assign_a = lambda: setattr(a, "foo", "a") with pytest.raises(Exception): - assign_a + assign_a() pkld_a = dumps(a) unpkld_a = loads(pkld_a) assign_a_again = lambda: setattr(unpkld_a, "foo", "a") with pytest.raises(Exception): - assign_a_again + assign_a_again() def test_DynamicTraitedSpec_tab_completion(): @@ -276,7 +276,7 @@ class TestCycle(nib.CommandLine): to0 = TestCycle() not_raised = True try: - to0.cmdline + to0.cmdline # noqa: B018 except nib.NipypeInterfaceError: not_raised = False assert not not_raised diff --git a/nipype/interfaces/freesurfer/tests/test_preprocess.py b/nipype/interfaces/freesurfer/tests/test_preprocess.py index a6e2c3cbf9..ebbc8c6c75 100644 --- a/nipype/interfaces/freesurfer/tests/test_preprocess.py +++ b/nipype/interfaces/freesurfer/tests/test_preprocess.py @@ -126,7 +126,7 @@ def test_mandatory_outvol(create_files_in_directory): # test raising error with mandatory args absent with pytest.raises(ValueError): - mni.cmdline + mni.cmdline # noqa: B018 # test with minimal args mni.inputs.in_file = filelist[0] @@ -164,7 +164,7 @@ def test_bbregister(create_files_in_directory): # test raising error with mandatory args absent with pytest.raises(ValueError): - bbr.cmdline + bbr.cmdline # noqa: B018 bbr.inputs.subject_id = "fsaverage" bbr.inputs.source_file = filelist[0] @@ -173,9 +173,9 @@ def test_bbregister(create_files_in_directory): # Check that 'init' is mandatory in FS < 6, but not in 6+ if Info.looseversion() < LooseVersion("6.0.0"): with pytest.raises(ValueError): - bbr.cmdline + bbr.cmdline # noqa: B018 else: - bbr.cmdline + bbr.cmdline # noqa: B018 bbr.inputs.init = "fsl" diff --git a/nipype/interfaces/fsl/tests/test_preprocess.py b/nipype/interfaces/fsl/tests/test_preprocess.py index 143179a5ec..cc0f6662ae 100644 --- a/nipype/interfaces/fsl/tests/test_preprocess.py +++ b/nipype/interfaces/fsl/tests/test_preprocess.py @@ -229,11 +229,11 @@ def test_flirt(setup_flirt): flirter = fsl.FLIRT() # infile not specified with pytest.raises(ValueError): - flirter.cmdline + flirter.cmdline # noqa: B018 flirter.inputs.in_file = infile # reference not specified with pytest.raises(ValueError): - flirter.cmdline + flirter.cmdline # noqa: B018 flirter.inputs.reference = reffile # Generate outfile and outmatrix @@ -253,7 +253,7 @@ def test_flirt(setup_flirt): axfm.inputs.apply_xfm = True # in_matrix_file or uses_qform must be defined with pytest.raises(RuntimeError): - axfm.cmdline + axfm.cmdline # noqa: B018 axfm2 = deepcopy(axfm) # test uses_qform axfm.inputs.uses_qform = True diff --git a/tools/checkspecs.py b/tools/checkspecs.py index 7c9ebf4157..4226f3a4f8 100644 --- a/tools/checkspecs.py +++ b/tools/checkspecs.py @@ -418,7 +418,7 @@ def _survives_exclude(self, matchstr, match_type): matchstr = matchstr[L:] for pat in patterns: try: - pat.search + pat.search # noqa: B018 except AttributeError: pat = re.compile(pat) if pat.search(matchstr): From e3227a4f66a75de26f73c597d4cf1a5cf3de38d9 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 19:38:47 +0200 Subject: [PATCH 04/24] Apply ruff/pycodestyle rule E741 E741 Ambiguous variable name --- nipype/interfaces/minc/base.py | 7 ++++--- nipype/utils/draw_gantt_chart.py | 2 +- nipype/utils/filemanip.py | 4 +++- nipype/utils/misc.py | 6 +++--- 4 files changed, 11 insertions(+), 8 deletions(-) diff --git a/nipype/interfaces/minc/base.py b/nipype/interfaces/minc/base.py index 8731627693..1563c9beed 100644 --- a/nipype/interfaces/minc/base.py +++ b/nipype/interfaces/minc/base.py @@ -78,15 +78,16 @@ def read_hdf5_version(s): versions = {"minc": None, "libminc": None, "netcdf": None, "hdf5": None} - for l in out.split("\n"): + for line in out.split("\n"): for name, f in [ ("minc", read_program_version), ("libminc", read_libminc_version), ("netcdf", read_netcdf_version), ("hdf5", read_hdf5_version), ]: - if f(l) is not None: - versions[name] = f(l) + version = f(line) + if version is not None: + versions[name] = version return versions diff --git a/nipype/utils/draw_gantt_chart.py b/nipype/utils/draw_gantt_chart.py index bdd9ad28c9..c38c5acc19 100644 --- a/nipype/utils/draw_gantt_chart.py +++ b/nipype/utils/draw_gantt_chart.py @@ -101,7 +101,7 @@ def log_to_dict(logfile): # read file separating each line lines = content.readlines() - nodes_list = [json.loads(l) for l in lines] + nodes_list = [json.loads(line) for line in lines] def _convert_string_to_datetime( datestring: Union[str, datetime.datetime], diff --git a/nipype/utils/filemanip.py b/nipype/utils/filemanip.py index 52558f59f0..933220b70e 100644 --- a/nipype/utils/filemanip.py +++ b/nipype/utils/filemanip.py @@ -216,7 +216,9 @@ def _parse_mount_table(exit_code, output): # Keep line and match for error reporting (match == None on failure) # Ignore empty lines - matches = [(l, pattern.match(l)) for l in output.strip().splitlines() if l] + matches = [ + (line, pattern.match(line)) for line in output.strip().splitlines() if line + ] # (path, fstype) tuples, sorted by path length (longest first) mount_info = sorted( diff --git a/nipype/utils/misc.py b/nipype/utils/misc.py index ed8a539e66..b1ee85d29f 100644 --- a/nipype/utils/misc.py +++ b/nipype/utils/misc.py @@ -15,8 +15,8 @@ import textwrap -def human_order_sorted(l): - """Sorts string in human order (i.e. 'stat10' will go after 'stat2')""" +def human_order_sorted(strings): + """Sorts strings in human order (i.e. 'stat10' will go after 'stat2')""" def atoi(text): return int(text) if text.isdigit() else text @@ -26,7 +26,7 @@ def natural_keys(text): text = text[0] return [atoi(c) for c in re.split(r"(\d+)", text)] - return sorted(l, key=natural_keys) + return sorted(strings, key=natural_keys) def trim(docstring, marker=None): From 121695ef1488a4f1822c010e3cccaf49a8a27dba Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:18:58 +0200 Subject: [PATCH 05/24] STY: Apply ruff/refurb rule FURB154 FURB154 Use of repeated consecutive `global` --- nipype/pipeline/engine/tests/test_join.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/nipype/pipeline/engine/tests/test_join.py b/nipype/pipeline/engine/tests/test_join.py index 2fe5f70564..650e37ff2b 100644 --- a/nipype/pipeline/engine/tests/test_join.py +++ b/nipype/pipeline/engine/tests/test_join.py @@ -71,8 +71,7 @@ class SumInterface(nib.SimpleInterface): output_spec = SumOutputSpec def _run_interface(self, runtime): - global _sum - global _sum_operands + global _sum, _sum_operands runtime.returncode = 0 self._results["operands"] = self.inputs.input1 self._results["output1"] = sum(self.inputs.input1) @@ -139,9 +138,7 @@ def _list_outputs(self): @pytest.mark.parametrize("needed_outputs", ["true", "false"]) def test_join_expansion(tmpdir, needed_outputs): - global _sums - global _sum_operands - global _products + global _sums, _sum_operands, _products tmpdir.chdir() # Clean up, just in case some other test modified them From b429e2d8f940d32fec8bdbd74b376c276c4da7ff Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:25:00 +0200 Subject: [PATCH 06/24] STY: Apply ruff/Pylint rule PLE0101 PLE0101 Explicit return in `__init__` --- nipype/interfaces/camino/dti.py | 14 +++++++------- nipype/interfaces/fsl/dti.py | 2 +- nipype/interfaces/fsl/epi.py | 4 ++-- nipype/interfaces/mrtrix/tracking.py | 6 +++--- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/nipype/interfaces/camino/dti.py b/nipype/interfaces/camino/dti.py index ba2131b8ac..91279e68ff 100644 --- a/nipype/interfaces/camino/dti.py +++ b/nipype/interfaces/camino/dti.py @@ -936,7 +936,7 @@ class TrackDT(Track): def __init__(self, command=None, **inputs): inputs["inputmodel"] = "dt" - return super().__init__(command, **inputs) + super().__init__(command, **inputs) class TrackPICoInputSpec(TrackInputSpec): @@ -973,7 +973,7 @@ class TrackPICo(Track): def __init__(self, command=None, **inputs): inputs["inputmodel"] = "pico" - return super().__init__(command, **inputs) + super().__init__(command, **inputs) class TrackBedpostxDeterInputSpec(TrackInputSpec): @@ -1023,7 +1023,7 @@ class TrackBedpostxDeter(Track): def __init__(self, command=None, **inputs): inputs["inputmodel"] = "bedpostx_dyad" - return super().__init__(command, **inputs) + super().__init__(command, **inputs) class TrackBedpostxProbaInputSpec(TrackInputSpec): @@ -1084,7 +1084,7 @@ class TrackBedpostxProba(Track): def __init__(self, command=None, **inputs): inputs["inputmodel"] = "bedpostx" - return super().__init__(command, **inputs) + super().__init__(command, **inputs) class TrackBayesDiracInputSpec(TrackInputSpec): @@ -1185,7 +1185,7 @@ class TrackBayesDirac(Track): def __init__(self, command=None, **inputs): inputs["inputmodel"] = "bayesdirac" - return super().__init__(command, **inputs) + super().__init__(command, **inputs) class TrackBallStick(Track): @@ -1204,7 +1204,7 @@ class TrackBallStick(Track): def __init__(self, command=None, **inputs): inputs["inputmodel"] = "ballstick" - return super().__init__(command, **inputs) + super().__init__(command, **inputs) class TrackBootstrapInputSpec(TrackInputSpec): @@ -1266,7 +1266,7 @@ class TrackBootstrap(Track): input_spec = TrackBootstrapInputSpec def __init__(self, command=None, **inputs): - return super().__init__(command, **inputs) + super().__init__(command, **inputs) class ComputeMeanDiffusivityInputSpec(CommandLineInputSpec): diff --git a/nipype/interfaces/fsl/dti.py b/nipype/interfaces/fsl/dti.py index cd46067daa..530229a1c0 100644 --- a/nipype/interfaces/fsl/dti.py +++ b/nipype/interfaces/fsl/dti.py @@ -813,7 +813,7 @@ def __init__(self, **inputs): ("Deprecated: Please use create_bedpostx_pipeline instead"), DeprecationWarning, ) - return super().__init__(**inputs) + super().__init__(**inputs) def _run_interface(self, runtime): for i in range(1, len(self.inputs.thsamples) + 1): diff --git a/nipype/interfaces/fsl/epi.py b/nipype/interfaces/fsl/epi.py index 7dda9a49d7..7019e17a77 100644 --- a/nipype/interfaces/fsl/epi.py +++ b/nipype/interfaces/fsl/epi.py @@ -1404,7 +1404,7 @@ def __init__(self, **inputs): ), DeprecationWarning, ) - return super().__init__(**inputs) + super().__init__(**inputs) def _run_interface(self, runtime): runtime = super()._run_interface(runtime) @@ -1507,7 +1507,7 @@ def __init__(self, **inputs): ("Deprecated: Please use nipype.interfaces.fsl.epi.Eddy instead"), DeprecationWarning, ) - return super().__init__(**inputs) + super().__init__(**inputs) def _run_interface(self, runtime): runtime = super()._run_interface(runtime) diff --git a/nipype/interfaces/mrtrix/tracking.py b/nipype/interfaces/mrtrix/tracking.py index 53e805eeb6..2fb518701f 100644 --- a/nipype/interfaces/mrtrix/tracking.py +++ b/nipype/interfaces/mrtrix/tracking.py @@ -432,7 +432,7 @@ class DiffusionTensorStreamlineTrack(StreamlineTrack): def __init__(self, command=None, **inputs): inputs["inputmodel"] = "DT_STREAM" - return super().__init__(command, **inputs) + super().__init__(command, **inputs) class ProbabilisticSphericallyDeconvolutedStreamlineTrackInputSpec( @@ -466,7 +466,7 @@ class ProbabilisticSphericallyDeconvolutedStreamlineTrack(StreamlineTrack): def __init__(self, command=None, **inputs): inputs["inputmodel"] = "SD_PROB" - return super().__init__(command, **inputs) + super().__init__(command, **inputs) class SphericallyDeconvolutedStreamlineTrack(StreamlineTrack): @@ -491,4 +491,4 @@ class SphericallyDeconvolutedStreamlineTrack(StreamlineTrack): def __init__(self, command=None, **inputs): inputs["inputmodel"] = "SD_STREAM" - return super().__init__(command, **inputs) + super().__init__(command, **inputs) From 00e19f40fc8d6d17439077e26f28946967d41a22 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:42:20 +0200 Subject: [PATCH 07/24] STY: Apply ruff/Pylint rule PLE1205 PLE1205 Too many arguments for `logging` format string --- nipype/interfaces/workbench/metric.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/workbench/metric.py b/nipype/interfaces/workbench/metric.py index 9183488f93..07e068e901 100644 --- a/nipype/interfaces/workbench/metric.py +++ b/nipype/interfaces/workbench/metric.py @@ -164,7 +164,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) From f0b6d58fc4cdf9c93752ca3141953bcf7b38d825 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:27:04 +0200 Subject: [PATCH 08/24] STY: Apply ruff/flake8-pytest-style rule PT006 PT006 Wrong type passed to first argument of `@pytest.mark.parametrize`; expected `tuple` --- nipype/algorithms/tests/test_CompCor.py | 2 +- nipype/algorithms/tests/test_stats.py | 2 +- nipype/interfaces/ants/tests/test_base.py | 2 +- .../interfaces/base/tests/test_resource_monitor.py | 8 ++++++-- nipype/interfaces/fsl/tests/test_base.py | 2 +- nipype/interfaces/fsl/tests/test_preprocess.py | 2 +- nipype/interfaces/tests/test_dcm2nii.py | 2 +- nipype/interfaces/tests/test_io.py | 2 +- nipype/interfaces/utility/tests/test_base.py | 4 ++-- nipype/pipeline/engine/tests/test_engine.py | 6 +++--- nipype/pipeline/engine/tests/test_nodes.py | 2 +- nipype/pipeline/engine/tests/test_workflows.py | 2 +- nipype/utils/tests/test_filemanip.py | 14 +++++++------- nipype/utils/tests/test_misc.py | 2 +- 14 files changed, 28 insertions(+), 24 deletions(-) diff --git a/nipype/algorithms/tests/test_CompCor.py b/nipype/algorithms/tests/test_CompCor.py index f506ded628..a747d3305d 100644 --- a/nipype/algorithms/tests/test_CompCor.py +++ b/nipype/algorithms/tests/test_CompCor.py @@ -28,7 +28,7 @@ def close_up_to_column_sign(a, b, rtol=1e-05, atol=1e-08, equal_nan=False): @pytest.mark.parametrize( - "a, b, close", + ("a", "b", "close"), [ ([[0.1, 0.2], [0.3, 0.4]], [[-0.1, 0.2], [-0.3, 0.4]], True), ([[0.1, 0.2], [0.3, 0.4]], [[-0.1, 0.2], [0.3, -0.4]], False), diff --git a/nipype/algorithms/tests/test_stats.py b/nipype/algorithms/tests/test_stats.py index ed698d47cf..4ccbaa2dd5 100644 --- a/nipype/algorithms/tests/test_stats.py +++ b/nipype/algorithms/tests/test_stats.py @@ -22,7 +22,7 @@ def test_ActivationCount(tmpdir): @pytest.mark.parametrize( - "threshold, above_thresh", + ("threshold", "above_thresh"), [ (1, 15.865), # above one standard deviation (one side) (2, 2.275), # above two standard deviations (one side) diff --git a/nipype/interfaces/ants/tests/test_base.py b/nipype/interfaces/ants/tests/test_base.py index 293aed72e6..23c5186a2c 100644 --- a/nipype/interfaces/ants/tests/test_base.py +++ b/nipype/interfaces/ants/tests/test_base.py @@ -20,6 +20,6 @@ # fmt: on -@pytest.mark.parametrize("raw_info, version", ANTS_VERSIONS) +@pytest.mark.parametrize(("raw_info", "version"), ANTS_VERSIONS) def test_version_parser(raw_info, version): assert Info.parse_version(raw_info) == version diff --git a/nipype/interfaces/base/tests/test_resource_monitor.py b/nipype/interfaces/base/tests/test_resource_monitor.py index 802e8e6ec9..5e2365bd39 100644 --- a/nipype/interfaces/base/tests/test_resource_monitor.py +++ b/nipype/interfaces/base/tests/test_resource_monitor.py @@ -55,7 +55,9 @@ class UseResources(CommandLine): @pytest.mark.skip(reason="inconsistent readings") @pytest.mark.skipif(os.getenv("CI_SKIP_TEST", False), reason="disabled in CI tests") -@pytest.mark.parametrize("mem_gb,n_procs", [(0.5, 3), (2.2, 8), (0.8, 4), (1.5, 1)]) +@pytest.mark.parametrize( + ("mem_gb", "n_procs"), [(0.5, 3), (2.2, 8), (0.8, 4), (1.5, 1)] +) def test_cmdline_profiling(tmpdir, mem_gb, n_procs, use_resource_monitor): """ Test runtime profiler correctly records workflow RAM/CPUs consumption @@ -80,7 +82,9 @@ def test_cmdline_profiling(tmpdir, mem_gb, n_procs, use_resource_monitor): @pytest.mark.skipif( True, reason="test disabled temporarily, until function profiling works" ) -@pytest.mark.parametrize("mem_gb,n_procs", [(0.5, 3), (2.2, 8), (0.8, 4), (1.5, 1)]) +@pytest.mark.parametrize( + ("mem_gb", "n_procs"), [(0.5, 3), (2.2, 8), (0.8, 4), (1.5, 1)] +) def test_function_profiling(tmpdir, mem_gb, n_procs, use_resource_monitor): """ Test runtime profiler correctly records workflow RAM/CPUs consumption diff --git a/nipype/interfaces/fsl/tests/test_base.py b/nipype/interfaces/fsl/tests/test_base.py index 1a76d0f6a5..aa7dd2777c 100644 --- a/nipype/interfaces/fsl/tests/test_base.py +++ b/nipype/interfaces/fsl/tests/test_base.py @@ -60,7 +60,7 @@ def test_FSLCommand2(): @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @pytest.mark.parametrize( - "args, desired_name", + ("args", "desired_name"), [ ({}, {"file": "foo.nii.gz"}), # just the filename # filename with suffix diff --git a/nipype/interfaces/fsl/tests/test_preprocess.py b/nipype/interfaces/fsl/tests/test_preprocess.py index cc0f6662ae..2a93916706 100644 --- a/nipype/interfaces/fsl/tests/test_preprocess.py +++ b/nipype/interfaces/fsl/tests/test_preprocess.py @@ -588,7 +588,7 @@ def setup_fugue(tmpdir): @pytest.mark.skipif(no_fsl(), reason="fsl is not installed") @pytest.mark.parametrize( - "attr, out_file", + ("attr", "out_file"), [ ( { diff --git a/nipype/interfaces/tests/test_dcm2nii.py b/nipype/interfaces/tests/test_dcm2nii.py index 5154534c5a..10d62cafdd 100644 --- a/nipype/interfaces/tests/test_dcm2nii.py +++ b/nipype/interfaces/tests/test_dcm2nii.py @@ -5,7 +5,7 @@ @pytest.mark.parametrize( - "fname, extension, search_crop", + ("fname", "extension", "search_crop"), [ ("output_1", ".txt", False), ("output_w_[]_meta_1", ".json", False), diff --git a/nipype/interfaces/tests/test_io.py b/nipype/interfaces/tests/test_io.py index fc7f03db9f..75a17481ee 100644 --- a/nipype/interfaces/tests/test_io.py +++ b/nipype/interfaces/tests/test_io.py @@ -104,7 +104,7 @@ def test_s3datagrabber(): @pytest.mark.parametrize( - "SF_args, inputs_att, expected", + ("SF_args", "inputs_att", "expected"), [ ( {"templates": templates1}, diff --git a/nipype/interfaces/utility/tests/test_base.py b/nipype/interfaces/utility/tests/test_base.py index 4a4e6d8899..014b22446a 100644 --- a/nipype/interfaces/utility/tests/test_base.py +++ b/nipype/interfaces/utility/tests/test_base.py @@ -37,7 +37,7 @@ def test_rename(tmpdir): @pytest.mark.parametrize( - "args, expected", [({}, ([0], [1, 2, 3])), ({"squeeze": True}, (0, [1, 2, 3]))] + ("args", "expected"), [({}, ([0], [1, 2, 3])), ({"squeeze": True}, (0, [1, 2, 3]))] ) def test_split(tmpdir, args, expected): tmpdir.chdir() @@ -52,7 +52,7 @@ def test_split(tmpdir, args, expected): @pytest.mark.parametrize( - "args, kwargs, in_lists, expected", + ("args", "kwargs", "in_lists", "expected"), [ ([3], {}, [0, [1, 2], [3, 4, 5]], [0, 1, 2, 3, 4, 5]), ([0], {}, None, None), diff --git a/nipype/pipeline/engine/tests/test_engine.py b/nipype/pipeline/engine/tests/test_engine.py index f1b6817e74..052852f56f 100644 --- a/nipype/pipeline/engine/tests/test_engine.py +++ b/nipype/pipeline/engine/tests/test_engine.py @@ -16,7 +16,7 @@ # XXX - SG I'll create a graphical version of these tests and actually # ensure that all connections are tested later @pytest.mark.parametrize( - "iterables, expected", + ("iterables", "expected"), [ ({"1": None}, (1, 0)), # test1 ({"1": dict(input1=lambda: [1, 2], input2=lambda: [1, 2])}, (4, 0)), # test2 @@ -34,7 +34,7 @@ def test_1mod(iterables, expected): @pytest.mark.parametrize( - "iterables, expected", + ("iterables", "expected"), [ ({"1": {}, "2": dict(input1=lambda: [1, 2])}, (3, 2)), # test3 ({"1": dict(input1=lambda: [1, 2]), "2": {}}, (4, 2)), # test4 @@ -58,7 +58,7 @@ def test_2mods(iterables, expected): @pytest.mark.parametrize( - "iterables, expected, connect", + ("iterables", "expected", "connect"), [ ( {"1": {}, "2": dict(input1=lambda: [1, 2]), "3": {}}, diff --git a/nipype/pipeline/engine/tests/test_nodes.py b/nipype/pipeline/engine/tests/test_nodes.py index d5ce4134f9..1edf30f329 100644 --- a/nipype/pipeline/engine/tests/test_nodes.py +++ b/nipype/pipeline/engine/tests/test_nodes.py @@ -114,7 +114,7 @@ def test_mapnode_iterfield_check(): @pytest.mark.parametrize( - "x_inp, f_exp", + ("x_inp", "f_exp"), [ (3, [6]), ([2, 3], [4, 6]), diff --git a/nipype/pipeline/engine/tests/test_workflows.py b/nipype/pipeline/engine/tests/test_workflows.py index 12d56de285..1d41c0350e 100644 --- a/nipype/pipeline/engine/tests/test_workflows.py +++ b/nipype/pipeline/engine/tests/test_workflows.py @@ -159,7 +159,7 @@ def _test_function3(arg): @pytest.mark.parametrize( - "plugin, remove_unnecessary_outputs, keep_inputs", + ("plugin", "remove_unnecessary_outputs", "keep_inputs"), list(product(["Linear", "MultiProc"], [False, True], [True, False])), ) def test_outputs_removal_wf(tmpdir, plugin, remove_unnecessary_outputs, keep_inputs): diff --git a/nipype/utils/tests/test_filemanip.py b/nipype/utils/tests/test_filemanip.py index be16a9cea1..11eb7b3d07 100644 --- a/nipype/utils/tests/test_filemanip.py +++ b/nipype/utils/tests/test_filemanip.py @@ -38,7 +38,7 @@ def _ignore_atime(stat): @pytest.mark.parametrize( - "filename, split", + ("filename", "split"), [ ("foo.nii", ("", "foo", ".nii")), ("foo.nii.gz", ("", "foo", ".nii.gz")), @@ -72,7 +72,7 @@ def test_fnames_presuffix(): @pytest.mark.parametrize( - "filename, newname", + ("filename", "newname"), [ ("foobar.nii", "foobar_0xabc123.nii"), ("foobar.nii.gz", "foobar_0xabc123.nii.gz"), @@ -280,7 +280,7 @@ def test_get_related_files_noninclusive(_temp_analyze_files): @pytest.mark.parametrize( - "filename, expected", + ("filename", "expected"), [ ("foo.nii", ["foo.nii"]), (["foo.nii"], ["foo.nii"]), @@ -294,7 +294,7 @@ def test_ensure_list(filename, expected): @pytest.mark.parametrize( - "list, expected", [(["foo.nii"], "foo.nii"), (["foo", "bar"], ["foo", "bar"])] + ("list", "expected"), [(["foo.nii"], "foo.nii"), (["foo", "bar"], ["foo", "bar"])] ) def test_simplify_list(list, expected): x = simplify_list(list) @@ -343,7 +343,7 @@ def test_json(tmpdir): @pytest.mark.parametrize( - "file, length, expected_files", + ("file", "length", "expected_files"), [ ("/path/test.img", 3, ["/path/test.hdr", "/path/test.img", "/path/test.mat"]), ("/path/test.hdr", 3, ["/path/test.hdr", "/path/test.img", "/path/test.mat"]), @@ -515,7 +515,7 @@ def test_related_files(file, length, expected_files): ) -@pytest.mark.parametrize("output, exit_code, expected", MOUNT_OUTPUTS) +@pytest.mark.parametrize(("output", "exit_code", "expected"), MOUNT_OUTPUTS) def test_parse_mount_table(output, exit_code, expected): assert _parse_mount_table(exit_code, output) == expected @@ -654,7 +654,7 @@ def test_pickle(tmp_path, save_versioning): @pytest.mark.parametrize( - "items,expected", + ("items", "expected"), [ ("", " \n\n"), ("A string", " A string\n\n"), diff --git a/nipype/utils/tests/test_misc.py b/nipype/utils/tests/test_misc.py index 6e71e7c0ca..87beadf5a1 100644 --- a/nipype/utils/tests/test_misc.py +++ b/nipype/utils/tests/test_misc.py @@ -37,7 +37,7 @@ def test_cont_to_str(): @pytest.mark.parametrize( - "string, expected", + ("string", "expected"), [ ("yes", True), ("true", True), From 990205b0bd1964f6aa6921dd028d252f65bd9a8b Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:28:28 +0200 Subject: [PATCH 09/24] STY: Apply ruff/flake8-pytest-style rule PT007 PT007 Wrong values type in `@pytest.mark.parametrize` expected `list` of `tuple` --- nipype/tests/test_nipype.py | 4 ++-- nipype/utils/tests/test_imagemanip.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nipype/tests/test_nipype.py b/nipype/tests/test_nipype.py index 128adbfa3a..a21ddf2644 100644 --- a/nipype/tests/test_nipype.py +++ b/nipype/tests/test_nipype.py @@ -70,8 +70,8 @@ def test_no_et_bare(tmp_path): assert next(iter(res.nodes)).result.outputs.out == et -@pytest.mark.parametrize("plugin", ("MultiProc", "LegacyMultiProc")) -@pytest.mark.parametrize("run_without_submitting", (True, False)) +@pytest.mark.parametrize("plugin", ["MultiProc", "LegacyMultiProc"]) +@pytest.mark.parametrize("run_without_submitting", [True, False]) def test_no_et_multiproc(tmp_path, plugin, run_without_submitting): from unittest.mock import patch from nipype.pipeline import engine as pe diff --git a/nipype/utils/tests/test_imagemanip.py b/nipype/utils/tests/test_imagemanip.py index a488633cab..85b0389e37 100644 --- a/nipype/utils/tests/test_imagemanip.py +++ b/nipype/utils/tests/test_imagemanip.py @@ -6,7 +6,7 @@ from ..imagemanip import copy_header -@pytest.mark.parametrize("keep_dtype", (True, False)) +@pytest.mark.parametrize("keep_dtype", [True, False]) def test_copy_header(tmp_path, keep_dtype): """Cover copy_header.""" fname1 = tmp_path / "reference.nii.gz" From b068caef38844ad76622f0e6722d47b25d9bfa0d Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:32:14 +0200 Subject: [PATCH 10/24] STY: Apply ruff/flake8-pytest-style rule PT014 PT014 Duplicate of test case in `@pytest_mark.parametrize` --- nipype/interfaces/utility/tests/test_base.py | 1 - 1 file changed, 1 deletion(-) diff --git a/nipype/interfaces/utility/tests/test_base.py b/nipype/interfaces/utility/tests/test_base.py index 014b22446a..9b9b07cf7c 100644 --- a/nipype/interfaces/utility/tests/test_base.py +++ b/nipype/interfaces/utility/tests/test_base.py @@ -60,7 +60,6 @@ def test_split(tmpdir, args, expected): ([], {}, [0, [1, 2], [3, 4, 5]], [0, [1, 2], [3, 4, 5]]), ([3], {"axis": "hstack"}, [[0], [1, 2], [3, 4, 5]], [[0, 1, 3]]), ([3], {"axis": "hstack"}, [[0, 1], [2, 3], [4, 5]], [[0, 2, 4], [1, 3, 5]]), - ([3], {"axis": "hstack"}, [[0, 1], [2, 3], [4, 5]], [[0, 2, 4], [1, 3, 5]]), ], ) def test_merge(tmpdir, args, kwargs, in_lists, expected): From 874b10881c80ae42860af8c1286c449c113c59d9 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:34:38 +0200 Subject: [PATCH 11/24] STY: Apply ruff/flake8-quotes rule Q000 Q000 Single quotes found but double quotes preferred --- doc/devel/matlab_example1.py | 4 ++-- doc/devel/matlab_example2.py | 2 +- nipype/interfaces/cmtk/cmtk.py | 8 ++++---- nipype/interfaces/cmtk/convert.py | 16 ++++++++-------- nipype/interfaces/cmtk/nbs.py | 6 +++--- nipype/interfaces/cmtk/nx.py | 10 +++++----- nipype/interfaces/cmtk/tests/test_nbs.py | 2 +- nipype/interfaces/dipy/tests/test_base.py | 8 ++++---- nipype/interfaces/freesurfer/model.py | 12 ++++++------ nipype/interfaces/freesurfer/petsurfer.py | 10 +++++----- nipype/interfaces/freesurfer/utils.py | 2 +- nipype/interfaces/fsl/model.py | 6 +++--- nipype/interfaces/nilearn.py | 2 +- nipype/interfaces/robex/preprocess.py | 6 +++--- nipype/interfaces/spm/model.py | 8 ++++---- nipype/interfaces/spm/preprocess.py | 4 ++-- nipype/interfaces/tests/test_io.py | 2 +- nipype/pipeline/engine/nodes.py | 4 ++-- nipype/pipeline/engine/tests/test_nodes.py | 12 ++++++------ nipype/pipeline/engine/utils.py | 8 ++++---- nipype/utils/subprocess.py | 2 +- tools/update_requirements.py | 2 +- tools/update_zenodo.py | 2 +- 23 files changed, 69 insertions(+), 69 deletions(-) diff --git a/doc/devel/matlab_example1.py b/doc/devel/matlab_example1.py index 12d1a1302a..9f15389669 100644 --- a/doc/devel/matlab_example1.py +++ b/doc/devel/matlab_example1.py @@ -11,7 +11,7 @@ class ConmapTxt2MatInputSpec(BaseInterfaceInputSpec): in_file = File(exists=True, mandatory=True) - out_file = File('cmatrix.mat', usedefault=True) + out_file = File("cmatrix.mat", usedefault=True) class ConmapTxt2MatOutputSpec(TraitedSpec): @@ -48,5 +48,5 @@ def _run_interface(self, runtime): def _list_outputs(self): outputs = self._outputs().get() - outputs['out_file'] = os.path.abspath(self.inputs.out_file) + outputs["out_file"] = os.path.abspath(self.inputs.out_file) return outputs diff --git a/doc/devel/matlab_example2.py b/doc/devel/matlab_example2.py index 224dc45d8c..7d75e307b1 100644 --- a/doc/devel/matlab_example2.py +++ b/doc/devel/matlab_example2.py @@ -4,7 +4,7 @@ class HelloWorldInputSpec(MatlabInputSpec): - name = traits.Str(mandatory=True, desc='Name of person to say hello to') + name = traits.Str(mandatory=True, desc="Name of person to say hello to") class HelloWorldOutputSpec(TraitedSpec): diff --git a/nipype/interfaces/cmtk/cmtk.py b/nipype/interfaces/cmtk/cmtk.py index 50902d5d1c..a5d267a42e 100644 --- a/nipype/interfaces/cmtk/cmtk.py +++ b/nipype/interfaces/cmtk/cmtk.py @@ -225,7 +225,7 @@ def cmat( # Add node information from specified parcellation scheme path, name, ext = split_filename(resolution_network_file) if ext == ".pck": - with open(resolution_network_file, 'rb') as f: + with open(resolution_network_file, "rb") as f: gp = pickle.load(f) elif ext == ".graphml": gp = nx.read_graphml(resolution_network_file) @@ -380,7 +380,7 @@ def cmat( fibdev.add_edge(u, v, weight=di["fiber_length_std"]) iflogger.info("Writing network as %s", matrix_name) - with open(op.abspath(matrix_name), 'wb') as f: + with open(op.abspath(matrix_name), "wb") as f: pickle.dump(G, f, pickle.HIGHEST_PROTOCOL) numfib_mlab = nx.to_numpy_array(numfib, dtype=int) @@ -396,7 +396,7 @@ def cmat( path, name, ext = split_filename(matrix_name) intersection_matrix_name = op.abspath(name + "_intersections") + ext iflogger.info("Writing intersection network as %s", intersection_matrix_name) - with open(intersection_matrix_name, 'wb') as f: + with open(intersection_matrix_name, "wb") as f: pickle.dump(I, f, pickle.HIGHEST_PROTOCOL) path, name, ext = split_filename(matrix_mat_name) @@ -1071,7 +1071,7 @@ def create_nodes(roi_file, resolution_network_file, out_filename): ) ) G.nodes[int(u)]["dn_position"] = (xyz[0], xyz[2], -xyz[1]) - with open(out_filename, 'wb') as f: + with open(out_filename, "wb") as f: pickle.dump(G, f, pickle.HIGHEST_PROTOCOL) return out_filename diff --git a/nipype/interfaces/cmtk/convert.py b/nipype/interfaces/cmtk/convert.py index 0c38fd3342..cc61084e57 100644 --- a/nipype/interfaces/cmtk/convert.py +++ b/nipype/interfaces/cmtk/convert.py @@ -18,7 +18,7 @@ def _read_pickle(fname): import pickle - with open(fname, 'rb') as f: + with open(fname, "rb") as f: return pickle.load(f) @@ -193,17 +193,17 @@ def _run_interface(self, runtime): for data in self.inputs.data_files: _, data_name, _ = split_filename(data) cda = cf.CData(name=data_name, src=data, fileformat="NumPy") - if 'lengths' in data_name: + if "lengths" in data_name: cda.dtype = "FinalFiberLengthArray" - if 'endpoints' in data_name: + if "endpoints" in data_name: cda.dtype = "FiberEndpoints" - if 'labels' in data_name: + if "labels" in data_name: cda.dtype = "FinalFiberLabels" a.add_connectome_data(cda) a.print_summary() _, name, ext = split_filename(self.inputs.out_file) - if ext != '.cff': + if ext != ".cff": ext = ".cff" cf.save_to_cff(a, op.abspath(name + ext)) @@ -212,7 +212,7 @@ def _run_interface(self, runtime): def _list_outputs(self): outputs = self._outputs().get() _, name, ext = split_filename(self.inputs.out_file) - if ext != '.cff': + if ext != ".cff": ext = ".cff" outputs["connectome_file"] = op.abspath(name + ext) return outputs @@ -280,7 +280,7 @@ def _run_interface(self, runtime): metadata.set_email("My Email") _, name, ext = split_filename(self.inputs.out_file) - if ext != '.cff': + if ext != ".cff": ext = ".cff" cf.save_to_cff(newcon, op.abspath(name + ext)) @@ -289,7 +289,7 @@ def _run_interface(self, runtime): def _list_outputs(self): outputs = self._outputs().get() _, name, ext = split_filename(self.inputs.out_file) - if ext != '.cff': + if ext != ".cff": ext = ".cff" outputs["connectome_file"] = op.abspath(name + ext) return outputs diff --git a/nipype/interfaces/cmtk/nbs.py b/nipype/interfaces/cmtk/nbs.py index b63144cb50..c60714450a 100644 --- a/nipype/interfaces/cmtk/nbs.py +++ b/nipype/interfaces/cmtk/nbs.py @@ -23,7 +23,7 @@ def _read_pickle(fname): - with open(fname, 'rb') as f: + with open(fname, "rb") as f: return pickle.load(f) @@ -174,13 +174,13 @@ def _run_interface(self, runtime): path = op.abspath("NBS_Result_" + details) iflogger.info(path) - with open(path, 'wb') as f: + with open(path, "wb") as f: pickle.dump(nbsgraph, f, pickle.HIGHEST_PROTOCOL) iflogger.info("Saving output NBS edge network as %s", path) pval_path = op.abspath("NBS_P_vals_" + details) iflogger.info(pval_path) - with open(pval_path, 'wb') as f: + with open(pval_path, "wb") as f: pickle.dump(nbs_pval_graph, f, pickle.HIGHEST_PROTOCOL) iflogger.info("Saving output p-value network as %s", pval_path) return runtime diff --git a/nipype/interfaces/cmtk/nx.py b/nipype/interfaces/cmtk/nx.py index d8d8314ba1..c932ccc3be 100644 --- a/nipype/interfaces/cmtk/nx.py +++ b/nipype/interfaces/cmtk/nx.py @@ -23,7 +23,7 @@ def _read_pickle(fname): - with open(fname, 'rb') as f: + with open(fname, "rb") as f: return pickle.load(f) @@ -203,7 +203,7 @@ def average_networks(in_files, ntwk_res_file, group_id): # Writes the networks and returns the name network_name = group_id + "_average.pck" - with open(op.abspath(network_name), 'wb') as f: + with open(op.abspath(network_name), "wb") as f: pickle.dump(avg_ntwk, f, pickle.HIGHEST_PROTOCOL) iflogger.info("Saving average network as %s", op.abspath(network_name)) avg_ntwk = fix_keys_for_gexf(avg_ntwk) @@ -487,7 +487,7 @@ def _run_interface(self, runtime): for key in list(node_measures.keys()): newntwk = add_node_data(node_measures[key], ntwk) out_file = op.abspath(self._gen_outfilename(key, "pck")) - with open(out_file, 'wb') as f: + with open(out_file, "wb") as f: pickle.dump(newntwk, f, pickle.HIGHEST_PROTOCOL) nodentwks.append(out_file) if isdefined(self.inputs.out_node_metrics_matlab): @@ -502,7 +502,7 @@ def _run_interface(self, runtime): for key in list(edge_measures.keys()): newntwk = add_edge_data(edge_measures[key], ntwk) out_file = op.abspath(self._gen_outfilename(key, "pck")) - with open(out_file, 'wb') as f: + with open(out_file, "wb") as f: pickle.dump(newntwk, f, pickle.HIGHEST_PROTOCOL) edgentwks.append(out_file) if isdefined(self.inputs.out_edge_metrics_matlab): @@ -527,7 +527,7 @@ def _run_interface(self, runtime): out_file = op.abspath( self._gen_outfilename(self.inputs.out_k_crust, "pck") ) - with open(out_file, 'wb') as f: + with open(out_file, "wb") as f: pickle.dump(ntwk_measures[key], f, pickle.HIGHEST_PROTOCOL) kntwks.append(out_file) gpickled.extend(kntwks) diff --git a/nipype/interfaces/cmtk/tests/test_nbs.py b/nipype/interfaces/cmtk/tests/test_nbs.py index efc8aed678..f6119e0e76 100644 --- a/nipype/interfaces/cmtk/tests/test_nbs.py +++ b/nipype/interfaces/cmtk/tests/test_nbs.py @@ -21,7 +21,7 @@ def creating_graphs(tmpdir): G = nx.from_numpy_array(graph) out_file = tmpdir.strpath + graphnames[idx] + ".pck" # Save as pck file - with open(out_file, 'wb') as f: + with open(out_file, "wb") as f: pickle.dump(G, f, pickle.HIGHEST_PROTOCOL) graphlist.append(out_file) return graphlist diff --git a/nipype/interfaces/dipy/tests/test_base.py b/nipype/interfaces/dipy/tests/test_base.py index 015215054d..e6899fd141 100644 --- a/nipype/interfaces/dipy/tests/test_base.py +++ b/nipype/interfaces/dipy/tests/test_base.py @@ -127,19 +127,19 @@ def test_get_default_args(): def test(dummy=11, x=3): return dummy, x - @deprecated_params('x', None, '0.3', '0.5', alternative='test2.y') + @deprecated_params("x", None, "0.3", "0.5", alternative="test2.y") def test2(dummy=11, x=3): return dummy, x - @deprecated_params(['dummy', 'x'], None, '0.3', alternative='test2.y') + @deprecated_params(["dummy", "x"], None, "0.3", alternative="test2.y") def test3(dummy=11, x=3): return dummy, x - @deprecated_params(['dummy', 'x'], None, '0.3', '0.5', alternative='test2.y') + @deprecated_params(["dummy", "x"], None, "0.3", "0.5", alternative="test2.y") def test4(dummy=11, x=3): return dummy, x - expected_res = {'dummy': 11, 'x': 3} + expected_res = {"dummy": 11, "x": 3} for func in [test, test2, test3, test4]: assert get_default_args(func) == expected_res diff --git a/nipype/interfaces/freesurfer/model.py b/nipype/interfaces/freesurfer/model.py index 6376c1b971..24b77f2810 100644 --- a/nipype/interfaces/freesurfer/model.py +++ b/nipype/interfaces/freesurfer/model.py @@ -451,9 +451,9 @@ class GLMFitInputSpec(FSTraitedSpec): sim_done_file = File( argstr="--sim-done %s", desc="create file when simulation finished" ) - _ext_xor = ['nii', 'nii_gz'] - nii = traits.Bool(argstr='--nii', desc='save outputs as nii', xor=_ext_xor) - nii_gz = traits.Bool(argstr='--nii.gz', desc='save outputs as nii.gz', xor=_ext_xor) + _ext_xor = ["nii", "nii_gz"] + nii = traits.Bool(argstr="--nii", desc="save outputs as nii", xor=_ext_xor) + nii_gz = traits.Bool(argstr="--nii.gz", desc="save outputs as nii.gz", xor=_ext_xor) class GLMFitOutputSpec(TraitedSpec): @@ -511,11 +511,11 @@ def _list_outputs(self): outputs["glm_dir"] = glmdir if isdefined(self.inputs.nii_gz): - ext = 'nii.gz' + ext = "nii.gz" elif isdefined(self.inputs.nii): - ext = 'nii' + ext = "nii" else: - ext = 'mgh' + ext = "mgh" # Assign the output files that always get created outputs["beta_file"] = os.path.join(glmdir, f"beta.{ext}") diff --git a/nipype/interfaces/freesurfer/petsurfer.py b/nipype/interfaces/freesurfer/petsurfer.py index 4505985127..958373a34f 100644 --- a/nipype/interfaces/freesurfer/petsurfer.py +++ b/nipype/interfaces/freesurfer/petsurfer.py @@ -125,10 +125,10 @@ class GTMSeg(FSCommand): def _list_outputs(self): outputs = self.output_spec().get() - outputs['out_file'] = os.path.join( + outputs["out_file"] = os.path.join( self.inputs.subjects_dir, self.inputs.subject_id, - 'mri', + "mri", self.inputs.out_file, ) return outputs @@ -516,7 +516,7 @@ class GTMPVC(FSCommand): def _format_arg(self, name, spec, val): # Values taken from # https://github.com/freesurfer/freesurfer/blob/fs-7.2/mri_gtmpvc/mri_gtmpvc.cpp#L115-L122 - if name == 'optimization_schema': + if name == "optimization_schema": return ( spec.argstr % { @@ -530,8 +530,8 @@ def _format_arg(self, name, spec, val): "MB3": 8, }[val] ) - if name == 'mg': - return spec.argstr % (val[0], ' '.join(val[1])) + if name == "mg": + return spec.argstr % (val[0], " ".join(val[1])) return super()._format_arg(name, spec, val) def _list_outputs(self): diff --git a/nipype/interfaces/freesurfer/utils.py b/nipype/interfaces/freesurfer/utils.py index 777f42f019..c0abc8ca98 100644 --- a/nipype/interfaces/freesurfer/utils.py +++ b/nipype/interfaces/freesurfer/utils.py @@ -1967,7 +1967,7 @@ def _format_arg(self, name, spec, value): if name == "lta_in" and self.inputs.invert_lta_in: spec = "--lta-inv %s" if name in ("fsl_out", "lta_out") and value is True: - value = self._list_outputs()[f'{name[:3]}_file'] + value = self._list_outputs()[f"{name[:3]}_file"] return super()._format_arg(name, spec, value) def _list_outputs(self): diff --git a/nipype/interfaces/fsl/model.py b/nipype/interfaces/fsl/model.py index 989c785335..e5a91030e9 100644 --- a/nipype/interfaces/fsl/model.py +++ b/nipype/interfaces/fsl/model.py @@ -821,9 +821,9 @@ class FILMGLS(FSLCommand): def __init__(self, **inputs): super(FILMGLS, self).__init__(**inputs) if Info.version() and LooseVersion(Info.version()) > LooseVersion("5.0.6"): - if 'output_type' not in inputs: - if isdefined(self.inputs.mode) and self.inputs.mode == 'surface': - self.inputs.output_type = 'GIFTI' + if "output_type" not in inputs: + if isdefined(self.inputs.mode) and self.inputs.mode == "surface": + self.inputs.output_type = "GIFTI" def _get_pe_files(self, cwd): files = None diff --git a/nipype/interfaces/nilearn.py b/nipype/interfaces/nilearn.py index df6413320e..7ca607d4dc 100644 --- a/nipype/interfaces/nilearn.py +++ b/nipype/interfaces/nilearn.py @@ -152,7 +152,7 @@ def _process_inputs(self): if self.inputs.include_global: global_label_data = label_data.dataobj.sum(axis=3) # sum across all regions global_label_data = ( - np.rint(global_label_data).clip(0, 1).astype('u1') + np.rint(global_label_data).clip(0, 1).astype("u1") ) # binarize global_label_data = self._4d(global_label_data, label_data.affine) global_masker = nl.NiftiLabelsMasker( diff --git a/nipype/interfaces/robex/preprocess.py b/nipype/interfaces/robex/preprocess.py index b2e92e94cb..6f3fdbf00a 100644 --- a/nipype/interfaces/robex/preprocess.py +++ b/nipype/interfaces/robex/preprocess.py @@ -16,7 +16,7 @@ class RobexInputSpec(CommandLineInputSpec): position=1, argstr="%s", hash_files=False, - name_template='%s_brain', + name_template="%s_brain", name_source=["in_file"], keep_extension=True, ) @@ -25,7 +25,7 @@ class RobexInputSpec(CommandLineInputSpec): position=2, argstr="%s", hash_files=False, - name_template='%s_brainmask', + name_template="%s_brainmask", name_source=["in_file"], keep_extension=True, ) @@ -61,4 +61,4 @@ class RobexSegment(CommandLine): input_spec = RobexInputSpec output_spec = RobexOutputSpec - _cmd = 'runROBEX.sh' + _cmd = "runROBEX.sh" diff --git a/nipype/interfaces/spm/model.py b/nipype/interfaces/spm/model.py index de5447b4b7..36fde88fc8 100644 --- a/nipype/interfaces/spm/model.py +++ b/nipype/interfaces/spm/model.py @@ -348,17 +348,17 @@ def _list_outputs(self): if contrast: outputs["con_images"] = [ - os.path.join(pth, cont) for cont in contrast if 'con' in cont + os.path.join(pth, cont) for cont in contrast if "con" in cont ] outputs["ess_images"] = [ - os.path.join(pth, cont) for cont in contrast if 'ess' in cont + os.path.join(pth, cont) for cont in contrast if "ess" in cont ] if contrast_spm: outputs["spmT_images"] = [ - os.path.join(pth, cont) for cont in contrast_spm if 'spmT' in cont + os.path.join(pth, cont) for cont in contrast_spm if "spmT" in cont ] outputs["spmF_images"] = [ - os.path.join(pth, cont) for cont in contrast_spm if 'spmF' in cont + os.path.join(pth, cont) for cont in contrast_spm if "spmF" in cont ] outputs["mask_image"] = os.path.join(pth, f"mask.{outtype}") diff --git a/nipype/interfaces/spm/preprocess.py b/nipype/interfaces/spm/preprocess.py index a0a81cf3a1..f7f124b5e6 100644 --- a/nipype/interfaces/spm/preprocess.py +++ b/nipype/interfaces/spm/preprocess.py @@ -335,11 +335,11 @@ class ApplyVDM(SPMCommand): def _format_arg(self, opt, spec, val): """Convert input to appropriate format for spm""" - if opt == 'in_files': + if opt == "in_files": return scans_for_fnames( ensure_list(val), keep4d=False, separate_sessions=False ) - if opt == 'vdmfile': + if opt == "vdmfile": return scans_for_fname(ensure_list(val)) return super()._format_arg(opt, spec, val) diff --git a/nipype/interfaces/tests/test_io.py b/nipype/interfaces/tests/test_io.py index 75a17481ee..94451e7996 100644 --- a/nipype/interfaces/tests/test_io.py +++ b/nipype/interfaces/tests/test_io.py @@ -707,7 +707,7 @@ def _mock_get_ssh_client(self): def test_ExportFile(tmp_path): test_in = tmp_path / "in.txt" - test_in.write_text("test string", encoding='utf-8') + test_in.write_text("test string", encoding="utf-8") i = nio.ExportFile() i.inputs.in_file = str(test_in) i.inputs.out_file = str(tmp_path / "out.tsv") diff --git a/nipype/pipeline/engine/nodes.py b/nipype/pipeline/engine/nodes.py index 31ee29e04d..7c3447c200 100644 --- a/nipype/pipeline/engine/nodes.py +++ b/nipype/pipeline/engine/nodes.py @@ -755,10 +755,10 @@ def _tab(text): if not text: return "" - return indent(text, '\t') + return indent(text, "\t") msg = f"Exception raised while executing Node {self.name}.\n\n" - if hasattr(runtime, 'cmdline'): + if hasattr(runtime, "cmdline"): msg += ( f"Cmdline:\n{_tab(runtime.cmdline)}\n" f"Stdout:\n{_tab(runtime.stdout)}\n" diff --git a/nipype/pipeline/engine/tests/test_nodes.py b/nipype/pipeline/engine/tests/test_nodes.py index 1edf30f329..983fcf46fd 100644 --- a/nipype/pipeline/engine/tests/test_nodes.py +++ b/nipype/pipeline/engine/tests/test_nodes.py @@ -339,7 +339,7 @@ def _producer(num=1, deadly_num=7): class FailCommandLine(nib.CommandLine): input_spec = nib.CommandLineInputSpec output_spec = nib.TraitedSpec - _cmd = 'nipype-node-execution-fail' + _cmd = "nipype-node-execution-fail" def test_NodeExecutionError(tmp_path, monkeypatch): @@ -348,18 +348,18 @@ def test_NodeExecutionError(tmp_path, monkeypatch): monkeypatch.chdir(tmp_path) # create basic executable and add to PATH - exebin = tmp_path / 'bin' + exebin = tmp_path / "bin" exebin.mkdir() - exe = exebin / 'nipype-node-execution-fail' + exe = exebin / "nipype-node-execution-fail" exe.write_text( '#!/bin/bash\necho "Running"\necho "This should fail" >&2\nexit 1', - encoding='utf-8', + encoding="utf-8", ) exe.chmod(exe.stat().st_mode | stat.S_IEXEC) monkeypatch.setenv("PATH", str(exe.parent.absolute()), prepend=os.pathsep) # Test with cmdline interface - cmd = pe.Node(FailCommandLine(), name="cmd-fail", base_dir='cmd') + cmd = pe.Node(FailCommandLine(), name="cmd-fail", base_dir="cmd") with pytest.raises(pe.nodes.NodeExecutionError) as exc: cmd.run() error_msg = str(exc.value) @@ -372,7 +372,7 @@ def test_NodeExecutionError(tmp_path, monkeypatch): def fail(): raise Exception("Functions can fail too") - func = pe.Node(niu.Function(function=fail), name='func-fail', base_dir='func') + func = pe.Node(niu.Function(function=fail), name="func-fail", base_dir="func") with pytest.raises(pe.nodes.NodeExecutionError) as exc: func.run() error_msg = str(exc.value) diff --git a/nipype/pipeline/engine/utils.py b/nipype/pipeline/engine/utils.py index 65c6c77888..6dbeadbae6 100644 --- a/nipype/pipeline/engine/utils.py +++ b/nipype/pipeline/engine/utils.py @@ -124,7 +124,7 @@ def write_node_report(node, result=None, is_mapnode=False): if result is None: logger.debug('[Node] Writing pre-exec report to "%s"', report_file) - report_file.write_text("\n".join(lines), encoding='utf-8') + report_file.write_text("\n".join(lines), encoding="utf-8") return logger.debug('[Node] Writing post-exec report to "%s"', report_file) @@ -137,7 +137,7 @@ def write_node_report(node, result=None, is_mapnode=False): outputs = result.outputs if outputs is None: lines += ["None"] - report_file.write_text("\n".join(lines), encoding='utf-8') + report_file.write_text("\n".join(lines), encoding="utf-8") return if isinstance(outputs, Bunch): @@ -162,7 +162,7 @@ def write_node_report(node, result=None, is_mapnode=False): subnode_report_files.append("subnode %d : %s" % (i, subnode_file)) lines.append(write_rst_list(subnode_report_files)) - report_file.write_text("\n".join(lines), encoding='utf-8') + report_file.write_text("\n".join(lines), encoding="utf-8") return lines.append(write_rst_header("Runtime info", level=1)) @@ -204,7 +204,7 @@ def write_node_report(node, result=None, is_mapnode=False): write_rst_dict(result.runtime.environ), ] - report_file.write_text("\n".join(lines), encoding='utf-8') + report_file.write_text("\n".join(lines), encoding="utf-8") def write_report(node, report_type=None, is_mapnode=False): diff --git a/nipype/utils/subprocess.py b/nipype/utils/subprocess.py index acd6b63256..804267f3d2 100644 --- a/nipype/utils/subprocess.py +++ b/nipype/utils/subprocess.py @@ -101,7 +101,7 @@ def run_command(runtime, output=None, timeout=0.01, write_cmdline=False): stderr = open(errfile, "wb") if write_cmdline: - (Path(runtime.cwd) / "command.txt").write_text(cmdline, encoding='utf-8') + (Path(runtime.cwd) / "command.txt").write_text(cmdline, encoding="utf-8") proc = Popen( cmdline, diff --git a/tools/update_requirements.py b/tools/update_requirements.py index b7a8a6cf8e..782cab14b4 100755 --- a/tools/update_requirements.py +++ b/tools/update_requirements.py @@ -15,4 +15,4 @@ # Write requirements lines[1:-1] = requirements -reqs.write_text("\n".join(lines), encoding='utf-8') +reqs.write_text("\n".join(lines), encoding="utf-8") diff --git a/tools/update_zenodo.py b/tools/update_zenodo.py index 359740363b..a541db262d 100755 --- a/tools/update_zenodo.py +++ b/tools/update_zenodo.py @@ -78,5 +78,5 @@ def decommify(name): zenodo["creators"] = creators zenodo_file.write_text( - "%s\n" % json.dumps(zenodo, indent=2, ensure_ascii=False), encoding='utf-8' + "%s\n" % json.dumps(zenodo, indent=2, ensure_ascii=False), encoding="utf-8" ) From 778ab94b50e0cc787b4b4ecf8332ee71b2e47340 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:35:22 +0200 Subject: [PATCH 12/24] STY: Apply ruff/flake8-quotes rule Q003 Q003 Change outer quotes to avoid escaping inner quotes --- nipype/algorithms/confounds.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/algorithms/confounds.py b/nipype/algorithms/confounds.py index 5e3588f4fc..bbb59c3548 100644 --- a/nipype/algorithms/confounds.py +++ b/nipype/algorithms/confounds.py @@ -53,7 +53,7 @@ class ComputeDVARSInputSpec(BaseInterfaceInputSpec): variance_tol = traits.Float( 1e-7, usedefault=True, - desc="maximum variance to consider \"close to\" zero for the purposes of removal", + desc='maximum variance to consider "close to" zero for the purposes of removal', ) save_std = traits.Bool(True, usedefault=True, desc="save standardized DVARS") save_nstd = traits.Bool(False, usedefault=True, desc="save non-standardized DVARS") From 7b23137f69a282777fe738acc72270c631e4311c Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 19:34:24 +0200 Subject: [PATCH 13/24] STY: Apply ruff rule RUF100 RUF100 Unused blanket `noqa` directive --- nipype/sphinxext/apidoc/docstring.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/sphinxext/apidoc/docstring.py b/nipype/sphinxext/apidoc/docstring.py index cbecc0a5de..f235a86d7e 100644 --- a/nipype/sphinxext/apidoc/docstring.py +++ b/nipype/sphinxext/apidoc/docstring.py @@ -68,7 +68,7 @@ class InterfaceDocstring(NipypeDocstring): def __init__( self, docstring, config=None, app=None, what="", name="", obj=None, options=None ): - # type: (Union[unicode, List[unicode]], SphinxConfig, Sphinx, unicode, unicode, Any, Any) -> None # NOQA + # type: (Union[unicode, List[unicode]], SphinxConfig, Sphinx, unicode, unicode, Any, Any) -> None super().__init__(docstring, config, app, what, name, obj, options) cmd = getattr(obj, "_cmd", "") From adf037f9c735a19ccfbdf60919945d4c62d0986e Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:38:17 +0200 Subject: [PATCH 14/24] STY: Apply ruff/pyupgrade rule UP008 UP008 Use `super()` instead of `super(__class__, self)` --- nipype/interfaces/fsl/model.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/fsl/model.py b/nipype/interfaces/fsl/model.py index e5a91030e9..3d9786171b 100644 --- a/nipype/interfaces/fsl/model.py +++ b/nipype/interfaces/fsl/model.py @@ -819,7 +819,7 @@ class FILMGLS(FSLCommand): input_spec = FILMGLSInputSpec505 def __init__(self, **inputs): - super(FILMGLS, self).__init__(**inputs) + super().__init__(**inputs) if Info.version() and LooseVersion(Info.version()) > LooseVersion("5.0.6"): if "output_type" not in inputs: if isdefined(self.inputs.mode) and self.inputs.mode == "surface": From c9ee51230a758ebe32f942e945f1a6aa4b9d4f21 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 14:07:38 +0200 Subject: [PATCH 15/24] STY: Apply ruff/pyupgrade rule UP032 UP032 Use f-string instead of `format` call Co-authored-by: Chris Markiewicz --- nipype/algorithms/confounds.py | 13 +++---- nipype/caching/memory.py | 2 +- nipype/interfaces/ants/registration.py | 28 +++++++-------- nipype/interfaces/base/core.py | 4 +-- nipype/interfaces/base/specs.py | 5 +-- nipype/interfaces/cmtk/parcellation.py | 11 ++---- nipype/interfaces/dtitk/base.py | 5 ++- nipype/interfaces/freesurfer/preprocess.py | 12 ++----- .../freesurfer/tests/test_preprocess.py | 10 ++---- .../interfaces/freesurfer/tests/test_utils.py | 5 +-- nipype/interfaces/freesurfer/utils.py | 24 ++++--------- nipype/interfaces/fsl/preprocess.py | 6 ++-- nipype/interfaces/fsl/tests/test_maths.py | 8 ++--- .../interfaces/fsl/tests/test_preprocess.py | 16 ++------- nipype/interfaces/fsl/tests/test_utils.py | 15 +++----- nipype/interfaces/fsl/utils.py | 23 +++++------- nipype/interfaces/io.py | 35 +++++-------------- nipype/interfaces/niftyreg/reg.py | 6 +--- nipype/interfaces/nilearn.py | 12 +++---- nipype/interfaces/slicer/generate_classes.py | 8 ++--- nipype/interfaces/spm/utils.py | 31 ++++++---------- nipype/interfaces/workbench/metric.py | 3 +- nipype/pipeline/engine/utils.py | 18 +++------- nipype/pipeline/engine/workflows.py | 3 +- nipype/pipeline/plugins/base.py | 7 ++-- nipype/pipeline/plugins/dagman.py | 6 ++-- nipype/pipeline/plugins/lsf.py | 6 +--- nipype/pipeline/plugins/sge.py | 32 +++++------------ nipype/pipeline/plugins/sgegraph.py | 9 +---- nipype/pipeline/plugins/slurmgraph.py | 9 +---- nipype/pipeline/plugins/tools.py | 6 ++-- nipype/scripts/utils.py | 5 +-- nipype/sphinxext/apidoc/docstring.py | 8 ++--- nipype/utils/filemanip.py | 6 +--- nipype/utils/tests/test_filemanip.py | 8 ++--- tools/checkspecs.py | 10 ++---- 36 files changed, 117 insertions(+), 298 deletions(-) diff --git a/nipype/algorithms/confounds.py b/nipype/algorithms/confounds.py index bbb59c3548..06fc41c90e 100644 --- a/nipype/algorithms/confounds.py +++ b/nipype/algorithms/confounds.py @@ -608,8 +608,7 @@ def _run_interface(self, runtime): if len(imgseries.shape) != 4: raise ValueError( - "{} expected a 4-D nifti file. Input {} has " - "{} dimensions (shape {})".format( + "{} expected a 4-D nifti file. Input {} has {} dimensions (shape {})".format( # noqa: UP032 self._header, self.inputs.realigned_file, len(imgseries.shape), @@ -648,8 +647,7 @@ def _run_interface(self, runtime): if TR == 0: raise ValueError( - "{} cannot detect repetition time from image - " - "Set the repetition_time input".format(self._header) + f"{self._header} cannot detect repetition time from image - Set the repetition_time input" ) if isdefined(self.inputs.variance_threshold): @@ -753,8 +751,7 @@ def _run_interface(self, runtime): f.write("\t".join(["component"] + list(metadata.keys())) + "\n") for i in zip(components_names, *metadata.values()): f.write( - "{0[0]}\t{0[1]}\t{0[2]:.10f}\t" - "{0[3]:.10f}\t{0[4]:.10f}\t{0[5]}\n".format(i) + f"{i[0]}\t{i[1]}\t{i[2]:.10f}\t{i[3]:.10f}\t{i[4]:.10f}\t{i[5]}\n" ) return runtime @@ -1398,9 +1395,7 @@ def compute_noise_components( if imgseries.shape[:3] != mask.shape: raise ValueError( "Inputs for CompCor, timeseries and mask, do not have " - "matching spatial dimensions ({} and {}, respectively)".format( - imgseries.shape[:3], mask.shape - ) + f"matching spatial dimensions ({imgseries.shape[:3]} and {mask.shape}, respectively)" ) voxel_timecourses = imgseries[mask, :] diff --git a/nipype/caching/memory.py b/nipype/caching/memory.py index a1d45ffff2..755b7c9fb9 100644 --- a/nipype/caching/memory.py +++ b/nipype/caching/memory.py @@ -86,7 +86,7 @@ def __call__(self, **kwargs): return out def __repr__(self): - return "{}({}.{}), base_dir={})".format( + return "{}({}.{}), base_dir={})".format( # noqa: UP032 self.__class__.__name__, self.interface.__module__, self.interface.__name__, diff --git a/nipype/interfaces/ants/registration.py b/nipype/interfaces/ants/registration.py index 91b131bbf3..9e1d0d5aa4 100644 --- a/nipype/interfaces/ants/registration.py +++ b/nipype/interfaces/ants/registration.py @@ -204,7 +204,7 @@ def _transformation_constructor(self): return "".join(retval) def _regularization_constructor(self): - return "--regularization {}[{},{}]".format( + return "--regularization {}[{},{}]".format( # noqa: UP032 self.inputs.regularization, self.inputs.regularization_gradient_field_sigma, self.inputs.regularization_deformation_field_sigma, @@ -1241,7 +1241,7 @@ def _format_winsorize_image_intensities(self): ) ) self._quantilesDone = True - return "--winsorize-image-intensities [ {}, {} ]".format( + return "--winsorize-image-intensities [ {}, {} ]".format( # noqa: UP032 self.inputs.winsorize_lower_quantile, self.inputs.winsorize_upper_quantile, ) @@ -1268,12 +1268,12 @@ def _get_initial_transform_filenames(self): def _format_arg(self, opt, spec, val): if opt == "fixed_image_mask": if isdefined(self.inputs.moving_image_mask): - return "--masks [ {}, {} ]".format( + return "--masks [ {}, {} ]".format( # noqa: UP032 self.inputs.fixed_image_mask, self.inputs.moving_image_mask, ) else: - return "--masks %s" % self.inputs.fixed_image_mask + return "--masks {}".format(self.inputs.fixed_image_mask) # noqa: UP032 elif opt == "transforms": return self._format_registration() elif opt == "initial_moving_transform": @@ -1308,18 +1308,20 @@ def _format_arg(self, opt, spec, val): out_filename = self._get_outputfilenames(inverse=False) inv_out_filename = self._get_outputfilenames(inverse=True) if out_filename and inv_out_filename: - return "--output [ {}, {}, {} ]".format( + return "--output [ {}, {}, {} ]".format( # noqa: UP032 self.inputs.output_transform_prefix, out_filename, inv_out_filename, ) elif out_filename: - return "--output [ {}, {} ]".format( + return "--output [ {}, {} ]".format( # noqa: UP032 self.inputs.output_transform_prefix, out_filename, ) else: - return "--output %s" % self.inputs.output_transform_prefix + return "--output {}".format( # noqa: UP032 + self.inputs.output_transform_prefix, + ) elif opt == "winsorize_upper_quantile" or opt == "winsorize_lower_quantile": if not self._quantilesDone: return self._format_winsorize_image_intensities() @@ -1590,7 +1592,7 @@ class MeasureImageSimilarity(ANTSCommand): def _metric_constructor(self): retval = ( '--metric {metric}["{fixed_image}","{moving_image}",{metric_weight},' - "{radius_or_number_of_bins},{sampling_strategy},{sampling_percentage}]".format( + "{radius_or_number_of_bins},{sampling_strategy},{sampling_percentage}]".format( # noqa: UP032 metric=self.inputs.metric, fixed_image=self.inputs.fixed_image, moving_image=self.inputs.moving_image, @@ -1604,13 +1606,13 @@ def _metric_constructor(self): def _mask_constructor(self): if self.inputs.moving_image_mask: - retval = '--masks ["{fixed_image_mask}","{moving_image_mask}"]'.format( + retval = '--masks ["{fixed_image_mask}","{moving_image_mask}"]'.format( # noqa: UP032 fixed_image_mask=self.inputs.fixed_image_mask, moving_image_mask=self.inputs.moving_image_mask, ) else: - retval = '--masks "{fixed_image_mask}"'.format( - fixed_image_mask=self.inputs.fixed_image_mask + retval = '--masks "{}"'.format( # noqa: UP032 + fixed_image_mask=self.inputs.fixed_image_mask, ) return retval @@ -1870,9 +1872,7 @@ def _list_outputs(self): f"00_{self.inputs.output_prefix}_AffineTransform.mat" ) outputs["displacement_field"] = os.path.abspath( - "01_{}_DisplacementFieldTransform.nii.gz".format( - self.inputs.output_prefix - ) + f"01_{self.inputs.output_prefix}_DisplacementFieldTransform.nii.gz" ) if self.inputs.process == "assemble": outputs["out_file"] = os.path.abspath(self.inputs.out_file) diff --git a/nipype/interfaces/base/core.py b/nipype/interfaces/base/core.py index 8fadd9cc2d..2812e641b4 100644 --- a/nipype/interfaces/base/core.py +++ b/nipype/interfaces/base/core.py @@ -849,8 +849,8 @@ def _filename_from_source(self, name, chain=None): if not isinstance(ns, (str, bytes)): raise ValueError( - "name_source of '{}' trait should be an input trait " - "name, but a type {} object was found".format(name, type(ns)) + f"name_source of '{name}' trait should be an input trait " + f"name, but a type {type(ns)} object was found" ) if isdefined(getattr(self.inputs, ns)): diff --git a/nipype/interfaces/base/specs.py b/nipype/interfaces/base/specs.py index defbca7f43..120f07dd60 100644 --- a/nipype/interfaces/base/specs.py +++ b/nipype/interfaces/base/specs.py @@ -142,10 +142,7 @@ def _deprecated_warn(self, obj, name, old, new): raise TraitError(msg) else: if trait_spec.new_name: - msg += "Unsetting old value {}; setting new value {}.".format( - name, - trait_spec.new_name, - ) + msg += f"Unsetting old value {name}; setting new value {trait_spec.new_name}." warn(msg) if trait_spec.new_name: self.trait_set( diff --git a/nipype/interfaces/cmtk/parcellation.py b/nipype/interfaces/cmtk/parcellation.py index 98e3166be0..d9a7ab1bda 100644 --- a/nipype/interfaces/cmtk/parcellation.py +++ b/nipype/interfaces/cmtk/parcellation.py @@ -315,15 +315,10 @@ def create_annot_label(subject_id, subjects_dir, fs_dir, parcellation_name): ) runCmd(mri_cmd, log) runCmd("mris_volmask %s" % subject_id, log) - mri_cmd = 'mri_convert -i "{}/mri/ribbon.mgz" -o "{}/mri/ribbon.nii.gz"'.format( - op.join(subjects_dir, subject_id), - op.join(subjects_dir, subject_id), - ) + subject_path = op.join(subjects_dir, subject_id) + mri_cmd = f'mri_convert -i "{subject_path}/mri/ribbon.mgz" -o "{subject_path}/mri/ribbon.nii.gz"' runCmd(mri_cmd, log) - mri_cmd = 'mri_convert -i "{}/mri/aseg.mgz" -o "{}/mri/aseg.nii.gz"'.format( - op.join(subjects_dir, subject_id), - op.join(subjects_dir, subject_id), - ) + mri_cmd = f'mri_convert -i "{subject_path}/mri/aseg.mgz" -o "{subject_path}/mri/aseg.nii.gz"' runCmd(mri_cmd, log) iflogger.info("[ DONE ]") diff --git a/nipype/interfaces/dtitk/base.py b/nipype/interfaces/dtitk/base.py index 6f46f8d404..50a23896f4 100644 --- a/nipype/interfaces/dtitk/base.py +++ b/nipype/interfaces/dtitk/base.py @@ -42,11 +42,10 @@ def __init__(self, *args, **kwargs): rename_idx = classes.index("DTITKRenameMixin") new_name = classes[rename_idx + 1] warnings.warn( - "The {} interface has been renamed to {}\n" + f"The {dep_name} interface has been renamed to {new_name}\n" "Please see the documentation for DTI-TK " "interfaces, as some inputs have been " - "added or renamed for clarity." - "".format(dep_name, new_name), + "added or renamed for clarity.", DeprecationWarning, ) super().__init__(*args, **kwargs) diff --git a/nipype/interfaces/freesurfer/preprocess.py b/nipype/interfaces/freesurfer/preprocess.py index 5b2fd19a0b..80fc64567c 100644 --- a/nipype/interfaces/freesurfer/preprocess.py +++ b/nipype/interfaces/freesurfer/preprocess.py @@ -729,10 +729,7 @@ def cmdline(self): outdir = self._get_outdir() cmd = [] if not os.path.exists(outdir): - cmdstr = "{} -c \"import os; os.makedirs('{}')\"".format( - op.basename(sys.executable), - outdir, - ) + cmdstr = f"{op.basename(sys.executable)} -c \"import os; os.makedirs('{outdir}')\"" cmd.extend([cmdstr]) infofile = os.path.join(outdir, "shortinfo.txt") if not os.path.exists(infofile): @@ -741,12 +738,7 @@ def cmdline(self): files = self._get_filelist(outdir) for infile, outfile in files: if not os.path.exists(outfile): - single_cmd = "{}{} {} {}".format( - self._cmd_prefix, - self.cmd, - infile, - os.path.join(outdir, outfile), - ) + single_cmd = f"{self._cmd_prefix}{self.cmd} {infile} {os.path.join(outdir, outfile)}" cmd.extend([single_cmd]) return "; ".join(cmd) diff --git a/nipype/interfaces/freesurfer/tests/test_preprocess.py b/nipype/interfaces/freesurfer/tests/test_preprocess.py index ebbc8c6c75..ef2755ef61 100644 --- a/nipype/interfaces/freesurfer/tests/test_preprocess.py +++ b/nipype/interfaces/freesurfer/tests/test_preprocess.py @@ -65,11 +65,7 @@ def test_fitmsparams(create_files_in_directory): # .inputs based parameters setting fit.inputs.in_files = filelist fit.inputs.out_dir = outdir - assert fit.cmdline == "mri_ms_fitparms {} {} {}".format( - filelist[0], - filelist[1], - outdir, - ) + assert fit.cmdline == f"mri_ms_fitparms {filelist[0]} {filelist[1]} {outdir}" # constructor based parameter setting fit2 = freesurfer.FitMSParams( @@ -184,9 +180,7 @@ def test_bbregister(create_files_in_directory): base, _ = os.path.splitext(base) assert bbr.cmdline == ( - "bbregister --t2 --init-fsl " - "--reg {base}_bbreg_fsaverage.dat " - "--mov {full} --s fsaverage".format(full=filelist[0], base=base) + f"bbregister --t2 --init-fsl --reg {base}_bbreg_fsaverage.dat --mov {filelist[0]} --s fsaverage" ) diff --git a/nipype/interfaces/freesurfer/tests/test_utils.py b/nipype/interfaces/freesurfer/tests/test_utils.py index 323c04166d..4dab8124be 100644 --- a/nipype/interfaces/freesurfer/tests/test_utils.py +++ b/nipype/interfaces/freesurfer/tests/test_utils.py @@ -210,10 +210,7 @@ def test_mrisexpand(tmpdir): nd_res = expand_nd.run() # Commandlines differ - node_cmdline = ( - "mris_expand -T 60 -pial {cwd}/lh.pial {cwd}/lh.smoothwm " - "1 expandtmp".format(cwd=nd_res.runtime.cwd) - ) + node_cmdline = f"mris_expand -T 60 -pial {nd_res.runtime.cwd}/lh.pial {nd_res.runtime.cwd}/lh.smoothwm 1 expandtmp" assert nd_res.runtime.cmdline == node_cmdline # Check output diff --git a/nipype/interfaces/freesurfer/utils.py b/nipype/interfaces/freesurfer/utils.py index c0abc8ca98..bc2b6196c4 100644 --- a/nipype/interfaces/freesurfer/utils.py +++ b/nipype/interfaces/freesurfer/utils.py @@ -355,8 +355,7 @@ def _format_arg(self, name, spec, value): if ext != filemap[value]: if ext in filemap.values(): raise ValueError( - "Cannot create {} file with extension " - "{}".format(value, ext) + f"Cannot create {value} file with extension {ext}" ) else: logger.warning( @@ -595,8 +594,7 @@ def _format_arg(self, name, spec, value): if ext != filemap[value]: if ext in filemap.values(): raise ValueError( - "Cannot create {} file with extension " - "{}".format(value, ext) + f"Cannot create {value} file with extension {ext}" ) else: logger.warning( @@ -998,10 +996,8 @@ def _format_arg(self, name, spec, value): if len(value) == 2: return "-fminmax %.3f %.3f" % value else: - return "-fminmax {:.3f} {:.3f} -fmid {:.3f}".format( - value[0], - value[2], - value[1], + return ( + f"-fminmax {value[0]:.3f} {value[2]:.3f} -fmid {value[1]:.3f}" ) elif name == "annot_name" and isdefined(value): # Matching annot by name needs to strip the leading hemi and trailing @@ -1015,11 +1011,7 @@ def _format_arg(self, name, spec, value): def _run_interface(self, runtime): if not isdefined(self.inputs.screenshot_stem): - stem = "{}_{}_{}".format( - self.inputs.subject_id, - self.inputs.hemi, - self.inputs.surface, - ) + stem = f"{self.inputs.subject_id}_{self.inputs.hemi}_{self.inputs.surface}" else: stem = self.inputs.screenshot_stem stem_args = self.inputs.stem_template_args @@ -1085,11 +1077,7 @@ def _write_tcl_script(self): def _list_outputs(self): outputs = self._outputs().get() if not isdefined(self.inputs.screenshot_stem): - stem = "{}_{}_{}".format( - self.inputs.subject_id, - self.inputs.hemi, - self.inputs.surface, - ) + stem = f"{self.inputs.subject_id}_{self.inputs.hemi}_{self.inputs.surface}" else: stem = self.inputs.screenshot_stem stem_args = self.inputs.stem_template_args diff --git a/nipype/interfaces/fsl/preprocess.py b/nipype/interfaces/fsl/preprocess.py index 2c12a8368a..12c07d0f4c 100644 --- a/nipype/interfaces/fsl/preprocess.py +++ b/nipype/interfaces/fsl/preprocess.py @@ -1319,9 +1319,9 @@ def _format_arg(self, name, spec, value): if name == "out_intensitymap_file": value = self._list_outputs()[name] value = [FNIRT.intensitymap_file_basename(v) for v in value] - assert len(set(value)) == 1, "Found different basenames for {}: {}".format( - name, value - ) + assert ( + len(set(value)) == 1 + ), f"Found different basenames for {name}: {value}" return spec.argstr % value[0] if name in list(self.filemap.keys()): return spec.argstr % self._list_outputs()[name] diff --git a/nipype/interfaces/fsl/tests/test_maths.py b/nipype/interfaces/fsl/tests/test_maths.py index 189fff8b3f..3d4a21fa83 100644 --- a/nipype/interfaces/fsl/tests/test_maths.py +++ b/nipype/interfaces/fsl/tests/test_maths.py @@ -401,9 +401,7 @@ def test_binarymaths(create_files_in_directory_plus_output_type): assert maths.cmdline == f"fslmaths a.nii -{op} b.nii c.nii" else: maths.inputs.operand_value = ent - assert maths.cmdline == "fslmaths a.nii -{} {:.8f} c.nii".format( - op, ent - ) + assert maths.cmdline == f"fslmaths a.nii -{op} {ent:.8f} c.nii" # Test that we don't need to ask for an out file for op in ops: @@ -461,9 +459,7 @@ def test_tempfilt(create_files_in_directory_plus_output_type): for win in windows: filt.inputs.highpass_sigma = win[0] filt.inputs.lowpass_sigma = win[1] - assert filt.cmdline == "fslmaths a.nii -bptf {:.6f} {:.6f} b.nii".format( - win[0], win[1] - ) + assert filt.cmdline == f"fslmaths a.nii -bptf {win[0]:.6f} {win[1]:.6f} b.nii" # Test that we don't need to ask for an out file filt = fsl.TemporalFilter(in_file="a.nii", highpass_sigma=64) diff --git a/nipype/interfaces/fsl/tests/test_preprocess.py b/nipype/interfaces/fsl/tests/test_preprocess.py index 2a93916706..d109effc52 100644 --- a/nipype/interfaces/fsl/tests/test_preprocess.py +++ b/nipype/interfaces/fsl/tests/test_preprocess.py @@ -240,12 +240,7 @@ def test_flirt(setup_flirt): pth, fname, ext = split_filename(infile) outfile = fsl_name(flirter, "%s_flirt" % fname) outmat = "%s_flirt.mat" % fname - realcmd = "flirt -in {} -ref {} -out {} -omat {}".format( - infile, - reffile, - outfile, - outmat, - ) + realcmd = f"flirt -in {infile} -ref {reffile} -out {outfile} -omat {outmat}" assert flirter.cmdline == realcmd # test apply_xfm option @@ -433,14 +428,7 @@ def test_fnirt(setup_flirt): " --iout=%s" % (infile, log, flag, strval, reffile, iout) ) elif item in ("in_fwhm", "intensity_mapping_model"): - cmd = "fnirt --in={} {}={} --logout={} --ref={} --iout={}".format( - infile, - flag, - strval, - log, - reffile, - iout, - ) + cmd = f"fnirt --in={infile} {flag}={strval} --logout={log} --ref={reffile} --iout={iout}" elif item.startswith("apply"): cmd = ( "fnirt %s=%s " diff --git a/nipype/interfaces/fsl/tests/test_utils.py b/nipype/interfaces/fsl/tests/test_utils.py index bfe895c6ee..feffe553e3 100644 --- a/nipype/interfaces/fsl/tests/test_utils.py +++ b/nipype/interfaces/fsl/tests/test_utils.py @@ -168,10 +168,7 @@ def test_overlay(create_files_in_directory_plus_output_type): ) assert ( overlay2.cmdline - == "overlay 1 0 {} -a {} 2.50 10.00 foo2_overlay.nii".format( - filelist[1], - filelist[0], - ) + == f"overlay 1 0 {filelist[1]} -a {filelist[0]} 2.50 10.00 foo2_overlay.nii" ) @@ -199,10 +196,7 @@ def test_slicer(create_files_in_directory_plus_output_type): slicer.inputs.out_file = "foo_bar.png" assert ( slicer.cmdline - == "slicer {} {} -L -i 10.000 20.000 -A 750 foo_bar.png".format( - filelist[0], - filelist[1], - ) + == f"slicer {filelist[0]} {filelist[1]} -L -i 10.000 20.000 -A 750 foo_bar.png" ) # .run based parameter setting @@ -317,9 +311,8 @@ def test_convertxfm(create_files_in_directory_plus_output_type): cvt2 = fsl.ConvertXFM( in_file=filelist[0], in_file2=filelist[1], concat_xfm=True, out_file="bar.mat" ) - assert cvt2.cmdline == "convert_xfm -omat bar.mat -concat {} {}".format( - filelist[1], - filelist[0], + assert ( + cvt2.cmdline == f"convert_xfm -omat bar.mat -concat {filelist[1]} {filelist[0]}" ) diff --git a/nipype/interfaces/fsl/utils.py b/nipype/interfaces/fsl/utils.py index 704fb77fef..25617b8061 100644 --- a/nipype/interfaces/fsl/utils.py +++ b/nipype/interfaces/fsl/utils.py @@ -1070,11 +1070,9 @@ def _format_arg(self, name, spec, value): else: return "1" if name == "show_negative_stats": - return "{} {:.2f} {:.2f}".format( - self.inputs.stat_image, - self.inputs.stat_thresh[0] * -1, - self.inputs.stat_thresh[1] * -1, - ) + thresh0 = self.inputs.stat_thresh[0] * -1 + thresh1 = self.inputs.stat_thresh[1] * -1 + return "{self.inputs.stat_image} {thresh0:.2f} {thresh1:.2f}" return super()._format_arg(name, spec, value) def _list_outputs(self): @@ -1085,10 +1083,9 @@ def _list_outputs(self): not isdefined(self.inputs.show_negative_stats) or not self.inputs.show_negative_stats ): - stem = "{}_and_{}".format( - split_filename(self.inputs.stat_image)[1], - split_filename(self.inputs.stat_image2)[1], - ) + image = split_filename(self.inputs.stat_image)[1] + image2 = split_filename(self.inputs.stat_image2)[1] + stem = f"{image}_and_{image2}" else: stem = split_filename(self.inputs.stat_image)[1] out_file = self._gen_fname(stem, suffix="_overlay") @@ -1455,11 +1452,7 @@ def _format_arg(self, name, spec, value): titledict = dict(fsl="MCFLIRT", spm="Realign") unitdict = dict(rot="radians", tra="mm") - title = "'{} estimated {} ({})'".format( - titledict[source], - value, - unitdict[value[:3]], - ) + title = f"'{titledict[source]} estimated {value} ({unitdict[value[:3]]})'" return f"-t {title} {sfstr} -a x,y,z" elif name == "plot_size": @@ -2580,7 +2573,7 @@ def _coords_to_trk(self, points, out_file): def _overload_extension(self, value, name): if name == "out_file": - return "{}.{}".format(value, self._outformat) + return f"{value}.{self._outformat}" def _run_interface(self, runtime): fname = self._in_file diff --git a/nipype/interfaces/io.py b/nipype/interfaces/io.py index 3efb7d680e..19f964a7f2 100644 --- a/nipype/interfaces/io.py +++ b/nipype/interfaces/io.py @@ -135,15 +135,11 @@ def _get_head_bucket(s3_resource, bucket_name): ) raise Exception(err_msg) else: - err_msg = "Unable to connect to bucket: {}. Error message:\n{}".format( - bucket_name, - exc, + err_msg = ( + f"Unable to connect to bucket: {bucket_name}. Error message:\n{exc}" ) except Exception as exc: - err_msg = "Unable to connect to bucket: {}. Error message:\n{}".format( - bucket_name, - exc, - ) + err_msg = f"Unable to connect to bucket: {bucket_name}. Error message:\n{exc}" raise Exception(err_msg) @@ -961,10 +957,7 @@ def _list_outputs(self): if not args: filelist = [fname for fname in bkt_files if re.match(template, fname)] if len(filelist) == 0: - msg = "Output key: {} Template: {} returned no files".format( - key, - template, - ) + msg = f"Output key: {key} Template: {template} returned no files" if self.inputs.raise_on_empty: raise OSError(msg) else: @@ -1009,10 +1002,7 @@ def _list_outputs(self): if re.match(filledtemplate, fname): outfiles.append(fname) if len(outfiles) == 0: - msg = "Output key: {} Template: {} returned no files".format( - key, - filledtemplate, - ) + msg = f"Output key: {key} Template: {filledtemplate} returned no files" if self.inputs.raise_on_empty: raise OSError(msg) else: @@ -1236,10 +1226,7 @@ def _list_outputs(self): if not args: filelist = glob.glob(template) if len(filelist) == 0: - msg = "Output key: {} Template: {} returned no files".format( - key, - template, - ) + msg = f"Output key: {key} Template: {template} returned no files" if self.inputs.raise_on_empty: raise OSError(msg) else: @@ -1281,10 +1268,7 @@ def _list_outputs(self): ) outfiles = glob.glob(filledtemplate) if len(outfiles) == 0: - msg = "Output key: {} Template: {} returned no files".format( - key, - filledtemplate, - ) + msg = f"Output key: {key} Template: {filledtemplate} returned no files" if self.inputs.raise_on_empty: raise OSError(msg) else: @@ -1454,9 +1438,8 @@ def _list_outputs(self): # Handle the case where nothing matched if not filelist: - msg = "No files were found matching {} template: {}".format( - field, - filled_template, + msg = ( + f"No files were found matching {field} template: {filled_template}" ) if self.inputs.raise_on_empty: raise OSError(msg) diff --git a/nipype/interfaces/niftyreg/reg.py b/nipype/interfaces/niftyreg/reg.py index 2c7657e6ae..d14b94dc6e 100644 --- a/nipype/interfaces/niftyreg/reg.py +++ b/nipype/interfaces/niftyreg/reg.py @@ -397,11 +397,7 @@ def _list_outputs(self): if self.inputs.vel_flag is True and isdefined(self.inputs.aff_file): cpp_file = os.path.abspath(outputs["cpp_file"]) flo_file = os.path.abspath(self.inputs.flo_file) - outputs["avg_output"] = "{} {} {}".format( - self.inputs.aff_file, - cpp_file, - flo_file, - ) + outputs["avg_output"] = f"{self.inputs.aff_file} {cpp_file} {flo_file}" else: cpp_file = os.path.abspath(outputs["cpp_file"]) flo_file = os.path.abspath(self.inputs.flo_file) diff --git a/nipype/interfaces/nilearn.py b/nipype/interfaces/nilearn.py index 7ca607d4dc..cfb38e4282 100644 --- a/nipype/interfaces/nilearn.py +++ b/nipype/interfaces/nilearn.py @@ -135,18 +135,14 @@ def _process_inputs(self): # check label list size if not np.isclose(int(n_labels), n_labels): raise ValueError( - "The label files {} contain invalid value {}. Check input.".format( - self.inputs.label_files, n_labels - ) + f"The label files {self.inputs.label_files} contain invalid value {n_labels}. Check input." ) if len(self.inputs.class_labels) != n_labels: raise ValueError( - "The length of class_labels {} does not " - "match the number of regions {} found in " - "label_files {}".format( - self.inputs.class_labels, n_labels, self.inputs.label_files - ) + f"The length of class_labels {self.inputs.class_labels} does not " + f"match the number of regions {n_labels} found in " + f"label_files {self.inputs.label_files}" ) if self.inputs.include_global: diff --git a/nipype/interfaces/slicer/generate_classes.py b/nipype/interfaces/slicer/generate_classes.py index a36dd6b55a..acddb887f6 100644 --- a/nipype/interfaces/slicer/generate_classes.py +++ b/nipype/interfaces/slicer/generate_classes.py @@ -327,9 +327,7 @@ def generate_class( ]: if not param.getElementsByTagName("channel"): raise RuntimeError( - "Insufficient XML specification: each element of type 'file', 'directory', 'image', 'geometry', 'transform', or 'table' requires 'channel' field.\n{}".format( - traitsParams - ) + f"Insufficient XML specification: each element of type 'file', 'directory', 'image', 'geometry', 'transform', or 'table' requires 'channel' field.\n{traitsParams}" ) elif ( param.getElementsByTagName("channel")[0].firstChild.nodeValue @@ -378,9 +376,7 @@ def generate_class( ) else: raise RuntimeError( - "Insufficient XML specification: each element of type 'file', 'directory', 'image', 'geometry', 'transform', or 'table' requires 'channel' field to be in ['input','output'].\n{}".format( - traitsParams - ) + f"Insufficient XML specification: each element of type 'file', 'directory', 'image', 'geometry', 'transform', or 'table' requires 'channel' field to be in ['input','output'].\n{traitsParams}" ) else: # For all other parameter types, they are implicitly only input types inputTraits.append( diff --git a/nipype/interfaces/spm/utils.py b/nipype/interfaces/spm/utils.py index 76944893e1..bc6a06edc6 100644 --- a/nipype/interfaces/spm/utils.py +++ b/nipype/interfaces/spm/utils.py @@ -105,22 +105,17 @@ def _make_matlab_command(self, _): self.inputs.mat = self._make_mat_file() if not isdefined(self.inputs.invmat): self.inputs.invmat = self._make_inv_file() - script = """ - target = '{}'; - moving = '{}'; + script = f""" + target = '{self.inputs.target}'; + moving = '{self.inputs.moving}'; targetv = spm_vol(target); movingv = spm_vol(moving); x = spm_coreg(targetv, movingv); M = spm_matrix(x); - save('{}' , 'M' ); + save('{self.inputs.mat}' , 'M' ); M = inv(M); - save('{}','M') - """.format( - self.inputs.target, - self.inputs.moving, - self.inputs.mat, - self.inputs.invmat, - ) + save('{self.inputs.invmat}','M') + """ return script def _list_outputs(self): @@ -166,10 +161,10 @@ def _make_matlab_command(self, _): """checks for SPM, generates script""" outputs = self._list_outputs() self.inputs.out_file = outputs["out_file"] - script = """ - infile = '{}'; - outfile = '{}' - transform = load('{}'); + script = f""" + infile = '{self.inputs.in_file}'; + outfile = '{self.inputs.out_file}' + transform = load('{self.inputs.mat}'); V = spm_vol(infile); X = spm_read_vols(V); @@ -178,11 +173,7 @@ def _make_matlab_command(self, _): V.fname = fullfile(outfile); spm_write_vol(V,X); - """.format( - self.inputs.in_file, - self.inputs.out_file, - self.inputs.mat, - ) + """ # img_space = spm_get_space(infile); # spm_get_space(infile, transform.M * img_space); return script diff --git a/nipype/interfaces/workbench/metric.py b/nipype/interfaces/workbench/metric.py index 07e068e901..50e4300cd5 100644 --- a/nipype/interfaces/workbench/metric.py +++ b/nipype/interfaces/workbench/metric.py @@ -149,8 +149,7 @@ def _format_arg(self, opt, spec, val): if opt in ["current_area", "new_area"]: if not self.inputs.area_surfs and not self.inputs.area_metrics: raise ValueError( - "{} was set but neither area_surfs or" - " area_metrics were set".format(opt) + f"{opt} was set but neither area_surfs or area_metrics were set" ) if opt == "method": if ( diff --git a/nipype/pipeline/engine/utils.py b/nipype/pipeline/engine/utils.py index 6dbeadbae6..1fc615ffa4 100644 --- a/nipype/pipeline/engine/utils.py +++ b/nipype/pipeline/engine/utils.py @@ -369,13 +369,7 @@ def format_node(node, format="python", include_config=False): args = ", ".join(filled_args) klass_name = klass.__class__.__name__ if isinstance(node, MapNode): - nodedef = '{} = MapNode({}({}), iterfield={}, name="{}")'.format( - name, - klass_name, - args, - node.iterfield, - name, - ) + nodedef = f'{name} = MapNode({klass_name}({args}), iterfield={node.iterfield}, name="{name}")' else: nodedef = f'{name} = Node({klass_name}({args}), name="{name}")' lines = [importline, comment, nodedef] @@ -777,9 +771,7 @@ def _merge_graphs( rootnode = list(Gc.nodes())[nodeidx] paramstr = "" for key, val in sorted(params.items()): - paramstr = "{}_{}_{}".format( - paramstr, _get_valid_pathstr(key), _get_valid_pathstr(val) - ) + paramstr = f"{paramstr}_{_get_valid_pathstr(key)}_{_get_valid_pathstr(val)}" rootnode.set_input(key, val) logger.debug("Parameterization: paramstr=%s", paramstr) @@ -911,10 +903,8 @@ def _propagate_internal_output(graph, node, field, connections, portinputs): src_func = src_port[1].split("\\n")[0] dst_func = src[1].split("\\n")[0] raise ValueError( - "Does not support two inline functions " - "in series ('{}' and '{}'), found when " - "connecting {} to {}. Please use a Function " - "node.".format(src_func, dst_func, srcnode, destnode) + f"Does not support two inline functions in series ('{src_func}' and '{dst_func}'), " + f"found when connecting {srcnode} to {destnode}. Please use a Function node." ) connect = graph.get_edge_data(srcnode, destnode, default={"connect": []}) diff --git a/nipype/pipeline/engine/workflows.py b/nipype/pipeline/engine/workflows.py index 93758b0a13..7bc4faef34 100644 --- a/nipype/pipeline/engine/workflows.py +++ b/nipype/pipeline/engine/workflows.py @@ -444,8 +444,7 @@ def write_graph( if graph2use in ["hierarchical", "colored"]: if self.name[:1].isdigit(): # these graphs break if int raise ValueError( - "{} graph failed, workflow name cannot begin " - "with a number".format(graph2use) + f"{graph2use} graph failed, workflow name cannot begin with a number" ) dotfilename = op.join(base_dir, dotfilename) self.write_hierarchical_dotfile( diff --git a/nipype/pipeline/plugins/base.py b/nipype/pipeline/plugins/base.py index 1571ab71a9..f84dccb039 100644 --- a/nipype/pipeline/plugins/base.py +++ b/nipype/pipeline/plugins/base.py @@ -534,11 +534,8 @@ def _get_result(self, taskid): results_file = None try: error_message = ( - "Job id ({}) finished or terminated, but " - "results file does not exist after ({}) " - "seconds. Batch dir contains crashdump file " - "if node raised an exception.\n" - "Node working directory: ({}) ".format(taskid, timeout, node_dir) + f"Job id ({taskid}) finished or terminated, but results file does not exist after ({timeout}) seconds. Batch dir contains crashdump file if node raised an exception.\n" + f"Node working directory: ({node_dir}) " ) raise OSError(error_message) except OSError: diff --git a/nipype/pipeline/plugins/dagman.py b/nipype/pipeline/plugins/dagman.py index 55f3f03bee..bd8a8b05b2 100644 --- a/nipype/pipeline/plugins/dagman.py +++ b/nipype/pipeline/plugins/dagman.py @@ -147,10 +147,8 @@ def _submit_graph(self, pyfiles, dependencies, nodes): ) if wrapper_cmd is not None: specs["executable"] = wrapper_cmd - specs["nodescript"] = "{} {} {}".format( - wrapper_args % specs, # give access to variables - sys.executable, - pyscript, + specs["nodescript"] = ( + f"{wrapper_args % specs} {sys.executable} {pyscript}" ) submitspec = template % specs # write submit spec for this job diff --git a/nipype/pipeline/plugins/lsf.py b/nipype/pipeline/plugins/lsf.py index cf334be051..fea0d4267d 100644 --- a/nipype/pipeline/plugins/lsf.py +++ b/nipype/pipeline/plugins/lsf.py @@ -85,11 +85,7 @@ def _submit_batchtask(self, scriptfile, node): jobnameitems = jobname.split(".") jobnameitems.reverse() jobname = ".".join(jobnameitems) - cmd.inputs.args = "{} -J {} sh {}".format( - bsubargs, - jobname, - scriptfile, - ) # -J job_name_spec + cmd.inputs.args = f"{bsubargs} -J {jobname} sh {scriptfile}" # -J job_name_spec logger.debug("bsub " + cmd.inputs.args) oldlevel = iflogger.level iflogger.setLevel(logging.getLevelName("CRITICAL")) diff --git a/nipype/pipeline/plugins/sge.py b/nipype/pipeline/plugins/sge.py index 38079e947d..0ea15f5713 100644 --- a/nipype/pipeline/plugins/sge.py +++ b/nipype/pipeline/plugins/sge.py @@ -82,9 +82,7 @@ def is_job_state_pending(self): time_diff = time.time() - self._job_info_creation_time if self.is_zombie(): sge_debug_print( - "DONE! QJobInfo.IsPending found in 'zombie' list, returning False so claiming done!\n{}".format( - self - ) + f"DONE! QJobInfo.IsPending found in 'zombie' list, returning False so claiming done!\n{self}" ) is_pending_status = False # Job explicitly found as being completed! elif self.is_initializing() and (time_diff > 600): @@ -154,9 +152,7 @@ def _qacct_verified_complete(taskid): from the qacct report """ sge_debug_print( - "WARNING: " - "CONTACTING qacct for finished jobs, " - "{}: {}".format(time.time(), "Verifying Completion") + f"WARNING: CONTACTING qacct for finished jobs, {time.time()}: Verifying Completion" ) this_command = "qacct" @@ -253,10 +249,7 @@ def _parse_qstat_job_list(self, xml_job_list): self._task_dictionary[dictionary_job].set_state("zombie") else: sge_debug_print( - "ERROR: Job not in current parselist, " - "and not in done list {}: {}".format( - dictionary_job, self._task_dictionary[dictionary_job] - ) + f"ERROR: Job not in current parselist, and not in done list {dictionary_job}: {self._task_dictionary[dictionary_job]}" ) if self._task_dictionary[dictionary_job].is_initializing(): is_completed = self._qacct_verified_complete(dictionary_job) @@ -264,10 +257,7 @@ def _parse_qstat_job_list(self, xml_job_list): self._task_dictionary[dictionary_job].set_state("zombie") else: sge_debug_print( - "ERROR: Job not in still in initialization mode, " - "and not in done list {}: {}".format( - dictionary_job, self._task_dictionary[dictionary_job] - ) + f"ERROR: Job not in still in initialization mode, and not in done list {dictionary_job}: {self._task_dictionary[dictionary_job]}" ) def _run_qstat(self, reason_for_qstat, force_instant=True): @@ -279,8 +269,7 @@ def _run_qstat(self, reason_for_qstat, force_instant=True): -s s suspended jobs """ sge_debug_print( - "WARNING: CONTACTING qmaster for jobs, " - "{}: {}".format(time.time(), reason_for_qstat) + f"WARNING: CONTACTING qmaster for jobs, {time.time()}: {reason_for_qstat}" ) if force_instant: this_command = self._qstat_instant_executable @@ -311,10 +300,7 @@ def _run_qstat(self, reason_for_qstat, force_instant=True): self._parse_qstat_job_list(runjobs) break except Exception as inst: - exception_message = "QstatParsingError:\n\t{}\n\t{}\n".format( - type(inst), # the exception instance - inst, # __str__ allows args to printed directly - ) + exception_message = f"QstatParsingError:\n\t{type(inst)}\n\t{inst}\n" sge_debug_print(exception_message) time.sleep(5) @@ -340,8 +326,7 @@ def is_job_pending(self, task_id): job_is_pending = self._task_dictionary[task_id].is_job_state_pending() else: sge_debug_print( - "ERROR: Job {} not in task list, " - "even after forced qstat!".format(task_id) + f"ERROR: Job {task_id} not in task list, even after forced qstat!" ) job_is_pending = False if not job_is_pending: @@ -352,8 +337,7 @@ def is_job_pending(self, task_id): self._task_dictionary.pop(task_id) else: sge_debug_print( - "ERROR: Job {} not in task list, " - "but attempted to be removed!".format(task_id) + f"ERROR: Job {task_id} not in task list, but attempted to be removed!" ) return job_is_pending diff --git a/nipype/pipeline/plugins/sgegraph.py b/nipype/pipeline/plugins/sgegraph.py index 3d9e8ac40d..17aa514f85 100644 --- a/nipype/pipeline/plugins/sgegraph.py +++ b/nipype/pipeline/plugins/sgegraph.py @@ -144,14 +144,7 @@ def make_job_name(jobnumber, nodeslist): stdoutFile = "" if self._qsub_args.count("-o ") == 0: stdoutFile = f"-o {batchscriptoutfile}" - full_line = "{jobNm}=$(qsub {outFileOption} {errFileOption} {extraQSubArgs} {dependantIndex} -N {jobNm} {batchscript} | awk '/^Your job/{{print $3}}')\n".format( - jobNm=jobname, - outFileOption=stdoutFile, - errFileOption=stderrFile, - extraQSubArgs=qsub_args, - dependantIndex=deps, - batchscript=batchscriptfile, - ) + full_line = f"{jobname}=$(qsub {stdoutFile} {stderrFile} {qsub_args} {deps} -N {jobname} {batchscriptfile} | awk '/^Your job/{{print $3}}')\n" fp.writelines(full_line) cmd = CommandLine( "bash", diff --git a/nipype/pipeline/plugins/slurmgraph.py b/nipype/pipeline/plugins/slurmgraph.py index 0999595f5d..5ed5701acb 100644 --- a/nipype/pipeline/plugins/slurmgraph.py +++ b/nipype/pipeline/plugins/slurmgraph.py @@ -144,14 +144,7 @@ def make_job_name(jobnumber, nodeslist): stdoutFile = "" if self._sbatch_args.count("-o ") == 0: stdoutFile = f"-o {batchscriptoutfile}" - full_line = "{jobNm}=$(sbatch {outFileOption} {errFileOption} {extraSBatchArgs} {dependantIndex} -J {jobNm} {batchscript} | awk '/^Submitted/ {{print $4}}')\n".format( - jobNm=jobname, - outFileOption=stdoutFile, - errFileOption=stderrFile, - extraSBatchArgs=sbatch_args, - dependantIndex=deps, - batchscript=batchscriptfile, - ) + full_line = f"{jobname}=$(sbatch {stdoutFile} {stderrFile} {sbatch_args} {deps} -J {jobname} {batchscriptfile} | awk '/^Submitted/ {{print $4}}')\n" fp.writelines(full_line) cmd = CommandLine( "bash", diff --git a/nipype/pipeline/plugins/tools.py b/nipype/pipeline/plugins/tools.py index bce3eb82da..ae0082d2ed 100644 --- a/nipype/pipeline/plugins/tools.py +++ b/nipype/pipeline/plugins/tools.py @@ -32,12 +32,10 @@ def report_crash(node, traceback=None, hostname=None): keepends=True ) except Exception as exc: - traceback += """ + traceback += f""" During the creation of this crashfile triggered by the above exception, -another exception occurred:\n\n{}.""".format( - exc - ).splitlines( +another exception occurred:\n\n{exc}.""".splitlines( keepends=True ) else: diff --git a/nipype/scripts/utils.py b/nipype/scripts/utils.py index 8d8dc52627..c77674b225 100644 --- a/nipype/scripts/utils.py +++ b/nipype/scripts/utils.py @@ -100,10 +100,7 @@ def add_args_options(arg_parser, interface): if has_multiple_inner_traits: raise NotImplementedError( - "This interface cannot be used. via the" - " command line as multiple inner traits" - " are currently not supported for mandatory" - " argument: {}.".format(name) + f"This interface cannot be used via the command line, as multiple inner traits are currently not supported for mandatory argument: {name}." ) arg_parser.add_argument(name, help=desc, **args) else: diff --git a/nipype/sphinxext/apidoc/docstring.py b/nipype/sphinxext/apidoc/docstring.py index f235a86d7e..25547ff726 100644 --- a/nipype/sphinxext/apidoc/docstring.py +++ b/nipype/sphinxext/apidoc/docstring.py @@ -138,15 +138,11 @@ def _parse_spec(inputs, name, spec): pos = spec.position if pos is None: desc_lines += [ - """Maps to a command-line argument: :code:`{arg}`.""".format( - arg=argstr.strip() - ) + f"""Maps to a command-line argument: :code:`{argstr.strip()}`.""" ] else: desc_lines += [ - """Maps to a command-line argument: :code:`{arg}` (position: {pos}).""".format( - arg=argstr.strip(), pos=pos - ) + f"""Maps to a command-line argument: :code:`{argstr.strip()}` (position: {pos}).""" ] xor = spec.xor diff --git a/nipype/utils/filemanip.py b/nipype/utils/filemanip.py index 933220b70e..742c9f1d81 100644 --- a/nipype/utils/filemanip.py +++ b/nipype/utils/filemanip.py @@ -591,11 +591,7 @@ def loadpkl(infile): fmlogger.debug(f"'{infile}' missing; waiting 2s") sleep(2) if timed_out: - error_message = ( - "Result file {} expected, but " - "does not exist after ({}) " - "seconds.".format(infile, timeout) - ) + error_message = f"Result file {infile} expected, but does not exist after {timeout} seconds." raise OSError(error_message) with pklopen(str(infile), "rb") as pkl_file: diff --git a/nipype/utils/tests/test_filemanip.py b/nipype/utils/tests/test_filemanip.py index 11eb7b3d07..895fef2d1e 100644 --- a/nipype/utils/tests/test_filemanip.py +++ b/nipype/utils/tests/test_filemanip.py @@ -207,8 +207,8 @@ def test_recopy(_temp_analyze_files): img_stat = _ignore_atime(os.stat(new_img)) hdr_stat = _ignore_atime(os.stat(new_hdr)) copyfile(orig_img, new_img, **kwargs) - err_msg = "Regular - OS: {}; Copy: {}; Hardlink: {}".format( - os.name, copy, use_hardlink + err_msg = ( + f"Regular - OS: {os.name}; Copy: {copy}; Hardlink: {use_hardlink}" ) assert img_stat == _ignore_atime(os.stat(new_img)), err_msg assert hdr_stat == _ignore_atime(os.stat(new_hdr)), err_msg @@ -219,8 +219,8 @@ def test_recopy(_temp_analyze_files): img_stat = _ignore_atime(os.stat(new_img)) hdr_stat = _ignore_atime(os.stat(new_hdr)) copyfile(img_link, new_img, **kwargs) - err_msg = "Symlink - OS: {}; Copy: {}; Hardlink: {}".format( - os.name, copy, use_hardlink + err_msg = ( + f"Symlink - OS: {os.name}; Copy: {copy}; Hardlink: {use_hardlink}" ) assert img_stat == _ignore_atime(os.stat(new_img)), err_msg assert hdr_stat == _ignore_atime(os.stat(new_hdr)), err_msg diff --git a/tools/checkspecs.py b/tools/checkspecs.py index 4226f3a4f8..c1ef27ff6a 100644 --- a/tools/checkspecs.py +++ b/tools/checkspecs.py @@ -257,10 +257,7 @@ def test_specs(self, uri): for key, value in sorted(trait.__dict__.items()): if key in in_built or key == "desc": continue - input_fields += "{}={},\n ".format( - key, - self._normalize_repr(value), - ) + input_fields += f"{key}={self._normalize_repr(value)},\n " input_fields += "),\n " cmd += [" input_map = dict(%s)" % input_fields] cmd += [" inputs = %s.input_spec()" % c] @@ -348,10 +345,7 @@ def test_specs(self, uri): for key, value in sorted(trait.__dict__.items()): if key in in_built or key == "desc": continue - input_fields += "{}={},\n ".format( - key, - self._normalize_repr(value), - ) + input_fields += f"{key}={self._normalize_repr(value)},\n " input_fields += "),\n " cmd += [" output_map = dict(%s)" % input_fields] cmd += [" outputs = %s.output_spec()" % c] From effe9092636acd9950d2d698390b52a6ff79527d Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Mon, 7 Oct 2024 13:51:43 +0200 Subject: [PATCH 16/24] STY: Enforce ruff rules Disable some rules and postpone fixes. --- .pre-commit-config.yaml | 5 +++ pyproject.toml | 83 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 88 insertions(+) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index c1bda308da..072542a218 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -12,6 +12,11 @@ repos: rev: 24.2.0 hooks: - id: black + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.6.9 + hooks: + - id: ruff + args: ["--fix", "--show-source"] - repo: https://github.com/codespell-project/codespell rev: v2.2.6 hooks: diff --git a/pyproject.toml b/pyproject.toml index 2b1282eb74..04c01777a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,3 +25,86 @@ doctest_optionflags = "ALLOW_UNICODE NORMALIZE_WHITESPACE ELLIPSIS" env = "PYTHONHASHSEED=0" filterwarnings = ["ignore::DeprecationWarning"] junit_family = "xunit2" + +[tool.ruff] +line-length = 88 # same as black + +[tool.ruff.lint] +extend-select = [ + "B", + "C4", + "FLY", + "FURB", + "PERF", + "PGH", + "PIE", + "PLE", + "PT", + "PYI", + "Q", + "RSE", + "RUF", + "UP", +] +ignore = [ + "B006", # requires annotations + "B011", + "B017", # TODO: enable rule + "B020", # TODO: enable rule + "B028", + "B904", + "C401", + "C408", + "C420", # TODO: enable rule + "E402", + "E722", + "E731", # TODO: enable rule + "F401", + "F403", + "F811", + "F841", + "FURB101", + "FURB103", + "FURB113", + "FURB118", # TODO: enable rule + "FURB140", # TODO: enable rule + "FURB171", # TODO: enable rule + "PGH003", # TODO: enable rule + "PGH004", # TODO: enable rule + "PERF203", + "PIE790", + "PIE794", + "PT001", + "PT004", # deprecated + "PT005", # deprecated + "PT011", + "PT015", # TODO: enable rule + "PT017", # TODO: enable rule + "PT018", + "PT019", # TODO: enable rule + "PT021", # TODO: enable rule + "PYI024", + "RUF002", + "RUF005", + "RUF012", # requires annotations + "RUF015", + "UP027", # deprecated + "UP031", # TODO: enable rule + "UP032", # TODO: enable rule + "UP038", # https://github.com/astral-sh/ruff/issues/7871 + # https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules + "W191", + "E111", + "E114", + "E117", + "D206", + "D300", + "Q000", + "Q001", + "Q002", + "Q003", + "COM812", + "COM819", + "ISC001", + "ISC002", +] From a9f97ca7f67b6e4952c1d9d04be2ed8dcc45b34c Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 24 Nov 2024 20:38:13 +0100 Subject: [PATCH 17/24] Update ruff to 0.8.0 --- .pre-commit-config.yaml | 2 +- pyproject.toml | 3 --- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 072542a218..d283957894 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,7 +13,7 @@ repos: hooks: - id: black - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.6.9 + rev: v0.8.0 hooks: - id: ruff args: ["--fix", "--show-source"] diff --git a/pyproject.toml b/pyproject.toml index 04c01777a2..2e6b62a4af 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -75,8 +75,6 @@ ignore = [ "PIE790", "PIE794", "PT001", - "PT004", # deprecated - "PT005", # deprecated "PT011", "PT015", # TODO: enable rule "PT017", # TODO: enable rule @@ -88,7 +86,6 @@ ignore = [ "RUF005", "RUF012", # requires annotations "RUF015", - "UP027", # deprecated "UP031", # TODO: enable rule "UP032", # TODO: enable rule "UP038", # https://github.com/astral-sh/ruff/issues/7871 From ac68f1ab529b39fadb49281ce46df65527a5b2ea Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 24 Nov 2024 20:43:25 +0100 Subject: [PATCH 18/24] STY: Apply ruff/flake8-bugbear rule B010 B010 Do not call `setattr` with a constant attribute value. It is not any safer than normal property access. --- nipype/utils/filemanip.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/nipype/utils/filemanip.py b/nipype/utils/filemanip.py index 742c9f1d81..17836aad5d 100644 --- a/nipype/utils/filemanip.py +++ b/nipype/utils/filemanip.py @@ -960,12 +960,12 @@ def load_spm_mat(spm_mat_file, **kwargs): obj_list = [] for i in range(len(fnames["Vbeta"])): obj = sio.matlab.mat_struct() - setattr(obj, "fname", np.array([fnames["Vbeta"][i]])) + obj.fname = np.array([fnames["Vbeta"][i]]) obj_list.append(obj) if len(obj_list) > 0: - setattr(mat["SPM"][0, 0], "Vbeta", np.array([obj_list])) + mat["SPM"][0, 0].Vbeta = np.array([obj_list]) else: - setattr(mat["SPM"][0, 0], "Vbeta", np.empty((0, 0), dtype=object)) + mat["SPM"][0, 0].Vbeta = np.empty((0, 0), dtype=object) # Structure Vcon and Vspm as returned by scipy.io.loadmat obj_list = [] @@ -973,12 +973,12 @@ def load_spm_mat(spm_mat_file, **kwargs): obj = sio.matlab.mat_struct() for contr_type in ["Vcon", "Vspm"]: temp = sio.matlab.mat_struct() - setattr(temp, "fname", np.array([fnames[contr_type][i]])) + temp.fname = np.array([fnames[contr_type][i]]) setattr(obj, contr_type, np.array([[temp]])) obj_list.append(obj) if len(obj_list) > 0: - setattr(mat["SPM"][0, 0], "xCon", np.array([obj_list])) + mat["SPM"][0, 0].xCon = np.array([obj_list]) else: - setattr(mat["SPM"][0, 0], "xCon", np.empty((0, 0), dtype=object)) + mat["SPM"][0, 0].xCon = np.empty((0, 0), dtype=object) return mat From dd57d7afce1b4a90d3535b9f84454a2d4dbaff5a Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 24 Nov 2024 20:50:43 +0100 Subject: [PATCH 19/24] STY: Ignore ruff/pycodestyle rule E741 for now --- pyproject.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/pyproject.toml b/pyproject.toml index 2e6b62a4af..4dc0c3b7a2 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -59,6 +59,7 @@ ignore = [ "E402", "E722", "E731", # TODO: enable rule + "E741", # TODO: enable rule "F401", "F403", "F811", From 45bc7978947a8d4280805dc1f8fba6235be913e0 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 24 Nov 2024 20:51:37 +0100 Subject: [PATCH 20/24] STY: Apply ruff/Pyflakes rule F522 F522 `.format` call has unused named argument --- nipype/interfaces/ants/registration.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/interfaces/ants/registration.py b/nipype/interfaces/ants/registration.py index 9e1d0d5aa4..845396a15b 100644 --- a/nipype/interfaces/ants/registration.py +++ b/nipype/interfaces/ants/registration.py @@ -1611,7 +1611,7 @@ def _mask_constructor(self): moving_image_mask=self.inputs.moving_image_mask, ) else: - retval = '--masks "{}"'.format( # noqa: UP032 + retval = '--masks "{fixed_image_mask}"'.format( # noqa: UP032 fixed_image_mask=self.inputs.fixed_image_mask, ) return retval From 92a6ffd0cf3be804c66ac737a6ff7ca016b1480d Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 24 Nov 2024 21:00:49 +0100 Subject: [PATCH 21/24] Apply ruff/Pyflakes rule F821 F821 Undefined name --- nipype/interfaces/fsl/model.py | 2 +- nipype/interfaces/mrtrix/convert.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/nipype/interfaces/fsl/model.py b/nipype/interfaces/fsl/model.py index 3d9786171b..6be0d86a29 100644 --- a/nipype/interfaces/fsl/model.py +++ b/nipype/interfaces/fsl/model.py @@ -1387,7 +1387,7 @@ def _run_interface(self, runtime): "", "/Matrix", ] - grp_txt.extend(["1"] * self.inputs.num_copes) + mat_txt.extend(["1"] * self.inputs.num_copes) mat_txt = "\n".join(mat_txt) con_txt = [ diff --git a/nipype/interfaces/mrtrix/convert.py b/nipype/interfaces/mrtrix/convert.py index 6d016db879..e2538ab947 100644 --- a/nipype/interfaces/mrtrix/convert.py +++ b/nipype/interfaces/mrtrix/convert.py @@ -102,7 +102,7 @@ def points_per_track(offset): if idx == 0: track_points.append(value) else: - track_points.append(value - last_value - 1) + track_points.append(value - last_value - 1) # noqa: F821 last_value = value return track_points, nonfinite_list From 6d7277a9162f017235d695333c40f91356b4ae13 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 24 Nov 2024 21:02:38 +0100 Subject: [PATCH 22/24] Apply ruff rule RUF100 RUF100 Unused blanket `noqa` directive RUF100 Unused `noqa` directive --- nipype/algorithms/confounds.py | 2 +- nipype/caching/memory.py | 2 +- nipype/interfaces/ants/registration.py | 20 +++++++++---------- .../interfaces/utility/tests/test_wrappers.py | 4 +++- nipype/pipeline/plugins/legacymultiproc.py | 2 +- nipype/pipeline/plugins/multiproc.py | 2 +- 6 files changed, 17 insertions(+), 15 deletions(-) diff --git a/nipype/algorithms/confounds.py b/nipype/algorithms/confounds.py index 06fc41c90e..a453bc111c 100644 --- a/nipype/algorithms/confounds.py +++ b/nipype/algorithms/confounds.py @@ -608,7 +608,7 @@ def _run_interface(self, runtime): if len(imgseries.shape) != 4: raise ValueError( - "{} expected a 4-D nifti file. Input {} has {} dimensions (shape {})".format( # noqa: UP032 + "{} expected a 4-D nifti file. Input {} has {} dimensions (shape {})".format( self._header, self.inputs.realigned_file, len(imgseries.shape), diff --git a/nipype/caching/memory.py b/nipype/caching/memory.py index 755b7c9fb9..a1d45ffff2 100644 --- a/nipype/caching/memory.py +++ b/nipype/caching/memory.py @@ -86,7 +86,7 @@ def __call__(self, **kwargs): return out def __repr__(self): - return "{}({}.{}), base_dir={})".format( # noqa: UP032 + return "{}({}.{}), base_dir={})".format( self.__class__.__name__, self.interface.__module__, self.interface.__name__, diff --git a/nipype/interfaces/ants/registration.py b/nipype/interfaces/ants/registration.py index 845396a15b..706ba23234 100644 --- a/nipype/interfaces/ants/registration.py +++ b/nipype/interfaces/ants/registration.py @@ -204,7 +204,7 @@ def _transformation_constructor(self): return "".join(retval) def _regularization_constructor(self): - return "--regularization {}[{},{}]".format( # noqa: UP032 + return "--regularization {}[{},{}]".format( self.inputs.regularization, self.inputs.regularization_gradient_field_sigma, self.inputs.regularization_deformation_field_sigma, @@ -1241,7 +1241,7 @@ def _format_winsorize_image_intensities(self): ) ) self._quantilesDone = True - return "--winsorize-image-intensities [ {}, {} ]".format( # noqa: UP032 + return "--winsorize-image-intensities [ {}, {} ]".format( self.inputs.winsorize_lower_quantile, self.inputs.winsorize_upper_quantile, ) @@ -1268,12 +1268,12 @@ def _get_initial_transform_filenames(self): def _format_arg(self, opt, spec, val): if opt == "fixed_image_mask": if isdefined(self.inputs.moving_image_mask): - return "--masks [ {}, {} ]".format( # noqa: UP032 + return "--masks [ {}, {} ]".format( self.inputs.fixed_image_mask, self.inputs.moving_image_mask, ) else: - return "--masks {}".format(self.inputs.fixed_image_mask) # noqa: UP032 + return "--masks {}".format(self.inputs.fixed_image_mask) elif opt == "transforms": return self._format_registration() elif opt == "initial_moving_transform": @@ -1308,18 +1308,18 @@ def _format_arg(self, opt, spec, val): out_filename = self._get_outputfilenames(inverse=False) inv_out_filename = self._get_outputfilenames(inverse=True) if out_filename and inv_out_filename: - return "--output [ {}, {}, {} ]".format( # noqa: UP032 + return "--output [ {}, {}, {} ]".format( self.inputs.output_transform_prefix, out_filename, inv_out_filename, ) elif out_filename: - return "--output [ {}, {} ]".format( # noqa: UP032 + return "--output [ {}, {} ]".format( self.inputs.output_transform_prefix, out_filename, ) else: - return "--output {}".format( # noqa: UP032 + return "--output {}".format( self.inputs.output_transform_prefix, ) elif opt == "winsorize_upper_quantile" or opt == "winsorize_lower_quantile": @@ -1592,7 +1592,7 @@ class MeasureImageSimilarity(ANTSCommand): def _metric_constructor(self): retval = ( '--metric {metric}["{fixed_image}","{moving_image}",{metric_weight},' - "{radius_or_number_of_bins},{sampling_strategy},{sampling_percentage}]".format( # noqa: UP032 + "{radius_or_number_of_bins},{sampling_strategy},{sampling_percentage}]".format( metric=self.inputs.metric, fixed_image=self.inputs.fixed_image, moving_image=self.inputs.moving_image, @@ -1606,12 +1606,12 @@ def _metric_constructor(self): def _mask_constructor(self): if self.inputs.moving_image_mask: - retval = '--masks ["{fixed_image_mask}","{moving_image_mask}"]'.format( # noqa: UP032 + retval = '--masks ["{fixed_image_mask}","{moving_image_mask}"]'.format( fixed_image_mask=self.inputs.fixed_image_mask, moving_image_mask=self.inputs.moving_image_mask, ) else: - retval = '--masks "{fixed_image_mask}"'.format( # noqa: UP032 + retval = '--masks "{fixed_image_mask}"'.format( fixed_image_mask=self.inputs.fixed_image_mask, ) return retval diff --git a/nipype/interfaces/utility/tests/test_wrappers.py b/nipype/interfaces/utility/tests/test_wrappers.py index 345d6483ad..68113d84f8 100644 --- a/nipype/interfaces/utility/tests/test_wrappers.py +++ b/nipype/interfaces/utility/tests/test_wrappers.py @@ -2,6 +2,8 @@ # vi: set ft=python sts=4 ts=4 sw=4 et: import pytest +import numpy as np + from nipype.interfaces import utility import nipype.pipeline.engine as pe @@ -52,7 +54,7 @@ def increment_array(in_array): def make_random_array(size): - return np.random.randn(size, size) # noqa + return np.random.randn(size, size) def should_fail(tmp): diff --git a/nipype/pipeline/plugins/legacymultiproc.py b/nipype/pipeline/plugins/legacymultiproc.py index 4c39be1ab2..c4dfe9773f 100644 --- a/nipype/pipeline/plugins/legacymultiproc.py +++ b/nipype/pipeline/plugins/legacymultiproc.py @@ -64,7 +64,7 @@ def run_node(node, updatehash, taskid): # Try and execute the node via node.run() try: result["result"] = node.run(updatehash=updatehash) - except: # noqa: E722, intendedly catch all here + except: result["traceback"] = format_exception(*sys.exc_info()) result["result"] = node.result diff --git a/nipype/pipeline/plugins/multiproc.py b/nipype/pipeline/plugins/multiproc.py index 401b01b388..f2c6414d10 100644 --- a/nipype/pipeline/plugins/multiproc.py +++ b/nipype/pipeline/plugins/multiproc.py @@ -64,7 +64,7 @@ def run_node(node, updatehash, taskid): # Try and execute the node via node.run() try: result["result"] = node.run(updatehash=updatehash) - except: # noqa: E722, intendedly catch all here + except: result["traceback"] = format_exception(*sys.exc_info()) result["result"] = node.result From 802475ef216c2ced4a5134ee87c83ef5560961a8 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 24 Nov 2024 21:03:37 +0100 Subject: [PATCH 23/24] Apply ruff/pyupgrade rule UP015 UP015 Unnecessary open mode parameters --- nipype/pipeline/plugins/tests/test_callback.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype/pipeline/plugins/tests/test_callback.py b/nipype/pipeline/plugins/tests/test_callback.py index b10238ec4a..1a35988cd3 100644 --- a/nipype/pipeline/plugins/tests/test_callback.py +++ b/nipype/pipeline/plugins/tests/test_callback.py @@ -91,7 +91,7 @@ def test_callback_gantt(tmp_path: Path, plugin: str) -> None: plugin_args["n_procs"] = 8 wf.run(plugin=plugin, plugin_args=plugin_args) - with open(log_filename, "r") as _f: + with open(log_filename) as _f: loglines = _f.readlines() # test missing duration From 8f8474171c421dc78b34a7983f8e4827f8d52442 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 24 Nov 2024 21:04:09 +0100 Subject: [PATCH 24/24] Apply ruff/pyupgrade rule UP025 UP025 Remove unicode literals from strings --- nipype/utils/filemanip.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/nipype/utils/filemanip.py b/nipype/utils/filemanip.py index 17836aad5d..abbdaa921d 100644 --- a/nipype/utils/filemanip.py +++ b/nipype/utils/filemanip.py @@ -942,7 +942,7 @@ def load_spm_mat(spm_mat_file, **kwargs): fnames = dict() try: fnames["Vbeta"] = [ - u"".join(chr(c[0]) for c in h5file[obj_ref[0]]) + "".join(chr(c[0]) for c in h5file[obj_ref[0]]) for obj_ref in h5file["SPM"]["Vbeta"]["fname"] ] except Exception: @@ -950,7 +950,7 @@ def load_spm_mat(spm_mat_file, **kwargs): for contr_type in ["Vcon", "Vspm"]: try: fnames[contr_type] = [ - u"".join(chr(c[0]) for c in h5file[obj_ref[0]]["fname"]) + "".join(chr(c[0]) for c in h5file[obj_ref[0]]["fname"]) for obj_ref in h5file["SPM"]["xCon"][contr_type] ] except Exception: