"""Import hook support.

Consistent use of this module will make it possible to change the
different mechanisms involved in loading modules independently.

While the built-in module imp exports interfaces to the built-in
module searching and loading algorithm, and it is possible to replace
the built-in function __import__ in order to change the semantics of
the import statement, until now it has been difficult to combine the
effect of different __import__ hacks, like loading modules from URLs
by rimport.py, or restricted execution by rexec.py.

This module defines three new concepts:

1) A "file system hooks" class provides an interface to a filesystem.

One hooks class is defined (Hooks), which uses the interface provided
by standard modules os and os.path.  It should be used as the base
class for other hooks classes.

2) A "module loader" class provides an interface to search for a
module in a search path and to load it.  It defines a method which
searches for a module in a single directory; by overriding this method
one can redefine the details of the search.  If the directory is None,
built-in and frozen modules are searched instead.

Two module loader class are defined, both implementing the search
strategy used by the built-in __import__ function: ModuleLoader uses
the imp module's find_module interface, while HookableModuleLoader
uses a file system hooks class to interact with the file system.  Both
use the imp module's load_* interfaces to actually load the module.

3) A "module importer" class provides an interface to import a
module, as well as interfaces to reload and unload a module.  It also
provides interfaces to install and uninstall itself instead of the
default __import__ and reload (and unload) functions.

One module importer class is defined (ModuleImporter), which uses a
module loader instance passed in (by default HookableModuleLoader is
instantiated).

The classes defined here should be used as base classes for extended
functionality along those lines.

If a module importer class supports dotted names, its import_module()
must return a different value depending on whether it is called on
behalf of a "from ... import ..." statement or not.  (This is caused
by the way the __import__ hook is used by the Python interpreter.)  It
would also do wise to install a different version of reload().

"""
from warnings import warnpy3k, warn
warnpy3k("the ihooks module has been removed in Python 3.0", stacklevel=2)
del warnpy3k

import __builtin__
import imp
import os
import sys

__all__ = ["BasicModuleLoader","Hooks","ModuleLoader","FancyModuleLoader",
           "BasicModuleImporter","ModuleImporter","install","uninstall"]

VERBOSE = 0


from imp import C_EXTENSION, PY_SOURCE, PY_COMPILED
from imp import C_BUILTIN, PY_FROZEN, PKG_DIRECTORY
BUILTIN_MODULE = C_BUILTIN
FROZEN_MODULE = PY_FROZEN


class _Verbose:

    def __init__(self, verbose = VERBOSE):
        self.verbose = verbose

    def get_verbose(self):
        return self.verbose

    def set_verbose(self, verbose):
        self.verbose = verbose

    # XXX The following is an experimental interface

    def note(self, *args):
        if self.verbose:
            self.message(*args)

    def message(self, format, *args):
        if args:
            print format%args
        else:
            print format


class BasicModuleLoader(_Verbose):

    """Basic module loader.

    This provides the same functionality as built-in import.  It
    doesn't deal with checking sys.modules -- all it provides is
    find_module() and a load_module(), as well as find_module_in_dir()
    which searches just one directory, and can be overridden by a
    derived class to change the module search algorithm when the basic
    dependency on sys.path is unchanged.

    The interface is a little more convenient than imp's:
    find_module(name, [path]) returns None or 'stuff', and
    load_module(name, stuff) loads the module.

    """

    def find_module(self, name, path = None):
        if path is None:
            path = [None] + self.default_path()
        for dir in path:
            stuff = self.find_module_in_dir(name, dir)
            if stuff: return stuff
        return None

    def default_path(self):
        return sys.path

    def find_module_in_dir(self, name, dir):
        if dir is None:
            return self.find_builtin_module(name)
        else:
            try:
                return imp.find_module(name, [dir])
            except ImportError:
                return None

    def find_builtin_module(self, name):
        # XXX frozen packages?
        if imp.is_builtin(name):
            return None, '', ('', '', BUILTIN_MODULE)
        if imp.is_frozen(name):
            return None, '', ('', '', FROZEN_MODULE)
        return None

    def load_module(self, name, stuff):
        file, filename, info = stuff
        try:
            return imp.load_module(name, file, filename, info)
        finally:
            if file: file.close()


