def compile_source(source, item, filename='<test>', namespace=None): """ Compile Enaml source code and return the target item. Parameters ---------- source : str The Enaml source code string to compile. item : str The name of the item in the resulting namespace to return. filename : str, optional The filename to use when compiling the code. The default is '<test>'. namespace : dict Namespace in which to execute the code Returns ------- result : object The named object from the resulting namespace. """ ast = parse(source, filename) code = EnamlCompiler.compile(ast, filename) namespace = namespace or {} exec_(code, namespace) return namespace[item]
def load_model(filename): """ Load a DeclaraCAD model from an enaml file. Ideally this should be used in a separate process but it's not required. Parameters ---------- filename: String Path to the enaml file to load Returns ------- result: List[occ.shape.Shape] A list of shapes that can be passed to the python-occ viewer. """ # Parse the enaml file with open(filename, 'rU') as f: ast = parse(f.read()) code = EnamlCompiler.compile(ast, filename) module = ModuleType(filename.rsplit('.', 1)[0]) module.__file__ = filename namespace = module.__dict__ with enaml.imports(): exec_(code, namespace) Assembly = namespace['Assembly'] return [Assembly()]
def refresh_model(self): """ Refresh the compiled model object. This method will (re)compile the model for the given model text and update the 'compiled_model' attribute. If a compiled view is available and has a member named 'model', the model will be applied to the view. """ text = self.model_text filename = self.model_filename _fake_linecache(text, filename) try: if not text: self.compiled_model = None self._model_module = None else: code = compile(text, filename, 'exec') module = ModuleType(filename.rsplit('.', 1)[0]) module.__file__ = filename namespace = module.__dict__ exec_(code, namespace) model = namespace.get(self.model_item, lambda: None)() self.compiled_model = model self._model_module = module self.relink_view() except Exception: self.traceback = traceback.format_exc() else: self.traceback = ''
def refresh_model(self): """ Refresh the compiled model object. This method will (re)compile the model for the given model text and update the 'compiled_model' attribute. If a compiled view is available and has a member named 'model', the model will be applied to the view. """ text = self.model_text filename = self.model_filename _fake_linecache(text, filename) try: if not text: self.compiled_model = None self._model_module = None else: code = compile(text, filename, 'exec') module = ModuleType(filename.rsplit('.', 1)[0]) module.__file__ = filename namespace = module.__dict__ exec_(code, namespace) model = namespace.get(self.model_item, lambda: None)() self.compiled_model = model self._model_module = module self.relink_view() except Exception: self.traceback = traceback.format_exc() else: self.traceback = ''
def main(): usage = 'usage: %prog [options] enaml_file [script arguments]' parser = optparse.OptionParser(usage=usage, description=__doc__) parser.allow_interspersed_args = False parser.add_option('-c', '--component', default='Main', help='The component to view') options, args = parser.parse_args() if len(args) == 0: print('No .enaml file specified') sys.exit() else: enaml_file = args[0] script_argv = args[1:] enaml_code = read_source(enaml_file) # Parse and compile the Enaml source into a code object ast = parse(enaml_code, filename=enaml_file) code = EnamlCompiler.compile(ast, enaml_file) # Create a proper module in which to execute the compiled code so # that exceptions get reported with better meaning module = types.ModuleType('__main__') module.__file__ = os.path.abspath(enaml_file) sys.modules['__main__'] = module ns = module.__dict__ # Put the directory of the Enaml file first in the path so relative # imports can work. sys.path.insert(0, os.path.abspath(os.path.dirname(enaml_file))) # Bung in the command line arguments. sys.argv = [enaml_file] + script_argv with imports(): exec_(code, ns) # Make sure ^C keeps working signal.signal(signal.SIGINT, signal.SIG_DFL) requested = options.component if requested in ns: from enaml.qt.qt_application import QtApplication app = QtApplication() window = ns[requested]() window.show() window.send_to_front() app.start() elif 'main' in ns: ns['main']() else: msg = "Could not find component '%s'" % options.component print(msg)
def main(): usage = 'usage: %prog [options] enaml_file [script arguments]' parser = optparse.OptionParser(usage=usage, description=__doc__) parser.allow_interspersed_args = False parser.add_option( '-c', '--component', default='Main', help='The component to view' ) options, args = parser.parse_args() if len(args) == 0: print('No .enaml file specified') sys.exit() else: enaml_file = args[0] script_argv = args[1:] enaml_code = read_source(enaml_file) # Parse and compile the Enaml source into a code object ast = parse(enaml_code, filename=enaml_file) code = EnamlCompiler.compile(ast, enaml_file) # Create a proper module in which to execute the compiled code so # that exceptions get reported with better meaning module = types.ModuleType('__main__') module.__file__ = os.path.abspath(enaml_file) sys.modules['__main__'] = module ns = module.__dict__ # Put the directory of the Enaml file first in the path so relative # imports can work. sys.path.insert(0, os.path.abspath(os.path.dirname(enaml_file))) # Bung in the command line arguments. sys.argv = [enaml_file] + script_argv with imports(): exec_(code, ns) # Make sure ^C keeps working signal.signal(signal.SIGINT, signal.SIG_DFL) requested = options.component if requested in ns: from enaml.qt.qt_application import QtApplication app = QtApplication() window = ns[requested]() window.show() window.send_to_front() app.start() elif 'main' in ns: ns['main']() else: msg = "Could not find component '%s'" % options.component print(msg)
def test_unicode_identifier(): source = dedent("""\ from enaml.widgets.api import Window enamldef MyWindow(Window): win: attr 𠁒 = 'test' # Check we do not mistake this for an invalid identifier attr a = 1.e6 """) myWindow = compile_source(source, 'MyWindow')() exec_("𠁒 = 'test'") assert locals()['𠁒'] == getattr(myWindow, """𠁒""")
def test_unicode_identifier(): source = dedent("""\ from enaml.widgets.api import Window enamldef MyWindow(Window): win: attr 𠁒 = 'test' # Check we do not mistake this for an invalid identifier attr a = 1.e6 """) myWindow = compile_source(source, 'MyWindow')() exec_("𠁒 = 'test'") assert locals()['𠁒'] == getattr(myWindow, """𠁒""")
def refresh_view(self): """ Refresh the compiled view object. This method will (re)compile the view for the given view text and update the 'compiled_view' attribute. If a compiled model is available and the view has a member named 'model', the model will be applied to the view. """ text = self.view_text filename = self.view_filename _fake_linecache(text, filename) try: if not text: self.compiled_view = None self._view_module = None else: ast = parse(text, filename=filename) code = EnamlCompiler.compile(ast, filename) module = ModuleType('__main__') module.__file__ = filename namespace = module.__dict__ with enaml.imports(): exec_(code, namespace) view = namespace.get(self.view_item, lambda: None)() if isinstance(view, Object) and 'model' in view.members(): view.model = self.compiled_model # trap any initialization errors and roll back the view old = self.compiled_view try: self.compiled_view = view except Exception: self.compiled_view = old if isinstance(old, Widget): old.show() raise self._view_module = module if old is not None and not old.is_destroyed: old.destroy() except Exception: self.traceback = traceback.format_exc() else: self.traceback = ''
def refresh_view(self): """ Refresh the compiled view object. This method will (re)compile the view for the given view text and update the 'compiled_view' attribute. If a compiled model is available and the view has a member named 'model', the model will be applied to the view. """ text = self.view_text filename = self.view_filename _fake_linecache(text, filename) try: if not text: self.compiled_view = None self._view_module = None else: ast = parse(text, filename=filename) code = EnamlCompiler.compile(ast, filename) module = ModuleType('__main__') module.__file__ = filename namespace = module.__dict__ with enaml.imports(): exec_(code, namespace) view = namespace.get(self.view_item, lambda: None)() if isinstance(view, Object) and 'model' in view.members(): view.model = self.compiled_model # trap any initialization errors and roll back the view old = self.compiled_view try: self.compiled_view = view except Exception: self.compiled_view = old if isinstance(old, Widget): old.show() raise self._view_module = module if old is not None and not old.is_destroyed: old.destroy() except Exception: self.traceback = traceback.format_exc() else: self.traceback = ''
def test_examples(enaml_qtbot, enaml_sleep, path, handler): """ Test the enaml examples. """ dir_path = os.path.abspath(os.path.split(os.path.dirname(__file__))[0]) enaml_file = os.path.join(dir_path, 'examples', os.path.normpath(path)) with open(enaml_file, 'rU') as f: enaml_code = f.read() # Parse and compile the Enaml source into a code object ast = parse(enaml_code, filename=enaml_file) code = EnamlCompiler.compile(ast, enaml_file) # Create a proper module in which to execute the compiled code so # that exceptions get reported with better meaning try: module = types.ModuleType('enaml_test') module.__file__ = os.path.abspath(enaml_file) sys.modules['enaml_test'] = module ns = module.__dict__ # Put the directory of the Enaml file first in the path so relative # imports can work. sys.path.insert(0, os.path.abspath(os.path.dirname(enaml_file))) with imports(): exec_(code, ns) window = ns['Main']() window.show() window.send_to_front() wait_for_window_displayed(enaml_qtbot, window) enaml_qtbot.wait(enaml_sleep*1000) if handler is not None: handler(enaml_qtbot, window) finally: # Make sure we clean up the sys modification before leaving sys.path.pop(0) del sys.modules['enaml_test']
def load_model(filename, source=None): """ Load a DeclaraCAD model from an enaml file. Ideally this should be used in a separate process but it's not required. Parameters ---------- filename: String Path to the enaml file to load source: String Source code to parse (optional) Returns ------- result: List[occ.shape.Shape] A list of shapes that can be passed to the python-occ viewer. """ # Parse the enaml file or load from source code if not source and os.path.exists(filename): with open(filename, 'rU') as f: source = f.read() if not source: raise EmptyFileError( f"No source code given or '{filename}' does not exist") # Parse and compile the code ast = parse(source) code = EnamlCompiler.compile(ast, filename) module = ModuleType(filename.rsplit('.', 1)[0]) module.__file__ = filename namespace = module.__dict__ with enaml.imports(): exec_(code, namespace) Assembly = namespace['Assembly'] return [Assembly()]