示例#1
0
def get_data(package, resource):
    """Get a resource from a package.

    This is a wrapper round the PEP 302 loader get_data API. The package
    argument should be the name of a package, in standard module format
    (foo.bar). The resource argument should be in the form of a relative
    filename, using '/' as the path separator. The parent directory name '..'
    is not allowed, and nor is a rooted name (starting with a '/').

    The function returns a binary string, which is the contents of the
    specified resource.

    For packages located in the filesystem, which have already been imported,
    this is the rough equivalent of

        d = os.path.dirname(sys.modules[package].__file__)
        data = open(os.path.join(d, resource), 'rb').read()

    If the package cannot be located or loaded, or it uses a PEP 302 loader
    which does not support get_data(), then None is returned.
    """

    spec = importlib.find_spec(package)
    if spec is None:
        return None
    loader = spec.loader
    if loader is None or not hasattr(loader, 'get_data'):
        return None
    # XXX needs test
    mod = (sys.modules.get(package) or
           importlib._bootstrap._SpecMethods(spec).load())
    if mod is None or not hasattr(mod, '__file__'):
        return None

    # Modify the resource name to be compatible with the loader.get_data
    # signature - an os.path format "filename" starting with the dirname of
    # the package's __file__
    parts = resource.split('/')
    parts.insert(0, os.path.dirname(mod.__file__))
    resource_name = os.path.join(*parts)
    return loader.get_data(resource_name)
示例#2
0
def get_data(package, resource):
    """Get a resource from a package.

    This is a wrapper round the PEP 302 loader get_data API. The package
    argument should be the name of a package, in standard module format
    (foo.bar). The resource argument should be in the form of a relative
    filename, using '/' as the path separator. The parent directory name '..'
    is not allowed, and nor is a rooted name (starting with a '/').

    The function returns a binary string, which is the contents of the
    specified resource.

    For packages located in the filesystem, which have already been imported,
    this is the rough equivalent of

        d = os.path.dirname(sys.modules[package].__file__)
        data = open(os.path.join(d, resource), 'rb').read()

    If the package cannot be located or loaded, or it uses a PEP 302 loader
    which does not support get_data(), then None is returned.
    """

    spec = importlib.find_spec(package)
    if spec is None:
        return None
    loader = spec.loader
    if loader is None or not hasattr(loader, 'get_data'):
        return None
    # XXX needs test
    mod = (sys.modules.get(package)
           or importlib._bootstrap._SpecMethods(spec).load())
    if mod is None or not hasattr(mod, '__file__'):
        return None

    # Modify the resource name to be compatible with the loader.get_data
    # signature - an os.path format "filename" starting with the dirname of
    # the package's __file__
    parts = resource.split('/')
    parts.insert(0, os.path.dirname(mod.__file__))
    resource_name = os.path.join(*parts)
    return loader.get_data(resource_name)
