def _classes_from_module(self, module):

        # Test whether this module imports from a Pure python file.
        # If it isn't represented as a file, we'll need to
        # use the import method of searching for classes.
        path = get_module_path(module)

        # fixme: What about zip files.

        if (os.path.exists(path) and os.path.splitext(path)[1] == '.py'):
            # If it is a file, then parse the ast.
            import_method = False
        elif (os.path.exists(path) and os.path.isdir(path)):
            # If it is a package directory, parse the ast.
            import_method = False
        else:
            # Must be extension module or built-in, or something else...
            # Use import to handle it.
            import_method = True

        mod_and_name = find_classes(module, import_method)
        clss = [
            self.class_factory(module=module, name=name)
            for module, name in mod_and_name
        ]
        return clss
Example #2
0
    def _classes_from_module(self, module):

        # Test whether this module imports from a Pure python file.
        # If it isn't represented as a file, we'll need to
        # use the import method of searching for classes.
        path = get_module_path(module)

        # fixme: What about zip files.

        if (os.path.exists(path) and
            os.path.splitext(path)[1] == '.py'):
            # If it is a file, then parse the ast.
            import_method = False
        elif (os.path.exists(path) and
            os.path.isdir(path)):
            # If it is a package directory, parse the ast.
            import_method = False
        else:
            # Must be extension module or built-in, or something else...
            # Use import to handle it.
            import_method = True

        mod_and_name = find_classes(module, import_method)
        clss = [self.class_factory(module=module,name=name)
                    for module, name in mod_and_name]
        return clss
Example #3
0
def find_classes_ast(package):
    """ Find classes by traversing an abstract syntax tree generated by the
        compiler module.
        fixme: expand docstring, possibly provide response about non-existant
        modules/packages
    """
    classes = []
    # It is a package (ie a directory)
    if is_package(package):
        package_path = get_module_path(package)
        file_paths = find_package_sub_modules(package)
        for file_path in file_paths:
            try:
                file = open(file_path)
                # Adding a new line to the source, so that compile wouldn't
                # throw a SyntaxError on EOF comment
                source = file.read().replace('\r\n', '\n') + '\n'
                ast = compile(source, file_path, 'exec', _ast.PyCF_ONLY_AST)
                file.close()
                python_path = python_path_from_file_path(
                    package, file_path, package_path=package_path)
                classes.extend(visit_ast_node(ast, file_path, python_path))
            except SyntaxError:
                msg = 'SyntaxError in parsing file %s' % file_path
                logger.error(msg)

    # It is a module (ie a .py file)
    elif is_module(package):
        file_path = get_module_path(package)
        file = open(file_path)

        # Adding a new line to the source, so that compile wouldn't
        # throw a SyntaxError on EOF comment
        source = file.read().replace('\r\n', '\n') + '\n'

        ast = compile(source, file_path, 'exec', _ast.PyCF_ONLY_AST)
        file.close()
        classes.extend(visit_ast_node(ast, file_path, package))

    return classes
def find_classes_ast(package):
    """ Find classes by traversing an abstract syntax tree generated by the
        compiler module.
        fixme: expand docstring, possibly provide response about non-existant
        modules/packages
    """
    classes = []
    # It is a package (ie a directory)
    if is_package(package):
        package_path = get_module_path(package)
        file_paths = find_package_sub_modules(package)
        for file_path in file_paths:
            try:
                file = open(file_path)
                # Adding a new line to the source, so that compile wouldn't
                # throw a SyntaxError on EOF comment
                source = file.read().replace('\r\n','\n')+'\n'
                ast = compile(source, file_path,'exec', _ast.PyCF_ONLY_AST)
                file.close()
                python_path = python_path_from_file_path(package, file_path, package_path=package_path)
                classes.extend(visit_ast_node(ast, file_path, python_path))
            except SyntaxError:
                msg = 'SyntaxError in parsing file %s'% file_path
                logger.error(msg)

    # It is a module (ie a .py file)
    elif is_module(package):
        file_path = get_module_path(package)
        file = open(file_path)

        # Adding a new line to the source, so that compile wouldn't
        # throw a SyntaxError on EOF comment
        source = file.read().replace('\r\n','\n')+'\n'

        ast = compile(source, file_path, 'exec', _ast.PyCF_ONLY_AST)
        file.close()
        classes.extend(visit_ast_node(ast, file_path, package))

    return classes
    def test_parse_error(self):
        # Because having a function checked in with a parse error creates problems
        # with the egg builder, we take an existing file and modify it.
        old_module = 'blockcanvas.function_tools.tests.sample_package.error_package'
        old_filename = get_module_path(old_module)
        new_filename = old_filename[:-3] + '2.py'
        new_module = old_module+'2'
        lines = open(old_filename).readlines()
        # Strip off the colon on the end of the second line to create a syntax error
        lines[1] = lines[1][:-1]
        open(new_filename, 'w').writelines(lines)

        func = PythonFunctionInfo(module=new_module, name='badfunction')
        self.assertEqual(func.load_error, "failed to parse module '%s'" % new_module)
        os.unlink(new_filename)
Example #6
0
    def test_parse_error(self):
        # Because having a function checked in with a parse error creates problems
        # with the egg builder, we take an existing file and modify it.
        old_module = 'blockcanvas.function_tools.tests.sample_package.error_package'
        old_filename = get_module_path(old_module)
        new_filename = old_filename[:-3] + '2.py'
        new_module = old_module + '2'
        lines = open(old_filename).readlines()
        # Strip off the colon on the end of the second line to create a syntax error
        lines[1] = lines[1][:-1]
        open(new_filename, 'w').writelines(lines)

        func = PythonFunctionInfo(module=new_module, name='badfunction')
        self.assertEqual(func.load_error,
                         "failed to parse module '%s'" % new_module)
        os.unlink(new_filename)
def find_classes_import(package):
    """ Find classes using an import statement. Sloppier and consumes more
        memory than find_classes_ast, but also get submodules of the modules,
        which the ast method cannot do. For example, giving it 'os', it would
        also find functions from os.path. It also follows import statements in
        the files, which may or may not be desirable.
    """
    classes = []
    if is_package(package):
        package_path = get_module_path(package)
        file_paths = find_package_sub_modules(package)

        for file_path in file_paths:
            python_path = python_path_from_file_path(package, file_path, package_path=package_path)
            results = find_classes_import_recurse(python_path)
            classes.extend(results)
    else:
        classes = find_classes_import_recurse(package)

    return classes
Example #8
0
def find_classes_import(package):
    """ Find classes using an import statement. Sloppier and consumes more
        memory than find_classes_ast, but also get submodules of the modules,
        which the ast method cannot do. For example, giving it 'os', it would
        also find functions from os.path. It also follows import statements in
        the files, which may or may not be desirable.
    """
    classes = []
    if is_package(package):
        package_path = get_module_path(package)
        file_paths = find_package_sub_modules(package)

        for file_path in file_paths:
            python_path = python_path_from_file_path(package,
                                                     file_path,
                                                     package_path=package_path)
            results = find_classes_import_recurse(python_path)
            classes.extend(results)
    else:
        classes = find_classes_import_recurse(package)

    return classes