Changeset 753

Show
Ignore:
Timestamp:
07/18/07 20:33:16 (1 year ago)
Author:
robin
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • commando/trunk/commandolite.py

    r751 r753  
    257257    if mtype not in allowmtypes: 
    258258        return None 
    259     abs_path = dirname(normpath(abspath(expanduser(path)))) 
     259    abs_path = dirname(normpath(abspath(expandvars(expanduser(path))))) 
    260260    return (abs_path, modname, ext, mode, mtype) 
    261261 
     
    396396    return filter_best_eggs(pth) 
    397397 
    398  
    399  
    400 #----------------------------------------------------------------------------- 
    401 # python code execution 
    402  
    403  
    404 def run_magic_syspath(argv=None, 
    405         import_modules=False, run_last_module=True): 
    406     """Run a module using a magicaly extended sys.path. 
    407  
    408     Discovers additional package paths by searching under directories listed as 
    409     non option arguments. Discovery is egg aware: it takes care to include only 
    410     the *best* version of each egg and only those eggs that match the python 
    411     interpreters version. 
    412  
    413     If the last argument names a legitemate python module then sys.path is 
    414     extended with the discovered paths, sys.argv is adjusted to reflect the 
    415     module name and the remaining arguments. Then runpy.run_module is used to 
    416     execute the module in this magicaly discovered path. 
    417  
    418     If any non option argument, other than the last, identifies a python module 
    419     then sys.path is updated and an attempt to import the module is made. This 
    420     feature allows import of packages whose import time behaviour would be 
    421     adversly affected by any paths added on behalf of subsequent modules. Note 
    422     that you can disable this by setting `import_modules=False` and 
    423     `run_last_module=True`. This will defer all import behaviour to the module 
    424     you chose to *run*. 
    425  
    426     If the last argument is not a python package then two lists are returned. 
    427     The first list contains the discovered path and the second list contains 
    428     any modules that were imported as it was discovered. The second list will 
    429     allways be empty if `import_modules` is False. 
    430  
    431     TODO: examples 
    432  
    433     """ 
    434  
    435     argv = argv or sys.argv[:] 
    436     lenargv = len(argv) 
    437     if lenargv < 2: 
    438         sys.exit(-1) 
    439  
    440     ia=1 
    441     for i in range(lenargv - 1): 
    442         ia = i + 1 
    443         a = argv[ia] 
    444         if a == '--': 
    445             del argv[ia] 
    446             break 
    447         elif a[:2] == '--' or a[:1] == '-': 
    448             break 
    449     else: 
    450         ia=lenargv 
    451  
    452     minfo = None 
    453  
    454     searchpaths = [] 
    455     pthset = set([]) 
    456     pathsadded = [] 
    457     pthextend = [] 
    458     sys_path_insertpos = 0 
    459  
    460     imported = [] # hold on to the references. 
    461  
    462     for i, a in enumerate(argv[1:ia]): 
    463  
    464         minfo = path_moduleinfo(a) 
    465         if minfo: 
    466             # if its a legitemate python module file, import it with the 
    467             # path we have discovered so far. 
    468             if minfo[1] in sys.modules: 
    469                 continue 
    470  
    471             if minfo[0] not in pthset: 
    472                 pthextend.append(minfo[0]) 
    473                 pthset.add(minfo[0]) 
    474  
    475             # Don't import modules or update sys.path if import_modules is 
    476             # False 
    477             if not import_modules: 
    478                 continue 
    479  
    480             # If the last argument is a module, then dont import it. We will 
    481             # run it instead. 
    482             if i+2 == ia: 
    483                 continue 
    484  
    485             newpaths = find_package_paths(pth=pthset, 
    486                 *searchpaths 
    487                 ) 
    488             pthextend.extend(newpaths) 
    489  
    490             sys.path[sys_path_insertpos:sys_path_insertpos 
    491                     ] = pthextend[:] 
    492             sys_path_insertpos += len(pthextend) 
    493  
    494             pathsadded.extend(newpaths) 
    495             pthextend[:] = [] 
    496             searchpaths[:] = [] 
    497  
    498             imported.append(__import__(minfo[1])) 
    499  
    500             minfo = None 
    501             continue 
    502  
    503         else: 
    504             searchpaths.append(a) 
    505  
    506  
    507     newpaths = find_package_paths(pth=pthset, 
    508         *searchpaths 
    509         ) 
    510  
    511     pthextend.extend(newpaths) 
    512  
    513     if import_modules or run_last_module: 
    514         sys.path[sys_path_insertpos:sys_path_insertpos 
    515                 ] = pthextend[:] 
    516  
    517     pathsadded.extend(newpaths) 
    518  
    519     if not run_last_module: 
    520         return pathsadded, imported 
    521  
    522     if minfo: 
    523         sys.argv[:] = [] 
    524         sys.argv.append(minfo[1]) 
    525         sys.argv.extend(argv[ia:]) 
    526         run_module(sys.argv[0], run_name='__main__', alter_sys=True) 
    527  
    528     return pathsadded, imported 
    529398 
    530399#----------------------------------------------------------------------------- 
     
    713582# main entry point wrappers and helpers 
    714583 
     584def enumerate_argv_args(argv, startpos=0): 
     585 
     586    for i in range(len(argv) - startpos): 
     587        ia = i + startpos 
     588        a = argv[ia] 
     589        if a == '--': 
     590            yield ia + 1, None 
     591            return 
     592        elif a[:2] == '--' or a[:1] == '-': 
     593            return 
     594        else: 
     595            yield ia, a 
     596 
     597 
    715598def get_module_code(mod_name): 
    716599    """like runpy.run_module but dont run.""" 
     
    787670 
    788671 
     672def run_magic_syspath(argv=None, run_last_module=True): 
     673    """Run a module using a magicaly extended sys.path. 
     674 
     675    Discovers additional package paths by searching under directories listed as 
     676    non option arguments. Discovery is egg aware: it takes care to include only 
     677    the *best* version of each egg and only those eggs that match the python 
     678    interpreters version. 
     679 
     680    If the last argument names a legitemate python module then it will be 
     681    executed using the `runpy.run_module` helper from the standard lib. This 
     682    feature can be disabled by passing a false value for `run_last_module`. 
     683 
     684    If any `interior` argument identifies a python module then its containing 
     685    directory is added to the path extension. 
     686 
     687    The extension path discovered by this api consists of unique paths in order 
     688    of discovery. Where egg directories or archive files are encountered care 
     689    is taken to ensure that eggs which are incompatible with the current 
     690    `sys.executable` are *excluded* and only the *best* available version for 
     691    each project is *included*. The measure of "best available" is the same as 
     692    used by pkg_resources.py from the setuptools project. 
     693 
     694 
     695    :Returns: 
     696        The discovered extension path. But note that if `run_last_module` is 
     697        true it resonably likely that this function will *not return*. 
     698 
     699    TODO: examples 
     700 
     701    """ 
     702 
     703    argv = argv or sys.argv[:] 
     704 
     705    pthextend = [] 
     706    searchpaths = [] 
     707    pthset = set([]) 
     708 
     709    minfo = None 
     710    for ia, a in enumerate_argv_args(argv, 1): 
     711        if a is None: 
     712            continue 
     713        minfo = path_moduleinfo(a) 
     714        if minfo: 
     715            # if its a legitemate python module file, import it with the 
     716            # path we have discovered so far. 
     717            if minfo[1] in sys.modules: 
     718                continue 
     719 
     720            a = minfo[0] 
     721            if a not in pthset: 
     722                pthextend.append(a) 
     723                pthset.add(a) 
     724 
     725        else: 
     726            searchpaths.append(a) 
     727 
     728    newpaths = find_package_paths(pth=pthset, 
     729        *searchpaths 
     730        ) 
     731    pthextend.extend(newpaths) 
     732 
     733    if run_last_module and minfo: 
     734        sys.path[0:0] = pthextend[:] 
     735        sys.argv[:] = [] 
     736        sys.argv.append(minfo[1]) 
     737        sys.argv.extend(argv[ia:]) 
     738        return run_module(sys.argv[0], run_name='__main__', alter_sys=True) 
     739 
     740    else: 
     741        return pthextend 
     742 
     743 
     744if __name__=='__main__': 
     745    try: 
     746        rval = run_magic_syspath() 
     747        if rval and isinstance(rval, list): 
     748            print os.pathsep.join(rval) 
     749    except SystemExit: 
     750        raise 
     751    except: 
     752        msg = exc_string() 
     753        print msg 
     754        sys.exit(-1) 
     755#EOF 
     756