;ς
ΞΡAHc           @   sl   d  Z  d k l Z d e i d Z e i Z d g Z d k Z d k	 Z	 d k
 l Z d f  d     YZ d S(   sh   Mimic C structs with lots of extra functionality.

$Id: ipstruct.py 1950 2006-11-28 19:15:35Z vivainio $(   s   Releases   %s <%s>s   Fernandos   StructN(   s
   list2dict2c           B   s.  t  Z d  Z d i   Z e d  Z d   Z d   Z d   Z	 d   Z
 d   Z d   Z d	   Z d
   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z d   Z e d  Z e e d  Z d   Z d   Z d   Z d   Z e d  Z e d  Z e d  Z  e! d  Z" RS(   s	  Class to mimic C structs but also provide convenient dictionary-like
    functionality.

    Instances can be initialized with a dictionary, a list of key=value pairs
    or both. If both are present, the dictionary must come first.

    Because Python classes provide direct assignment to their members, it's
    easy to overwrite normal methods (S.copy = 1 would destroy access to
    S.copy()). For this reason, all builtin method names are protected and
    can't be assigned to. An attempt to do s.copy=1 or s['copy']=1 will raise
    a KeyError exception. If you really want to, you can bypass this
    protection by directly assigning to __dict__: s.__dict__['copy']=1 will
    still work. Doing this will break functionality, though. As in most of
    Python, namespace protection is weakly enforced, so feel free to shoot
    yourself if you really want to.

    Note that this class uses more memory and is *much* slower than a regular
    dictionary, so be careful in situations where memory or performance are
    critical. But for day to day use it should behave fine. It is particularly
    convenient for storing configuration data in programs.

    +,+=,- and -= are implemented. +/+= do merges (non-destructive updates),
    -/-= remove keys from the original. See the method descripitions.

    This class allows a quick access syntax: both s.key and s['key'] are
    valid.  This syntax has a limitation: each 'key' has to be explicitly
    accessed by its original name. The normal s.key syntax doesn't provide
    access to the keys via variables whose values evaluate to the desired
    keys. An example should clarify this:

    Define a dictionary and initialize both with dict and k=v pairs:
    >>> d={'a':1,'b':2}
    >>> s=Struct(d,hi=10,ho=20)
    The return of __repr__ can be used to create a new instance:
    >>> s
    Struct({'ho': 20, 'b': 2, 'hi': 10, 'a': 1})
    __str__ (called by print) shows it's not quite a regular dictionary:
    >>> print s
    Struct {a: 1, b: 2, hi: 10, ho: 20}
    Access by explicitly named key with dot notation:
    >>> s.a
    1
    Or like a dictionary:
    >>> s['a']
    1
    If you want a variable to hold the key value, only dictionary access works:
    >>> key='hi'
    >>> s.key
    Traceback (most recent call last):
      File "<stdin>", line 1, in ?
    AttributeError: Struct instance has no attribute 'key'
    >>> s[key]
    10

    Another limitation of the s.key syntax (and Struct(key=val)
    initialization): keys can't be numbers. But numeric keys can be used and
    accessed using the dictionary syntax. Again, an example:

    This doesn't work:
    >>> s=Struct(4='hi')
    SyntaxError: keyword can't be an expression
    But this does:
    >>> s=Struct()
    >>> s[4]='hi'
    >>> s
    Struct({4: 'hi'})
    >>> s[4]
    'hi'
    st   copy dict dictcopy get has_attr has_key items keys merge popitem setdefault update values __make_dict __dict_invert c         K   s¦   t  |  i d <| t j o
 h  } n t | t  o | i   } n+ | o t |  t i	 j	 o t
 d  n | i |  x$ | i   D] \ } } | |  | <q Wd S(   sτ   Initialize with a dictionary, another Struct, or by giving
        explicitly the list of attributes.

        Both can be used, but the dictionary must come first:
        Struct(dict), Struct(k1=v1,k2=v2) or Struct(dict,k1=v1,k2=v2).
        s
   __allownews.   Initialize with a dictionary or key=val pairs.N(   s   Trues   selfs   __dict__s   dicts   Nones
   isinstances   Structs   types   typess   DictTypes	   TypeErrors   updates   kws   itemss   ks   v(   s   selfs   dicts   kws   vs   k(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __init__f   s     
 c         C   sg   | t i j o t d | d  n |  d o | |  i j o t d |   n | |  i | <d S(   s+   Used when struct[key] = val calls are made.s   Key s$    is a protected key of class Struct.s
   __allownewsd   Can't create unknown attribute %s - Check for typos, or use allow_new_attr to create new attributes!N(   s   keys   Structs   _Struct__protecteds   KeyErrors   selfs   __dict__s   value(   s   selfs   keys   value(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __setitem__|   s     c         C   s   |  i | |  d S(   s*   Used when struct.key = val calls are made.N(   s   selfs   __setitem__s   keys   value(   s   selfs   keys   value(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __setattr__   s     c         C   s   d t  i |  i  d Sd S(   s   Gets called by print.s   Struct(s   )N(   s   pprints   pformats   selfs   __dict__(   s   self(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __str__   s     c         C   s   |  i   Sd S(   s]   Gets called by repr.
        
        A Struct can be recreated with S_new=eval(repr(S_old)).N(   s   selfs   __str__(   s   self(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __repr__   s     c         C   s   |  i | Sd S(   s   Allows struct[key] access.N(   s   selfs   __dict__s   key(   s   selfs   key(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __getitem__   s     c         C   s   |  i i |  Sd S(   s    Allows use of the 'in' operator.N(   s   selfs   __dict__s   has_keys   key(   s   selfs   key(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __contains__   s     c         C   s   |  i |  |  Sd S(   s'   S += S2 is a shorthand for S.merge(S2).N(   s   selfs   merges   other(   s   selfs   other(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __iadd__   s     c         C   s!   |  i   } | i |  | Sd S(   s0   S + S2 -> New Struct made form S and S.merge(S2)N(   s   selfs   copys   Souts   merges   other(   s   selfs   others   Sout(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __add__£   s     c         C   s   |  i   } | | 8} | Sd S(   sR   Return S1-S2, where all keys in S2 have been deleted (if present)
        from S1.N(   s   selfs   copys   Souts   other(   s   selfs   others   Sout(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __sub__©   s     
c         C   s9   x2 | i   D]$ } |  i |  o |  i | =q q Wd S(   s^   Do in place S = S - S2, meaning all keys in S2 have been deleted
        (if present) from S1.N(   s   others   keyss   ks   selfs   has_keys   __dict__(   s   selfs   others   k(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __isub__°   s
      c         K   s}   | t j o
 h  } nG t |  t i j o
 | } n' t | t  o | i } n
 t	 d  | o | i |  n | Sd S(   s>   Helper function for update and merge. Return a dict from data.s.   Update with a dict, a Struct or key=val pairs.N(   s   __loc_data__s   Nones   dicts   types   typess   DictTypes
   isinstances   Structs   __dict__s	   TypeErrors   kws   update(   s   selfs   __loc_data__s   kws   dict(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __make_dictΈ   s     

	c         C   sl   h  } x[ | i   D]M \ } } t |  t i j o | i   } n x | D] } | | | <qL Wq W| Sd S(   s°   Helper function for merge. Takes a dictionary whose values are
        lists and returns a dict. with the elements of each list as keys and
        the original keys as values.N(
   s   outdicts   dicts   itemss   ks   lsts   types   typess
   StringTypes   splits   entry(   s   selfs   dicts   outdicts   lsts   entrys   k(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   __dict_invertΗ   s       c         C   s   |  i i   d S(   s   Clear all attributes.N(   s   selfs   __dict__s   clear(   s   self(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   clearΤ   s     c         C   s   t  |  i i    Sd S(   s$   Return a (shallow) copy of a Struct.N(   s   Structs   selfs   __dict__s   copy(   s   self(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   copyΨ   s     c         C   s   |  i Sd S(   s   Return the Struct's dictionary.N(   s   selfs   __dict__(   s   self(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   dictά   s     c         C   s   |  i i   Sd S(   s3   Return a (shallow) copy of the Struct's dictionary.N(   s   selfs   __dict__s   copy(   s   self(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   dictcopyΰ   s     c         C   s   |  i i   Sd S(   sw   S.popitem() -> (k, v), remove and return some (key, value) pair as
        a 2-tuple; but raise KeyError if S is empty.N(   s   selfs   __dict__s   popitem(   s   self(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   popitemδ   s     c         K   s@   t  i |  | |  } x$ | i   D] \ } } | |  | <q" Wd S(   s₯   Update (merge) with data from another Struct or from a dictionary.
        Optionally, one or more key=value pairs can be given at the end for
        direct update.N(	   s   Structs   _Struct__make_dicts   selfs   __loc_data__s   kws   newdicts   itemss   ks   v(   s   selfs   __loc_data__s   kws   newdicts   vs   k(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   updateι   s
      c         K   sM  t  i |  | |  } d   } d   } d   } d   }	 d   } t |  i   d | } | o | i   } xm d | f d | f d	 | f d
 |	 f d | f g D]8 \ } } | | i   j o | | | | <| | =q‘ q‘ W| i t  i |  |   n xL | D]D }
 |
 |  j o | |
 |  |
 <q| |
 |  |
 | |
  |  |
 <qWd S(   s³	  S.merge(data,conflict,k=v1,k=v2,...) -> merge data and k=v into S.

        This is similar to update(), but much more flexible.  First, a dict is
        made from data+key=value pairs. When merging this dict with the Struct
        S, the optional dictionary 'conflict' is used to decide what to do.

        If conflict is not given, the default behavior is to preserve any keys
        with their current value (the opposite of the update method's
        behavior).

        conflict is a dictionary of binary functions which will be used to
        solve key conflicts. It must have the following structure:

          conflict == { fn1 : [Skey1,Skey2,...], fn2 : [Skey3], etc }

        Values must be lists or whitespace separated strings which are
        automatically converted to lists of strings by calling string.split().

        Each key of conflict is a function which defines a policy for
        resolving conflicts when merging with the input data. Each fn must be
        a binary function which returns the desired outcome for a key
        conflict. These functions will be called as fn(old,new).

        An example is probably in order. Suppose you are merging the struct S
        with a dict D and the following conflict policy dict:

            S.merge(D,{fn1:['a','b',4], fn2:'key_c key_d'})

        If the key 'a' is found in both S and D, the merge method will call:

            S['a'] = fn1(S['a'],D['a'])

        As a convenience, merge() provides five (the most commonly needed)
        pre-defined policies: preserve, update, add, add_flip and add_s. The
        easiest explanation is their implementation:

          preserve = lambda old,new: old
          update   = lambda old,new: new
          add      = lambda old,new: old + new
          add_flip = lambda old,new: new + old  # note change of order!
          add_s    = lambda old,new: old + ' ' + new  # only works for strings!

        You can use those four words (as strings) as keys in conflict instead
        of defining them as functions, and the merge method will substitute
        the appropriate functions for you. That is, the call

          S.merge(D,{'preserve':'a b c','add':[4,5,'d'],my_function:[6]})

        will automatically substitute the functions preserve and add for the
        names 'preserve' and 'add' before making any function calls.

        For more complicated conflict resolution policies, you still need to
        construct your own functions. c         C   s   |  S(   N(   s   old(   s   olds   new(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   <lambda>1  s    c         C   s   | S(   N(   s   new(   s   olds   new(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   <lambda>2  s    c         C   s   |  | S(   N(   s   olds   new(   s   olds   new(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   <lambda>3  s    c         C   s   | |  S(   N(   s   news   old(   s   olds   new(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   <lambda>4  s    c         C   s   |  d | S(   Ns    (   s   olds   new(   s   olds   new(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   <lambda>5  s    s   defaults   preserves   updates   adds   add_flips   add_sN(   s   Structs   _Struct__make_dicts   selfs   __loc_data__s   kws	   data_dicts   preserves   updates   adds   add_flips   add_ss
   list2dict2s   keyss   conflict_solves   _Struct__conflict_solves   copys   inv_conflict_solve_users   names   funcs   _Struct__dict_inverts   key(   s   selfs   __loc_data__s   _Struct__conflict_solves   kws   preserves   conflict_solves   names   add_ss   updates   add_flips   keys   adds   funcs   inv_conflict_solve_users	   data_dict(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   mergeφ   s*    5 					4  c         C   s   |  i i |  Sd S(   s!   Like has_key() dictionary method.N(   s   selfs   __dict__s   has_keys   key(   s   selfs   key(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   has_keyN  s     c         C   s   |  i i |  Sd S(   sΧ   hasattr function available as a method.

        Implemented like has_key, to make sure that all available keys in the
        internal dictionary of the Struct appear also as attributes (even
        numeric keys).N(   s   selfs   __dict__s   has_keys   key(   s   selfs   key(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   hasattrR  s     c         C   s   |  i i   Sd S(   s`   Return the items in the Struct's dictionary, in the same format
        as a call to {}.items().N(   s   selfs   __dict__s   items(   s   self(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   itemsZ  s     c         C   s   |  i i   Sd S(   s^   Return the keys in the Struct's dictionary, in the same format
        as a call to {}.keys().N(   s   selfs   __dict__s   keys(   s   self(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   keys_  s     c         C   sI   | o |  i i   Sn- g  } x | D] } | i |  |  q& W| Sd S(   s@  Return the values in the Struct's dictionary, in the same format
        as a call to {}.values().

        Can be called with an optional argument keys, which must be a list or
        tuple of keys. In this case it returns only the values corresponding
        to those keys (allowing a form of 'slicing' for Structs).N(   s   keyss   selfs   __dict__s   valuess   rets   ks   append(   s   selfs   keyss   ks   ret(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   valuesd  s      c         C   s*   y |  | SWn t j
 o | Sn Xd S(   sB   S.get(k[,d]) -> S[k] if S.has_key(k), else d.  d defaults to None.N(   s   selfs   attrs   KeyErrors   val(   s   selfs   attrs   val(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   gets  s
     c         C   s3   |  i |  o | |  | <n |  i | |  Sd S(   sF   S.setdefault(k[,d]) -> S.get(k,d), also set S[k]=d if not S.has_key(k)N(   s   selfs   has_keys   attrs   vals   get(   s   selfs   attrs   val(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys
   setdefaultz  s     c         C   s   | |  d <d S(   sΟ    Set whether new attributes can be created inside struct
        
        This can be used to catch typos by verifying that the attribute user tries to 
        change already exists in this Struct.
        s
   __allownewN(   s   allows   self(   s   selfs   allow(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   allow_new_attr  s     (#   s   __name__s
   __module__s   __doc__s   splits   _Struct__protecteds   Nones   __init__s   __setitem__s   __setattr__s   __str__s   __repr__s   __getitem__s   __contains__s   __iadd__s   __add__s   __sub__s   __isub__s   _Struct__make_dicts   _Struct__dict_inverts   clears   copys   dicts   dictcopys   popitems   updates   merges   has_keys   hasattrs   itemss   keyss   valuess   gets
   setdefaults   Trues   allow_new_attr(    (    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   Struct   s<   E 																	X				(   s   __doc__s   IPythons   Releases   authorss
   __author__s   licenses   __license__s   __all__s   typess   pprints   IPython.genutilss
   list2dict2s   Struct(   s   __license__s   __all__s   pprints
   __author__s   Releases
   list2dict2s   typess   Struct(    (    s@   /nyx/web/d/b/dbachman/work/src/ipython-0.8.4/IPython/ipstruct.pys   ?   s   					