def getModule(name,
              directory=".",
              source_extension=".prep",
              verbose=0,
              savefile=None,
              sourcetext=None,
              savePy=0,
              force=0,
              savePyc=1,
              importModule=1,_globals=None):
    """Returns a python module implementing the template, compiling if needed.

    force: ignore up-to-date checks and always recompile.
    """
    if isinstance(name,unicode): name = name.encode('utf8')
    if isinstance(directory,unicode): directory = directory.encode('utf8')
    if isinstance(source_extension,unicode): source_extension = source_extension.encode('utf8')
    if isinstance(sourcetext,unicode): sourcetext = sourcetext.encode('utf8')
    if hasattr(name,'read'):
        sourcetext = name.read()
        name = getattr(name,'name',None)
        if not name: name = '_preppy_'+md5(sourcetext+repr(VERSION)).digest()
    else:
        # it's possible that someone could ask for
        #  name "subdir/spam.prep" in directory "/mydir", instead of
        #  "spam.prep" in directory "/mydir/subdir".  Failing to get
        # this right means getModule can fail to find it and recompile
        # every time.  This is common during batch compilation of directories.
        extraDir, name = os.path.split(name)
        if extraDir:
            if os.path.isabs(extraDir):
                directory = extraDir
            else:
                directory = directory + os.sep + extraDir
        dir = os.path.abspath(os.path.normpath(directory))

        # they may ask for 'spam.prep' instead of just 'spam'.  Trim off
        # any extension
        name = os.path.splitext(name)[0]
        if verbose:
            print 'checking %s...' % os.path.join(dir, name),
        # savefile is deprecated but kept for safety.  savePy and savePyc are more
        # explicit and are the preferred.  By default it generates a pyc and no .py
        # file to reduce clutter.
        if savefile and savePyc == 0:
            savePyc = 1

    if sourcetext is not None:
        # they fed us the source explicitly
        if not name: name = '_preppy_'+md5(sourcetext+repr(VERSION)).digest()
        if verbose: print "sourcetext provided...",
        sourcefilename = "<input text %s>" % name
        sourcechecksum = md5(sourcetext + repr(VERSION)).digest()
        nosourcefile = 1
        module = SOURCE_MODULES.get(sourcetext,None)
        if module:
            return module
    else:
        nosourcefile = 0
        # see if the module exists as a python file
        sourcefilename = os.path.join(dir, name+source_extension)
        module = FILE_MODULES.get(sourcefilename,None)
        if module:
            return module

        try:
            module = rl_get_module(name,dir)
            module.__dict__['include'] = include
            if _globals:
                module.__dict__.update(_globals)
            checksum = module.__checksum__
            if verbose: print "found...",
        except: # ImportError:  #catch ALL Errors importing the module (eg name="")
            module = checksum = None
            if verbose: print " py/pyc not found...",
            # check against source file
        try:
            sourcefile = open(sourcefilename, "r")
        except:
            if verbose: print "no source file, reuse...",
            if module is None:
                raise ValueError, "couldn't find source %s or module %s" % (sourcefilename, name)
            # use the existing module??? (NO SOURCE PRESENT)
            FILE_MODULES[sourcefilename] = module
            return module
        else:
            sourcetext = sourcefile.read()
            # NOTE: force recompile on each new version of this module.
            sourcechecksum = md5(sourcetext + repr(VERSION)).digest()
            if sourcechecksum==checksum:
                if force==0:
                    # use the existing module. it matches
                    if verbose:
                        print "up to date."
                    FILE_MODULES[sourcefilename] = module
                    return module
                else:
                    # always recompile
                    if verbose: print 'forced recompile,',
            elif verbose:
                print "changed,",

    # if we got here we need to rebuild the module from source
    if verbose: print "recompiling"
    global DIAGNOSTIC_FUNCTION
    DIAGNOSTIC_FUNCTION = None
    P = PreppyParser(sourcetext,sourcefilename)
    P.nosourcefile = nosourcefile
    P.sourcechecksum = sourcechecksum
    P.compile(0)

    # default is compile to bytecode and save that.
    if savePyc:
        f = open(dir + os.sep + name + '.pyc','wb')
        P.dump(f)
        f.close()

    # now make a module
    from imp import new_module
    module = new_module(name)
    module.__dict__['include'] = include
    if _globals:
        module.__dict__.update(_globals)
    exec P.code in module.__dict__
    if importModule:
        if nosourcefile:
            SOURCE_MODULES[sourcetext] = module
        else:
            FILE_MODULES[sourcefilename] = module
    return module

# support the old form here
dataset/ETHPy150Open CGATOxford/cgat/obsolete/preppy.py/getModule/original