
    +                        S r SSKJr  SSKJr  SSKJr  SSKrSSKrSSKJr  SSK	r	 " S S\
5      r " S	 S
\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      rS rS rS rS rS r " S S\5      r " S S\5      rg)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                       \ rS rSrSrSrg)ErrorB   z0Base class for exceptions raised by this module. N__name__
__module____qualname____firstlineno____doc____static_attributes__r
       7lib/googlecloudsdk/api_lib/compute/property_selector.pyr   r   B   s    8r   r   c                       \ rS rSrSrSrg)IllegalPropertyF   z7Raised for properties that are syntactically incorrect.r
   Nr   r
   r   r   r   r   F   s    ?r   r   c                       \ rS rSrSrSrg)ConflictingPropertiesJ   zRaised when a property conflicts with another.

Examples of conflicting properties:

    - "a.b" and "a[0].b"
    - "a[0].b" and "a[].b"
r
   Nr   r
   r   r   r   r   J   s    r   r   c                       \ rS rSrSrg)_KeyT   r
   Nr   r   r   r   r   r
   r   r   r   r   T       r   r   c                       \ rS rSrSrg)_IndexX   r
   Nr   r
   r   r   r    r    X   r   r   r    c                        \ rS rSrS rS rSrg)_Slice\   c                 0    [        U 5      [        U5      :H  $ )N)type)selfothers     r   __eq___Slice.__eq__^   s    :e$$r   c                     g)Nr   r
   )r'   s    r   __hash___Slice.__hash__a   s    r   r
   N)r   r   r   r   r)   r,   r   r
   r   r   r#   r#   \   s    %r   r#   c                    [         R                  " U / SQ5      nU Vs/ s H  o"(       d  M  UPM     nnU(       d  [        SR                  U 5      5      e/ nU(       Ga`  [	        US   [         R
                  5      (       d  [        SR                  U 5      5      eUR                  [        US   5      5        USS nU(       d   U$ [	        US   [         R                  5      (       d  [        SR                  U 5      5      e[	        US   [         R                  5      (       Ga3  US   S:X  Ga)  [        U5      S:  a  [        SR                  U 5      5      eUSS n[	        US   [         R                  5      (       a(  US   S:X  a  UR                  [        5       5        USS nO[	        US   [         R
                  5      (       au  US   R                  5       (       a]  [        U5      S:  aN  [	        US   [         R                  5      (       a,  US   S:X  a#  UR                  [        US   5      5        USS nO[        SR                  U 5      5      eU(       d   U$ [        U5      S:  a3  [	        US   [         R                  5      (       a  US   S	:X  a  USS nGMN  [        SR                  U 5      5      eU$ s  snf )
z2Parses the given tokens that represent a property.)[].zillegal property: {0}r      Nr/      r0   r1   )r   Tokenizer   format
isinstanceLiteralappendr   	Separatorlenr#   isdigitr    )proptokenstokenress       r   _Parser@   e   sj   dO4&%/veEv&/	
188>
??
#fQi!2!2333::4@AAJJtF1IABZF V 
*S fQi!4!4553::4@AA&)Y0011fQi36F	Vq5<<TBCCabzf VAY	 3 3
4
4
)s


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

6&)$% 5<<TBCC  
* 	Fa6!9i1122q	Sabzf3::4@AA	*{ 0s
   
KKc           	         U c  gU(       d  U $ [        US   [        5      (       a6  [        U [        5      (       a!  [        U R	                  US   5      USS 5      $ [        US   [
        5      (       a;  [        U [        5      (       a&  US   [        U 5      :  a  [        XS      USS 5      $ [        US   [        5      (       a4  [        U [        5      (       a  U  Vs/ s H  n[        X!SS 5      PM     sn$ gs  snf )zGrabs a property from obj.Nr   r2   )	r6   r   dict_GetPropertygetr    listr:   r#   )obj
componentsitems      r   rC   rC      s    [J:a=$''3
1.
12??:a=&))jd.C.C1C qM*JqrN;;:a=&))3;>?34L!"~.3??  @s    C<c                 z   [        U [        5      (       a[  [        R                  " [	        U R                  5       5      5      n[        R                  " U5       H  u  p#[        U5      X'   M     U$ [        U [        5      (       a  U  Vs/ s H  n[        U5      PM     sn$ [        R                  " U 5      $ s  snf )z@Recursively converts a JSON-serializable dict to an OrderedDict.)r6   rB   collectionsOrderedDictsorteditemssix	iteritems_DictToOrderedDictrE   copydeepcopy)rF   new_objkeyvaluerH   s        r   rP   rP      s    T%%fSYY[&9:GmmG,
'.gl -N#t145t$55== 6s   
B8c                    [        U5      (       d  [        U 5      $ [        R                  " 5       nU H4  nU(       d  M  US   USS pTXB;   a  X$   R	                  U5        M/  U/X$'   M6     [        U [        5      (       a  [        R                  " 5       n[        R                  " U5       HW  u  pxXp;   d  M  [        U5      (       a"  [        X   U5      n	U	b  X[        U5      '   M<  M>  [        X   5      U[        U5      '   MY     U(       a  U$ g[        U [        5      (       Ga"  U(       d  U $ [        / 5      n
U H<  n[        U[        5      (       d  M  U[        U 5      :  d  M+  U
R                  U5        M>     UR!                  [#        5       5      nU(       a@  / n	[%        U 5       H.  u  pX;   a  X,   U-   nOUnU	R	                  [        X5      5        M0     OMS/[        U 5      -  n	U
 H8  nX.   n[        U5      (       a  [        X   U5      X'   M)  [        X   5      X'   M:     U	 Vs/ s H	  oc  M  UPM     sn(       a  U	$ g[        U 5      $ s  snf )zERetains the data specified by properties in a JSON-serializable dict.r   r2   N)allrP   rJ   rK   r8   r6   rB   rN   rO   _FilterstrrE   setr    r:   addrD   r#   	enumerate)rF   
propertieshead_to_tailr<   headtailfiltered_objrT   rU   r?   indices
slice_tailirH   indexs                  r   rX   rX      s	    
Zc""((*,dt7DHD		!!$'"V  T**,LmmL1
	 u::%(#_%(S"  $6ch#?,s3x
  2 #tj"gG	C	 	 S3s8^C  !!&(+Jcs^'!<#3*!*

74,- $ FSXc%!(
z??sz:6#*)#*5#*  11j c"" 2s   -I7Ic                    [        U[        5      (       a]  [        U S   [        5      (       aE  UR                  U S   5      nUc  g[	        U 5      S:X  a  U" U5      X S   '   g[        U SS X5        g[        U[        5      (       a_  [        U S   [        5      (       aG  U S   nU[	        U5      S-
  :  a  g[	        U 5      S:X  a  U" X$   5      X$'   g[        U SS XU   5        g[        U[        5      (       aX  [        U S   [        5      (       a?  [        U5       H/  u  pS[	        U 5      S:X  a  U" U5      X%'   M   [        U SS X5        M1     ggg)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   Nr2   )
r6   rB   r   rD   r:   _ApplyTransformationrE   r    r#   r\   )rG   funcrF   validxrd   s         r   rg   rg     s*   " Tz*Q->>
''*Q-
 C
{
:!9cQ-:ab>45#tJqM6!B!B
Q-C
SX\
:!chch:ab>4S:#tJqM6!B!BC.	ZA	cZ^T7	 ! "Cr   c                   (    \ rS rSrSrSS jrS rSrg)PropertySelectoriF  a)  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                     U(       a"  U Vs/ s H  n[        U5      PM     snU l        OSU l        U(       a(  U VVs/ s H  u  p4[        U5      U4PM     snnU l        OSU l        Xl        X l        gs  snf s  snnf )z9Creates a new PropertySelector with the given properties.N)r@   _compiled_properties_compiled_transformationsr]   transformations)r'   r]   rp   prh   s        r   __init__PropertySelector.__init___  sr    6@"Aj6!9j"Ad"&d+:(<+:6!9d
?(<d$ (,d$ O* #B
(<s
   A4A9c                    U R                   (       a2  [        XR                   5      =(       d    [        R                  " 5       nO[	        U5      nU R
                  (       a!  U R
                   H  u  p4[        X4U5        M     U$ )z=An OrderedDict resulting from filtering and transforming obj.)rn   rX   rJ   rK   rP   ro   rg   )r'   rF   r?   compiled_propertyrh   s        r   ApplyPropertySelector.Applyo  sc      C223P{7N7N7Pcs#c%%%)%C%C
!
.c: &D Jr   )rn   ro   r]   rp   )NN)r   r   r   r   r   rr   rv   r   r
   r   r   rl   rl   F  s    0+ r   rl   c                   $    \ rS rSrSrS rS rSrg)PropertyGetteri}  zExtracts 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                 $    [        U5      U l        g)z5Creates a new PropertyGetter with the given property.N)r@   _compiled_property)r'   rq   s     r   rr   PropertyGetter.__init__  s    $QiDr   c                 T    [         R                  " [        XR                  5      5      $ )zCReturns the property in obj or None if the property does not exist.)rQ   rR   rC   r{   )r'   rF   s     r   GetPropertyGetter.Get  s    ==c+B+BCDDr   )r{   N)r   r   r   r   r   rr   r~   r   r
   r   r   ry   ry   }  s    
(Er   ry   )r   
__future__r   r   r   rJ   rQ   googlecloudsdk.core.utilr   rN   	Exceptionr   r   r   rY   r   intr    objectr#   r@   rC   rP   rX   rg   rl   ry   r
   r   r   <module>r      s   'R '  '   . 
9I 9@e @E 3 S V @F0
IX*8Z4v 4nEV Er   