Source code for spicerack.actions

"""Actions module."""
import logging

from collections import OrderedDict
from typing import Hashable, List


logger = logging.getLogger(__name__)  # pylint: disable=invalid-name


[docs]class Actions: """Class to keep track and log a set of actions performed and their result with a nice string representation.""" def __init__(self, name: Hashable): """Initialize the instance. When converted to string returns a nicely formatted representation of the instance and all its actions. It exposes the following properties: - ``name``: the name passed to the instance at instantiation time. - ``has_warnings``: a :py:class:`bool` that is :py:data:`True` when at least one warning action was registered, :py:data:`False` otherwise. - ``has_failures``: a :py:class:`bool` that is :py:data:`True` when at least one failed action was registered, :py:data:`False` otherwise. Arguments: name (typing.Hashable): the name of the set of actions to be registered. """ self.name = name self.actions = [] # type: List[str] self.has_warnings = False self.has_failures = False def __str__(self) -> str: """Custom string representation of the actions performed. Returns: str: the string representation. """ actions = '\n'.join(' - {action}'.format(action=action) for action in self.actions) return '{name} (**{status}**)\n{actions}'.format(name=self.name, status=self.status, actions=actions) @property def status(self) -> str: """Return the current status of the actions based on the worst result recorded. Returns: str: the short string representation of the status, one of: ``PASS``, ``WARN``, ``FAIL``. """ if self.has_failures: return 'FAIL' if self.has_warnings: return 'WARN' return 'PASS'
[docs] def success(self, message: str) -> None: """Register a successful action. Arguments: message (str): the action description. """ self._action(logging.INFO, message)
[docs] def failure(self, message: str) -> None: """Register a failed action. Arguments: message (str): the action description. """ self._action(logging.ERROR, message) self.has_failures = True
[docs] def warning(self, message: str) -> None: """Register an action that require some attention. Arguments: message (str): the action description. """ self._action(logging.WARNING, message) self.has_warnings = True
def _action(self, level: int, message: str) -> None: """Register a generic action. Arguments: level (int): a logging level integer to register the action for. message (str): the action description. """ logger.log(level, message) self.actions.append(message)
[docs]class ActionsDict(OrderedDict): """OrderedDict with defaultdict capabilities for the :py:class:`spicerack.actions.Action` class. Inherits from :py:class:`collections.OrderedDict` and automatically instantiate and returns a new instance of the :py:class:`spicerack.actions.Actions` class for every missing key like a :py:class:`collections.defaultdict`. When accessing a missing key, the key itself is passed to the new :py:class:`spicerack.actions.Actions` instance as ``name``. When converted to string returns a nicely formatted representation of the instance and all its items. Todo: Once the support of Python 3.5 is dropped this can be converted into a simple factory with a single ``new()`` method that returns an instance of ``defaultdict(Actions)``. """ def __missing__(self, key: Hashable) -> Actions: """Instantiate a new Actions instance for the missing key like a defaultdict. Parameters as required by Python's data model, see :py:method:`object.__missing__`. """ self[key] = Actions(key) return self[key] def __str__(self) -> str: """Custom string representation of the instance. Returns: str: the string representation. """ return '\n'.join('- {actions}\n'.format(actions=value) for key, value in self.items())