class Hooks(_Verbose):

    """Hooks into the filesystem and interpreter.

    By deriving a subclass you can redefine your filesystem interface,
    e.g. to merge it with the URL space.

    This base class behaves just like the native filesystem.

    """

    # imp interface
    def get_suffixes(self): return imp.get_suffixes()
    def new_module(self, name): return imp.new_module(name)
    def is_builtin(self, name): return imp.is_builtin(name)
    def init_builtin(self, name): return imp.init_builtin(name)
    def is_frozen(self, name): return imp.is_frozen(name)
    def init_frozen(self, name): return imp.init_frozen(name)
    def get_frozen_object(self, name): return imp.get_frozen_object(name)
    def load_source(self, name, filename, file=None):
        return imp.load_source(name, filename, file)
    def load_compiled(self, name, filename, file=None):
        return imp.load_compiled(name, filename, file)
    def load_dynamic(self, name, filename, file=None):
        return imp.load_dynamic(name, filename, file)
    def load_package(self, name, filename, file=None):
        return imp.load_module(name, file, filename, ("", "", PKG_DIRECTORY))

    def add_module(self, name):
        d = self.modules_dict()
        if name in d: return d[name]
        d[name] = m = self.new_module(name)
        return m

    # sys interface
    def modules_dict(self): return sys.modules
    def default_path(self): return sys.path

    def path_split(self, x): return os.path.split(x)
    def path_join(self, x, y): return os.path.join(x, y)
    def path_isabs(self, x): return os.path.isabs(x)
    # etc.

    def path_exists(self, x): return os.path.exists(x)
    def path_isdir(self, x): return os.path.isdir(x)
    def path_isfile(self, x): return os.path.isfile(x)
    def path_islink(self, x): return os.path.islink(x)
    # etc.

    def openfile(self, *x): return open(*x)
    openfile_error = IOError
    def listdir(self, x): return os.listdir(x)
    listdir_error = os.error
    # etc.


class ModuleLoader(BasicModuleLoader):

    """Default module loader; uses file system hooks.

    By defining suitable hooks, you might be able to load modules from
    other sources than the file system, e.g. from compressed or
    encrypted files, tar files or (if you're brave!) URLs.

    """

    def __init__(self, hooks = None, verbose = VERBOSE):
        BasicModuleLoader.__init__(self, verbose)
        self.hooks = hooks or Hooks(verbose)

    def default_path(self):
        return self.hooks.default_path()

    def modules_dict(self):
        return self.hooks.modules_dict()

    def get_hooks(self):
        return self.hooks

    def set_hooks(self, hooks):
        self.hooks = hooks

    def find_builtin_module(self, name):
        # XXX frozen packages?
        if self.hooks.is_builtin(name):
            return None, '', ('', '', BUILTIN_MODULE)
        if self.hooks.is_frozen(name):
            return None, '', ('', '', FROZEN_MODULE)
        return None

    def find_module_in_dir(self, name, dir, allow_packages=1):
        if dir is None:
            return self.find_builtin_module(name)
        if allow_packages:
            fullname = self.hooks.path_join(dir, name)
            if self.hooks.path_isdir(fullname):
                stuff = self.find_module_in_dir("__init__", fullname, 0)
                if stuff:
                    file = stuff[0]
                    if file: file.close()
                    return None, fullname, ('', '', PKG_DIRECTORY)
        for info in self.hooks.get_suffixes():
            suff, mode, type = info
            fullname = self.hooks.path_join(dir, name+suff)
            try:
                fp = self.hooks.openfile(fullname, mode)
                return fp, fullname, info
            except self.hooks.openfile_error:
                pass
        return None

    def load_module(self, name, stuff):
        file, filename, info = stuff
        (suff, mode, type) = info
        try:
            if type == BUILTIN_MODULE:
                return self.hooks.init_builtin(name)
            if type == FROZEN_MODULE:
                return self.hooks.init_frozen(name)
            if type == C_EXTENSION:
                m = self.hooks.load_dynamic(name, filename, file)
            elif type == PY_SOURCE:
                m = self.hooks.load_source(name, filename, file)
            elif type == PY_COMPILED:
                m = self.hooks.load_compiled(name, filename, file)
            elif type == PKG_DIRECTORY:
                m = self.hooks.load_package(name, filename, file)
            else:
                raise ImportError, "Unrecognized module type (%r) for %s" % \
                      (type, name)
        finally:
            if file: file.close()
        m.__file__ = filename
        return m


