def __new__(mcls, name, bases, namespace_dict):
     my_type = super(FunctionAnchoringType, mcls).__new__(mcls,
                                                          name,
                                                          bases,
                                                          namespace_dict)
     
     # We want the type's `vars`, but we want them "getted," and not in a
     # `dict`, so we'll get method objects instead of plain functions.
     my_getted_vars = misc_tools.getted_vars(my_type)
     # Repeat after me: "Getted, not dict."
     
     functions_to_anchor = [value for key, value in my_getted_vars.items()
                            if isinstance(value, types.FunctionType) and not
                            misc_tools.is_magic_variable_name(key)]
     for function in functions_to_anchor:
         module_name = function.__module__
         module = sys.modules[module_name]
         function_name = function.__name__
         
         # Since this metaclass is a hacky enough solution as it is, let's
         # be careful and ensure no object is already defined by the same
         # name in the module level: (todotest)
         try:
             already_defined_object = getattr(module, function_name)
         except AttributeError:
             # Good, there is no object defined under our anchor address.
             # This is the normal case.
             setattr(module, function_name, function)
         else:
             # Something already exists at the anchor address; let's be
             # careful.
             if already_defined_object is not function:
                 raise Exception("An object `%s.%s` already exists! Can't "
                                 "anchor function." % \
                                 (module_name, function_name))
     return my_type
