예제 #1
0
파일: module.py 프로젝트: ishikawa/modipyd
def load_bytecode_processors():
    """
    Loading BytecodeProcessor from modipyd.BYTECODE_PROCESSORS
    settings. Return ChainedBytecodeProcessor instance holds
    all loaded processors.
    """
    if (BYTECODE_PROCESSORS and 
            (len(BYTECODE_PROCESSORS_CACHE) != len(BYTECODE_PROCESSORS))):
        del BYTECODE_PROCESSORS_CACHE[:]
        for i, name in enumerate(BYTECODE_PROCESSORS[:]):
            LOGGER.info("Loading BytecodeProcesser '%s'" % name)
            try:
                klass = utils.import_component(name)
            except (ImportError, AttributeError):
                LOGGER.warn(
                    "Loading BytecodeProcesser '%s' failed. "
                    "This setting is removed" % name,
                    exc_info=True)
                del BYTECODE_PROCESSORS[i]
            else:
                BYTECODE_PROCESSORS_CACHE.append(klass)

    processors = []
    for klass in BYTECODE_PROCESSORS_CACHE:
        processors.append(klass())
    return bc.ChainedBytecodeProcessor(processors)
예제 #2
0
    def install_plugin(self, plugin):
        """
        Install a plugin specified by *plugin*. The *plugin* argument
        must be callable object (e.g. function, class) or a qualified
        name of the plugin itself.

        Read the ``modipyd.application.plugins`` module documentation
        for the plugin architecture details.
        """

        if isinstance(plugin, basestring):
            try:
                plugin = import_component(plugin)
            except (ImportError, AttributeError):
                LOGGER.error("Loading plugin '%s' failed" % plugin)
                raise

        if not callable(plugin):
            raise TypeError("The plugin must be callable object")

        if hasattr(plugin, 'func_code'):
            LOGGER.info("Loading plugin: %s" % plugin.func_code.co_name)
        else:
            LOGGER.info("Loading plugin: %s" % plugin)

        self.plugins.append(plugin)
예제 #3
0
def main(paths, test_runner_class="unittest.TextTestRunner"):
    suite = collect_unittest(paths)
    if not suite.countTestCases():
        return

    testRunner = import_component(test_runner_class)
    runner = testRunner()
    runner.run(suite)
예제 #4
0
def has_subclass(module_descriptor, baseclass):
    """
    Return ``True`` if the module has a class
    derived from *baseclass*
    """
    # We can't use ``unittest.TestLoader`` to loading tests,
    # bacause ``TestLoader`` imports (execute) module code.
    # If imported/executed module have a statement such as
    # ``sys.exit()``, ...program exit!

    if not isinstance(baseclass, (type, types.ClassType)):
        raise TypeError(
            "The baseclass argument must be instance of type or class, "
            "but was instance of %s" % type(baseclass))

    modcode = module_descriptor.module_code
    assert modcode

    # How to check unittest.TestCase
    # ============================================
    # 1. For all class definition in module code
    # 2. Check class is derived from base class(s)
    # 3. Check base class(s) is imported from another module
    # 4. Load base class(s) from that module
    #    Notes: Assume the module contains base class does not have
    #           a dangerous code such as ``sys.exit``.
    # 5. Check loaded class is *baseclass* or its subclass

    # Construct imported symbols.
    # This is used in phase 3.
    symbols = dict([(imp[0], imp) for imp in modcode.context['imports']])

    # 1. For all class definition in module code
    for klass in modcode.context['classdefs']:

        # 2. Check class is derived from base class(s)
        bases = klass[1]
        if not bases:
            continue

        # 3. Check base class(s) is imported from another module
        for base in bases:
            # Search imported symbol that is class name or module name
            if '.' in base:
                names = list(split_module_name(base))
            else:
                names = [base]

            import_ = symbols.get(names[0])
            if import_ is None:
                # Not an imported base class
                continue

            # Convert a name to a qualified module name
            #
            #   1. Resolve import alias if exists
            #   2. Qualify name as full module name
            #   3. Resolve relative module name
            #
            level = import_[2]
            names[0] = import_[1]

            fqn = '.'.join(names)
            fqn = resolve_relative_modulename(fqn, modcode.package_name, level)

            assert '.' in fqn, "fqn must be a qualified module fqn"
            LOGGER.debug("'%s' is derived from '%s'" % (module_descriptor.name, fqn))

            try:
                try:
                    klass = utils.import_component(fqn)
                except ImportError:
                    if level == -1 and modcode.package_name:
                        # The qualified name may be relative to current package.
                        fqn = '.'.join((modcode.package_name, fqn))
                        klass = utils.import_component(fqn)
                    else:
                        raise
            except (ImportError, AttributeError):
                LOGGER.warn("Exception occurred "
                    "while importing component '%s'" % fqn,
                    exc_info=True)
            else:
                # 5. Check loaded class is specified class or its subclass
                if isinstance(klass, (type, types.ClassType)) and \
                        issubclass(klass, baseclass):
                    return True

    return False
