def test_api_compatibility(self):
     executing_context = ExecutingContext(executable=self.restricting_exec,
                                          subcontext=self.context)
     self.assertIs(self.context, executing_context.subcontext.subcontext)
     executing_context.execute_for_names(None)
     executing_context.on_trait_change(self._change_detect,
                                       'items_modified')
     executing_context['bb'] = 5
     self.assertEqual(self.events, ['fired', 'fired'])
     expected_context = {'a': 1, 'b': 10, 'aa': 2, 'bb': 5, 'c': 18}
     self.assertEqual(self.context, expected_context)
Ejemplo n.º 2
0
def test_defer_execution():
    """ Does deferring execution work?
    """
    d = DataContext()
    ec = ExecutingContext(subcontext=d, executable=ce)

    ec.defer_execution = True
    ec['a'] = 1
    assert 'c' not in ec
    ec['b'] = 2
    assert 'c' not in ec
    ec.defer_execution = False
    assert 'c' in ec
    assert ec['c'] == 3
Ejemplo n.º 3
0
    def _update_exec_context(self):
        mc = MultiContext(
            # Put the function filter in front so we don't dirty up the data
            # context with function objects.
            FunctionFilterContext(name='functions'),
            self._local_context,
            name='multi',
        )

        if self._shared_context is not None:
            mc.subcontexts.append(self._shared_context)

        self.context = ExecutingContext(
            executable=self.exec_model,
            subcontext=mc,
            name='exec',
        )
Ejemplo n.º 4
0
def test_basic():
    """ Does the basic functionality of an ExecutingContext work?
    """
    d = DataContext()
    d['a'] = 1
    d['b'] = 2
    ec = ExecutingContext(subcontext=d, executable=ce)
    assert 'a' in ec
    assert 'b' in ec
    assert 'c' not in ec

    ec['a'] = 2
    assert ec['a'] == 2
    assert 'c' in ec
    assert ec['c'] == 4

    ec['a'] = 4
    assert ec['a'] == 4
    assert ec['c'] == 6
