Example #1
0
def test_reporting_errors_f_strings(source, line):
    """Test that we properly report error on f-string.

    """
    with pytest.raises(SyntaxError) as e:
        parse(source)

    assert "backslash" in e.value.args[0]
    assert line == e.value.args[1][1]
Example #2
0
 def refresh_view(self, change):
     """ 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.
 
     """
     viewer = self.workbench.get_plugin('declaracad.viewer')
     doc = self.active_document
     try:
         ast = parse(doc.source, filename=doc.name)
         code = EnamlCompiler.compile(ast, doc.name)
         module = ModuleType('__main__')
         module.__file__ = doc.name
         namespace = module.__dict__
         with enaml.imports():
             exec_(code, namespace)
         assembly = namespace.get('Assembly', lambda: None)()
         viewer.parts = [assembly] if assembly else []
     except Exception as e:
         errors = doc.errors[:]
         log.warning(traceback.format_exc())
         tb = traceback.format_exc().strip().split("\n")
         print(tb[-3])
         m = re.search(r'File "(.+)", line (\d+),', tb[-3])
         if m:
             errors.append("{}:{}: {}".format(m.group(1), m.group(2),
                                              tb[-1]))
         doc.errors = errors
         viewer.parts = []
Example #3
0
    def parse_and_create(self, source, **kwargs):
        """ Parses and compiles the source. The source should have a
        component defined with the name 'MainView'. 

        Arguments
        ---------
        source : str
            The enaml source file

        kwargs : dict
            The default attribute values to pass to the component.

        Returns
        -------
            The component tree for the 'MainView' component.

        """
        # Start the app instance first.
        app = MockApplication.instance()
        if app is None:
            app = MockApplication()
        self.app = app

        enaml_ast = parse(source)
        enaml_module = types.ModuleType('__tests__')
        ns = enaml_module.__dict__
        code = EnamlCompiler.compile(enaml_ast, '__enaml_tests__')

        exec code in ns
        view = ns['MainView']
        self.view = view(**kwargs)
        self.view.prepare()

        self.client_view = app.builder().root
Example #4
0
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()]
Example #5
0
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]
Example #6
0
    def parse_and_create(self, source, **kwargs):
        """ Parses and compiles the source. The source should have a
        component defined with the name 'MainView'. 

        Arguments
        ---------
        source : str
            The enaml source file

        kwargs : dict
            The default attribute values to pass to the component.

        """
        enaml_ast = parse(source)
        enaml_module = types.ModuleType('__tests__')
        ns = enaml_module.__dict__
        code = EnamlCompiler.compile(enaml_ast, '__enaml_tests__')

        toolkit = self.toolkit

        with toolkit:
            exec code in ns
            view = ns['MainView']
            cmpnt = view(**kwargs)

        toolkit.app.initialize()
        self.app = toolkit.app.app_object()
        cmpnt.setup()
        return cmpnt
Example #7
0
def compile_source(source, item, filename='<test>'):
    """ 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>'.

    Returns
    -------
    result : object
        The named object from the resulting namespace.

    """
    ast = parse(source, filename)
    code = EnamlCompiler.compile(ast, filename)
    namespace = {}
    exec code in namespace
    return namespace[item]
Example #8
0
    def parse_and_create(self, source, **kwargs):
        """ Parses and compiles the source. The source should have a
        component defined with the name 'MainView'. 

        Arguments
        ---------
        source : str
            The enaml source file

        kwargs : dict
            The default attribute values to pass to the component.

        """
        enaml_ast = parse(source)
        enaml_module = types.ModuleType('__tests__')
        ns = enaml_module.__dict__
        code = EnamlCompiler.compile(enaml_ast, '__enaml_tests__')

        toolkit = self.toolkit

        with toolkit:
            exec code in ns
            view = ns['MainView']
            cmpnt = view(**kwargs)

        toolkit.app.initialize()
        self.app = toolkit.app.app_object()
        cmpnt.setup()
        return cmpnt
Example #9
0
def test_func_return_annotation_parsing():
    """Test that we parse properly functions with a return type annotation.

    """
    src = "def f() -> int:\n    pass"
    py_ast = ast.parse(src).body[0]
    enaml_ast = parse(src).body[0].ast.body[0]
    validate_ast(py_ast, enaml_ast, True)