예제 #5
0
def has_subclass(module_descriptor, baseclass):
    """
    Return ``True`` if the module has a class
    derived from *baseclass*
    """
    # We can't use ``unittest.TestLoader`` to loading tests,
    # bacause ``TestLoader`` imports (execute) module code.
    # If imported/executed module have a statement such as
    # ``sys.exit()``, ...program exit!

    if not isinstance(baseclass, (type, types.ClassType)):
        raise TypeError(
            "The baseclass argument must be instance of type or class, "
            "but was instance of %s" % type(baseclass))

    modcode = module_descriptor.module_code
    assert modcode

    # How to check unittest.TestCase
    # ============================================
    # 1. For all class definition in module code
    # 2. Check class is derived from base class(s)
    # 3. Check base class(s) is imported from another module
    # 4. Load base class(s) from that module
    #    Notes: Assume the module contains base class does not have
    #           a dangerous code such as ``sys.exit``.
    # 5. Check loaded class is *baseclass* or its subclass

    # Construct imported symbols.
    # This is used in phase 3.
    symbols = dict([(imp[0], imp) for imp in modcode.context['imports']])

    # 1. For all class definition in module code
    for klass in modcode.context['classdefs']:

        # 2. Check class is derived from base class(s)
        bases = klass[1]
        if not bases:
            continue

        # 3. Check base class(s) is imported from another module
        for base in bases:
            # Search imported symbol that is class name or module name
            symbol = base
            if '.' in symbol:
                symbol = split_module_name(symbol)[0]

            import_ = symbols.get(symbol)
            if import_ is None:
                continue

            # Convert name to a qualified module name
            name, level = base, import_[2]
            parent = split_module_name(import_[1])[0]
            if parent:
                name = '.'.join((parent, name))
            name = resolve_relative_modulename(
                name, modcode.package_name, level)

            assert '.' in name, "name must be a qualified module name"
            LOGGER.debug("'%s' is derived from '%s'" % (base, name))

            try:
                klass = utils.import_component(name)
            except ImportError:
                klass = None
                exc = sys.exc_info()[:]

                if level == -1 and modcode.package_name:
                    # Try to resolve a name as relative module name.
                    try:
                        name2 = '.'.join((modcode.package_name, name))
                        klass = utils.import_component(name2)
                    except:
                        LOGGER.warn(
                            "Exception occurred while importing module '%s'" % name2,
                            exc_info=True)

                if not klass:
                    LOGGER.warn(
                        "Exception occurred while importing module '%s'" % name,
                        exc_info=exc)

                # Make sure to delete the traceback to avoid creating cycles.
                del exc

            except AttributeError:
                LOGGER.warn(
                    "Exception occurred while importing module '%s'" % name,
                    exc_info=True)
            else:
                # 5. Check loaded class is specified class or its subclass
                if isinstance(klass, (type, types.ClassType)) and \
                        issubclass(klass, baseclass):
                    return True

    return False