class FancyModuleLoader(ModuleLoader):

    """Fancy module loader -- parses and execs the code itself."""

    def load_module(self, name, stuff):
        file, filename, (suff, mode, type) = stuff
        realfilename = filename
        path = None

        if type == PKG_DIRECTORY:
            initstuff = self.find_module_in_dir("__init__", filename, 0)
            if not initstuff:
                raise ImportError, "No __init__ module in package %s" % name
            initfile, initfilename, initinfo = initstuff
            initsuff, initmode, inittype = initinfo
            if inittype not in (PY_COMPILED, PY_SOURCE):
                if initfile: initfile.close()
                raise ImportError, \
                    "Bad type (%r) for __init__ module in package %s" % (
                    inittype, name)
            path = [filename]
            file = initfile
            realfilename = initfilename
            type = inittype

        if type == FROZEN_MODULE:
            code = self.hooks.get_frozen_object(name)
        elif type == PY_COMPILED:
            import marshal
            file.seek(8)
            code = marshal.load(file)
        elif type == PY_SOURCE:
            data = file.read()
            code = compile(data, realfilename, 'exec')
        else:
            return ModuleLoader.load_module(self, name, stuff)

        m = self.hooks.add_module(name)
        if path:
            m.__path__ = path
        m.__file__ = filename
        try:
            exec code in m.__dict__
        except:
            d = self.hooks.modules_dict()
            if name in d:
                del d[name]
            raise
        return m


class BasicModuleImporter(_Verbose):

    """Basic module importer; uses module loader.

    This provides basic import facilities but no package imports.

    """

    def __init__(self, loader = None, verbose = VERBOSE):
        _Verbose.__init__(self, verbose)
        self.loader = loader or ModuleLoader(None, verbose)
        self.modules = self.loader.modules_dict()

    def get_loader(self):
        return self.loader

    def set_loader(self, loader):
        self.loader = loader

    def get_hooks(self):
        return self.loader.get_hooks()

    def set_hooks(self, hooks):
        return self.loader.set_hooks(hooks)

    def import_module(self, name, globals={}, locals={}, fromlist=[]):
        name = str(name)
        if name in self.modules:
            return self.modules[name] # Fast path
        stuff = self.loader.find_module(name)
        if not stuff:
            raise ImportError, "No module named %s" % name
        return self.loader.load_module(name, stuff)

    def reload(self, module, path = None):
        name = str(module.__name__)
        stuff = self.loader.find_module(name, path)
        if not stuff:
            raise ImportError, "Module %s not found for reload" % name
        return self.loader.load_module(name, stuff)

    def unload(self, module):
        del self.modules[str(module.__name__)]
        # XXX Should this try to clear the module's namespace?

    def install(self):
        self.save_import_module = __builtin__.__import__
        self.save_reload = __builtin__.reload
        if not hasattr(__builtin__, 'unload'):
            __builtin__.unload = None
        self.save_unload = __builtin__.unload
        __builtin__.__import__ = self.import_module
        __builtin__.reload = self.reload
        __builtin__.unload = self.unload

    def uninstall(self):
        __builtin__.__import__ = self.save_import_module
        __builtin__.reload = self.save_reload
        __builtin__.unload = self.save_unload
        if not __builtin__.unload:
            del __builtin__.unload


