
    Ef/                     (   d Z ddlZddlZddlmZ ddlmZmZmZm	Z	m
Z
mZmZ ddlmZ ddlmZ ddlmZ ddlmZmZmZ dd	lmZ d
dlmZmZ d
dlmZ daddZ  ejB                  e         edd      Z" eddd      Z# G d deeee#         ZdgZ$y)zPython bindings for 0MQ.    N)Lock)AnyDictGenericListOptionalTypeTypeVar)warn)WeakSet)Context)ContextOptionErrnoSocketOption)ZMQError   )AttributeSetterOptValT)SocketFc                      da y NT)_exiting     3/usr/lib/python3/dist-packages/zmq/sugar/context.py_notice_atexitr      s    Hr   Tr   )boundSTr   T)r   	covariantc            	       8    e Zd ZU dZeeef   ed<   dZeed<    e	       Z
dZee   ed<   dZdZeed<   eZee   ed<   d1d	d
dededdf fdZd2dZdZdefdZd	edefdZdedededdfdZd3d	ededefdZeZedee   dedefd       Zedee   dedefd       Z ed1dee   dedefd       Z!d2 fdZ"de#e   fd Z$d!eddfd"Z%d!eddfd#Z&d3d$ee   ddfd%Z'd	ed&ededefd'Z(d(ed)eddfd*Z)d(ede*fd+Z+d,ed(ed)e*ddfd-Z,d,ed(ede*fd.Z-d/eddfd0Z. xZ/S )4r   au  Create a zmq Context

    A zmq Context creates sockets via its ``ctx.socket`` method.

    .. versionchanged:: 24

        When using a Context as a context manager (``with zmq.Context()``),
        or deleting a context without closing it first,
        ``ctx.destroy()`` is called,
        closing any leftover sockets,
        instead of `ctx.term()` which requires sockets to be closed first.

        This prevents hangs caused by `ctx.term()` if sockets are left open,
        but means that unclean destruction of contexts
        (with sockets left open) is not safe
        if sockets are managed in other threads.
    sockoptsN	_instance_instance_pidF_sockets_socket_classselfzContext[Socket]
io_threadskwargsreturnc                     t        |   dd|i| |j                  dd      rd| _        nd| _        i | _        t               | _        y )Nr(   shadowFTr   )super__init__get_shadowr"   r   r%   )r'   r(   r)   	__class__s      r   r.   zContext.__init__@   sD    9J9&9::h&DL DL	r   c                     t                | j                  sUt        sN| j                  sAd| _        t
        r#t        | dd      t        d|  t        d|        | j                          yyyy)a)  Deleting a Context without closing it destroys it and all sockets.

        .. versionchanged:: 24
            Switch from threadsafe `term()` which hangs in the event of open sockets
            to less safe `destroy()` which
            warns about any leftover sockets and closes them.
        Tr%   NzUnclosed context    
stacklevelsource)	localsr0   r   closed_warn_destroy_closer   getattrResourceWarningdestroyr'   s    r   __del__zContext.__del__I   sa     	||HT[['+D$j$7C'v.# 	 LLN 6AH|r   zzmq.Contextc           
      V   | j                   }|j                  j                  dd       }||j                   d|j                   }| j
                  rdnd}t        | dd       r&t        | j                        }|dkD  rdnd}| d| }nd}d	| d
