How to use the transitions.core.Machine function in transitions

To help you get started, we’ve selected a few transitions examples, based on popular ways it is used in public projects.

Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.

github pytransitions / transitions / transitions / extensions / nesting.py View on Github external
    @Machine.initial.setter
    def initial(self, value):
        if isinstance(value, NestedState):
            if value.name not in self.states:
                self.add_state(value)
            else:
                assert self._has_state(value)
            state = value
        else:
            state_name = value.name if isinstance(value, Enum) else value
            if state_name not in self.states:
                self.add_state(state_name)
            state = self.get_state(state_name)
        if state.initial:
            self.initial = state.initial
        else:
            self._initial = state.name
github mottosso / allzpark / allzpark / vendor / transitions / extensions / locking.py View on Github external
""" An event type which uses the parent's machine context map when triggered. """

    def trigger(self, model, *args, **kwargs):
        """ Extends transitions.core.Event.trigger by using locks/machine contexts. """
        # pylint: disable=protected-access
        # noinspection PyProtectedMember
        # LockedMachine._locked should not be called somewhere else. That's why it should not be exposed
        # to Machine users.
        if self.machine._locked != get_ident():
            with nested(*self.machine.model_context_map[model]):
                return _super(LockedEvent, self).trigger(model, *args, **kwargs)
        else:
            return _super(LockedEvent, self).trigger(model, *args, **kwargs)


class LockedMachine(Machine):
    """ Machine class which manages contexts. In it's default version the machine uses a `threading.Lock`
        context to lock access to its methods and event triggers bound to model objects.
    Attributes:
        machine_context (dict): A dict of context managers to be entered whenever a machine method is
            called or an event is triggered. Contexts are managed for each model individually.
    """

    event_cls = LockedEvent

    def __init__(self, *args, **kwargs):
        self._locked = 0

        try:
            self.machine_context = listify(kwargs.pop('machine_context'))
        except KeyError:
            self.machine_context = [PicklableLock()]
github pytransitions / transitions / transitions / core.py View on Github external
queued (boolean): When True, processes transitions sequentially. A trigger
                executed in a state callback function will be queued and executed later.
                Due to the nature of the queued processing, all transitions will
                _always_ return True since conditional checks cannot be conducted at queueing time.
            prepare_event: A callable called on for before possible transitions will be processed.
                It receives the very same args as normal callbacks.
            finalize_event: A callable called on for each triggered event after transitions have been processed.
                This is also called when a transition raises an exception.

            **kwargs additional arguments passed to next class in MRO. This can be ignored in most cases.
        """

        # calling super in case `Machine` is used as a mix in
        # all keyword arguments should be consumed by now if this is not the case
        try:
            super(Machine, self).__init__(**kwargs)
        except TypeError as err:
            raise ValueError('Passing arguments {0} caused an inheritance error: {1}'.format(kwargs.keys(), err))

        # initialize protected attributes first
        self._queued = queued
        self._transition_queue = deque()
        self._before_state_change = []
        self._after_state_change = []
        self._prepare_event = []
        self._finalize_event = []
        self._initial = None

        self.states = OrderedDict()
        self.events = {}
        self.send_event = send_event
        self.auto_transitions = auto_transitions
github pytransitions / transitions / transitions / extensions / factory.py View on Github external
pass


class LockedHierarchicalGraphMachine(GraphMachine, LockedMachine, HierarchicalMachine):
    """
        A threadsafe hiearchical machine with graph support.
    """

    transition_cls = NestedGraphTransition
    event_cls = LockedNestedEvent
    graph_cls = NestedGraph


# 3d tuple (graph, nested, locked)
_CLASS_MAP = {
    (False, False, False): Machine,
    (False, False, True): LockedMachine,
    (False, True, False): HierarchicalMachine,
    (False, True, True): LockedHierarchicalMachine,
    (True, False, False): GraphMachine,
    (True, False, True): LockedGraphMachine,
    (True, True, False): HierarchicalGraphMachine,
    (True, True, True): LockedHierarchicalGraphMachine
}
github pytransitions / transitions / transitions / extensions / asyncio.py View on Github external
try:
            for trans in self.transitions[event_data.state.name]:
                event_data.transition = trans
                if await trans.execute(event_data):
                    event_data.result = True
                    break
        except Exception as err:
            event_data.error = err
            raise
        finally:
            await self.machine.callbacks(self.machine.finalize_event, event_data)
            _LOGGER.debug("%sExecuted machine finalize callbacks", self.machine.name)
        return event_data.result


class AsyncMachine(Machine):
    """ Machine manages states, transitions and models. In case it is initialized without a specific model
    (or specifically no model), it will also act as a model itself. Machine takes also care of decorating
    models with conveniences functions related to added transitions and states during runtime.

    Attributes:
        states (OrderedDict): Collection of all registered states.
        events (dict): Collection of transitions ordered by trigger/event.
        models (list): List of models attached to the machine.
        initial (str): Name of the initial state for new models.
        prepare_event (list): Callbacks executed when an event is triggered.
        before_state_change (list): Callbacks executed after condition checks but before transition is conducted.
            Callbacks will be executed BEFORE the custom callbacks assigned to the transition.
        after_state_change (list): Callbacks executed after the transition has been conducted.
            Callbacks will be executed AFTER the custom callbacks assigned to the transition.
        finalize_event (list): Callbacks will be executed after all transitions callbacks have been executed.
            Callbacks mentioned here will also be called if a transition or condition check raised an error.