class ModuleImporter(BasicModuleImporter):

    """A module importer that supports packages."""

    def import_module(self, name, globals=None, locals=None, fromlist=None,
                      level=-1):
        parent = self.determine_parent(globals, level)
        q, tail = self.find_head_package(parent, str(name))
        m = self.load_tail(q, tail)
        if not fromlist:
            return q
        if hasattr(m, "__path__"):
            self.ensure_fromlist(m, fromlist)
        return m

    def determine_parent(self, globals, level=-1):
        if not globals or not level:
            return None
        pkgname = globals.get('__package__')
        if pkgname is not None:
            if not pkgname and level > 0:
                raise ValueError, 'Attempted relative import in non-package'
        else:
            # __package__ not set, figure it out and set it
            modname = globals.get('__name__')
            if modname is None:
                return None
            if "__path__" in globals:
                # __path__ is set so modname is already the package name
                pkgname = modname
            else:
                # normal module, work out package name if any
                if '.' not in modname:
                    if level > 0:
                        raise ValueError, ('Attempted relative import in '
                                           'non-package')
                    globals['__package__'] = None
                    return None
                pkgname = modname.rpartition('.')[0]
            globals['__package__'] = pkgname
        if level > 0:
            dot = len(pkgname)
            for x in range(level, 1, -1):
                try:
                    dot = pkgname.rindex('.', 0, dot)
                except ValueError:
                    raise ValueError('attempted relative import beyond '
                                     'top-level package')
            pkgname = pkgname[:dot]
        try:
            return sys.modules[pkgname]
        except KeyError:
            if level < 1:
                warn("Parent module '%s' not found while handling "
                     "absolute import" % pkgname, RuntimeWarning, 1)
                return None
            else:
                raise SystemError, ("Parent module '%s' not loaded, cannot "
                                    "perform relative import" % pkgname)

    def find_head_package(self, parent, name):
        if '.' in name:
            i = name.find('.')
            head = name[:i]
            tail = name[i+1:]
        else:
            head = name
            tail = ""
        if parent:
            qname = "%s.%s" % (parent.__name__, head)
        else:
            qname = head
        q = self.import_it(head, qname, parent)
        if q: return q, tail
        if parent:
            qname = head
            parent = None
            q = self.import_it(head, qname, parent)
            if q: return q, tail
        raise ImportError, "No module named '%s'" % qname

    def load_tail(self, q, tail):
        m = q
        while tail:
            i = tail.find('.')
            if i < 0: i = len(tail)
            head, tail = tail[:i], tail[i+1:]
            mname = "%s.%s" % (m.__name__, head)
            m = self.import_it(head, mname, m)
            if not m:
                raise ImportError, "No module named '%s'" % mname
        return m

    def ensure_fromlist(self, m, fromlist, recursive=0):
        for sub in fromlist:
            if sub == "*":
                if not recursive:
                    try:
                        all = m.__all__
                    except AttributeError:
                        pass
                    else:
                        self.ensure_fromlist(m, all, 1)
                continue
            if sub != "*" and not hasattr(m, sub):
                subname = "%s.%s" % (m.__name__, sub)
                submod = self.import_it(sub, subname, m)
                if not submod:
                    raise ImportError, "No module named '%s'" % subname

    def import_it(self, partname, fqname, parent, force_load=0):
        if not partname:
            # completely empty module name should only happen in
            # 'from . import' or __import__("")
            return parent
        if not force_load:
            try:
                return self.modules[fqname]
            except KeyError:
                pass
        try:
            path = parent and parent.__path__
        except AttributeError:
            return None
        partname = str(partname)
        stuff = self.loader.find_module(partname, path)
        if not stuff:
            return None
        fqname = str(fqname)
        m = self.loader.load_module(fqname, stuff)
        if parent:
            setattr(parent, partname, m)
        return m

    def reload(self, module):
        name = str(module.__name__)
        if '.' not in name:
            return self.import_it(name, name, None, force_load=1)
        i = name.rfind('.')
        pname = name[:i]
        parent = self.modules[pname]
        return self.import_it(name[i+1:], name, parent, force_load=1)


default_importer = None
current_importer = None

def install(importer = None):
    global current_importer
    current_importer = importer or default_importer or ModuleImporter()
    current_importer.install()

def uninstall():
    global current_importer
    current_importer.uninstall()