Example #10
0
def test_raise_exception():
    """Test raising an exception.

    """
    src = """raise Exception()"""
    py_ast = ast.parse(src).body[0]
    enaml_ast = parse(src).body[0].ast.body[0]
    validate_ast(py_ast, enaml_ast, True)
Example #11
0
def test_invalid_walrus_operator(desc):
    """Test that we produce valid ast use of the := walrus operator.

    """
    src = dedent(TEST_BAD_SOURCE[desc]).strip()
    print(src)
    with pytest.raises(SyntaxError):
        enaml_ast = parse(src).body[0].ast
Example #12
0
def test_func_definition_parsing(signature):
    """Test parsing all possible function signatures.

    """
    src = FUNC_TEMPLATE.format(signature)
    py_ast = ast.parse(src).body[0]
    enaml_ast = parse(src).body[0].ast.body[0]
    validate_ast(py_ast, enaml_ast, True)
Example #13
0
def test_f_strings(desc):
    """Async function with await list comp statement
    """
    src = TEST_SOURCE[desc].strip()
    print(src)
    # Ensure it's valid
    py_ast = ast.parse(src)
    enaml_ast = parse(src).body[0].ast
    validate_ast(py_ast.body[0], enaml_ast.body[0], True)
Example #14
0
def test_async(desc):
    """Async function with await list comp statement. """
    src = FUNC_TEMPLATE.format(dedent(TEST_SOURCE[desc]))
    # Ensure it's valid
    py_ast = ast.parse(src)
    enaml_ast = parse(src).body[0].ast
    validate_ast(py_ast.body[0], enaml_ast.body[0], True)
    validate_ast(py_ast.body[1], enaml_ast.body[1], True)
    validate_ast(py_ast.body[2], enaml_ast.body[2], True)
Example #15
0
def test_f_strings(desc):
    """Test that we produce valid ast for f-strings.

    """
    src = TEST_SOURCE[desc].strip()
    print(src)
    # Ensure it's valid
    py_ast = ast.parse(src)
    enaml_ast = parse(src).body[0].ast
    validate_ast(py_ast.body[0], enaml_ast.body[0], True)
Example #16
0
def test_async(desc):
    """Async function with await list comp statement
    """
    src = FUNC_TEMPLATE.format(dedent(TEST_SOURCE[desc]))
    # Ensure it's valid 
    py_ast = ast.parse(src)
    enaml_ast = parse(src).body[0].ast
    validate_ast(py_ast.body[0], enaml_ast.body[0], True)
    validate_ast(py_ast.body[1], enaml_ast.body[1], True)
    validate_ast(py_ast.body[2], enaml_ast.body[2], True)
Example #17
0
def test_walrus_operator(desc):
    """Test that we produce valid ast use of the := walrus operator.

    """
    src = dedent(TEST_SOURCE[desc]).strip()
    print(src)
    # Ensure it's valid
    py_ast = ast.parse(src)
    enaml_ast = parse(src).body[0].ast
    validate_ast(py_ast.body[0], enaml_ast.body[0], True)
Example #18
0
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')
    parser.add_option(
        '-t',
        '--toolkit',
        default='default',
        help='The GUI toolkit to use [default: qt or ETS_TOOLKIT].')

    options, args = parser.parse_args()
    toolkit = prepare_toolkit(options.toolkit)

    if len(args) == 0:
        print 'No .enaml file specified'
        sys.exit()
    else:
        enaml_file = args[0]
        script_argv = args[1:]

    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
    module = types.ModuleType('__main__')
    module.__file__ = enaml_file
    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 in ns

    requested = options.component
    if requested in ns:
        component = ns[requested]
        descr = 'Enaml-run "%s" view' % requested
        show_simple_view(component(), toolkit, descr)
    elif 'main' in ns:
        ns['main']()
    else:
        msg = "Could not find component '%s'" % options.component
        print msg
Example #19
0
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)
Example #20
0
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)
Example #21
0
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')
    parser.add_option('-t', '--toolkit', default='default',
                      choices=['default', 'wx', 'qt'],
                      help='The toolkit backend to use')

    options, args = parser.parse_args()

    # Preapare the toolkit
    toolkit = prepare_toolkit(options.toolkit)

    if len(args) == 0:
        print 'No .enaml file specified'
        sys.exit()
    else:
        enaml_file = args[0]
        script_argv = args[1:]

    with open(enaml_file) 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
    module = types.ModuleType('__main__')
    module.__file__ = enaml_file
    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 in ns

    with toolkit:
        requested = options.component
        if requested in ns:
            component = ns[requested]
            window = component()
            window.show()
        elif 'main' in ns:
            ns['main']()
        else:
            msg = "Could not find component '%s'" % options.component
            print msg
