Changeset 181

Show
Ignore:
Timestamp:
25.05.2008 14:48:57 (8 months ago)
Author:
poillubo
Message:

* is_strict_subclass now works correctly with tuple of classes
* added some misc functions needed bu the (future) config generators
* added some docstrings in the misc module
* added unit tests for the misc modules (we now have 190 unit tests)

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/pycawm/misc.py

    r166 r181  
    2323    raise ImportError('misc module needs at least Python 2.5!') 
    2424 
     25from types import ClassType, TypeType, MethodType, FunctionType 
     26 
    2527import focuses 
    2628import placements 
     
    3234    if klass is base: 
    3335        return False 
     36    if type(base) is tuple: 
     37        # include neither the klass in the tuple, nor the non-class objects 
     38        # TypeType is the type of new-style classes 
     39        # ClassType is the type of old-style classes 
     40        base = tuple([cls for cls in base 
     41                      if (type(cls) in (TypeType, ClassType) and 
     42                          cls is not klass)]) 
    3443    try: 
    3544        return issubclass(klass, base) 
    3645    except TypeError: 
    3746        return False 
     47 
     48def get_func_object(fun): 
     49    """Get the function object from a method or function (designed to be hooked 
     50    or not). 
     51    Return None if the argument is not correct.""" 
     52    if type(fun) in (MethodType, FunctionType): 
     53        # is fun designed to be hooked? 
     54        if hasattr(fun, '_wrapped_fun'): 
     55            # remove the hook wrapper 
     56            fun = fun._wrapped_fun 
     57        # normal method? 
     58        elif type(fun) is MethodType: 
     59            fun = fun.im_func 
     60        # do not change the "fun" for normal functions 
     61        return fun 
     62    return None 
     63 
     64def get_args_names(fun): 
     65    """Get all the arguments names from a method or function (designed to be 
     66    hooked or not).""" 
     67    fun = get_func_object(fun) 
     68    if fun is None: 
     69        return None 
     70 
     71    co = fun.func_code 
     72    arg_count = co.co_argcount 
     73    # code object has *args? 
     74    if (co.co_flags & 4) != 0: 
     75        arg_count += 1 
     76    # code object has **kwargs? 
     77    if (co.co_flags & 8) != 0: 
     78        arg_count += 1 
     79    return co.co_varnames[:arg_count] 
     80 
     81def get_default_arg(fun, name): 
     82    """Find the default parameter from an argument name. 
     83    The argument name belongs to a method or function (designed to be hooked or 
     84    not). 
     85    Return None if an error occured of if no default parameter was found.""" 
     86    fun = get_func_object(fun) 
     87    if fun is None: 
     88        return None 
     89 
     90    co = fun.func_code 
     91    if name not in co.co_varnames: 
     92        return None 
     93 
     94    defaults = fun.func_defaults 
     95    indice = list(co.co_varnames).index(name) 
     96    offset = co.co_argcount - len(defaults) 
     97    # arg has a default value? 
     98    if indice >= offset: 
     99        return defaults[indice - offset] 
     100    return None 
    38101 
    39102def is_class_valid(klass, base): 
     
    45108 
    46109def find_default_focuses(): 
     110    """Find all the focus classes in the "focuses" module.""" 
    47111    gen_focuses = (focuses.__dict__.get(focus_name) 
    48112                   for focus_name in dir(focuses)) 
     
    53117 
    54118def find_default_placements(): 
     119    """Find all the placement classes in the "placements" module.""" 
    55120    gen_placements = (placements.__dict__.get(placement_name) 
    56121                      for placement_name in dir(placements)) 
     
    62127 
    63128def find_default_plugins(): 
     129    """Find all the plugin classes in the "plugins" module.""" 
    64130    gen_plugs = (plugins.__dict__.get(plugin_name) 
    65131                 for plugin_name in dir(plugins))