
    +                        d Z ddlmZ ddlmZ ddlmZ ddlZddlZddlmZ ddl	Z	 G d de
      Z G d	 d
e      Z G d de      Z G d de      Z G d de      Z G d de      Zd Zd Zd Zd Zd Z G d de      Z G d de      Zy)a  A module for extracting properties from Python dicts.

A property is a string that represents a value in a JSON-serializable
dict. For example, "x.y" matches 1 in {'x': {'y': 1, 'z': 2}, 'y': [1,
2, 3]}.

See PropertySelector and PropertyGetter's docstrings for example
usage.

The grammar for properties is as follows:

    path
        ::= primary
        ::= primary '.' path

    primary
        ::= attribute
        ::= attribute '[' ']'
        ::= attribute '[' index ']'

    index
        ::= Any non-negative integer. Integers beginning with 0 are
            interpreted as base-10.

    attribute
        := Any non-empty sequence of characters; The special characters
           '[', ']', and '.' may appear if they are preceded by '\'.
           The literal '\' may appear if it is itself preceded by a '\'.

There are three operators in the language of properties:

    '.': Attribute access which allows one to select the key of
        a dict.

    '[]': List operator which allows one to apply the rest of the
        property to each element of a list.

    '[INDEX]': List access which allows one to select an element of
        a list.
    )absolute_import)division)unicode_literalsN)	tokenizerc                       e Zd ZdZy)Errorz0Base class for exceptions raised by this module.N__name__
__module____qualname____doc__     7lib/googlecloudsdk/api_lib/compute/property_selector.pyr   r   B   s    8r   r   c                       e Zd ZdZy)IllegalPropertyz7Raised for properties that are syntactically incorrect.Nr	   r   r   r   r   r   F   s    ?r   r   c                       e Zd ZdZy)ConflictingPropertieszRaised when a property conflicts with another.

  Examples of conflicting properties:

      - "a.b" and "a[0].b"
      - "a[0].b" and "a[].b"
  Nr	   r   r   r   r   r   J   s    r   r   c                       e Zd Zy)_KeyNr
   r   r   r   r   r   r   r   T       r   r   c                       e Zd Zy)_IndexNr   r   r   r   r   r   X   r   r   r   c                       e Zd Zd Zd Zy)_Slicec                 0    t        |       t        |      k(  S )N)type)selfothers     r   __eq__z_Slice.__eq__^   s    :e$$r   c                      y)Nr   r   )r   s    r   __hash__z_Slice.__hash__a   s    r   N)r
   r   r   r!   r#   r   r   r   r   r   \   s    %r   r   c                    t        j                  | g d      }|D cg c]  }|s|	 }}|st        dj                  |             g }|r&t	        |d   t         j
                        st        dj                  |             |j                  t        |d                |dd }|s	 |S t	        |d   t         j                        st        dj                  |             t	        |d   t         j                        r|d   dk(  rt        |      dk  rt        dj                  |             |dd }t	        |d   t         j                        r'|d   dk(  r|j                  t                      |dd }nt	        |d   t         j
                        ri|d   j                         rVt        |      dk\  rHt	        |d   t         j                        r+|d   dk(  r#|j                  t        |d                |dd }nt        dj                  |             |s	 |S t        |      dkD  r,t	        |d   t         j                        r|d   d	k(  r|dd }t        dj                  |             |S c c}w )
z2Parses the given tokens that represent a property.)[].zillegal property: {0}r      Nr%      r&   r'   )r   Tokenizer   format
isinstanceLiteralappendr   	Separatorlenr   isdigitr   )proptokenstokenress       r   _Parser6   e   sR   dO4&%/veEv&/	
188>
??
#fQi!2!233::4@AAJJtF1IABZF V 
*S fQi!4!453::4@AA&)Y001fQi36F	Vq5<<TBCCabzf VAY	 3 3
4
)s


68 vay)"3"341IK1vay)"5"561I

6&)$% 5<<TBCC  
* 	Fa6!9i112q	Sabzf3::4@AA	*{ 0s
   I4I4c           	         | y|s| S t        |d   t              r1t        | t              r!t        | j	                  |d         |dd       S t        |d   t
              r6t        | t              r&|d   t        |       k  rt        | |d      |dd       S t        |d   t              r-t        | t              r| D cg c]  }t        ||dd        c}S yc c}w )zGrabs a property from obj.Nr   r(   )	r,   r   dict_GetPropertygetr   listr0   r   )obj
