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:
		 Joshua Harlow
					Joshua Harlow
				
			
				
					committed by
					
						 Joshua Harlow
						Joshua Harlow
					
				
			
			
				
	
			
			
			 Joshua Harlow
						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