Example #22
0
def test_raise_exception_with_cause():
    """Test that we parse properly functions with a return type annotation.

    """
    src = dedent("""
    try:
        a = ""/0
    except Exception as e:
        raise Exception() from e
    """)
    py_ast = ast.parse(src).body[0]
    enaml_ast = parse(src).body[0].ast.body[0]
    validate_ast(py_ast, enaml_ast, True)
Example #23
0
def test_reraise_exception():
    """Test raising an exception.

    """
    src = dedent("""
    try:
        a = ""/0
    except:
        raise
    """)
    py_ast = ast.parse(src).body[0]
    enaml_ast = parse(src).body[0].ast.body[0]
    validate_ast(py_ast, enaml_ast, True)
 def __init__(self, text, code=None, filename=None):
     self.text = text
     if code:
         self.code = code
     else:
         try:
             self.code = EnamlCompiler.compile(parse(text), filename)
         except SyntaxError as synerr:
             raise NotPython(
                 u"Couldn't parse '%s' as Enaml source: '%s' at line %d" % (
                     filename, synerr.msg, synerr.lineno
                 )
             )
Example #25
0
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:]

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

    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)
Example #26
0
def read_component(enaml_file, requested='Main'):
    """ Read a component from an .enaml file.

    Parameters
    ----------
    enaml_file : str
        The name of the .enaml file.
    requested : str, optional
        The name of the MainWindow holding the root Container.

    Returns
    -------
    factory : callable
        The factory for the MainWindow, usually a MainWindow
        EnamlDefinition.
    module : module
        The module object from the .enaml file itself. Keep this alive
        at least until after the component gets constructed.

    Raises
    ------
    NameError if the requested component does not exist in the module.
    """
    with open(enaml_file) 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
    module = types.ModuleType('__main__')
    module.__file__ = enaml_file
    ns = module.__dict__

    old_path = sys.path[:]
    sys.path.insert(0, os.path.dirname(enaml_file))
    with imports():
        exec code in ns
    sys.path[:] = old_path

    if requested in ns:
        factory = ns[requested]
    else:
        msg = "Could not find component {0!r}".format(requested)
        raise NameError(msg)

    return factory, module
    def __init__(self, text, statements, multiline):
        self.root_node = parse(neuter_encoding_declaration(text))
        self.statements = set(multiline.get(l, l) for l in statements)
        self.multiline = multiline

        self.arcs = set()

        # A map from arc pairs to a pair of sentence fragments:
        #     (startmsg, endmsg).
        # For an arc from line 17, they should be usable like:
        #    "Line 17 {endmsg}, because {startmsg}"
        self.missing_arc_fragments = collections.defaultdict(list)
        self.block_stack = []

        self.debug = bool(int(os.environ.get("COVERAGE_TRACK_ARCS", 0)))
Example #28
0
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")
    parser.add_option("-t", "--toolkit", default="default", help="The GUI toolkit to use [default: qt or ETS_TOOLKIT].")

    options, args = parser.parse_args()
    toolkit = prepare_toolkit(options.toolkit)

    if len(args) == 0:
        print "No .enaml file specified"
        sys.exit()
    else:
        enaml_file = args[0]
        script_argv = args[1:]

    with open(enaml_file) 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
    module = types.ModuleType("__main__")
    module.__file__ = enaml_file
    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 in ns

    requested = options.component
    if requested in ns:
        component = ns[requested]
        descr = 'Enaml-run "%s" view' % requested
        show_simple_view(component(), toolkit, descr)
    elif "main" in ns:
        ns["main"]()
    else:
        msg = "Could not find component '%s'" % options.component
        print msg
