Changeset 755

Show
Ignore:
Timestamp:
07/19/07 09:22:27 (1 year ago)
Author:
robin
Message:

--

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • pyrun/trunk/pyrun.py

    r754 r755  
    33from os.path import abspath, normpath, join, expanduser, expandvars, dirname 
    44from os.path import basename, isabs, exists, isfile, isdir 
    5 from runpy import run_module 
    65 
    76def exc_string(einfo=None): 
     
    243242 
    244243 
    245 def run_magic_syspath(argv=None, run_last_module=True): 
    246     """Run a module using a magicaly extended sys.path. 
    247  
    248     Discovers additional package paths by searching under directories listed as 
    249     non option arguments. Discovery is egg aware: it takes care to include only 
    250     the *best* version of each egg and only those eggs that match the python 
    251     interpreters version. 
    252  
    253     If the last argument names a legitemate python module then it will be 
    254     executed using the `runpy.run_module` helper from the standard lib. This 
    255     feature can be disabled by passing a false value for `run_last_module`. 
    256  
    257     If any `interior` argument identifies a python module then its containing 
    258     directory is added to the path extension. 
     244def discover_path(offset, *args): 
     245 
     246    """Discover a python path. 
     247 
     248    Discovers additional package paths by considering each item in args. args 
     249    should typically be a sys.argv style argument list. Discovery terminates 
     250    with the first argument that looks like an option. "Looks like an option" 
     251    means is exactly ``--`` or startswith either '--' or '-'. The non option 
     252    arguments should identify either: directories under which you want to 
     253    discover package paths OR legitemate python module files. 
     254 
     255    The results are returned as a 3 element tuple. The first element is the 
     256    discovered path and the second is a list containing the result of 
     257    `path_moduleinfo` for any explict references to python module files and 
     258    the last is the index of the first non option argument with your supplied 
     259    offset added to it.: 
     260 
     261        ``(pathextension, moduleinfos, inonoption)`` 
     262 
     263    See the implementation of `discover_and_run` for a typical usage example. 
     264 
     265    Note that the path implied by an explicit module reference is included in 
     266    pathextension. The moduleinfos element of the return is a convenience to 
     267    asist cases where you want to imediately `run` one or more of the 
     268    discovered modules. 
     269 
     270    Discovery is egg aware: it takes care to include only the *best* version of 
     271    each egg and only those eggs that match the python interpreters version. 
    259272 
    260273    The extension path discovered by this api consists of unique paths in order 
     
    265278    used by pkg_resources.py from the setuptools project. 
    266279 
    267  
    268     :Returns: 
    269         The discovered extension path. But note that if `run_last_module` is 
    270         true it resonably likely that this function will *not return*. 
    271  
    272     TODO: examples 
    273  
    274     """ 
    275  
    276     argv = argv or sys.argv[:] 
    277  
     280    """ 
     281 
     282    minfos = [] 
    278283    pthextend = [] 
    279284    searchpaths = [] 
     
    281286 
    282287    minfo = None 
    283     for ia, a in enumerate_argv_args(argv, 1): 
     288    for ia, a in enumerate_argv_args(args, offset): 
    284289        if a is None: 
    285290            continue 
     
    291296                continue 
    292297 
     298            minfos.append(minfo) 
    293299            a = minfo[0] 
    294300            if a not in pthset: 
    295301                pthextend.append(a) 
    296302                pthset.add(a) 
    297  
    298303        else: 
    299304            searchpaths.append(a) 
     
    304309    pthextend.extend(newpaths) 
    305310 
    306     if run_last_module and minfo: 
     311    return pthextend, minfos, ia 
     312 
     313 
     314def discover_and_run(argv=None, run_module=True): 
     315    """Discover package paths and run the last module listed in argv. 
     316 
     317    Uses `discover_path` to perform the path discovery and identify any 
     318    module files listed on the command line. 
     319 
     320    Uses runpy.run_module to run the module as though it was '__main__'. 
     321 
     322    """ 
     323    if run_module is True: 
     324        from runpy import run_module 
     325 
     326    argv = argv or sys.argv[:] 
     327 
     328    pthextend, minfos, ia = discover_path(1, *argv) 
     329    if run_module and minfos: 
    307330        sys.path[0:0] = pthextend[:] 
    308331        sys.argv[:] = [] 
    309         sys.argv.append(minfo[1]) 
     332        sys.argv.append(minfos[0][1]) 
    310333        sys.argv.extend(argv[ia:]) 
    311334        return run_module(sys.argv[0], run_name='__main__', alter_sys=True) 
    312  
    313     else: 
    314         return pthextend 
    315  
    316  
    317 if __name__=='__main__': 
     335    return pthextend, minfos, ia 
     336 
     337 
     338def run(argv=None): 
     339    """setuptools compatible entry point - basic features only. 
     340 
     341    Command line help is not provided by this entry point and all 
     342    options are expected to be for the target module. 
     343    """ 
     344 
    318345    try: 
    319         rval = run_magic_syspath(
    320         if rval and isinstance(rval, list): 
    321             print os.pathsep.join(rval) 
     346        rval = discover_and_run(argv
     347        if not isinstance(rval, int): 
     348            rval = 0 
    322349    except SystemExit: 
    323350        raise 
    324351    except: 
     352        rval = -1 
    325353        msg = exc_string() 
    326354        print msg 
    327         sys.exit(-1) 
     355    return rval 
     356 
     357def runex(argv=None): 
     358    return run(argv) 
     359 
     360if __name__=='__main__': 
     361    sys.exit(run()) 
     362 
  • pyrun/trunk/setup.py

    r754 r755  
    1919        info.setdefault(k,[]).append(v.strip()) 
    2020    return info 
    21   
     21 
    2222try: 
    2323    from setuptools import setup 
     24    HAVE_SETUPTOOLS = True 
    2425except ImportError: 
     26    HAVE_SETUPTOOLS = False 
    2527    from distutils.core import setup 
    2628 
     
    5456update_docs('*.rst', ignore=['pkg-info.rst']) 
    5557 
    56 setup
     58setupkw=dict
    5759    name=PKG_INFO['Name'][0], 
    5860    version=PKG_INFO['Version'][0], 
     
    6769    package_dir = {'':'.'}, 
    6870    classifiers=PKG_INFO['Classifiers'], 
    69     # Force unzip because pyrun is used to *discover* eggs and use them without 
    70     # installing, or in cases where the setuptools easy-install.pth machinery 
    71     # has been borked. To pyrun a python egg is no more than a distribution 
    72     # format. 
    73     zip_safe=False  
    7471) 
     72if HAVE_SETUPTOOLS: 
     73    setupkw.update( 
     74        entry_points = { 
     75            'console_scripts': [ 
     76                'pyrun = pyrun:run', 
     77                'pyrunex = pyrun:runex' 
     78                ] 
     79            }, 
     80        # Force unzip because pyrun is used to *discover* eggs and use them without 
     81        # installing, or in cases where the setuptools easy-install.pth machinery 
     82        # has been borked. To pyrun a python egg is no more than a distribution 
     83        # format. 
     84        zip_safe=False 
     85    ) 
     86setup(**setupkw) 
    7587