"""Implementation of Python's import machinery in Python source code.

The Import class implements the semantics of import.  This means that an
instance of this class can be called to properly check sys.modules,
sys.meta_path, sys.path, etc. to import the requested module.

The importing of built-in, frozen, extension, .py, and .pyc files are all
handled by implementing importers and loaders as specified by PEP 302.  This
leads to the ability to easily control imports based on the type of module.
There is also a clear distinction between how the module is stored and how it
is formatted (e.g., a Python source file does not require it be stored as a
file on a filesystem).

To help with the distinction between how a module is stored compared to its
format the idea of handlers is introduced.  A handler implements a specific
interface while specifying the type of module it handles (usually by the what
one would expect as a file extension if the module was on a filesystem).  This
allows a PEP 302 importer/loader to represent how a module is stored while the
handler deals with how the module is formatted.

A handler is expected to implement the handle_code method only.  The handler
for Python source and bytecode modules goes farther and defines an extensive
interface that is designed so that alternatives on module formatting can be
supported easily without needing to write a new importer/loader.  The Python
source and bytecode handler also expects loaders to define a more extensive
interface to allow for different backend stores (e.g., databases) to use the
handler without modification.  All of this helps with code reuse and possible
errors from the complicated relationship between Python source and bytecode
modules.
"""
import _importlib

# XXX Temporary functions that should eventually be removed.
import os

def _set__import__():
    """Set __import__ to an instance of Import."""
    global original__import__
    original__import__ = __import__
    __builtins__['__import__'] = Import()


def _reset__import__():
    """Set __import__ back to the original implementation (assumes
    _set__import__ was called previously)."""
    __builtins__['__import__'] = original__import__


def _w_long(x):
    """Convert a 32-bit integer to little-endian.

    XXX Temporary until marshal's long functions are exposed.

    """
    x = int(x)
    int_bytes = []
    int_bytes.append(x & 0xFF)
    int_bytes.append((x >> 8) & 0xFF)
    int_bytes.append((x >> 16) & 0xFF)
    int_bytes.append((x >> 24) & 0xFF)
    return ''.join(chr(x) for x in int_bytes)


def _r_long(int_bytes):
    """Convert 4 bytes in little-endian to an integer.

    XXX Temporary until marshal's long function are exposed.

    """
    x = ord(int_bytes[0])
    x |= ord(int_bytes[1]) << 8
    x |= ord(int_bytes[2]) << 16
    x |= ord(int_bytes[3]) << 24
    return x


def _case_ok(directory, file_name):
    """Verify that file_name (as found in 'directory') has the proper case.

    The path is assumed to already exist.

    XXX Temporary until imp's case_ok function can be exposed.

    XXX Better to roll this into a single function some how so that existence
    check can be part of case check and thus cut down on stat calls?

    """
    # If platform is not case-sensitive *or* the environment variable
    # PYTHONCASEOK is defined, then os.path.exists already handled the case by
    # either doing a case-sensitive check or from the user saying he does not
    # want case-sensitivity, respectively.
    if sys.platform not in ('win32', 'mac', 'riscos', 'darwin', 'cygwin',
            'os2emx') or os.environ.get('PYTHONCASEOK'):
        return True
    directory_contents = set(os.path.splitext(x)[0]
                                for x in os.listdir(directory))
    file_wo_ext = os.path.splitext(file_name)[0]
    if file_wo_ext in directory_contents:
        return True
    else:
        return False



# Required built-in modules.
try:
    import posix as _os
except ImportError:
    try:
        import nt as _os
    except ImportError:
        try:
            import os2 as _os
        except ImportError:
            raise ImportError('posix, nt, or os2 module required for importlib')
_importlib._os = _os
import imp, sys, marshal, errno
_importlib.imp = imp
_importlib.sys = sys
_importlib.marshal = marshal
_importlib.errno = errno
# XXX 'warnings' needs become a built-in module (<cough>Neal</cough>).
import warnings
_importlib.warnings = warnings


from os import sep
_importlib._r_long = _r_long  #XXX Expose original from marshal.
_importlib._w_long = _w_long  #XXX Expose original from marshal.
_importlib._case_ok = _case_ok  #XXX Expose original from imp.
# For os.path.join replacement; pull from Include/osdefs.h:SEP .
_importlib.path_sep = sep


del _importlib

from _importlib import *