Example #29
0
def main():
    usage = 'usage: %prog [options] enaml_file'
    parser = optparse.OptionParser(usage=usage, description=__doc__)
    parser.add_option('-c', '--component', default='Main',
                      help='The component to view')
    parser.add_option('-t', '--toolkit', default='default',
                      choices=['default', 'wx', 'qt'],
                      help='The toolkit backend to use')
    
    options, args = parser.parse_args()

    if len(args) == 0:
        print 'No .enaml file specified'
        sys.exit()
    elif len(args) > 1:
        print 'Too many files specified'
        sys.exit()
    else:
        enaml_file = args[0]

    with open(enaml_file) 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
    module = types.ModuleType('__main__')
    module.__file__ = enaml_file
    ns = module.__dict__

    with imports():
        exec code in ns

    with toolkits[options.toolkit]():
        requested = options.component
        if requested in ns:
            component = ns[requested]
            window = component()
            window.show()
        elif 'main' in ns:
            ns['main']()
        else:
            msg = "Could not find component '%s'" % options.component
            print msg
Example #30
0
    def parse_and_create(self, source, **kwargs):
        """ Parses and compiles the source. The source should have a
        component defined with the name 'MainView'.

        Arguments
        ---------
        source : str
            The enaml source file

        kwargs : dict
            The default attribute values to pass to the component.

        Returns
        -------
            The component tree for the 'MainView' component.

        """
        enaml_ast = parse(source)
        enaml_module = types.ModuleType('__tests__')
        ns = enaml_module.__dict__
        code = EnamlCompiler.compile(enaml_ast, '__enaml_tests__')

        exec code in ns
        View = ns['MainView']

        # Start the app instance first.
        session_name =  get_unique_session_identifier()
        view_factory = simple_session(session_name, 'test', View)

        self.app = TestingQtApplication.instance()

        if self.app is None:
            self.app = TestingQtApplication([])

        self.app.add_factories([view_factory])

        session_id = self.app.start_session(session_name)

        self.app.start()

        session = self.app._sessions[session_id]

        # retrieve the enaml server side root widget
        self.view = session.windows[0]

        # retrieve the enaml client side root widget
        self.client_view = self.app._qt_sessions[session_id]._windows[0]
Example #31
0
def test_decl_async_func():
    py_src = dedent("""
    from enaml.core.declarative import d_func
    from enaml.widgets.api import Window, Label
    
    async def fetch(query):
        return query
    
    class MainWindow(Window):
        @d_func
        async def search(self, query):
            result = await fetch(query)
            return result
    """)
    
    enaml_src = dedent("""
    from enaml.core.declarative import d_func
    from enaml.widgets.api import Window, Label
    
    async def fetch(query):
        return query
        
    enamldef MainWindow(Window):
        async func search(query):
            result = await fetch(query)
            return result

    enamldef CustomWindow(MainWindow):
        async search => (query):
            result = await fetch(query)
            return result
    
    """)
    py_ast = ast.parse(py_src)
    enaml_ast = parse(enaml_src)
    validate_ast(py_ast.body[3].body[0], 
                 enaml_ast.body[1].body[0].funcdef, True)
    
    # Check override syntax
    validate_ast(py_ast.body[3].body[0], 
                 enaml_ast.body[2].body[0].funcdef, True)
    
    # Make sure it compiles
    CustomWindow = compile_source(enaml_src, 'CustomWindow')
Example #32
0
def test_decl_async_func():
    py_src = dedent("""
    from enaml.core.declarative import d_func
    from enaml.widgets.api import Window, Label

    async def fetch(query):
        return query

    class MainWindow(Window):
        @d_func
        async def search(self, query):
            result = await fetch(query)
            return result
    """)

    enaml_src = dedent("""
    from enaml.core.declarative import d_func
    from enaml.widgets.api import Window, Label

    async def fetch(query):
        return query

    enamldef MainWindow(Window):
        async func search(query):
            result = await fetch(query)
            return result

    enamldef CustomWindow(MainWindow):
        async search => (query):
            result = await fetch(query)
            return result

    """)
    py_ast = ast.parse(py_src)
    enaml_ast = parse(enaml_src)
    validate_ast(py_ast.body[3].body[0], enaml_ast.body[1].body[0].funcdef,
                 True)

    # Check override syntax
    validate_ast(py_ast.body[3].body[0], enaml_ast.body[2].body[0].funcdef,
                 True)

    # Make sure it compiles
    CustomWindow = compile_source(enaml_src, 'CustomWindow')
    def parse_and_create(self, source, **kwargs):
        """ Parses and compiles the source. The source should have a
        component defined with the name 'MainView'.

        Arguments
        ---------
        source : str
            The enaml source file

        kwargs : dict
            The default attribute values to pass to the component.

        Returns
        -------
            A tuple of the server and client component trees for the
            'MainView' component.

        """

        # This replicates what enaml.runner.main does
        enaml_ast = parse(source, filename='__enaml_tests__')
        code = EnamlCompiler.compile(enaml_ast, '__enaml_tests__')

        enaml_module = types.ModuleType('__tests__')
        ns = enaml_module.__dict__

        with traits_enaml.imports():
            six.exec_(code, ns, ns)
        View = ns['MainView']

        enaml_view = View(**kwargs)
        enaml_view.initialize()
        if not enaml_view.proxy_is_active:
            enaml_view.activate_proxy()

        toolkit_view = enaml_view.proxy

        # We need to keep a reference to the enaml_module to ensure it does not
        # get collected. If no reference is kept, enaml operators will not be
        # able to resolve objects properly (eg. validator = IntValidator(...)
        # will fail)
        self.enaml_module = enaml_module

        return enaml_view, toolkit_view
