
    ^h                    x    S r SSKJr  SrSSKJr  SSKr " S S5      r " S S	\5      r " S
 S\5      r	S r
S rg)ae  Decorators for running functions with context/sockets.

.. versionadded:: 15.3

Like using Contexts and Sockets as context managers, but with decorator syntax.
Context and sockets are closed at the end of the function.

For example::

    from zmq.decorators import context, socket

    @context()
    @socket(zmq.PUSH)
    def work(ctx, push):
        ...
    )annotations)contextsocketwrapsNc                  4    \ rS rSrSrS	S jrS rS rS rSr	g)

_Decorator!   zThe mini decorator factoryNc                    Xl         g N_target)selftargets     H/home/james-whalen/.local/lib/python3.13/site-packages/zmq/decorators.py__init___Decorator.__init__$   s        c                L   ^ ^^^ T R                   " T0 TD6u  mmmUUUU 4S jnU$ )ab  
The main logic of decorator

Here is how those arguments works::

    @out_decorator(*dec_args, *dec_kwargs)
    def func(*wrap_args, **wrap_kwargs):
        ...

And in the ``wrapper``, we simply create ``self.target`` instance via
``with``::

    target = self.get_target(*args, **kwargs)
    with target(*dec_args, **dec_kwargs) as obj:
        ...

c                :   >^  [        T 5      UUU UU4S j5       nU$ )Nc                    > TR                   " U 0 UD6nU" T0 TD6 nT(       a  TU;  a  X1T'   O-T(       a!  TU;   a  [        TR                   ST S35      eX4-   n T" U 0 UD6sS S S 5        $ ! , (       d  f       g = f)Nz%() got multiple values for argument '')
get_target	TypeError__name__)	argskwargsr   objdec_args
dec_kwargsfunckw_namer   s	       r   wrapper7_Decorator.__call__.<locals>.decorator.<locals>.wrapper>   s    $9&9X447&#8*-w W%6'#}}o .**1!5 
  $f}00 544s   AA--
A;r   )r!   r#   r   r    r"   r   s   ` r   	decorator&_Decorator.__call__.<locals>.decorator=   s%    4[1 1 1" Nr   )process_decorator_args)r   r   r    r%   r"   s   ``` @r   __call___Decorator.__call__'   s9    $ )-(C(C)
#)
%:	 	* r   c                    U R                   $ )zGReturn the target function

Allows modifying args/kwargs to be passed.
r   )r   r   r   s      r   r   _Decorator.get_targetT   s    
 ||r   c                    Sn[        UR                  S5      [        5      (       a  UR                  S5      nO1[	        U5      S:  a"  [        US   [        5      (       a
  US   nUSS nX1U4$ )zProcess args passed to the decorator.

args not consumed by the decorator will be passed to the target factory
(Context/Socket constructor).
Nname   r   )
isinstancegetstrpoplen)r   r   r   r"   s       r   r'   !_Decorator.process_decorator_args[   sg     fjj(#..jj(GY!^
47C 8 81gG8Df$$r   r   r   )
r   
__module____qualname____firstlineno____doc__r   r(   r   r'   __static_attributes__ r   r   r	   r	   !   s    $+Z%r   r	   c                  ,   ^  \ rS rSrSrU 4S jrSrU =r$ )_ContextDecoratorl   zDecorator subclass for Contextsc                @   > [         TU ]  [        R                  5        g r   )superr   zmqContext)r   	__class__s    r   r   _ContextDecorator.__init__o   s    %r   r:   )r   r5   r6   r7   r8   r   r9   __classcell__rB   s   @r   r<   r<   l   s    )& &r   r<   c                  8   ^  \ rS rSrSrU 4S jrS rS rSrU =r	$ )_SocketDecorators   zBDecorator subclass for sockets

Gets the context from other args.
c                `   > [         TU ]  " U0 UD6u  p1nUR                  SS5      U l        X1U4$ )z$Also grab context_name out of kwargscontext_namer   )r?   r'   r2   rJ   )r   r   r   r"   rB   s       r   r'   '_SocketDecorator.process_decorator_argsy   s:     % > O Ov"JJ~yAf$$r   c                >    U R                   " U0 UD6nUR                  $ )z$Get context, based on call-time args)_get_contextr   )r   r   r   r   s       r   r   _SocketDecorator.get_target   s!    ##T4V4~~r   c                   U R                   U;   a/  X R                      n[        U[        R                  5      (       a  U$ U H&  n[        U[        R                  5      (       d  M$  Us  $    [        R                  R	                  5       $ )ao  
Find the ``zmq.Context`` from ``args`` and ``kwargs`` at call time.

First, if there is an keyword argument named ``context`` and it is a
``zmq.Context`` instance , we will take it.

Second, we check all the ``args``, take the first ``zmq.Context``
instance.

Finally, we will provide default Context -- ``zmq.Context.instance``

:return: a ``zmq.Context`` instance
)rJ   r/   r@   rA   instance)r   r   r   ctxargs        r   rM   _SocketDecorator._get_context   sk     &**+C#s{{++
C#s{{++
  {{##%%r   )rJ   )
r   r5   r6   r7   r8   r'   r   rM   r9   rD   rE   s   @r   rG   rG   s   s    
%
& &r   rG   c                 "    [        5       " U 0 UD6$ )zDecorator for adding a Context to a function.

Usage::

    @context()
    def foo(ctx):
        ...

.. versionadded:: 15.3

:param str name: the keyword argument passed to decorated function
)r<   r   r   s     r   r   r      s     ///r   c                 "    [        5       " U 0 UD6$ )a/  Decorator for adding a socket to a function.

Usage::

    @socket(zmq.PUSH)
    def foo(push):
        ...

.. versionadded:: 15.3

:param str name: the keyword argument passed to decorated function
:param str context_name: the keyword only argument to identify context
                         object
)rG   rU   s     r   r   r      s     t.v..r   )r8   
__future__r   __all__	functoolsr   r@   r	   r<   rG   r   r   r:   r   r   <module>rZ      sN   " #

  
H% H%V&
 &)&z )&X0 /r   