| dt        t        |              | dS )N	_repr_cls.z closed r%   r   sz socket<(z) at >)r1   __dict__r/   
__module____name__r8   r:   lenr%   hexid)r'   clsr@   r8   	n_socketsrC   socketss          r   __repr__zContext.__repr__c   s    nnLL$$[$7	>>*!CLL>:I"kkr4T*DMM*I 1}"A"71#.GG9+QwiuSD]OF81EEr   c                     | S Nr   r=   s    r   	__enter__zContext.__enter__s   s    r   exc_type	exc_value	tracebackc                 2    d| _         | j                          y r   )r9   r<   )r'   rT   rU   rV   s       r   __exit__zContext.__exit__v   s    #' r   memoc                 L    | j                   j                  | j                        S )z'Copying a Context creates a shadow copy)r1   r,   
underlying)r'   rY   s     r   __copy__zContext.__copy__{   s    ~~$$T__55r   rM   addressc                 0    ddl m}  ||      } | |      S )zShadow an existing libzmq context

        address is the integer address of the libzmq context
        or an FFI pointer to it.

        .. versionadded:: 14.1
        r   cast_int_addrr,   )zmq.utils.interopr`   )rM   r]   r`   s      r   r,   zContext.shadow   s     	4('""r   ctxc                 ^    ddl m} ddlm} |j	                  |      } ||      } | |      S )zuShadow an existing pyczmq context

        ctx is the FFI `zctx_t *` pointer

        .. versionadded:: 14.1
        r   )zctxr_   ra   )pyczmqre   rb   r`   r[   )rM   rc   re   r`   r[   r]   s         r   shadow_pyczmqzContext.shadow_pyczmq   s-     	 3__S)

+'""r   c                    | j                   7| j                  t        j                         k7  s| j                   j                  r| j
                  5  | j                   7| j                  t        j                         k7  s| j                   j                  r' | |      | _         t        j                         | _        ddd       | j                   S | j                   S # 1 sw Y   | j                   S xY w)a  Returns a global Context instance.

        Most single-threaded applications have a single, global Context.
        Use this method instead of passing around Context instances
        throughout your code.

        A common pattern for classes that depend on Contexts is to use
        a default argument to enable programs with multiple Contexts
        but not require the argument for simpler applications::

            class MyClass(object):
                def __init__(self, context=None):
                    self.context = context or Context.instance()

        .. versionchanged:: 18.1

            When called in a subprocess after forking,
            a new global instance is created instead of inheriting
            a Context that won't work from the parent process.
        N)r(   )r#   r$   osgetpidr8   _instance_lock)rM   r(   s     r   instancezContext.instance   s    . MM!  BIIK/}}#### 4MM)((BIIK7}}++$':$>CM(*		C%4 }}s}}4 }}s   A+CC/c                 "    t         |           y)aL  Close or terminate the context.

        Context termination is performed in the following steps:

        - Any blocking operations currently in progress on sockets open within context shall
          raise :class:`zmq.ContextTerminated`.
          With the exception of socket.close(), any further operations on sockets open within this context
          shall raise :class:`zmq.ContextTerminated`.
        - After interrupting all blocking calls, term shall block until the following conditions are satisfied:
            - All sockets open within context have been closed.
            - For each socket within context, all messages sent on the socket have either been
              physically transferred to a network peer,
              or the socket's linger period set with the zmq.LINGER socket option has expired.

        For further details regarding socket linger behaviour refer to libzmq documentation for ZMQ_LINGER.

        This can be called to close the context by hand. If this is not called,
        the context will automatically be closed when it is garbage collected.
        N)r-   term)r'   r1   s    r   rn   zContext.term   s    ( 	r   c                 n    t        | j                        }|j                  t        j                         |S rR   )dirr1   extendr   __members__)r'   keyss     r   __dir__zContext.__dir__   s'    4>>"M--.r   socketc                 :    | j                   j                  |       y)zBAdd a weakref to a socket for Context.destroy / reference countingN)r%   addr'   ru   s     r   _add_socketzContext._add_socket   s    &!r   c                 V    t        | dd      | j                  j                  |       yy)z8Remove a socket for Context.destroy / reference countingr%   N)r:   r%   discardrx   s     r   
_rm_socketzContext._rm_socket   s*     4T*6MM!!&) 7r   lingerc                 T   | j                   ryt        t        | dd      xs g       }|D ]l  }|s|j                   r| j                  rt        rt	        d| t
        d|       | |j                  t        j                  |       |j                          n | j                          y)a  Close all sockets associated with this context and then terminate
        the context.

        .. warning::

            destroy involves calling ``zmq_close()``, which is **NOT** threadsafe.
            If there are active sockets in other threads, this must not be called.

        Parameters
        ----------

        linger : int, optional
            If specified, set LINGER on sockets prior to closing them.
        Nr%   z(Destroying context with unclosed socket    r4   )r8   listr:   r9   r   r;   