Ejemplo n.º 5
0
class Application(HasTraits):
    """
    The Application object that ties together an
    execution model, the canvas, the function search window,
    and the shell.
    """

    ######################################################################
    # Application Traits
    ######################################################################

    # The currently loaded, active project
    project = Instance(Project)

    # The view model for the current project's context.
    context_viewer = Instance(ContextVariableList)

    # The Function Search
    # fixme: This should probably not live here.
    function_search = Instance(FunctionSearch, args=())

    # The Function Library
    # fixme: This should probably not live here.
    function_library = Instance(FunctionLibrary, args=())

    # The data directory.
    data_directory = Str()

    # The directory for other files.
    file_directory = Str()

    # Window for displaying HTML help for functions.
    # FIXME: It would be better to re-factor this into an active_help_item
    # trait with an HTML Editor.
    html_window = Instance(HtmlInfoUI, args=())

    # Status bar text
    status = Str

    # Exectue automatically whenever the nodes, bindings, etc. are changed
    auto_execute = Bool(False)

    ######################################################################
    # object interface
    ######################################################################

    def __init__(self, code=None, data_context=None, *args, **kwargs):
        super(Application, self).__init__(*args, **kwargs)

        # Set the global app object in the scripting module.
        scripting.app = self

        self.project = Project()

        if data_context is None:
            data_context = DataContext(name='data')
        self.project.add_context(data_context)

        if code is not None:
            exp = Experiment(code=code, shared_context=data_context)
        else:
            exp = Experiment(shared_context=data_context)
        self.project.active_experiment = exp

        self.context_viewer = ContextVariableList(context=exp.context)

        # XXX: the @on_trait_change decorator is not working for this!
        self.on_trait_change(self._context_items_modified,
            'project:active_experiment.context:items_modified')


    ######################################################################
    # HasTraits interface
    ######################################################################

    def trait_view(self, name=None, view_elements=None):
        if name is None or name=='full':
            return View(
              VGroup( 
                HSplit(
                      VSplit(
                        Item('function_search',
                             editor = InstanceEditor(view=function_search_view),
                             label      = 'Search',
                             id         = 'search',
                             style      = 'custom',
                             dock       = 'horizontal',
                             show_label = False,                      
                        ),
                        Item('html_window',
                             style='custom',
                             show_label=False,
                             springy= True,
                             resizable=True,
                        ),
                        id='search_help_view'
                      ),      
                    VSplit(
                        Item( 'object.project.active_experiment.canvas',
                              label      = 'Canvas',
                              id         = 'canvas',
                              # FIXME:  need a new way to control the canvas
                              # not using BlockEditor
                              editor     = BlockEditor(),
                              dock       = 'horizontal',
                              show_label = False
                        ),
                        Item( 'object.project.active_experiment.exec_model.code',
                              label      = 'Code',
                              id         = 'code',
                              editor     = CodeEditor(dim_lines = 'dim_lines',
                                                      dim_color = 'dim_color',
                                                      squiggle_lines = 'squiggle_lines'),
                              dock       = 'horizontal',
                              show_label = False
                        ),
                    ),
                    Item( 'context_viewer',
                          label = 'Context',
                          id = 'context_table',
                          editor = InstanceEditor(),
                          style = 'custom',
                          dock = 'horizontal',
                          show_label = False,
                    ),
                    id='panel_split',
                ),
                Item( 'status',
                      style      = 'readonly',
                      show_label = False,
                      resizable  = False 
                ),
              ),
              title     = 'Block Canvas',
              menubar   = BlockApplicationMenuBar,
              width     = 1024,
              height    = 768,
              id        = 'blockcanvas.app.application',
              resizable = True,
              handler   = BlockApplicationViewHandler(model=self),
              key_bindings = KeyBindings(
                KeyBinding(binding1='F5', method_name='_on_execute'),
                ),
            )
        elif name == 'simple':
            return View( 
                        HSplit(
                                VSplit(
                                        Item('function_search',
                                             editor = InstanceEditor(view=function_search_view),
                                             label      = 'Search',
                                             id         = 'search',
                                             style      = 'custom',
                                             dock       = 'horizontal',
                                             show_label = False),
                                        Item('html_window',
                                             style='custom',
                                             show_label=False,
                                             springy= True,
                                             resizable=True),
                                        id='search_help_view'
                                        ),      
                                  Item( 'object.project.active_experiment.canvas',
                                              label      = 'Canvas',
                                              id         = 'canvas',
                                              # FIXME:  need a new way to control the canvas
                                              # not using BlockEditor
                                              editor     = BlockEditor(),
                                              dock       = 'horizontal',
                                              show_label = False),
                                id='panel_split'),
                      title     = 'Block Canvas - Simple View',
                      menubar   = BlockApplicationMenuBar,
                      width     = 800,
                      height    = 600,
                      id        = 'blockcanvas.app.application.simple',
                      resizable = True,
                      handler   = BlockApplicationViewHandler(model=self),
                      key_bindings = KeyBindings(
                                                 KeyBinding(binding1='F5', method_name='_on_execute'),
                                                 )
                    )


    ######################################################################
    # Application interface
    ######################################################################

    def reset(self):
        """ Reset the Application to its initial state. 
        
        Clean all old attributes and instanciate new ones.
        """
                
        for context in self.project.contexts:
            self.project.remove_context(context)

        data_context = DataContext(name='data')
        self.project.add_context(data_context)
        exp = Experiment(shared_context=data_context)                
        self.project.active_experiment = exp
        self.context_viewer = ContextVariableList(context=exp.context)

    ### load/save python scripts #########################################

    def load_code_from_file(self, filename):
        experiment = Experiment()
        experiment.load_code_from_file(filename)
        self.project.experiments.append(experiment)
        self.project.active_experiment = experiment
        self.update_functions_UI(self.project.active_experiment.exec_model.statements)   
        self.update_functions_context(self.project.active_experiment,
                                      self.project.active_experiment.exec_model.statements)
        
    def save_code_to_file(self, filename=""):
        self.project.active_experiment.save_script(filename)   

    def run_custom_ui(self, filename, live=True):
        """ Load a module to visually interact with the context.

        Parameters
        ----------
        filename : str
            The filename of the module with the view. It should expose
            a function called "viewable(context)" which takes an
            ExecutingContext and returns a HasTraits instance which can be
            edited with .edit_traits().
        live : bool, optional
            If True, then the interaction happens directly with the context
            itself. If False, a "copy-on-write" shadow context is put in front
            of the context.
        """
        globals = {}
        try:
            execfile(filename, globals)
        except Exception, e:
            msg = ("Cannot execute the file %s\n%s: %s" % (filename,
                e.__class__.__name__, e))
            dlg = MessageDialog(message=msg, severity='error')
            dlg.open()
            return

        if 'viewable' not in globals:
            msg = ("Cannot find the 'viewable' function in the module %s"
                % filename)
            dlg = MessageDialog(message=msg, severity='error')
            dlg.open()
            return

        viewable = globals['viewable']
        if live:
            context = self.project.active_experiment.context
        else:
            # Create a copy-on-write context.
            exp_context = self.project.active_experiment.context
            context = ExecutingContext(executable=exp_context.executable,
                subcontext=MultiContext({}, exp_context.subcontext))
            # XXX: put this in a view model with a button to shove the data back
            # into the main context.
        tui = viewable(context)
        tui.edit_traits(kind='live')