U
    gu=                     @  sB  U d dl mZ d dlZd dlmZmZ d dlmZmZ d dl	Z	ddl
mZ ddlmZmZ ddlmZmZ erd d	lmZ d d
lmZ ddlmZ dZejejhZeddddZeG dd deZdddddddddddddd d!gZe  Z!d"e"d#< eD ](Z#ee$ e!%e&ee# W 5 Q R X qeG d$d% d%ee Z'dS )&    )annotationsN)contextmanagersuppress)TYPE_CHECKINGoverload   socket)ConflictDetectorfinal)HalfCloseableStreamListener)	Generator)Buffer)
SocketTypei   zGenerator[(None, None, None)]returnc               
   c  s\   z
d V  W nL t k
rV }  z.| jtkr4tdd ntd|  | W 5 d } ~ X Y nX d S )Nzthis socket was already closedzsocket connection broken: )OSErrorerrno_closed_stream_errnostrioClosedResourceErrorZBrokenResourceError)exc r   :/tmp/pip-unpacked-wheel-ks04xdmi/trio/_highlevel_socket.py)_translate_socket_errors_to_stream_errors#   s    

r   c                   @  s   e Zd ZdZddddZdddd	d
ZddddZddddZd)dddddZddddZ	e
dddddddZe
ddddddddZd*ddddddd dZe
dddd!d"d#Ze
ddddd$d%d#Zd+dddd'd$d(d#ZdS ),SocketStreamuf  An implementation of the :class:`trio.abc.HalfCloseableStream`
    interface based on a raw network socket.

    Args:
      socket: The Trio socket object to wrap. Must have type ``SOCK_STREAM``,
          and be connected.

    By default for TCP sockets, :class:`SocketStream` enables ``TCP_NODELAY``,
    and (on platforms where it's supported) enables ``TCP_NOTSENT_LOWAT`` with
    a reasonable buffer size (currently 16 KiB) – see `issue #72
    <https://github.com/python-trio/trio/issues/72>`__ for discussion. You can
    of course override these defaults by calling :meth:`setsockopt`.

    Once a :class:`SocketStream` object is constructed, it implements the full
    :class:`trio.abc.HalfCloseableStream` interface. In addition, it provides
    a few extra features:

    .. attribute:: socket

       The Trio socket object that this stream wraps.

    r   r   c              	   C  s   t |tjstd|jtjkr(td|| _td| _	t
t | tjtjd W 5 Q R X ttdrt
t | tjtjd W 5 Q R X d S )Nz*SocketStream requires a Trio socket objectz*SocketStream requires a SOCK_STREAM socketz;another task is currently sending data on this SocketStreamTTCP_NOTSENT_LOWATi @  )
isinstancetsocketr   	TypeErrortypeSOCK_STREAM
ValueErrorr	   r
   _send_conflict_detectorr   r   
setsockoptIPPROTO_TCPTCP_NODELAYhasattrr   )selfr	   r   r   r   __init__G   s    



zSocketStream.__init__zbytes | bytearray | memoryviewNone)datar   c                   s   | j jrtd| j t  t|}|sz| j  dkrHtdtj	 I d H  W 5 Q R  W 5 Q R  W 5 Q R  d S d}|t
|k r||d  }| j |I d H }W 5 Q R X ||7 }q~W 5 Q R X W 5 Q R X W 5 Q R X d S )Nz!can't send data after sending EOFzsocket was already closedr   )r	   did_shutdown_SHUT_WRr   r   r$   r   
memoryviewfilenolowlevel
checkpointlensend)r)   r,   
total_sent	remainingsentr   r   r   send_alle   s    


"zSocketStream.send_allr   c              
     sL   | j < | j dkrtjt  | j I d H  W 5 Q R X W 5 Q R X d S )Nr-   )r$   r	   r0   r   r   r   Zwait_writabler)   r   r   r   wait_send_all_might_not_blockv   s
    z*SocketStream.wait_send_all_might_not_blockc              
     s\   | j L tj I d H  | jjr.W 5 Q R  d S t  | jtj	 W 5 Q R X W 5 Q R X d S N)
r$   r   r1   r2   r	   r.   r   shutdownr   SHUT_WRr9   r   r   r   send_eof}   s    zSocketStream.send_eofNz
int | Nonebytes)	max_bytesr   c              
     sL   |d krt }|dk rtdt   | j|I d H W  5 Q R  S Q R X d S )Nr   zmax_bytes must be >= 1)DEFAULT_RECEIVE_SIZEr#   r   r	   recv)r)   r@   r   r   r   receive_some   s    zSocketStream.receive_somec                   s   | j   tj I d H  d S r;   r	   closer   r1   r2   r9   r   r   r   aclose   s    