示例#3
0
def _readmodule(module, path, inpackage=None):
    '''Do the hard work for readmodule[_ex].

    If INPACKAGE is given, it must be the dotted name of the package in
    which we are searching for a submodule, and then PATH must be the
    package search path; otherwise, we are searching for a top-level
    module, and PATH is combined with sys.path.
    '''
    # Compute the full module name (prepending inpackage if set)
    if inpackage is not None:
        fullmodule = "%s.%s" % (inpackage, module)
    else:
        fullmodule = module

    # Check in the cache
    if fullmodule in _modules:
        return _modules[fullmodule]

    # Initialize the dict for this module's contents
    dict = {}

    # Check if it is a built-in module; we don't do much for these
    if module in sys.builtin_module_names and inpackage is None:
        _modules[module] = dict
        return dict

    # Check for a dotted module name
    i = module.rfind('.')
    if i >= 0:
        package = module[:i]
        submodule = module[i+1:]
        parent = _readmodule(package, path, inpackage)
        if inpackage is not None:
            package = "%s.%s" % (inpackage, package)
        if not '__path__' in parent:
            raise ImportError('No package named {}'.format(package))
        return _readmodule(submodule, parent['__path__'], package)

    # Search the path for the module
    f = None
    if inpackage is not None:
        search_path = path
    else:
        search_path = path + sys.path
    # XXX This will change once issue19944 lands.
    spec = importlib.find_spec(fullmodule, search_path)
    fname = spec.loader.get_filename(fullmodule)
    _modules[fullmodule] = dict
    if spec.loader.is_package(fullmodule):
        dict['__path__'] = [os.path.dirname(fname)]
    try:
        source = spec.loader.get_source(fullmodule)
        if source is None:
            return dict
    except (AttributeError, ImportError):
        # not Python source, can't do anything with this module
        return dict

    f = io.StringIO(source)

    stack = [] # stack of (class, indent) pairs

    g = tokenize.generate_tokens(f.readline)
    try:
        for tokentype, token, start, _end, _line in g:
            if tokentype == DEDENT:
                lineno, thisindent = start
                # close nested classes and defs
                while stack and stack[-1][1] >= thisindent:
                    del stack[-1]
            elif token == 'def':
                lineno, thisindent = start
                # close previous nested classes and defs
                while stack and stack[-1][1] >= thisindent:
                    del stack[-1]
                tokentype, meth_name, start = next(g)[0:3]
                if tokentype != NAME:
                    continue # Syntax error
                if stack:
                    cur_class = stack[-1][0]
                    if isinstance(cur_class, Class):
                        # it's a method
                        cur_class._addmethod(meth_name, lineno)
                    # else it's a nested def
                else:
                    # it's a function
                    dict[meth_name] = Function(fullmodule, meth_name,
                                               fname, lineno)
                stack.append((None, thisindent)) # Marker for nested fns
            elif token == 'class':
                lineno, thisindent = start
                # close previous nested classes and defs
                while stack and stack[-1][1] >= thisindent:
                    del stack[-1]
                tokentype, class_name, start = next(g)[0:3]
                if tokentype != NAME:
                    continue # Syntax error
                # parse what follows the class name
                tokentype, token, start = next(g)[0:3]
                inherit = None
                if token == '(':
                    names = [] # List of superclasses
                    # there's a list of superclasses
                    level = 1
                    super = [] # Tokens making up current superclass
                    while True:
                        tokentype, token, start = next(g)[0:3]
                        if token in (')', ',') and level == 1:
                            n = "".join(super)
                            if n in dict:
                                # we know this super class
                                n = dict[n]
                            else:
                                c = n.split('.')
                                if len(c) > 1:
                                    # super class is of the form
                                    # module.class: look in module for
                                    # class
                                    m = c[-2]
                                    c = c[-1]
                                    if m in _modules:
                                        d = _modules[m]
                                        if c in d:
                                            n = d[c]
                            names.append(n)
                            super = []
                        if token == '(':
                            level += 1
                        elif token == ')':
                            level -= 1
                            if level == 0:
                                break
                        elif token == ',' and level == 1:
                            pass
                        # only use NAME and OP (== dot) tokens for type name
                        elif tokentype in (NAME, OP) and level == 1:
                            super.append(token)
                        # expressions in the base list are not supported
                    inherit = names
                cur_class = Class(fullmodule, class_name, inherit,
                                  fname, lineno)
                if not stack:
                    dict[class_name] = cur_class
                stack.append((cur_class, thisindent))
            elif token == 'import' and start[1] == 0:
                modules = _getnamelist(g)
                for mod, _mod2 in modules:
                    try:
                        # Recursively read the imported module
                        if inpackage is None:
                            _readmodule(mod, path)
                        else:
                            try:
                                _readmodule(mod, path, inpackage)
                            except ImportError:
                                _readmodule(mod, [])
                    except:
                        # If we can't find or parse the imported module,
                        # too bad -- don't die here.
                        pass
            elif token == 'from' and start[1] == 0:
                mod, token = _getname(g)
                if not mod or token != "import":
                    continue
                names = _getnamelist(g)
                try:
                    # Recursively read the imported module
                    d = _readmodule(mod, path, inpackage)
                except:
                    # If we can't find or parse the imported module,
                    # too bad -- don't die here.
                    continue
                # add any classes that were defined in the imported module
                # to our name space if they were mentioned in the list
                for n, n2 in names:
                    if n in d:
                        dict[n2 or n] = d[n]
                    elif n == '*':
                        # don't add names that start with _
                        for n in d:
                            if n[0] != '_':
                                dict[n] = d[n]
    except StopIteration:
        pass

    f.close()
    return dict
