Changeset 779

Show
Ignore:
Timestamp:
08/01/07 09:03:50 (1 year ago)
Author:
robin
Message:

* feature: for each explicitly listed module file, discover the top most

package directory - the parent of the top most package directory is then
used for the path entry. -m must use fully qualified module names now.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pyrun/trunk/ChangeLog

    r754 r779  
    22~~~~~~~~~ 
    33 
    4 NEXTREVISION 
     40.1c 
     5  * Use the parent directory of the top package directory for each explicitly 
     6    listed python file in the discovery path. This means you need to *always*  
     7    provide fully qualified module names to ``-m``. This change is necessary 
     8    to allow the targeted modules imports to work correctly. 
     9 
     100.1b 
    511 
    612  * path discovery and  python module execution 
  • pyrun/trunk/pkg-info.rst

    r777 r779  
    11:License: MIT 
    22:Name: pyrun 
    3 :Version: 0.1b 
     3:Version: 0.1c 
    44:Author: Robin Bryce 
    55:Author-email: robinbryce@gmail.com 
  • pyrun/trunk/pyrun.py

    r777 r779  
    7373    return (dirname(path), modname, ext, mode, mtype) 
    7474 
     75 
     76def path_pkg_moduleinfo(path, allowmtypes=(imp.PY_SOURCE, imp.PY_COMPILED)): 
     77    """Get extended module info for `path` 
     78 
     79    `path` must be the location of a real file on disk. 
     80 
     81    If path identifies a legitemate python file (as determined by 
     82    inspect.getmoduleinfo) then return a 4 element tuple: 
     83 
     84    (pkg_path, modname, ext, mode, mtype) 
     85 
     86    ext, mode and mtype are obtained using `inspect.getmoduleinfo` 
     87 
     88    `modname` is the fully qualified module name. 
     89    `path` is the directory containing the top most package. 
     90 
     91    `modname` and `pkg_path` are found by testing succesive directories above 
     92    `path`. The upward walk terminates when it encounters a directory whose 
     93    basename is not a legal python module name OR which does not contain a 
     94    suitable __init__.py (The search allows for __init__.py, __init__.pyc, 
     95    and __init__.pyo). 
     96 
     97    """ 
     98 
     99    if not isfile(path): 
     100        return None 
     101 
     102    v = inspect.getmoduleinfo(path) 
     103    if not v: 
     104        return 
     105    modname, ext, mode, mtype = v 
     106    if mtype not in allowmtypes: 
     107        return None 
     108 
     109    p = dirname(path) 
     110    packagedirs = [] 
     111    packages = [] 
     112    m = basename(p) 
     113    while (p and '.' not in m 
     114            and (isfile(join(p, '__init__.py')) 
     115                or isfile(join(p, '__init__.pyc')))): 
     116        packagedirs.append(p) 
     117        packages.append(m) 
     118        p = dirname(p) 
     119        m = basename(p) 
     120 
     121    packagedirs.reverse() 
     122    packages.reverse() 
     123    packages.append(modname) 
     124 
     125    return (p, '.'.join(packages), ext, mode, mtype) 
     126 
     127 
     128def run_pkg_minfo(): 
     129    print path_pkg_moduleinfo(sys.argv[1]) 
     130    return 0 
     131 
    75132# from distutils.util, because fools at debian think its a good idea to remove 
    76133# distutils from the standard distribution. 
     
    306363    for ia, a in enumerate_argv_args(args, offset): 
    307364 
    308         minfo = path_moduleinfo(a) 
     365        #minfo = path_moduleinfo(a) 
     366        minfo = path_pkg_moduleinfo(a) 
    309367        if minfo: 
    310368            minfos.append(minfo) 
     
    461519        modname = opts.m or (minfos and minfos[0][1]) or '' 
    462520 
     521        # Allways update the sys path. pthextend is the record of what we have 
     522        # done. The record only matters for interative mode in cases where you 
     523        # want to adjust the find results. 
     524        sys.path[0:0] = pthextend[:] 
     525 
     526        # But defer sys.argv changes until the last instant. This lets 
     527        # the interpreted mode be used to conveniently fiddle with argv. 
     528 
    463529        target_argv = [] 
    464530        if modname: 
    465531            target_argv.append(modname) 
    466532            target_argv.extend(argv[ia:]) 
     533 
    467534        def run_module(): 
    468535            if opts.n: 
     
    474541            import runpy 
    475542            sys.argv[:] = target_argv[:] 
    476             sys.path[0:0] = pthextend[:] 
    477543            return runpy.run_module( 
    478544                    modname, run_name='__main__', alter_sys=True 
     
    494560                banner += '\n\n' 
    495561            banner += """\ 
    496 Call `run_module` with no arguments to execute the implied or explicit 
    497 module. You can safely manipulate the target sys.path and sys.argv before 
    498 calling `run_module` by updating `target_argv` and `pthextend` in place. 
    499 `minfos` is a list of tuples describing any module files you listed in 
    500 the discovery path.""" 
     562handy locals() are: 
     563    The function run_module (runs the discovered module if there was one) 
     564    The variables target_argv, pthextend 
     565 
     566Update target_argv *in place* before calling run_module if you want to tweak 
     567the sys.argv the module sees.""" 
     568 
    501569            import code 
    502570            code.interact(banner=banner, local=locals()) 
     
    616684 
    617685if __name__=='__main__': 
     686    #sys.exit(run_top_minfo()) 
    618687    sys.exit(runex()) 
    619688