
    ]gz9                        S SK r S SKrS SKJr  S SKrS SKJr  S SKJr  S SK	J
r
  S SKJr  SSKJr  SS	KJrJrJr  \ R&                  " \5      rS
 rS r " S S5      r " S S5      r " S S5      r " S S5      r " S S5      rg)    N)partial)with_current_context)WaiterDocstring)register_feature_id)get_service_module_name   )
xform_name)ClientErrorWaiterConfigErrorWaiterErrorc                    UR                  U 5      n[        UR                  5      n[        [	        X$5      5      nS n[        U UR                  R                  UR                  R                  USS9Ul	        [        [        UR                  R                  5       SU  35      n[        U[        4SU05      nU" XU5      $ )a  

:type waiter_name: str
:param waiter_name: The name of the waiter.  The name should match
    the name (including the casing) of the key name in the waiter
    model file (typically this is CamelCasing).

:type waiter_model: botocore.waiter.WaiterModel
:param waiter_model: The model for the waiter configuration.

:type client: botocore.client.BaseClient
:param client: The botocore client associated with the service.

:rtype: botocore.waiter.Waiter
:return: The waiter object.

c                 2    [         R                  " U 40 UD6  g N)Waiterwait)selfkwargss     1/usr/lib/python3/dist-packages/botocore/waiter.pyr   'create_waiter_with_client.<locals>.wait9   s    D#F#    F)waiter_nameevent_emitterservice_modelservice_waiter_modelinclude_signaturez.Waiter.r   )
get_waiterr	   	operationNormalizedOperationMethodgetattrr   metaeventsr   __doc__strr   typer   )	r   waiter_modelclientsingle_waiter_configoperation_nameoperation_methodr   waiter_class_namedocumented_waiter_clss	            r   create_waiter_with_clientr,      s    $ (22;? 4 > >?N0'$ #kk((kk//)DL "6;;#<#<=
>h{mT
 !!2VI~N !+; r   c                 ^    U R                  S5      n[        U[        5      (       a  SU;   a  gg)NErrorCodeTF)get
isinstancedict)responseerrors     r   is_valid_waiter_errorr5   R   s)    LL!E%6U?r   c                        \ rS rSrS rS rSrg)r   Y   c                     Xl         g r   _client_method)r   client_methods     r   __init__"NormalizedOperationMethod.__init__Z   s    +r   c                 n     U R                   " S0 UD6$ ! [         a  nUR                  s S nA$ S nAff = f)N )r:   r
   r3   )r   r   es      r   __call__"NormalizedOperationMethod.__call__]   s5    	&&000 	::	s    
4/44r9   N)__name__
__module____qualname____firstlineno__r<   rA   __static_attributes__r?   r   r   r   r   Y   s    ,r   r   c                   *    \ rS rSrSrS rS rS rSrg)WaiterModeld      c                     US   U l         UR                  SS5      nU R                  U5        X l        [	        [        US   R                  5       5      5      U l        g)a  

Note that the WaiterModel takes ownership of the waiter_config.
It may or may not mutate the waiter_config.  If this is a concern,
it is best to make a copy of the waiter config before passing it to
the WaiterModel.

:type waiter_config: dict
:param waiter_config: The loaded waiter config
    from the <service>*.waiters.json file.  This can be
    obtained from a botocore Loader object as well.

waitersversionunknownN)_waiter_configr0   _verify_supported_versionrN   listsortedkeyswaiter_names)r   waiter_configrN   s      r   r<   WaiterModel.__init__g   sX     ,I6
  ##Iy9&&w/ i(@(E(E(G!HIr   c                 T    XR                   :w  a  [        SU R                    SU 3S9eg )Nz7Unsupported waiter version, supported version must be: z#, but version of waiter config is: 	error_msg)SUPPORTED_VERSIONr   )r   rN   s     r   rQ   %WaiterModel._verify_supported_version   s@    ,,,#  $ 6 67 8,,396  -r   c                 p     U R                   U   n[        U5      $ ! [         a    [        SU 35      ef = f)NzWaiter does not exist: )rP   KeyError
ValueErrorSingleWaiterConfig)r   r   r'   s      r   r   WaiterModel.get_waiter   sM    	F#'#6#6{#C  ""677  	F6{mDEE	Fs    5)rP   rN   rU   N)	rC   rD   rE   rF   r[   r<   rQ   r   rG   r?   r   r   rI   rI   d   s    J08r   rI   c                   .    \ rS rSrSrS r\S 5       rSrg)r`      zRepresents the waiter configuration for a single waiter.

A single waiter is considered the configuration for a single
value associated with a named waiter (i.e TableExists).

c                 z    Xl         UR                  SS5      U l        US   U l        US   U l        US   U l        g )Ndescription r   delaymaxAttempts)_configr0   re   r   rg   max_attempts)r   r'   s     r   r<   SingleWaiterConfig.__init__   sC    + 033M2F-k:)'2
0?r   c                 n    / nU R                   S    H  n[        U5      nUR                  U5        M!     U$ )N	acceptors)ri   AcceptorConfigappend)r   rm   acceptor_configacceptors       r   rm   SingleWaiterConfig.acceptors   s:    	#||K8O%o6HX&  9 r   )ri   rg   re   rj   r   N)	rC   rD   rE   rF   r"   r<   propertyrm   rG   r?   r   r   r`   r`      s!    @  r   r`   c                   N    \ rS rSrS r\S 5       rS rS rS r	S r
S rS	 rS
rg)rn      c                     US   U l         US   U l        US   U l        UR                  S5      U l        U R                  5       U l        g )Nstatematcherexpectedargument)rw   rx   ry   r0   rz   _create_matcher_funcmatcher_func)r   configs     r   r<   AcceptorConfig.__init__   sF    G_
i(z*

:. 557r   c                    U R                   S:X  a  SU R                   SU R                   S3$ U R                   S:X  a  SU R                   SU R                   S3$ U R                   S:X  a  SU R                   SU R                   S3$ U R                   S	:X  a  S
U R                   3$ U R                   S:X  a  SU R                   3$ SU R                    S3$ )NpathzFor expression "z" we matched expected path: ""pathAllz&" all members matched expected path: "pathAnyz" at least oncestatusz#Matched expected HTTP status code: r4   z%Matched expected service error code: z)No explanation for unknown waiter type: ")rx   rz   ry   r   s    r   explanationAcceptorConfig.explanation   s    <<6!%dmm_4QRVR_R_Q``abb\\Y&"4==/ 2##'==/4 \\Y&"4==/ 2--9 \\X%8HH\\W$:4==/JJ>t||nANNr   c                 n   U R                   S:X  a  U R                  5       $ U R                   S:X  a  U R                  5       $ U R                   S:X  a  U R                  5       $ U R                   S:X  a  U R	                  5       $ U R                   S:X  a  U R                  5       $ [        SU R                    3S9e)Nr   r   r   r   r4   zUnknown acceptor: rY   )rx   _create_path_matcher_create_path_all_matcher_create_path_any_matcher_create_status_matcher_create_error_matcherr   r   s    r   r{   #AcceptorConfig._create_matcher_func   s     <<6!,,..\\Y&0022\\Y&0022\\X%..00\\W$--//#.t||n= r   c                 p   ^^ [         R                  " U R                  5      mU R                  mUU4S jnU$ )Nc                 N   > [        U 5      (       a  g TR                  U 5      T:H  $ r   )r5   search)r3   ry   
expressions    r   acceptor_matches=AcceptorConfig._create_path_matcher.<locals>.acceptor_matches   s'    $X..$$X.(::r   jmespathcompilerz   ry   r   r   ry   r   s     @@r   r   #AcceptorConfig._create_path_matcher   s-    %%dmm4
==	;
  r   c                 p   ^^ [         R                  " U R                  5      mU R                  mUU4S jnU$ )Nc                    > [        U 5      (       a  g TR                  U 5      n[        U[        5      (       a  U(       d  gU H  nUT:w  d  M    g   gNFTr5   r   r1   rR   r3   resultelementry   r   s      r   r   AAcceptorConfig._create_path_all_matcher.<locals>.acceptor_matches   sO    $X..&&x0Ffd++6
 !h&  " r   r   r   s     @@r   r   'AcceptorConfig._create_path_all_matcher   s-    %%dmm4
==	  r   c                 p   ^^ [         R                  " U R                  5      mU R                  mUU4S jnU$ )Nc                    > [        U 5      (       a  g TR                  U 5      n[        U[        5      (       a  U(       d  gU H  nUT:X  d  M    g   gr   r   r   s      r   r   AAcceptorConfig._create_path_any_matcher.<locals>.acceptor_matches  sO    $X..&&x0Ffd++6
 !h& " r   r   r   s     @@r   r   'AcceptorConfig._create_path_any_matcher  s-    %%dmm4
==	  r   c                 ,   ^ U R                   mU4S jnU$ )Nc                 P   > U R                  S0 5      R                  S5      nUT:H  $ )NResponseMetadataHTTPStatusCoder0   )r3   status_codery   s     r   r   ?AcceptorConfig._create_status_matcher.<locals>.acceptor_matches  s1     #,,'92>BB K (**r   ry   r   r   ry   s     @r   r   %AcceptorConfig._create_status_matcher  s    ==	+  r   c                 ,   ^ U R                   mU4S jnU$ )Nc                    > TSL a  SU ;   =(       a    SU S   ;   $ TSL a  SU ;  $ U R                  S0 5      R                  SS5      T:H  $ )NTr.   r/   Frf   r   )r3   ry   s    r   r   >AcceptorConfig._create_error_matcher.<locals>.acceptor_matches'  s]     4(*Jv'9J/JJU"h..||GR044VR@HLLr   r   r   s     @r   r   $AcceptorConfig._create_error_matcher$  s    ==	M"  r   )rz   ry   rx   r|   rw   N)rC   rD   rE   rF   r<   rs   r   r{   r   r   r   r   r   rG   r?   r   r   rn   rn      s;    8 O O(0	  * *  r   rn   c                   D    \ rS rSrS r\" \" \S5      5      S 5       rSr	g)r   i;  c                 (    X0l         Xl        X l        g)aT  