示例#4
-1
文件: spawn.py 项目: ifedorov/cpython
def import_main_path(main_path):
    '''
    Set sys.modules['__main__'] to module at main_path
    '''
    # XXX (ncoghlan): The following code makes several bogus
    # assumptions regarding the relationship between __file__
    # and a module's real name. See PEP 302 and issue #10845
    if getattr(sys.modules['__main__'], '__file__', None) == main_path:
        return

    main_name = os.path.splitext(os.path.basename(main_path))[0]
    if main_name == '__init__':
        main_name = os.path.basename(os.path.dirname(main_path))

    if main_name == '__main__':
        main_module = sys.modules['__main__']
        main_module.__file__ = main_path
    elif main_name != 'ipython':
        # Main modules not actually called __main__.py may
        # contain additional code that should still be executed
        import importlib
        import types

        if main_path is None:
            dirs = None
        elif os.path.basename(main_path).startswith('__init__.py'):
            dirs = [os.path.dirname(os.path.dirname(main_path))]
        else:
            dirs = [os.path.dirname(main_path)]

        assert main_name not in sys.modules, main_name
        sys.modules.pop('__mp_main__', None)
        # We should not try to load __main__
        # since that would execute 'if __name__ == "__main__"'
        # clauses, potentially causing a psuedo fork bomb.
        main_module = types.ModuleType(main_name)
        # XXX Use a target of main_module?
        spec = importlib.find_spec(main_name, path=dirs)
        if spec is None:
            raise ImportError(name=main_name)
        methods = importlib._bootstrap._SpecMethods(spec)
        methods.init_module_attrs(main_module)
        main_module.__name__ = '__mp_main__'
        code = spec.loader.get_code(main_name)
        exec(code, main_module.__dict__)

        old_main_modules.append(sys.modules['__main__'])
        sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module
示例#5
-1
def import_main_path(main_path):
    '''
    Set sys.modules['__main__'] to module at main_path
    '''
    # XXX (ncoghlan): The following code makes several bogus
    # assumptions regarding the relationship between __file__
    # and a module's real name. See PEP 302 and issue #10845
    if getattr(sys.modules['__main__'], '__file__', None) == main_path:
        return

    main_name = os.path.splitext(os.path.basename(main_path))[0]
    if main_name == '__init__':
        main_name = os.path.basename(os.path.dirname(main_path))

    if main_name == '__main__':
        main_module = sys.modules['__main__']
        main_module.__file__ = main_path
    elif main_name != 'ipython':
        # Main modules not actually called __main__.py may
        # contain additional code that should still be executed
        import importlib
        import types

        if main_path is None:
            dirs = None
        elif os.path.basename(main_path).startswith('__init__.py'):
            dirs = [os.path.dirname(os.path.dirname(main_path))]
        else:
            dirs = [os.path.dirname(main_path)]

        assert main_name not in sys.modules, main_name
        sys.modules.pop('__mp_main__', None)
        # We should not try to load __main__
        # since that would execute 'if __name__ == "__main__"'
        # clauses, potentially causing a psuedo fork bomb.
        main_module = types.ModuleType(main_name)
        # XXX Use a target of main_module?
        spec = importlib.find_spec(main_name, path=dirs)
        if spec is None:
            raise ImportError(name=main_name)
        methods = importlib._bootstrap._SpecMethods(spec)
        methods.init_module_attrs(main_module)
        main_module.__name__ = '__mp_main__'
        code = spec.loader.get_code(main_name)
        exec(code, main_module.__dict__)

        old_main_modules.append(sys.modules['__main__'])
        sys.modules['__main__'] = sys.modules['__mp_main__'] = main_module