示例#2
0
    def __new__(mcls, name, bases, namespace_dict):
        my_type = super(FunctionAnchoringType,
                        mcls).__new__(mcls, name, bases, namespace_dict)

        # We want the type's `vars`, but we want them "getted," and not in a
        # `dict`, so we'll get method objects instead of plain functions.
        my_getted_vars = misc_tools.getted_vars(my_type)
        # Repeat after me: "Getted, not dict."

        functions_to_anchor = [
            value for key, value in my_getted_vars.items()
            if isinstance(value, types.FunctionType)
            and not misc_tools.is_magic_variable_name(key)
        ]
        for function in functions_to_anchor:
            module_name = function.__module__
            module = sys.modules[module_name]
            function_name = function.__name__

            # Since this metaclass is a hacky enough solution as it is, let's
            # be careful and ensure no object is already defined by the same
            # name in the module level: (todotest)
            try:
                already_defined_object = getattr(module, function_name)
            except AttributeError:
                # Good, there is no object defined under our anchor address.
                # This is the normal case.
                setattr(module, function_name, function)
            else:
                # Something already exists at the anchor address; let's be
                # careful.
                if already_defined_object is not function:
                    raise Exception("An object `%s.%s` already exists! Can't "
                                    "anchor function." % \
                                    (module_name, function_name))
        return my_type
    def __init_analysis(self):
        '''Analyze the simpack.'''
        
        simpack = self.simpack
        
        try:
            State = simpack.State
        except AttributeError:
            raise InvalidSimpack("The `%s` simpack does not define a `State` "
                                 "class." % simpack.__name__.rsplit('.')[-1])
        
        if not misc_tools.is_subclass(State, garlicsim.data_structures.State):
            raise InvalidSimpack("The `%s` simpack defines a `State` class, "
                                 "but it's not a subclass of "
                                 "`garlicsim.data_structures.State`." % \
                                 simpack.__name__.rsplit('.')[-1])


        state_methods = dict(
            (name, value) for (name, value) in
            list(misc_tools.getted_vars(State).items()) if isinstance(value, collections.Callable)
        )

        self.step_functions_by_type = dict((step_type, []) for step_type in
                                           step_types.step_types_list)
        '''dict mapping from each step type to step functions of that type.'''
        
        
        for method in list(state_methods.values()):
            step_type = StepType.get_step_type(method)
            if step_type:
                self.step_functions_by_type[step_type].append(method)
            
                
        if self.step_functions_by_type[step_types.HistoryStep] or \
           self.step_functions_by_type[step_types.HistoryStepGenerator]:
            
            self.history_dependent = True

            self.all_step_functions = (
                self.step_functions_by_type[step_types.HistoryStepGenerator] +
                self.step_functions_by_type[step_types.HistoryStep]
            )
            
            if (self.step_functions_by_type[step_types.SimpleStep] or
                self.step_functions_by_type[step_types.StepGenerator] or
                self.step_functions_by_type[step_types.InplaceStep] or
                self.step_functions_by_type[step_types.InplaceStepGenerator]):
                
                raise InvalidSimpack("The `%s` simpack is defining both a "
                                     "history-dependent step and a "
                                     "non-history-dependent step - which "
                                     "is forbidden." % \
                                     simpack.__name__.rsplit('.')[-1])
        else: # No history step defined
            
            self.history_dependent = False
            
            self.all_step_functions = (
                self.step_functions_by_type[step_types.StepGenerator] + \
                self.step_functions_by_type[step_types.SimpleStep] + \
                self.step_functions_by_type[step_types.InplaceStepGenerator] +\
                self.step_functions_by_type[step_types.InplaceStep]
            )
            
            
        # (no-op assignments, just for docs:)
        
        self.history_dependent = self.history_dependent
        '''Flag saying whether the simpack looks at previous states.'''
        
        self.all_step_functions = self.all_step_functions
        '''
        All the step functions that the simpack provides, sorted by priority.
        '''
               
        if not self.all_step_functions:
            raise InvalidSimpack("The `%s` simpack has not defined any kind "
                                 "of step function." % \
                                 simpack.__name__.rsplit('.')[-1])
        
        self.default_step_function = self.all_step_functions[0]
        '''
示例#4
0
    def __init_analysis(self):
        '''Analyze the simpack.'''

        simpack = self.simpack

        try:
            State = simpack.State
        except AttributeError:
            raise InvalidSimpack("The `%s` simpack does not define a `State` "
                                 "class." % simpack.__name__.rsplit('.')[-1])

        if not misc_tools.is_subclass(State, garlicsim.data_structures.State):
            raise InvalidSimpack("The `%s` simpack defines a `State` class, "
                                 "but it's not a subclass of "
                                 "`garlicsim.data_structures.State`." % \
                                 simpack.__name__.rsplit('.')[-1])

        state_methods = dict(
            (name, value)
            for (name, value) in misc_tools.getted_vars(State).iteritems()
            if callable(value))

        self.step_functions_by_type = dict(
            (step_type, []) for step_type in step_types.step_types_list)
        '''dict mapping from each step type to step functions of that type.'''

        for method in state_methods.itervalues():
            step_type = StepType.get_step_type(method)
            if step_type:
                self.step_functions_by_type[step_type].append(method)


        if self.step_functions_by_type[step_types.HistoryStep] or \
           self.step_functions_by_type[step_types.HistoryStepGenerator]:

            self.history_dependent = True

            self.all_step_functions = (
                self.step_functions_by_type[step_types.HistoryStepGenerator] +
                self.step_functions_by_type[step_types.HistoryStep])

            if (self.step_functions_by_type[step_types.SimpleStep]
                    or self.step_functions_by_type[step_types.StepGenerator]
                    or self.step_functions_by_type[step_types.InplaceStep]
                    or self.step_functions_by_type[
                        step_types.InplaceStepGenerator]):

                raise InvalidSimpack("The `%s` simpack is defining both a "
                                     "history-dependent step and a "
                                     "non-history-dependent step - which "
                                     "is forbidden." % \
                                     simpack.__name__.rsplit('.')[-1])
        else:  # No history step defined

            self.history_dependent = False

            self.all_step_functions = (
                self.step_functions_by_type[step_types.StepGenerator] + \
                self.step_functions_by_type[step_types.SimpleStep] + \
                self.step_functions_by_type[step_types.InplaceStepGenerator] +\
                self.step_functions_by_type[step_types.InplaceStep]
            )

        # (no-op assignments, just for docs:)

        self.history_dependent = self.history_dependent
        '''Flag saying whether the simpack looks at previous states.'''

        self.all_step_functions = self.all_step_functions
        '''
        All the step functions that the simpack provides, sorted by priority.
        '''

        if not self.all_step_functions:
            raise InvalidSimpack("The `%s` simpack has not defined any kind "
                                 "of step function." % \
                                 simpack.__name__.rsplit('.')[-1])

        self.default_step_function = self.all_step_functions[0]
        '''