
    f                    x    d Z ddlmZ dZddlmZ ddlZ G d d      Z G d d	e      Z G d
 de      Z	d Z
d Zy)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                  *    e Zd ZdZddZd Zd Zd Zy)
_DecoratorzThe mini decorator factoryNc                    || _         y N_target)selftargets     I/var/www/cvtools/html/venv/lib/python3.12/site-packages/zmq/decorators.py__init__z_Decorator.__init__$   s	        c                J       j                   i \   fd}|S )a  
        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                8     t                fd       }|S )Nc                      j                   | i |} |i 5 }r
|vr||<   n'r|v rt        j                   d d      | |fz   }  | i |cd d d        S # 1 sw Y   y xY w)Nz%() got multiple values for argument '')
get_target	TypeError__name__)	argskwargsr   objdec_args
dec_kwargsfunckw_namer   s	       r   wrapperz7_Decorator.__call__.<locals>.decorator.<locals>.wrapper>   s    ($9&9X44 17&#8*-w W%6'#}}o .**1!5 
  $sf}001 1 1s   ;A!!A*r   )r   r!   r   r   r    r   s   ` r   	decoratorz&_Decorator.__call__.<locals>.decorator=   s     4[1 1" Nr   )process_decorator_args)r   r   r   r"   r    s   ``` @r   __call__z_Decorator.__call__'   s7    $ )D(C(C)
#)
%:	* r   c                    | j                   S )zWReturn the target function

        Allows modifying args/kwargs to be passed.
        r   )r   r   r   s      r   r   z_Decorator.get_targetT   s    
 ||r   c                    d}t        |j                  d      t              r|j                  d      }n+t	        |      dk\  rt        |d   t              r
|d   }|dd }|||fS )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#   z!_Decorator.process_decorator_args[   sc     fjj(#.jj(GY!^
47C 81gG8Df$$r   r   )r   
__module____qualname____doc__r   r$   r   r#    r   r   r	   r	   !   s    $+Z%r   r	   c                  "     e Zd ZdZ fdZ xZS )_ContextDecoratorzDecorator subclass for Contextsc                @    t         |   t        j                         y r   )superr   zmqContext)r   	__class__s    r   r   z_ContextDecorator.__init__o   s    %r   )r   r.   r/   r0   r   __classcell__r8   s   @r   r3   r3   l   s    )& &r   r3   c                  .     e Zd ZdZ fdZd Zd Z xZS )_SocketDecoratorzJDecorator subclass for sockets

    Gets the context from other args.
    c                b    t        |   |i |\  }}}|j                  dd      | _        |||fS )z$Also grab context_name out of kwargscontext_namer   )r5   r#   r,   r>   )r   r   r   r    r8   s       r   r#   z'_SocketDecorator.process_decorator_argsy   s>     % > O Ov"JJ~yAf$$r   c                >     | j                   |i |}|j                  S )z$Get context, based on call-time args)_get_contextr   )r   r   r   r   s       r   r   z_SocketDecorator.get_target   s#    #$##T4V4~~r   c                    | j                   |v r+|| j                      }t        |t        j                        r|S |D ]   }t        |t        j                        s|c S  t        j                  j	                         S )a  
        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
        )r>   r)   r6   r7   instance)r   r   r   ctxargs        r   r@   z_SocketDecorator._get_context   sl     &**+C#s{{+
 	C#s{{+
	 {{##%%r   )r   r.   r/   r0   r#   r   r@   r9   r:   s   @r   r<   r<   s   s    
%
&r   r<   c                 "     t               | i |S )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
    )r3   r   r   s     r   r   r      s     ///r   c                 "     t               | i |S )aS  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
    )r<   rF   s     r   r   r      s     t.v..r   )r0   
__future__r   __all__	functoolsr   r6   r	   r3   r<   r   r   r1   r   r   <module>rK      sN   " #

  
H% H%V&
 &)&z )&X0 /r   