B “äî\ý_ã@sÄddlZddlZddlmZmZmZddlmZmZddl m Z e  e ¡Z eddddgƒZdZd Zd ZGd d„deƒZdd d „ZGdd„deƒZGdd„deƒZGdd„deƒZGdd„deƒZdS)éN)Ú defaultdictÚdequeÚ namedtuple)Úaccepts_kwargsÚsix)Ú EVENT_ALIASESÚNodeListÚfirstÚmiddleÚlastééc@seZdZdd„ZdS)rcCs4t |j¡}t |j¡}t |j¡}t|||ƒ}|S)N)Úcopyr r r r)ÚselfZ first_copyZ middle_copyZ last_copyÚcopied©rú2/tmp/pip-build-uw_ogi45/botocore/botocore/hooks.pyÚ__copy__s     zNodeList.__copy__N)Ú__name__Ú __module__Ú __qualname__rrrrrrscCs&x |D]}|ddk r|dSqW|S)aFind first non None response in a list of tuples. This function can be used to find the first non None response from handlers connected to an event. This is useful if you are interested in the returned responses from event handlers. Example usage:: print(first_non_none_response([(func1, None), (func2, 'foo'), (func3, 'bar')])) # This will print 'foo' :type responses: list of tuples :param responses: The responses from the ``EventHooks.emit`` method. This is a list of tuples, and each tuple is (handler, handler_response). :param default: If no non-None responses are found, then this default value will be returned. :return: The first non-None response in the list of tuples. r Nr)Ú responsesÚdefaultÚresponserrrÚfirst_non_none_response&s   rc@sTeZdZdd„Zddd„Zddd„Zdd d „Zd d „Zdd d„Zdd„Z dd„Z dS)ÚBaseEventHookscKsgS)aäCall all handlers subscribed to an event. :type event_name: str :param event_name: The name of the event to emit. :type **kwargs: dict :param **kwargs: Arbitrary kwargs to pass through to the subscribed handlers. The ``event_name`` will be injected into the kwargs so it's not necesary to add this to **kwargs. :rtype: list of tuples :return: A list of ``(handler_func, handler_func_return_value)`` r)rÚ event_nameÚkwargsrrrÚemitCszBaseEventHooks.emitNFcCs|j||||j|ddS)a@Register an event handler for a given event. If a ``unique_id`` is given, the handler will not be registered if a handler with the ``unique_id`` has already been registered. Handlers are called in the order they have been registered. Note handlers can also be registered with ``register_first()`` and ``register_last()``. All handlers registered with ``register_first()`` are called before handlers registered with ``register()`` which are called before handlers registered with ``register_last()``. )Úregister_methodÚunique_id_uses_countN)Ú_verify_and_registerÚ _register)rrÚhandlerÚ unique_idr rrrÚregisterTs zBaseEventHooks.registercCs|j||||j|ddS)zìRegister an event handler to be called first for an event. All event handlers registered with ``register_first()`` will be called before handlers registered with ``register()`` and ``register_last()``. )rr N)r!Ú_register_first)rrr#r$r rrrÚregister_firstgs zBaseEventHooks.register_firstcCs|j||||j|ddS)zâRegister an event handler to be called last for an event. All event handlers registered with ``register_last()`` will be called after handlers registered with ``register_first()`` and ``register()``. )rr N)r!Ú_register_last)rrr#r$r rrrÚ register_lastts zBaseEventHooks.register_lastcCs&| |¡| |¡|||||ƒdS)N)Ú_verify_is_callableÚ_verify_accept_kwargs)rrr#r$rr rrrr!€s  z#BaseEventHooks._verify_and_registercCsdS)z÷Unregister an event handler for a given event. If no ``unique_id`` was given during registration, then the first instance of the event handler is removed (if the event handler has been registered multiple times). Nr)rrr#r$r rrrÚ unregister†s zBaseEventHooks.unregistercCst |¡std|ƒ‚dS)Nz"Event handler %s must be callable.)rÚcallableÚ ValueError)rÚfuncrrrr*‘s z"BaseEventHooks._verify_is_callablecCs2yt|ƒstd|ƒ‚Wntk r,dSXdS)z¸Verifies a callable accepts kwargs :type func: callable :param func: A callable object. :returns: True, if ``func`` accepts kwargs, otherwise False. z9Event handler %s must accept keyword arguments (**kwargs)FN)rr.Ú TypeError)rr/rrrr+•s  z$BaseEventHooks._verify_accept_kwargs)NF)NF)NF)NNF) rrrrr%r'r)r!r,r*r+rrrrrBs    rc@sfeZdZdd„Zddd„Zdd„Zdd „Zdd d „Zdd d„Zddd„Z dd„Z ddd„Z dd„Z d S)ÚHierarchicalEmittercCsi|_tƒ|_i|_dS)N)Ú _lookup_cacheÚ _PrefixTrieÚ _handlersÚ_unique_id_handlers)rrrrÚ__init__§szHierarchicalEmitter.__init__FcCsŒg}|j |¡}|dkr0|j |¡}||j|<n|s8gS||d<g}xB|D]:}t d||¡|f|Ž}| ||f¡|rJ|dk rJ|SqJW|S)aö Emit an event with optional keyword arguments. :type event_name: string :param event_name: Name of the event :type kwargs: dict :param kwargs: Arguments to be passed to the handler functions. :type stop_on_response: boolean :param stop_on_response: Whether to stop on the first non-None response. If False, then all handlers will be called. This is especially useful to handlers which mutate data and then want to stop propagation of the event. :rtype: list :return: List of (handler, response) tuples from all processed handlers. NrzEvent %s: calling handler %s)r2Úgetr4Ú prefix_searchÚloggerÚdebugÚappend)rrrÚstop_on_responserZhandlers_to_callr#rrrrÚ_emit±s       zHierarchicalEmitter._emitcKs | ||¡S)a; Emit an event by name with arguments passed as keyword args. >>> responses = emitter.emit( ... 'my-event.service.operation', arg1='one', arg2='two') :rtype: list :return: List of (handler, response) tuples from all processed handlers. )r=)rrrrrrrÙs zHierarchicalEmitter.emitcKs$|j||dd}|r|dSdSdS)a÷ Emit an event by name with arguments passed as keyword args, until the first non-``None`` response is received. This method prevents subsequent handlers from being invoked. >>> handler, response = emitter.emit_until_response( 'my-event.service.operation', arg1='one', arg2='two') :rtype: tuple :return: The first (handler, response) tuple where the response is not ``None``, otherwise (``None``, ``None``). T)r<éÿÿÿÿ)NNN)r=)rrrrrrrÚemit_until_responseæs z'HierarchicalEmitter.emit_until_responseNcCs|j||||tddS)N)Úsection)Ú_register_sectionÚ_MIDDLE)rrr#r$r rrrr"ùs zHierarchicalEmitter._registercCs|j||||tddS)N)r@)rAÚ_FIRST)rrr#r$r rrrr&þs z#HierarchicalEmitter._register_firstcCs|j||||tddS)N)r@)rAÚ_LAST)rrr#r$r rrrr(s z"HierarchicalEmitter._register_lastcCs´|dk r˜||jkrf|j| dd¡}|rR|s:td|ƒ‚qb|j|dd7<n|rbtd|ƒ‚dS|jj|||dd|i}|rŒd|d<||j|<n|jj|||di|_dS)NÚcountz“Initial registration of unique id %s was specified to use a counter. Subsequent register calls to unique id must specify use of a counter as well.r zšInitial registration of unique id %s was specified to not use a counter. Subsequent register calls to unique id must specify not to use a counter as well.)r@r#)r5r7r.r4Ú append_itemr2)rrr#r$r r@rEZunique_id_handler_itemrrrrAs,    z%HierarchicalEmitter._register_sectioncCsÖ|dk r¤y|j| dd¡}Wntk r2dSX|r„|dkrNtd|ƒ‚q¤|dkrh|j |¡d}q¤|j|dd8<dSn |r”td|ƒ‚|j |¡d}y|j ||¡i|_Wntk rÐYnXdS)NrEz”Initial registration of unique id %s was specified to use a counter. Subsequent unregister calls to unique id must specify use of a counter as well.r r#zœInitial registration of unique id %s was specified to not use a counter. Subsequent unregister calls to unique id must specify not to use a counter as well.)r5r7ÚKeyErrorr.Úpopr4Ú remove_itemr2)rrr#r$r rErrrr,0s0  zHierarchicalEmitter.unregistercCs<| ¡}|j ¡}t |j¡|d<t |j¡|d<||_|S)Nr4r5)Ú __class__Ú__dict__rr4r5)rZ new_instanceZ new_staterrrrRs  zHierarchicalEmitter.__copy__)F)NF)NF)F)NNF) rrrr6r=rr?r"r&r(rAr,rrrrrr1¦s (    ( !r1c@sfeZdZddd„Zdd„Zdd„Zdd d „Zdd d „Zdd d„Zddd„Z dd„Z dd„Z dd„Z dS)Ú EventAliaserNcCs||_|dkrt|_||_dS)N)Ú_event_aliasesrÚ_emitter)rZ event_emitterZ event_aliasesrrrr6\szEventAliaser.__init__cKs| |¡}|jj|f|ŽS)N)Ú_alias_event_namerNr)rrrÚaliased_event_namerrrrbs zEventAliaser.emitcKs| |¡}|jj|f|ŽS)N)rOrNr?)rrrrPrrrr?fs z EventAliaser.emit_until_responseFcCs| |¡}|j ||||¡S)N)rOrNr%)rrr#r$r rPrrrr%js zEventAliaser.registercCs| |¡}|j ||||¡S)N)rOrNr')rrr#r$r rPrrrr'qs zEventAliaser.register_firstcCs| |¡}|j ||||¡S)N)rOrNr))rrr#r$r rPrrrr)xs zEventAliaser.register_lastcCs| |¡}|j ||||¡S)N)rOrNr,)rrr#r$r rPrrrr,s zEventAliaser.unregisterc Csœx–|j ¡D]ˆ\}}| d¡}d|krRy||| |¡<Wqvtk rNw YqvXn$||kr | d¡}| |||¡nq d |¡}t d||f¡|SW|S)NÚ.z!Changing event name from %s to %s) rMÚitemsÚsplitÚindexr.Ú_replace_subsectionÚjoinr9r:)rrZold_partÚnew_partZ event_partsÚ old_partsÚnew_namerrrrO†s      zEventAliaser._alias_event_namecCs\xVtt|ƒƒD]F}|||dkr|||t|ƒ…|kr|g|||t|ƒ…<dSqWdS)Nr)ÚrangeÚlen)rÚsectionsrXrWÚirrrrU¦s z EventAliaser._replace_subsectioncCs| t |j¡t |j¡¡S)N)rJrrNrM)rrrrr­s zEventAliaser.__copy__)N)NF)NF)NF)NNF) rrrr6rr?r%r'r)r,rOrUrrrrrrL[s      rLc@sTeZdZdZdd„Zefdd„Zdd„Zdd „Zd d „Z d d „Z dd„Z dd„Z dS)r3ajSpecialized prefix trie that handles wildcards. The prefixes in this case are based on dot separated names so 'foo.bar.baz' is:: foo -> bar -> baz Wildcard support just means that having a key such as 'foo.bar.*.baz' will be matched with a call to ``get_items(key='foo.bar.ANYTHING.baz')``. You can think of this prefix trie as the equivalent as defaultdict(list), except that it can do prefix searches: foo.bar.baz -> A foo.bar -> B foo -> C Calling ``get_items('foo.bar.baz')`` will return [A + B + C], from most specific to least specific. cCsdiddœ|_dS)N)ÚchunkÚchildrenÚvalues)Ú_root)rrrrr6Êsz_PrefixTrie.__init__cCs†| d¡}|j}xB|D]:}||dkrD|didœ}||d|<|}q|d|}qW|ddkrptgggƒ|d<|d| |¡dS)z’Add an item to a key. If a value is already associated with that key, the new value is appended to the list for the key. rQr_N)r^r`r_r`)rSrarr;)rÚkeyÚvaluer@Ú key_partsÚcurrentÚpartÚ new_childrrrrFÒs      z_PrefixTrie.append_itemcCs*tƒ}| d¡}|j}| |||d¡|S)zÖCollect all items that are prefixes of key. Prefix in this case are delineated by '.' characters so 'foo.bar.baz' is a 3 chunk sequence of 3 "prefixes" ( "foo", "bar", and "baz"). rQr)rrSraÚ _get_items)rrbÚ collectedrdrerrrr8ås  z_PrefixTrie.prefix_searchcCs¸||fg}t|ƒ}x |r²| ¡\}}|drT|d} | j| j| j} | t| ƒ¡||ks|d} |  ||¡} |  d¡} |d}| dk rš| | |f¡| dk r| | |f¡qWdS)Nr`r_Ú*r ) r[rHr r r Ú extendleftÚreversedr7r;)rZ starting_noderdriZstarting_indexÚstackZ key_parts_lenÚ current_noderTÚ node_listZcomplete_orderr_ZdirectsZwildcardZ next_indexrrrrhós$    z_PrefixTrie._get_itemscCs&| d¡}|j}|j|||dddS)zÞRemove an item associated with a key. If the value is not associated with the key a ``ValueError`` will be raised. If the key does not exist in the trie, a ``ValueError`` will be raised. rQr)rTN)rSraÚ _remove_item)rrbrcrdrerrrrIs z_PrefixTrie.remove_itemcCsÚ|dkr dS|t|ƒkrÖ|d ||¡}|dk rÄ| ||||d¡|t|ƒdkr¤|d}||jkrv|j |¡n.||jkrŽ|j |¡n||jkr¤|j |¡|dsÖ|dsÖ|d||=ntdd |¡ƒ‚dS)Nr_r r`zkey is not in trie: %srQ) r[r7rpr Úremover r r.rV)rrnrdrcrTZ next_noderorrrrps$     z_PrefixTrie._remove_itemcCs| ¡}| |j¡}||_|S)N)rJÚ_recursive_copyrK)rZnew_copyZ copied_attrsrrrr7s z_PrefixTrie.__copy__cCsZi}xP| ¡D]D\}}t|tƒr0t |¡||<qt|tƒrJ| |¡||<q|||<qW|S)N)rRÚ isinstancerrÚdictrr)rÚnodeZ copied_noderbrcrrrrrAs   z_PrefixTrie._recursive_copyN) rrrÚ__doc__r6rBrFr8rhrIrprrrrrrrr3´s   r3)N)rÚloggingÚ collectionsrrrZbotocore.compatrrZbotocore.utilsrÚ getLoggerrr9Z _NodeListrCrBrDrrÚobjectrr1rLr3rrrrÚ s    d6Y