From edea004c3a262bcb21dda0af14296590aec1644f Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 22 Sep 2024 10:08:23 +0200 Subject: [PATCH 1/4] STY: Apply ruff/flake8-bugbear rule B004 B004 Using `hasattr(x, "__call__")` to test if x is callable is unreliable. Use `callable(x)` for consistent results. --- nipype/interfaces/utility/wrappers.py | 4 ++-- nipype/pipeline/plugins/debug.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/utility/wrappers.py b/nipype/interfaces/utility/wrappers.py index dffe98c862..cc9d5088d9 100644 --- a/nipype/interfaces/utility/wrappers.py +++ b/nipype/interfaces/utility/wrappers.py @@ -72,7 +72,7 @@ def __init__( super().__init__(**inputs) if function: - if hasattr(function, "__call__"): + if callable(function): try: self.inputs.function_str = getsource(function) except OSError: @@ -103,7 +103,7 @@ def __init__( def _set_function_string(self, obj, name, old, new): if name == "function_str": - if hasattr(new, "__call__"): + if callable(new): function_source = getsource(new) fninfo = new.__code__ elif isinstance(new, (str, bytes)): diff --git a/nipype/pipeline/plugins/debug.py b/nipype/pipeline/plugins/debug.py index 956d1b0694..1dac35cf8f 100644 --- a/nipype/pipeline/plugins/debug.py +++ b/nipype/pipeline/plugins/debug.py @@ -15,7 +15,7 @@ def __init__(self, plugin_args=None): if ( plugin_args and "callable" in plugin_args - and hasattr(plugin_args["callable"], "__call__") + and callable(plugin_args["callable"]) ): self._callable = plugin_args["callable"] else: From beeab868678f6b310b249b9d16b780e4e4c601d6 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sat, 5 Oct 2024 17:41:06 +0200 Subject: [PATCH 2/4] STY: Apply ruff/flake8-bugbear rule B009 B009 Do not call `getattr` with a constant attribute value. It is not any safer than normal property access. --- nipype/interfaces/afni/utils.py | 2 +- nipype/interfaces/ants/utils.py | 2 +- nipype/interfaces/base/support.py | 2 +- nipype/interfaces/elastix/utils.py | 4 ++-- nipype/interfaces/fsl/utils.py | 6 +++--- nipype/pipeline/engine/utils.py | 2 +- nipype/utils/profiler.py | 6 +++--- nipype/utils/provenance.py | 2 +- tools/checkspecs.py | 4 ++-- 9 files changed, 15 insertions(+), 15 deletions(-) diff --git a/nipype/interfaces/afni/utils.py b/nipype/interfaces/afni/utils.py index ab528f3bae..61123687bf 100644 --- a/nipype/interfaces/afni/utils.py +++ b/nipype/interfaces/afni/utils.py @@ -3248,7 +3248,7 @@ def _run_interface(self, runtime): return runtime def _list_outputs(self): - return {"out": getattr(self, "_gcor")} + return {"out": self._gcor} class AxializeInputSpec(AFNICommandInputSpec): diff --git a/nipype/interfaces/ants/utils.py b/nipype/interfaces/ants/utils.py index 05cebf6728..57202f5a34 100644 --- a/nipype/interfaces/ants/utils.py +++ b/nipype/interfaces/ants/utils.py @@ -536,7 +536,7 @@ def _format_arg(self, opt, spec, val): return super()._format_arg(opt, spec, val) def _list_outputs(self): - return getattr(self, "_output") + return self._output class AverageAffineTransformInputSpec(ANTSCommandInputSpec): diff --git a/nipype/interfaces/base/support.py b/nipype/interfaces/base/support.py index 06f7df906a..dd3c1aa60d 100644 --- a/nipype/interfaces/base/support.py +++ b/nipype/interfaces/base/support.py @@ -99,7 +99,7 @@ def __exit__(self, exc_type, exc_value, exc_tb): traceback.format_exception(exc_type, exc_value, exc_tb) ) # Gather up the exception arguments and append nipype info. - exc_args = exc_value.args if getattr(exc_value, "args") else tuple() + exc_args = exc_value.args if exc_value.args else tuple() exc_args += ( f"An exception of type {exc_type.__name__} occurred while " f"running interface {self._runtime.interface}.", diff --git a/nipype/interfaces/elastix/utils.py b/nipype/interfaces/elastix/utils.py index aa8296e4a0..3e42160112 100644 --- a/nipype/interfaces/elastix/utils.py +++ b/nipype/interfaces/elastix/utils.py @@ -164,11 +164,11 @@ def _run_interface(self, runtime): def _list_outputs(self): outputs = self.output_spec().get() - outputs["output_file"] = getattr(self, "_out_file") + outputs["output_file"] = self._out_file return outputs def _get_outfile(self): - val = getattr(self, "_out_file") + val = self._out_file if val is not None and val != "": return val diff --git a/nipype/interfaces/fsl/utils.py b/nipype/interfaces/fsl/utils.py index b0a3685ab9..c48d7c1b19 100644 --- a/nipype/interfaces/fsl/utils.py +++ b/nipype/interfaces/fsl/utils.py @@ -2580,11 +2580,11 @@ def _coords_to_trk(self, points, out_file): def _overload_extension(self, value, name): if name == "out_file": - return "{}.{}".format(value, getattr(self, "_outformat")) + return "{}.{}".format(value, self._outformat) def _run_interface(self, runtime): - fname = getattr(self, "_in_file") - outformat = getattr(self, "_outformat") + fname = self._in_file + outformat = self._outformat tmpfile = None if outformat == "vtk": diff --git a/nipype/pipeline/engine/utils.py b/nipype/pipeline/engine/utils.py index 3601290cd9..bf554c69e9 100644 --- a/nipype/pipeline/engine/utils.py +++ b/nipype/pipeline/engine/utils.py @@ -852,7 +852,7 @@ def _identity_nodes(graph, include_iterables): node for node in nx.topological_sort(graph) if isinstance(node.interface, IdentityInterface) - and (include_iterables or getattr(node, "iterables") is None) + and (include_iterables or node.iterables is None) ] diff --git a/nipype/utils/profiler.py b/nipype/utils/profiler.py index 2ca93bf720..370097e90b 100644 --- a/nipype/utils/profiler.py +++ b/nipype/utils/profiler.py @@ -174,9 +174,9 @@ def log_nodes_cb(node, status): status_dict = { "name": node.name, "id": node._id, - "start": getattr(node.result.runtime, "startTime"), - "finish": getattr(node.result.runtime, "endTime"), - "duration": getattr(node.result.runtime, "duration"), + "start": node.result.runtime.startTime, + "finish": node.result.runtime.endTime, + "duration": node.result.runtime.duration, "runtime_threads": getattr(node.result.runtime, "cpu_percent", "N/A"), "runtime_memory_gb": getattr(node.result.runtime, "mem_peak_gb", "N/A"), "estimated_memory_gb": node.mem_gb, diff --git a/nipype/utils/provenance.py b/nipype/utils/provenance.py index 84e1ab076d..95e54d405d 100644 --- a/nipype/utils/provenance.py +++ b/nipype/utils/provenance.py @@ -300,7 +300,7 @@ def write_provenance(results, filename="provenance", format="all"): import traceback err_msg = traceback.format_exc() - if getattr(e, "args"): + if e.args: err_msg += "\n\nException arguments:\n" + ", ".join( ['"%s"' % arg for arg in e.args] ) diff --git a/tools/checkspecs.py b/tools/checkspecs.py index ea3d877484..7f0beccf1e 100644 --- a/tools/checkspecs.py +++ b/tools/checkspecs.py @@ -287,7 +287,7 @@ def test_specs(self, uri): continue parent_metadata = [] if "parent" in trait.__dict__: - parent_metadata = list(getattr(trait, "parent").__dict__.keys()) + parent_metadata = list(trait.parent.__dict__.keys()) if ( key not in allowed_keys @@ -375,7 +375,7 @@ def test_specs(self, uri): continue parent_metadata = [] if "parent" in trait.__dict__: - parent_metadata = list(getattr(trait, "parent").__dict__.keys()) + parent_metadata = list(trait.parent.__dict__.keys()) if ( key not in allowed_keys From 323e7e30f65b94c9743f2307fd11d81d6e0ca868 Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sat, 5 Oct 2024 17:42:16 +0200 Subject: [PATCH 3/4] 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/algorithms/tests/test_modelgen.py | 4 ++-- nipype/interfaces/afni/utils.py | 2 +- nipype/interfaces/elastix/utils.py | 4 ++-- nipype/interfaces/fsl/utils.py | 6 ++--- nipype/interfaces/spm/model.py | 26 +++++++-------------- nipype/interfaces/tests/test_io.py | 2 +- nipype/pipeline/engine/tests/test_engine.py | 6 ++--- nipype/utils/config.py | 2 +- 8 files changed, 22 insertions(+), 30 deletions(-) diff --git a/nipype/algorithms/tests/test_modelgen.py b/nipype/algorithms/tests/test_modelgen.py index 9bc0e8376d..2707b93faa 100644 --- a/nipype/algorithms/tests/test_modelgen.py +++ b/nipype/algorithms/tests/test_modelgen.py @@ -122,7 +122,7 @@ def test_modelgen_spm_concat(tmpdir): s = SpecifySPMModel() s.inputs.input_units = "secs" s.inputs.concatenate_runs = True - setattr(s.inputs, "output_units", "secs") + s.inputs.output_units = "secs" assert s.inputs.output_units == "secs" s.inputs.functional_runs = [filename1, filename2] s.inputs.time_repetition = 6 @@ -147,7 +147,7 @@ def test_modelgen_spm_concat(tmpdir): ) # Test case of scans as output units instead of seconds - setattr(s.inputs, "output_units", "scans") + s.inputs.output_units = "scans" assert s.inputs.output_units == "scans" s.inputs.subject_info = deepcopy(info) res = s.run() diff --git a/nipype/interfaces/afni/utils.py b/nipype/interfaces/afni/utils.py index 61123687bf..a3236d1a28 100644 --- a/nipype/interfaces/afni/utils.py +++ b/nipype/interfaces/afni/utils.py @@ -3244,7 +3244,7 @@ def _run_interface(self, runtime): for line in runtime.stdout.split("\n") if line.strip().startswith("GCOR = ") ][-1] - setattr(self, "_gcor", float(gcor_line[len("GCOR = ") :])) + self._gcor = float(gcor_line[len("GCOR = ") :]) return runtime def _list_outputs(self): diff --git a/nipype/interfaces/elastix/utils.py b/nipype/interfaces/elastix/utils.py index 3e42160112..912216af9a 100644 --- a/nipype/interfaces/elastix/utils.py +++ b/nipype/interfaces/elastix/utils.py @@ -173,9 +173,9 @@ def _get_outfile(self): return val if isdefined(self.inputs.output_file): - setattr(self, "_out_file", self.inputs.output_file) + self._out_file = self.inputs.output_file return self.inputs.output_file out_file = op.abspath(op.basename(self.inputs.transform_file)) - setattr(self, "_out_file", out_file) + self._out_file = out_file return out_file diff --git a/nipype/interfaces/fsl/utils.py b/nipype/interfaces/fsl/utils.py index c48d7c1b19..acdd771fc8 100644 --- a/nipype/interfaces/fsl/utils.py +++ b/nipype/interfaces/fsl/utils.py @@ -929,7 +929,7 @@ def _run_interface(self, runtime): float(r) for r in out["translations"].strip().split(" ") ] - setattr(self, "_results", outputs) + self._results = outputs return runtime def _list_outputs(self): @@ -2513,8 +2513,8 @@ def _format_arg(self, name, trait_spec, value): def _parse_inputs(self, skip=None): fname, ext = op.splitext(self.inputs.in_coords) - setattr(self, "_in_file", fname) - setattr(self, "_outformat", ext[1:]) + self._in_file = fname + self._outformat = ext[1:] first_args = super()._parse_inputs(skip=["in_coords", "out_file"]) second_args = fname + ".txt" diff --git a/nipype/interfaces/spm/model.py b/nipype/interfaces/spm/model.py index 62bf4447ea..8625e3bfd1 100644 --- a/nipype/interfaces/spm/model.py +++ b/nipype/interfaces/spm/model.py @@ -849,30 +849,22 @@ def _make_matlab_command(self, _): def aggregate_outputs(self, runtime=None): outputs = self._outputs() - setattr(outputs, "thresholded_map", self._gen_thresholded_map_filename()) - setattr(outputs, "pre_topo_fdr_map", self._gen_pre_topo_map_filename()) + outputs.thresholded_map = self._gen_thresholded_map_filename() + outputs.pre_topo_fdr_map = self._gen_pre_topo_map_filename() for line in runtime.stdout.split("\n"): if line.startswith("activation_forced = "): - setattr( - outputs, - "activation_forced", - line[len("activation_forced = ") :].strip() == "1", + outputs.activation_forced = ( + line[len("activation_forced = ") :].strip() == "1" ) elif line.startswith("n_clusters = "): - setattr( - outputs, "n_clusters", int(line[len("n_clusters = ") :].strip()) - ) + outputs.n_clusters = int(line[len("n_clusters = ") :].strip()) elif line.startswith("pre_topo_n_clusters = "): - setattr( - outputs, - "pre_topo_n_clusters", - int(line[len("pre_topo_n_clusters = ") :].strip()), + outputs.pre_topo_n_clusters = int( + line[len("pre_topo_n_clusters = ") :].strip() ) elif line.startswith("cluster_forming_thr = "): - setattr( - outputs, - "cluster_forming_thr", - float(line[len("cluster_forming_thr = ") :].strip()), + outputs.cluster_forming_thr = float( + line[len("cluster_forming_thr = ") :].strip() ) return outputs diff --git a/nipype/interfaces/tests/test_io.py b/nipype/interfaces/tests/test_io.py index 3537c12d78..d0af921f09 100644 --- a/nipype/interfaces/tests/test_io.py +++ b/nipype/interfaces/tests/test_io.py @@ -517,7 +517,7 @@ def test_datasink_copydir_2(_temp_analyze_files, tmpdir): base_directory=tmpdir.mkdir("basedir").strpath, parameterization=False ) ds.inputs.remove_dest_dir = True - setattr(ds.inputs, "outdir", pth) + ds.inputs.outdir = pth ds.run() sep = os.path.sep assert not tmpdir.join("basedir", pth.split(sep)[-1], fname).check() diff --git a/nipype/pipeline/engine/tests/test_engine.py b/nipype/pipeline/engine/tests/test_engine.py index bcb44865fa..abf9426d43 100644 --- a/nipype/pipeline/engine/tests/test_engine.py +++ b/nipype/pipeline/engine/tests/test_engine.py @@ -25,7 +25,7 @@ def test_1mod(iterables, expected): pipe = pe.Workflow(name="pipe") mod1 = pe.Node(interface=EngineTestInterface(), name="mod1") - setattr(mod1, "iterables", iterables["1"]) + mod1.iterables = iterables["1"] pipe.add_nodes([mod1]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) @@ -49,7 +49,7 @@ def test_2mods(iterables, expected): mod1 = pe.Node(interface=EngineTestInterface(), name="mod1") mod2 = pe.Node(interface=EngineTestInterface(), name="mod2") for nr in ["1", "2"]: - setattr(eval("mod" + nr), "iterables", iterables[nr]) + eval("mod" + nr).iterables = iterables[nr] pipe.connect([(mod1, mod2, [("output1", "input2")])]) pipe._flatgraph = pipe._create_flat_graph() pipe._execgraph = pe.generate_expanded_graph(deepcopy(pipe._flatgraph)) @@ -87,7 +87,7 @@ def test_3mods(iterables, expected, connect): mod2 = pe.Node(interface=EngineTestInterface(), name="mod2") mod3 = pe.Node(interface=EngineTestInterface(), name="mod3") for nr in ["1", "2", "3"]: - setattr(eval("mod" + nr), "iterables", iterables[nr]) + eval("mod" + nr).iterables = iterables[nr] if connect == ("1-2", "2-3"): pipe.connect( [ diff --git a/nipype/utils/config.py b/nipype/utils/config.py index bf29f81de8..e7ec7fd64b 100644 --- a/nipype/utils/config.py +++ b/nipype/utils/config.py @@ -353,7 +353,7 @@ def _mock(): # Older versions of xvfbwrapper used vdisplay_num if not hasattr(self._display, "new_display"): - setattr(self._display, "new_display", self._display.vdisplay_num) + self._display.new_display = self._display.vdisplay_num return self.get_display() def stop_display(self): From fdab8eff01d88cbd4993024447e9b179f85642ec Mon Sep 17 00:00:00 2001 From: Dimitri Papadopoulos Orfanos <3234522+DimitriPapadopoulos@users.noreply.github.com> Date: Sun, 6 Oct 2024 17:50:02 +0200 Subject: [PATCH 4/4] STY: Further simplification Co-authored-by: Chris Markiewicz --- nipype/interfaces/base/support.py | 2 +- tools/checkspecs.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/nipype/interfaces/base/support.py b/nipype/interfaces/base/support.py index dd3c1aa60d..e6467ebb44 100644 --- a/nipype/interfaces/base/support.py +++ b/nipype/interfaces/base/support.py @@ -99,7 +99,7 @@ def __exit__(self, exc_type, exc_value, exc_tb): traceback.format_exception(exc_type, exc_value, exc_tb) ) # Gather up the exception arguments and append nipype info. - exc_args = exc_value.args if exc_value.args else tuple() + exc_args = exc_value.args or () exc_args += ( f"An exception of type {exc_type.__name__} occurred while " f"running interface {self._runtime.interface}.", diff --git a/tools/checkspecs.py b/tools/checkspecs.py index 7f0beccf1e..3e54ca12e8 100644 --- a/tools/checkspecs.py +++ b/tools/checkspecs.py @@ -287,7 +287,7 @@ def test_specs(self, uri): continue parent_metadata = [] if "parent" in trait.__dict__: - parent_metadata = list(trait.parent.__dict__.keys()) + parent_metadata = list(trait.parent.__dict__) if ( key not in allowed_keys @@ -375,7 +375,7 @@ def test_specs(self, uri): continue parent_metadata = [] if "parent" in trait.__dict__: - parent_metadata = list(trait.parent.__dict__.keys()) + parent_metadata = list(trait.parent.__dict__) if ( key not in allowed_keys