zSocketStream.acloseintzint | Buffer)leveloptionvaluer   c                 C  s   d S r;   r   )r)   rH   rI   rJ   r   r   r   r%      s    zSocketStream.setsockopt)rH   rI   rJ   lengthr   c                 C  s   d S r;   r   r)   rH   rI   rJ   rK   r   r   r   r%      s    zint | Buffer | Nonec                 C  sR   |dkr(|dkrt d| j|||S |dk	r@t d|d| j||||S )zlSet an option on the underlying socket.

        See :meth:`socket.socket.setsockopt` for details.

        NzKinvalid value for argument 'value', must not be None when specifying lengthz$invalid value for argument 'value': z%, must be None when specifying optlen)r    r	   r%   rL   r   r   r   r%      s    
)rH   rI   r   c                 C  s   d S r;   r   )r)   rH   rI   r   r   r   
getsockopt   s    zSocketStream.getsockopt)rH   rI   
buffersizer   c                 C  s   d S r;   r   r)   rH   rI   rN   r   r   r   rM      s    r   zint | bytesc                 C  s*   |dkr| j ||S | j |||S dS )zCheck the current value of an option on the underlying socket.

        See :meth:`socket.socket.getsockopt` for details.

        r   N)r	   rM   rO   r   r   r   rM      s    	)N)N)r   )__name__
__module____qualname____doc__r*   r8   r:   r>   rC   rF   r   r%   rM   r   r   r   r   r   .   s$   
 r   EPERMECONNABORTEDZEPROTOZENETDOWNZENOPROTOOPTZ	EHOSTDOWNZENONETZEHOSTUNREACH
EOPNOTSUPPZENETUNREACHZENOSRZESOCKTNOSUPPORTZEPROTONOSUPPORTZ	ETIMEDOUT
ECONNRESETzset[int]_ignorable_accept_errnosc                   @  s:   e Zd ZdZddddZdddd	Zd
dddZdS )SocketListenera  A :class:`~trio.abc.Listener` that uses a listening socket to accept
    incoming connections as :class:`SocketStream` objects.

    Args:
      socket: The Trio socket object to wrap. Must have type ``SOCK_STREAM``,
          and be listening.

    Note that the :class:`SocketListener` "takes ownership" of the given
    socket; closing the :class:`SocketListener` will also close the socket.

    .. attribute:: socket

       The Trio socket object that this stream wraps.

    r   r   c                 C  sh   t |tjstd|jtjkr(tdz|tjtj	}W n t
k
rP   Y nX |s^td|| _d S )Nz,SocketListener requires a Trio socket objectz,SocketListener requires a SOCK_STREAM socketz*SocketListener requires a listening socket)r   r   r   r    r!   r"   r#   rM   
SOL_SOCKETSO_ACCEPTCONNr   r	   )r)   r	   Z	listeningr   r   r   r*   o  s    zSocketListener.__init__r   r   c              
     sh   z| j  I dH \}}W n@ tk
rX } z"|jtkr<tjd|jtkrH W 5 d}~X Y q X t|S q dS )a#  Accept an incoming connection.

        Returns:
          :class:`SocketStream`

        Raises:
          OSError: if the underlying call to ``accept`` raises an unexpected
              error.
          ClosedResourceError: if you already closed the socket.

        This method handles routine errors like ``ECONNABORTED``, but passes
        other errors on to its caller. In particular, it does *not* make any
        special effort to handle resource exhaustion errors like ``EMFILE``,
        ``ENFILE``, ``ENOBUFS``, ``ENOMEM``.

        N)	r	   acceptr   r   r   r   r   rX   r   )r)   sock_r   r   r   r   r\     s    

zSocketListener.acceptr+   c                   s   | j   tj I dH  dS )z.Close this listener and its underlying socket.NrD   r9   r   r   r   rF     s    
zSocketListener.acloseN)rP   rQ   rR   rS   r*   r\   rF   r   r   r   r   rY   ]  s   rY   )(
__future__r   r   
contextlibr   r   typingr   r   r    r	   r   Z_utilr
   r   abcr   r   collections.abcr   Ztyping_extensionsr   _socketr   rA   EBADFENOTSOCKr   r   r   Z_ignorable_accept_errno_namessetrX   __annotations__nameAttributeErroraddgetattrrY   r   r   r   r   <module>   sX    
  