Example #34
0
    def parse_and_create(self, source, **kwargs):
        """ Parses and compiles the source. The source should have a
        component defined with the name 'MainView'.

        Arguments
        ---------
        source : str
            The enaml source file

        kwargs : dict
            The default attribute values to pass to the component.

        Returns
        -------
            A tuple of the server and client component trees for the
            'MainView' component.

        """

        # This replicates what enaml.runner.main does
        enaml_ast = parse(source, filename='__enaml_tests__')
        code = EnamlCompiler.compile(enaml_ast, '__enaml_tests__')

        enaml_module = types.ModuleType('__tests__')
        ns = enaml_module.__dict__

        with traits_enaml.imports():
            six.exec_(code, ns, ns)
        View = ns['MainView']

        enaml_view = View(**kwargs)
        enaml_view.initialize()
        if not enaml_view.proxy_is_active:
            enaml_view.activate_proxy()

        toolkit_view = enaml_view.proxy

        # We need to keep a reference to the enaml_module to ensure it does not
        # get collected. If no reference is kept, enaml operators will not be
        # able to resolve objects properly (eg. validator = IntValidator(...)
        # will fail)
        self.enaml_module = enaml_module

        return enaml_view, toolkit_view
Example #35
0
    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 = ''
Example #36
0
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, 'r') 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']
Example #37
0
def generate_cache(path):
    #: Read
    with open(path, 'rU') as f:
        enaml_code = f.read()

    #: Compile
    ast = parse(enaml_code, filename=path)
    code = EnamlCompiler.compile(ast, path)

    #: Generate cache
    with open('tmp.enamlc', 'wb') as f:
        f.write(MAGIC)
        f.write(struct.pack('i', int(os.path.getmtime(path))))
        marshal.dump(code, f)
    with open('tmp.enamlc', 'rb') as f:
        data = f.read()
    #: Cleanup
    if os.path.exists('tmp.enamlc'):
        os.remove('tmp.enamlc')

    return data
Example #38
0
def generate_cache(path):
    #: Read
    with open(path, 'rU') as f:
        enaml_code = f.read()

    #: Compile
    ast = parse(enaml_code, filename=path)
    code = EnamlCompiler.compile(ast, path)

    #: Generate cache
    with open('tmp.enamlc', 'wb') as f:
        f.write(MAGIC)
        f.write(struct.pack('i', int(os.path.getmtime(path))))
        marshal.dump(code, f)
    with open('tmp.enamlc', 'rb') as f:
        data = f.read()
    #: Cleanup
    if os.path.exists('tmp.enamlc'):
        os.remove('tmp.enamlc')

    return data
Example #39
0
def load_model(filename, source=None):
    """ Load a DeclaraCAD model from an enaml file, source, or a shape
    supported by the LoadShape node.

    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 source or filename.endswith('.enaml'):
        # Parse and compile the code
        with open(filename, 'r') as f:
            source = f.read()
        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()]
    elif os.path.exists(filename):
        # Try to load from filename
        with enaml.imports():
            from .loader import LoadedPart
        return [LoadedPart(filename=filename)]
    else:
        return []
Example #40
0
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, 'r') 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()]