setsockoptr   LINGERclosern   )r'   r}   rO   rC   s       r   r<   zContext.destroy   s     ;; z4!@!FBG 	A++B1#F'#$ 	 %LL!4!4f=		 			r   socket_typec                 "   | j                   rt        t        j                         | j                  | |fi |}| j
                  j                         D ]  \  }}	 |j                  ||        | j                  |       |S # t        $ r Y 9w xY w)a]  Create a Socket associated with this Context.

        Parameters
        ----------
        socket_type : int
            The socket type, which can be any of the 0MQ socket types:
            REQ, REP, PUB, SUB, PAIR, DEALER, ROUTER, PULL, PUSH, etc.

        kwargs:
            will be passed to the __init__ method of the socket class.
        )	r8   r   r   ENOTSUPr&   r"   itemsr   ry   )r'   r   r)   rC   optvalues         r   ru   zContext.socket  s     ;;5==))"""+
!'
 ----/ 	JCS%(	 	   	s   B	BBr   r   c                 "    || j                   |<   y)zkset default socket options for new sockets created by this Context

        .. versionadded:: 13.0
        Nr"   )r'   r   r   s      r   r   zContext.setsockopt1  s    
 #cr   c                      | j                   |   S )zkget default socket options for new sockets created by this Context

        .. versionadded:: 13.0
        r   )r'   r   s     r   
getsockoptzContext.getsockopt8  s    
 }}S!!r   namec                     |t         j                  v r| j                  ||      S |t        j                  v r|| j                  |<   yt        d|       )z"set default sockopts as attributesz"No such context or socket option: N)r   rr   setr   r"   AttributeError)r'   r   r   r   s       r   _set_attr_optzContext._set_attr_opt?  sP    =,,,88C''\---!&DMM# #EdV!LMMr   c                     |t         j                  v r| j                  |      S || j                  vrt	        |      | j                  |   S )z"get default sockopts as attributes)r   rr   r/   r"   r   )r'   r   r   s      r   _get_attr_optzContext._get_attr_optH  sD    =,,,88C= $--'$T**}}S))r   keyc                     |j                         }	 t        t        |      }|| j                  vrt	        |      | j                  |= y# t        $ r t	        d|      w xY w)z%delete default sockopts as attributeszNo such socket option: N)upperr:   r   r"   r   )r'   r   r   s      r   __delattr__zContext.__delattr__R  si    iik	',,C $--'$S))MM#&  	D #:3'!BCC	Ds   A	 	A!)r   r*   NrR   )0rI   rH   __qualname____doc__r   intr   __annotations__r#   r   rk   r$   r   r0   r9   r   r   r&   r	   r   r.   r>   r@   strrP   r   rS   rX   r\   __deepcopy__classmethodr,   rg   rl   rn   r   rt   ry   r|   r<   ru   r   r   r   r   r   r   __classcell__)r1   s   @r   r   r   #   sb   $ 38nIsVN#'M8C='G$M48$"( "c " "QU "0 IF# F  a     
6q 6 6q 6 L#DG #c #a # # #47 # # # #  "d1g "3 "q " "H4c "# "$ "* * *!hsm !t !FQ S C B 8#c ## #$ #"c "g "N# NC N ND N*# *C *G *'s 't 'r   r   )%r   atexitri   	threadingr   typingr   r   r   r   r   r	   r
   warningsr   weakrefr   zmq.backendr   ContextBasezmq.constantsr   r   r   	zmq.errorr   	attrsettrr   r   ru   r   r   r   registerr   r   __all__r   r   r   <module>r      s    
  	  D D D   . < <  /  
  Cy!TT2z'k?GBK z'z	 +r   