From c55fc5a967ece118184840503d211cca9b8834a1 Mon Sep 17 00:00:00 2001 From: erick Date: Sat, 31 Oct 2009 01:17:28 +0000 Subject: Integrated comments from simpoir --- (limited to 'tutorius/tutorial.py') diff --git a/tutorius/tutorial.py b/tutorius/tutorial.py index a2011f1..9831a7b 100644 --- a/tutorius/tutorial.py +++ b/tutorius/tutorial.py @@ -20,6 +20,8 @@ from .constraints import ConstraintException from .properties import TPropContainer +_NAME_SEPARATOR = "/" + class Tutorial(object): """ This class replaces the previous Tutorial class and allows manipulation of the abstract representation @@ -30,7 +32,6 @@ class Tutorial(object): END = "END" INITIAL_TRANSITION_NAME = INIT + "/transition0" - _NAME_SEPARATOR = "/" def __init__(self, name, state_dict=None): """ @@ -68,6 +69,7 @@ class Tutorial(object): else: raise NotImplementedError("Tutorial: Initilization from a dictionary is not supported yet") + # Minimally check for the presence of an INIT and an END # state if not self._state_dict.has_key(Tutorial.INIT): @@ -84,25 +86,8 @@ class Tutorial(object): # existing state names self._state_name_nb = 0 - # Validation decorators to assert preconditions - def validateStateName(meth): - """ - Assert that the state name found in the first part of the string - actually exists - """ - def new(self, name, *args, **kwargs): - state_name = name - if name.find(Tutorial._NAME_SEPARATOR) != -1: - state_name = name[:name.find(Tutorial._NAME_SEPARATOR)] - - if not self._state_dict.has_key(state_name): - raise LookupError("Tutorial: state <" + str(state_name) +\ - "> is not defined") - return meth(self, name, *args, **kwargs) - return new - - def add_state(self, action_list=[], transition_list=[]): + def add_state(self, action_list=(), transition_list=()): """ Add a new state to the state machine. The state is initialized with the action list and transition list @@ -176,7 +161,6 @@ class Tutorial(object): # The unicity of the transition is validated by the state return self._state_dict[state_name].add_transition(transition) - @validateStateName def update_action(self, action_name, new_properties): """ Update the action with action_name with a property dictionary @@ -189,14 +173,13 @@ class Tutorial(object): @raise LookupError if action_name doesn't exist @raise ConstraintException if a property constraint is violated """ - state_name = action_name[:action_name.find(Tutorial._NAME_SEPARATOR)] + state_name = self._validate_state_name(action_name) #TODO: We should validate that only properties defined on the action # are passed in return self._state_dict[state_name].update_action(action_name, new_properties) - @validateStateName def update_transition(self, transition_name, new_properties=None, new_state=None): """ Update the transition with transition_name with new properties and/or @@ -211,7 +194,7 @@ class Tutorial(object): @raise LookupError if transition_name doesn't exist @raise ConstraintException if a property constraint is violated """ - state_name = transition_name[:transition_name.find(Tutorial._NAME_SEPARATOR)] + state_name = self._validate_state_name(transition_name) if not self._state_dict.has_key(state_name): raise LookupError("Tutorial: transition <" + transition_name +\ @@ -226,7 +209,6 @@ class Tutorial(object): return self._state_dict[state_name].update_transition(transition_name, new_properties, new_state) - @validateStateName def delete_action(self, action_name): """ Delete the action identified by action_name. @@ -235,11 +217,10 @@ class Tutorial(object): @return the action that has been deleted @raise LookupError if transition_name doesn't exist """ - state_name = action_name[:action_name.find(Tutorial._NAME_SEPARATOR)] + state_name = self._validate_state_name(action_name) return self._state_dict[state_name].delete_action(action_name) - @validateStateName def delete_transition(self, transition_name): """ Delete the transition identified by transition_name. @@ -248,11 +229,10 @@ class Tutorial(object): @return the transition that has been deleted @raise LookupError if transition_name doesn't exist """ - state_name = transition_name[:transition_name.find(Tutorial._NAME_SEPARATOR)] + state_name = self._validate_state_name(transition_name) return self._state_dict[state_name].delete_transition(transition_name) - @validateStateName def delete_state(self, state_name): """ Delete the state, delete all the actions and transitions @@ -267,6 +247,8 @@ class Tutorial(object): @raise StateDeletionError when trying to delete the INIT or the END state @raise LookupError if state_name doesn't exist """ + self._validate_state_name(state_name) + if state_name == Tutorial.INIT or state_name == Tutorial.END: raise StateDeletionError("<" + state_name + "> cannot be deleted") @@ -310,7 +292,7 @@ class Tutorial(object): raise LookupError("Tutorial: state <" + state_name +\ "> is not defined") elif state_name: - return self._state_dict.get_action_dict() + return self._state_dict[state_name].get_action_dict() else: action_dict = {} for state in self._state_dict.itervalues(): @@ -331,7 +313,7 @@ class Tutorial(object): raise LookupError("Tutorial: state <" + state_name +\ "> is not defined") elif state_name: - return self._state_dict.get_transition_dict() + return self._state_dict[state_name].get_transition_dict() else: transition_dict = {} for state in self._state_dict.itervalues(): @@ -510,6 +492,27 @@ class Tutorial(object): """ pass + # Validation decorators to assert preconditions + def _validate_state_name(self,name): + """ + Assert that the state name found in the first part of the string + actually exists + + @param name The name that starts with a state name + @return the state_name from name + @raise LookupError if state_name doesn't exist + """ + state_name = name + + if name.find(_NAME_SEPARATOR) != -1: + state_name = name[:name.find(_NAME_SEPARATOR)] + + if not self._state_dict.has_key(state_name): + raise LookupError("Tutorial: state <" + str(state_name) +\ + "> is not defined") + + return state_name + def validate(self): """ Validate the state machine for a serie of properties: @@ -545,7 +548,7 @@ class State(object): inputs, the validation should be done by the containing class. """ - def __init__(self, name, action_list=[], transition_list=[]): + def __init__(self, name, action_list=(), transition_list=()): """ Initializes the content of the state, such as loading the actions that are required and building the correct transitions. @@ -678,17 +681,18 @@ class State(object): tmp_event = transition[0] tmp_state = transition[1] + + prop = new_properties or {} old_properties = transition[0].get_properties_dict_copy() old_state = transition[1] - if new_properties: - try: - for property_name, property_value in new_properties.iteritems(): - tmp_event.__setattr__(property_name, property_value) - except ConstraintException, e: - tmp_event._props = old_properties - raise e + try: + for property_name, property_value in prop.iteritems(): + tmp_event.__setattr__(property_name, property_value) + except ConstraintException, e: + tmp_event._props = old_properties + raise e if new_state: tmp_state = new_state @@ -736,7 +740,7 @@ class State(object): #TODO use the action class name to generate a name # to make it easier to debug and know what we are # manipulating - name = self.name + Tutorial._NAME_SEPARATOR + "action" + str(self.action_name_nb) + name = self.name + _NAME_SEPARATOR + "action" + str(self.action_name_nb) self.action_name_nb += 1 return name @@ -752,7 +756,7 @@ class State(object): #TODO use the event class name from the transition to # generate a name to make it easier to debug and know # what we are manipulating - name = self.name + Tutorial._NAME_SEPARATOR + "transition" + str(self.transition_name_nb) + name = self.name + _NAME_SEPARATOR + "transition" + str(self.transition_name_nb) self.transition_name_nb += 1 return name -- cgit v0.9.1