componentsitems      r   r9   r9      s    [J:a=$'3
1.
12??:a=&)jd.C1C JqM*JqrN;;:a=&)3;>?34Lz!"~.3??  @s   <Cc                 Z   t        | t              rYt        j                  t	        | j                                     }t        j                  |      D ]  \  }}t        |      ||<    |S t        | t              r| D cg c]  }t        |       c}S t        j                  |       S c c}w )z@Recursively converts a JSON-serializable dict to an OrderedDict.)r,   r8   collectionsOrderedDictsorteditemssix	iteritems_DictToOrderedDictr;   copydeepcopy)r<   new_objkeyvaluer>   s        r   rF   rF      s    T%%fSYY[&9:GmmG,
U'.gcl -N#t145t$55== 6s   >B(c                 $   t        |      st        |       S t        j                         }|D ].  }|s|d   |dd }}||v r||   j	                  |       )|g||<   0 t        | t              rt        j                         }t        j                  |      D ]P  \  }}|| v st        |      r!t        | |   |      }	|	(|	|t        |      <   7t        | |         |t        |      <   R |r|S yt        | t              r|s| S t        g       }
|D ]3  }t        |t              s|t        |       k  s#|
j                  |       5 |j!                  t#                     }|r@g }	t%        |       D ]/  \  }}||
v r	||   |z   }n|}|	j	                  t        ||             1 nJdgt        |       z  }	|
D ]6  }||   }t        |      rt        | |   |      |	|<   &t        | |         |	|<   8 |	D cg c]  }||	 c}r|	S yt        |       S c c}w )zERetains the data specified by properties in a JSON-serializable dict.r   r(   N)allrF   r@   rA   r.   r,   r8   rD   rE   _Filterstrr;   setr   r0   addr:   r   	enumerate)r<   
propertieshead_to_tailr2   headtailfiltered_objrJ   rK   r5   indices
slice_tailir>   indexs                  r   rN   rN      s    
Zc""((*,d7DHDd		T!!$'"VT  T**,LmmL1
U	 u:C%(#_%(LS"#5c#h#?,s3x
  2 #tj"gG	C	 S3s8^C  !!&(+Jcs^'!T<#A3*!*

74,- $ FSXc%!%(
z?s5z:6#e*)#e*5#e*  1 01j c"" 2s   0H8Hc                 n   t        |t              rXt        | d   t              rE|j                  | d         }|yt	        |       dk(  r ||      || d   <   yt        | dd ||       yt        |t              r[t        | d   t              rH| d   }|t	        |      dz
  kD  ryt	        |       dk(  r |||         ||<   yt        | dd |||          yt        |t              rRt        | d   t              r>t        |      D ]/  \  }}t	        |       dk(  r ||      ||<    t        | dd ||       1 yyy)a  Applies the given function to the property pointed to by components.

  For example:

      obj = {'x': {'y': 1, 'z': 2}, 'y': [1, 2, 3]}
      _ApplyTransformation(_Parse('x.y'), lambda x: x* 2, obj)

  results in obj becoming:

      {'x': {'y': 2, 'z': 2}, 'y': [1, 2, 3]}

  Args:
    components: A parsed property.
    func: The function to apply.
    obj: A JSON-serializable dict to apply the function to.
  r   Nr(   )
r,   r8   r   r:   r0   _ApplyTransformationr;   r   r   rR   )r=   funcr<   validxrZ   s         r   r]   r]     s(   " Tz*Q->
''*Q-
 C
{
:!9c*Q-:ab>45#tJqM6!B
Q-C
SX\
:!c#hc#h:ab>4S:#tJqM6!BC.3	ZA	cAZ^T37	 ! "Cr   c                       e Zd ZdZddZd Zy)PropertySelectoraK  Extracts and/or transforms values in JSON-serializable dicts.

  For example:

      selector = PropertySelector(
          properties=['x.y', 'y[0]'],
          transformations=[
              ('x.y', lambda x: x + 5),
              ('y[]', lambda x: x * 5),
      ])
      selector.SelectProperties(
          {'x': {'y': 1, 'z': 2}, 'y': [1, 2, 3]})

  returns:

      collections.OrderedDict([
          ('x', collections.OrderedDict([('y', 6)])),
          ('y', [5])
      ])

  Items are extracted in the order requested. Transformations are applied
  in the order they appear.
  Nc                     |r|D cg c]  }t        |       c}| _        nd| _        |r&|D cg c]  \  }}t        |      |f c}}| _        nd| _        || _        || _        yc c}w c c}}w )z9Creates a new PropertySelector with the given properties.N)r6   _compiled_properties_compiled_transformationsrS   transformations)r   rS   rf   pr^   s        r   __init__zPropertySelector.__init___  sx    6@"Aj6!9j"Ad"&d+:(<+:46!9d
?(<d$ (,d$ DO*D #B
(<s
   A'A,c                     | j                   r-t        || j                         xs t        j                         }nt	        |      }| j
                  r!| j
                  D ]  \  }}t        |||        |S )z=An OrderedDict resulting from filtering and transforming obj.)rd   rN   r@   rA   rF   re   r]   )r   r<   r5   compiled_propertyr^   s        r   ApplyzPropertySelector.Applyo  si      C223P{7N7N7Pcs#c%%%)%C%C
!
T.c: &D Jr   )NN)r
   r   r   r   rh   rk   r   r   r   rb   rb   F  s    0+ r   rb   c                       e Zd ZdZd Zd Zy)PropertyGetterzExtracts a single field from JSON-serializable dicts.

  For example:

      getter = PropertyGetter('x.y')
      getter.Get({'x': {'y': 1, 'z': 2}, 'y': [1, 2, 3]})

  returns:

      1
  c                 $    t        |      | _        y)z5Creates a new PropertyGetter with the given property.N)r6   _compiled_property)r   rg   s     r   rh   zPropertyGetter.__init__  s    $QiDr   c                 T    t        j                  t        || j                              S )zCReturns the property in obj or None if the property does not exist.)rG   rH   r9   ro   )r   r<   s     r   GetzPropertyGetter.Get  s    ==c4+B+BCDDr   N)r
   r   r   r   rh   rq   r   r   r   rm   rm   }  s    
(Er   rm   )r   
__future__r   r   r   r@   rG   googlecloudsdk.core.utilr   rD   	Exceptionr   r   r   rO   r   intr   objectr   r6   r9   rF   rN   r]   rb   rm   r   r   r   <module>rw      s   'R '  '   . 
9I 9@e @E 3 S V @F0
IX*8Z4v 4nEV Er   