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)
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
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', )
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
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')