Add a frozen checking decorator
Since quite a few of the types check for being frozen and disallow mutations on there instances we can take advantage of a common decorator that checks the frozen attribute and raises instead of duplicating the same logic at the start of the mutating methods. Change-Id: I8c81a26d2d39bb9da4f68d64e07f67ac26ee0b08
This commit is contained in:
committed by
Joshua Harlow
parent
f391702f0e
commit
3c806b1d6a
@@ -23,6 +23,7 @@ import six
|
||||
|
||||
from taskflow import exceptions as excp
|
||||
from taskflow.types import table
|
||||
from taskflow.utils import misc
|
||||
|
||||
|
||||
class _Jump(object):
|
||||
@@ -97,6 +98,7 @@ class FSM(object):
|
||||
return False
|
||||
return self._states[self._current.name]['terminal']
|
||||
|
||||
@misc.disallow_when_frozen(FrozenMachine)
|
||||
def add_state(self, state, terminal=False, on_enter=None, on_exit=None):
|
||||
"""Adds a given state to the state machine.
|
||||
|
||||
@@ -111,8 +113,6 @@ class FSM(object):
|
||||
:param state: state being entered or exited
|
||||
:type state: string
|
||||
"""
|
||||
if self.frozen:
|
||||
raise FrozenMachine()
|
||||
if state in self._states:
|
||||
raise excp.Duplicate("State '%s' already defined" % state)
|
||||
if on_enter is not None:
|
||||
@@ -129,6 +129,7 @@ class FSM(object):
|
||||
}
|
||||
self._transitions[state] = OrderedDict()
|
||||
|
||||
@misc.disallow_when_frozen(FrozenMachine)
|
||||
def add_reaction(self, state, event, reaction, *args, **kwargs):
|
||||
"""Adds a reaction that may get triggered by the given event & state.
|
||||
|
||||
@@ -149,8 +150,6 @@ class FSM(object):
|
||||
processed (and this process typically repeats) until the state
|
||||
machine reaches a terminal state.
|
||||
"""
|
||||
if self.frozen:
|
||||
raise FrozenMachine()
|
||||
if state not in self._states:
|
||||
raise excp.NotFound("Can not add a reaction to event '%s' for an"
|
||||
" undefined state '%s'" % (event, state))
|
||||
@@ -162,6 +161,7 @@ class FSM(object):
|
||||
raise excp.Duplicate("State '%s' reaction to event '%s'"
|
||||
" already defined" % (state, event))
|
||||
|
||||
@misc.disallow_when_frozen(FrozenMachine)
|
||||
def add_transition(self, start, end, event):
|
||||
"""Adds an allowed transition from start -> end for the given event.
|
||||
|
||||
@@ -169,8 +169,6 @@ class FSM(object):
|
||||
:param end: end of the transition
|
||||
:param event: event that caused the transition
|
||||
"""
|
||||
if self.frozen:
|
||||
raise FrozenMachine()
|
||||
if start not in self._states:
|
||||
raise excp.NotFound("Can not add a transition on event '%s' that"
|
||||
" starts in a undefined state '%s'" % (event,
|
||||
|
||||
@@ -21,6 +21,8 @@ import os
|
||||
|
||||
import six
|
||||
|
||||
from taskflow.utils import misc
|
||||
|
||||
|
||||
class FrozenNode(Exception):
|
||||
"""Exception raised when a frozen node is modified."""
|
||||
@@ -98,9 +100,12 @@ class Node(object):
|
||||
n.freeze()
|
||||
self.frozen = True
|
||||
|
||||
@misc.disallow_when_frozen(FrozenNode)
|
||||
def add(self, child):
|
||||
if self.frozen:
|
||||
raise FrozenNode()
|
||||
"""Adds a child to this node (appends to left of existing children).
|
||||
|
||||
NOTE(harlowja): this will also set the childs parent to be this node.
|
||||
"""
|
||||
child.parent = self
|
||||
self._children.append(child)
|
||||
|
||||
|
||||
@@ -227,6 +227,23 @@ def look_for(haystack, needles, extractor=None):
|
||||
return [needles[i] for (_hay_i, i) in sorted(matches)]
|
||||
|
||||
|
||||
def disallow_when_frozen(excp_cls):
|
||||
"""Frozen checking/raising method decorator."""
|
||||
|
||||
def decorator(f):
|
||||
|
||||
@six.wraps(f)
|
||||
def wrapper(self, *args, **kwargs):
|
||||
if self.frozen:
|
||||
raise excp_cls()
|
||||
else:
|
||||
return f(self, *args, **kwargs)
|
||||
|
||||
return wrapper
|
||||
|
||||
return decorator
|
||||
|
||||
|
||||
def clamp(value, minimum, maximum, on_clamped=None):
|
||||
"""Clamps a value to ensure its >= minimum and <= maximum."""
|
||||
if minimum > maximum:
|
||||
|
||||
Reference in New Issue
Block a user