diff --git a/pyiron_workflow/io.py b/pyiron_workflow/io.py index 4d983996..6e79778a 100644 --- a/pyiron_workflow/io.py +++ b/pyiron_workflow/io.py @@ -534,8 +534,8 @@ def _copy_connections( except Exception as e: if fail_hard: # If you run into trouble, unwind what you've done - for this, other in new_connections: - this.disconnect(other) + for this, that in new_connections: + this.disconnect(that) raise ConnectionCopyError( f"{self.label} could not copy connections from " f"{other.label} due to the channel {key} on " diff --git a/pyiron_workflow/node.py b/pyiron_workflow/node.py index 07a2d7d3..903a9832 100644 --- a/pyiron_workflow/node.py +++ b/pyiron_workflow/node.py @@ -412,7 +412,7 @@ def run_args(self) -> tuple[tuple, dict]: @property @abstractmethod - def _run_args(self, *args, **kwargs) -> Any: + def _run_args(self) -> tuple[tuple, dict]: pass def run( diff --git a/pyiron_workflow/nodes/for_loop.py b/pyiron_workflow/nodes/for_loop.py index bc408821..7ce94e27 100644 --- a/pyiron_workflow/nodes/for_loop.py +++ b/pyiron_workflow/nodes/for_loop.py @@ -112,15 +112,12 @@ def merge(d1, d2): key_index_maps = tuple( zipped_index_map(zipped_index) for zipped_index in zipped_generator() ) + elif nested_keys is None and zipped_keys is None: + raise ValueError( + "At least one of `nested_keys` or `zipped_keys` must be specified." + ) else: - if nested_keys is None and zipped_keys is None: - raise ValueError( - "At least one of `nested_keys` or `zipped_keys` must be specified." - ) - else: - raise ValueError( - "Received keys to iterate over, but all values had length 0." - ) + raise ValueError("Received keys to iterate over, but all values had length 0.") return key_index_maps @@ -376,9 +373,12 @@ def _build_inputs_preview(cls) -> dict[str, tuple[Any, Any]]: for label, (hint, default) in cls._body_node_class.preview_inputs().items(): # TODO: Leverage hint and default, listing if it's looped on if label in cls._zip_on + cls._iter_on: - hint = list if hint is None else list[hint] # type: ignore[valid-type] - default = NOT_DATA # TODO: Figure out a generator pattern to get lists - preview[label] = (hint, default) + preview[label] = ( + list if hint is None else list[hint], # type: ignore[valid-type] + NOT_DATA, # TODO: Figure out a generator pattern to get lists + ) + else: + preview[label] = (hint, default) return preview @classmethod @@ -392,8 +392,7 @@ def _build_outputs_preview(cls) -> dict[str, Any]: _default, ) in cls._body_node_class.preview_inputs().items(): if label in cls._zip_on + cls._iter_on: - hint = list if hint is None else list[hint] # type: ignore[valid-type] - preview[label] = hint + preview[label] = list if hint is None else list[hint] # type: ignore[valid-type] for label, hint in cls._body_node_class.preview_outputs().items(): preview[cls.output_column_map()[label]] = ( list if hint is None else list[hint] # type: ignore[valid-type] diff --git a/pyiron_workflow/nodes/macro.py b/pyiron_workflow/nodes/macro.py index ec09f8e8..5cb0d13e 100644 --- a/pyiron_workflow/nodes/macro.py +++ b/pyiron_workflow/nodes/macro.py @@ -13,6 +13,7 @@ from pyiron_snippets.factory import classfactory +from pyiron_workflow.compatibility import Self from pyiron_workflow.io import Inputs from pyiron_workflow.mixin.has_interface_mixins import HasChannel from pyiron_workflow.mixin.injection import OutputsWithInjection @@ -196,7 +197,6 @@ class Macro(Composite, StaticNode, ScrapesIO, ABC): >>> class AddThreeMacro(Macro): ... _output_labels = ["three"] ... - ... @staticmethod ... def graph_creator(self, x): ... add_three_macro(self, one__x=x) ... return self.three @@ -252,7 +252,7 @@ def _setup_node(self) -> None: super()._setup_node() ui_nodes = self._prepopulate_ui_nodes_from_graph_creator_signature() - returned_has_channel_objects = self.graph_creator(self, *ui_nodes) + returned_has_channel_objects = self.graph_creator(*ui_nodes) if returned_has_channel_objects is None: returned_has_channel_objects = () elif isinstance(returned_has_channel_objects, HasChannel): @@ -271,10 +271,9 @@ def _setup_node(self) -> None: remaining_ui_nodes = self._purge_single_use_ui_nodes(ui_nodes) self._configure_graph_execution(remaining_ui_nodes) - @staticmethod @abstractmethod def graph_creator( - self: Macro, *args, **kwargs + self: Self, *args, **kwargs ) -> HasChannel | tuple[HasChannel, ...] | None: """Build the graph the node will run.""" @@ -480,7 +479,8 @@ def macro_node_factory( Create a new :class:`Macro` subclass using the given graph creator function. Args: - graph_creator (callable): Function to create the graph for the :class:`Macro`. + graph_creator (callable): Function to create the graph for this subclass of + :class:`Macro`. validate_output_labels (bool): Whether to validate the output labels against the return values of the wrapped function. use_cache (bool): Whether nodes of this type should default to caching their @@ -495,7 +495,7 @@ def macro_node_factory( graph_creator.__name__, (Macro,), # Define parentage { - "graph_creator": staticmethod(graph_creator), + "graph_creator": graph_creator, "__module__": graph_creator.__module__, "__qualname__": graph_creator.__qualname__, "_output_labels": None if len(output_labels) == 0 else output_labels, diff --git a/pyproject.toml b/pyproject.toml index f3e7f5fc..c18ce4e3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -86,8 +86,25 @@ select = [ "C4", # eradicate "ERA", + # pylint + "PL", +] +ignore = [ + # ignore line-length violations + "E501", + # Too many arguments in function definition + "PLR0913", + # Magic value used in comparison + "PLR2004", + # Import alias does not rename original package + "PLC0414", + # Too many branches + "PLR0912", + # Too many statements + "PLR0915", + # Too many return statements + "PLR0911", ] -ignore = ["E501"] #ignore line-length violations [tool.ruff.lint.per-file-ignores] "__init__.py" = ["F401"] # Ignore unused imports in init files -- we specify APIs this way diff --git a/tests/unit/nodes/test_macro.py b/tests/unit/nodes/test_macro.py index fb402fda..401db81a 100644 --- a/tests/unit/nodes/test_macro.py +++ b/tests/unit/nodes/test_macro.py @@ -172,7 +172,6 @@ def test_creation_from_subclass(self): class MyMacro(Macro): _output_labels = ("three__result",) - @staticmethod def graph_creator(self, one__x): add_three_macro(self, one__x) return self.three