github pytransitions / transitions / transitions / extensions / nesting.py View on Github external
state = self.machine.get_state(model.state)
        while state.parent and state.name not in self.transitions:
            state = state.parent
        if state.name not in self.transitions:
            msg = "%sCan't trigger event %s from state %s!" % (self.machine.name, self.name,
                                                               model.state)
            if self.machine.get_state(model.state).ignore_invalid_triggers:
                _LOGGER.warning(msg)
            else:
                raise MachineError(msg)
        event_data = EventData(state, self, self.machine,
                               model, args=args, kwargs=kwargs)
        return self._process(event_data)


class HierarchicalMachine(Machine):
    """ Extends transitions.core.Machine by capabilities to handle nested states.
        A hierarchical machine REQUIRES NestedStates (or any subclass of it) to operate.
    """

    state_cls = NestedState
    transition_cls = NestedTransition
    event_cls = NestedEvent

    def __init__(self, *args, **kwargs):
        self._buffered_transitions = []
        _super(HierarchicalMachine, self).__init__(*args, **kwargs)

    @Machine.initial.setter
    def initial(self, value):
        if isinstance(value, NestedState):
            if value.name not in self.states:
github pytransitions / transitions / transitions / extensions / markup.py View on Github external
from six import string_types, iteritems
from functools import partial
import itertools
import importlib
from collections import defaultdict

from ..core import Machine
import numbers


class MarkupMachine(Machine):

    # Special attributes such as NestedState._name/_parent or Transition._condition are handled differently
    state_attributes = ['on_exit', 'on_enter', 'ignore_invalid_triggers', 'timeout', 'on_timeout', 'tags']
    transition_attributes = ['source', 'dest', 'prepare', 'before', 'after']

    def __init__(self, *args, **kwargs):
        self._markup = kwargs.pop('markup', {})
        self._auto_transitions_markup = kwargs.pop('auto_transitions_markup', False)
        self.skip_references = True

        if self._markup:
            models_markup = self._markup.pop('models', [])
            super(MarkupMachine, self).__init__(None, **self._markup)
            for m in models_markup:
                self._add_markup_model(m)
        else:
github pytransitions / transitions / transitions / extensions / diagrams.py View on Github external
if 'ltail' in edge_attr:
                        if _get_subgraph(container, edge_attr['ltail']).has_node(dst):
                            del edge_attr['ltail']

                    edge_attr[label_pos] = self._transition_label(label, t)
                    if container.has_edge(src, dst):
                        edge = container.get_edge(src, dst)
                        edge.attr[label_pos] += ' | ' + edge_attr[label_pos]
                    else:
                        container.add_edge(src, dst, **edge_attr)

        return events


class GraphMachine(Machine):
    _pickle_blacklist = ['graph']

    def __getstate__(self):
        return {k: v for k, v in self.__dict__.items() if k not in self._pickle_blacklist}

    def __setstate__(self, state):
        self.__dict__.update(state)
        for model in self.models:
            graph = self._get_graph(model, title=self.title)
            self.set_node_style(graph, model.state, 'active')

    def __init__(self, *args, **kwargs):
        # remove graph config from keywords
        self.title = kwargs.pop('title', 'State Machine')
        self.show_conditions = kwargs.pop('show_conditions', False)
        self.show_auto_transitions = kwargs.pop('show_auto_transitions', False)
github pytransitions / transitions / transitions / extensions / locking.py View on Github external
""" An event type which uses the parent's machine context map when triggered. """

    def trigger(self, model, *args, **kwargs):
        """ Extends transitions.core.Event.trigger by using locks/machine contexts. """
        # pylint: disable=protected-access
        # noinspection PyProtectedMember
        # LockedMachine._locked should not be called somewhere else. That's why it should not be exposed
        # to Machine users.
        if self.machine._locked != get_ident():
            with nested(*self.machine.model_context_map[model]):
                return _super(LockedEvent, self).trigger(model, *args, **kwargs)
        else:
            return _super(LockedEvent, self).trigger(model, *args, **kwargs)


class LockedMachine(Machine):
    """ Machine class which manages contexts. In it's default version the machine uses a `threading.Lock`
        context to lock access to its methods and event triggers bound to model objects.
    Attributes:
        machine_context (dict): A dict of context managers to be entered whenever a machine method is
            called or an event is triggered. Contexts are managed for each model individually.
    """

    event_cls = LockedEvent

    def __init__(self, *args, **kwargs):
        self._locked = 0

        try:
            self.machine_context = listify(kwargs.pop('machine_context'))
        except KeyError:
            self.machine_context = [PicklableLock()]