Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add property for optional runner #913

Merged
merged 3 commits into from
Jun 14, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion nornir/core/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
from typing import TYPE_CHECKING, Any, Callable, Dict, Generator, List, Optional, Type

from nornir.core.configuration import Config
from nornir.core.exceptions import PluginNotRegistered
from nornir.core.inventory import Inventory
from nornir.core.plugins.runners import RunnerPlugin
from nornir.core.processor import Processor, Processors
Expand Down Expand Up @@ -142,7 +143,7 @@ def run(
else:
logger.warning("Task %r has not been run – 0 hosts selected", task.name)

result = self.runner.run(task, run_on)
result = self._runner.run(task, run_on)

raise_on_error = (
raise_on_error
Expand All @@ -168,6 +169,13 @@ def close_connections_task(task):

self.run(task=close_connections_task, on_good=on_good, on_failed=on_failed)

@property
def _runner(self) -> RunnerPlugin:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

shouldn't we do the opposite? store in _runner and have the propery be runner?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that first however it breaks some other things, in the below functions we use self.__dict__ which causes issues with an attributed such as self._runner as we'd send in "_runner" as an argument to Nornir instead of "runner".

    def with_processors(self, processors: List[Processor]) -> "Nornir":
        """
        Given a list of Processor objects return a copy of the nornir object with the processors
        assigned to the copy. The orinal object is left unmodified.
        """
        return Nornir(**{**self.__dict__, **{"processors": Processors(processors)}})

    def with_runner(self, runner: RunnerPlugin) -> "Nornir":
        """
        Given a runner return a copy of the nornir object with the runner
        assigned to the copy. The orinal object is left unmodified.
        """
        return Nornir(**{**self.__dict__, **{"runner": runner}})

    def filter(self, *args: Any, **kwargs: Any) -> "Nornir":
        """
        See :py:meth:`nornir.core.inventory.Inventory.filter`

        Returns:
            :obj:`Nornir`: A new object with same configuration as ``self`` but filtered inventory.
        """
        b = Nornir(**self.__dict__)
        b.inventory = self.inventory.filter(*args, **kwargs)
        return b

What we could do instead is to replace self.__dict__ in these cases with a property that returns a dictionary where the keys are hardcoded instead, i.e: inventory, data, config, runner, processors.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah, either that or just a cleaner clone method

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can update the PR to add something like that. Within that property or method I will have to call self._runner but that might be the best option for now. Would be nice too then go back and delete this when there's a new major version to clean it up a bit..

if self.runner:
return self.runner

raise PluginNotRegistered("Runner plugin not registered")

@classmethod
def get_validators(cls) -> Generator[Callable[["Nornir"], "Nornir"], None, None]:
yield cls.validate
Expand Down
1 change: 0 additions & 1 deletion setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,6 @@ warn_redundant_casts = True
[mypy-nornir.core]
disallow_untyped_defs = False
disallow_incomplete_defs = False
strict_optional = False

[mypy-tests.*]
ignore_errors = True