:type name: string
:param name: The name of the waiter

:type config: botocore.waiter.SingleWaiterConfig
:param config: The configuration for the waiter.

:type operation_method: callable
:param operation_method: A callable that accepts **kwargs
    and returns a response.  For example, this can be
    a method from a botocore client.

N)_operation_methodnamer}   )r   r   r}   r)   s       r   r<   Waiter.__init__<  s     "2 	r   WAITERc           
      h   [        U R                  R                  5      nSnUR                  S0 5      nUR	                  SU R                  R
                  5      nUR	                  SU R                  R                  5      nS nSn U R                  " S0 UD6n	US-  nU H)  n
U
R                  U	5      (       d  M  U
nU
R                  n  O]   [        U	5      (       aK  [        U R                  SR                  U	S   R	                  S	S
5      U	S   R	                  SS
5      5      U	S9eUS:X  a  [        R                  S5        g US:X  a$  SW
R                    3n[        U R                  UU	S9eX:  a*  Uc  SnOSW
R                    3n[        U R                  UU	S9e["        R$                  " U5        GM/  )NwaitingWaiterConfigDelayMaxAttemptsr   r   zAn error occurred ({}): {}r.   r/   UnknownMessage)r   reasonlast_responsesuccessz3Waiting complete, waiter matched the success state.failurez-Waiter encountered a terminal failure state: zMax attempts exceededz2Max attempts exceeded. Previously accepted state: r?   )rR   r}   rm   popr0   rg   rj   r   r|   rw   r5   r   r   formatloggerdebugr   timesleep)r   r   rm   current_stater}   sleep_amountrj   last_matched_acceptornum_attemptsr3   rq   r   s               r   r   Waiter.waitQ  s   ../	!NB/zz'4;;+<+<=zz-1I1IJ $--77HAL%((22,4)$,NNM	 & )22 &!YY;BB$W-11&)D$W-11)YG  '/  	)L 	)HI]I]H^_!!"* 
 +(04F M#//02  "!"* 
 JJ|$a r   )r   r}   r   N)
rC   rD   rE   rF   r<   r   r   r   r   rG   r?   r   r   r   r   ;  s)    * '"5x@A:% B:%r   r   )loggingr   	functoolsr   r   botocore.contextr   botocore.docs.docstringr   botocore.useragentr   botocore.utilsr   rf   r	   
exceptionsr
   r   r   	getLoggerrC   r   r,   r5   r   rI   r`   rn   r   r?   r   r   <module>r      s{        1 3 2 2  C C			8	$1h *8 *8Z 6L  L ^Q% Q%r   