U
    n5{iê!  ã                   @   sü   d Z ddlZddlZddlmZ ddlmZ ddlmZm	Z	 ddl
mZ ddd	„ZG d
d„ deƒZG dd„ de	jƒZdi dddfdd„ZG dd„ de	jƒZdi ddfdd„ZG dd„ de	jƒZdi dddfdd„Zdd„ Zdd„ Zdd„ ZdddddgZdS )z
Utility methods.
é    N©Úwraps)ÚBytesIO)ÚdeferÚprotocol)Úfailure© c           	      C   sJ   |d krddl m} t ¡ }| |f|žŽ }| |||ft|ƒ ||¡ |S )Nr   )Úreactor)Útwisted.internetr	   r   ÚDeferredZspawnProcessÚtuple)	r   Ú
executableÚargsÚenvÚpathr	   Ú	protoArgsÚdÚpr   r   ú:/tmp/pip-unpacked-wheel-mnhg7r0q/twisted/internet/utils.pyÚ_callProtocolWithDeferred   s    r   c                   @   s   e Zd ZdZdd„ ZdS )Ú_UnexpectedErrorOutputay  
    Standard error data was received where it was not expected.  This is a
    subclass of L{IOError} to preserve backward compatibility with the previous
    error behavior of L{getProcessOutput}.

    @ivar processEnded: A L{Deferred} which will fire when the process which
        produced the data on stderr has ended (exited and all file descriptors
        closed).
    c                 C   s   t  | d|›�¡ || _d S )Nzgot stderr: )ÚIOErrorÚ__init__ÚprocessEnded)ÚselfÚtextr   r   r   r   r   *   s    z_UnexpectedErrorOutput.__init__N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r   r   r      s   
r   c                   @   s:   e Zd ZdZddd„Zdd„ Zdd„ Zd	d
„ Zdd„ ZdS )Ú
_BackRelaya·  
    Trivial protocol for communicating with a process and turning its output
    into the result of a L{Deferred}.

    @ivar deferred: A L{Deferred} which will be called back with all of stdout
        and, if C{errortoo} is true, all of stderr as well (mixed together in
        one string).  If C{errortoo} is false and any bytes are received over
        stderr, this will fire with an L{_UnexpectedErrorOutput} instance and
        the attribute will be set to L{None}.

    @ivar onProcessEnded: If C{errortoo} is false and bytes are received over
        stderr, this attribute will refer to a L{Deferred} which will be called
        back when the process ends.  This C{Deferred} is also associated with
        the L{_UnexpectedErrorOutput} which C{deferred} fires with earlier in
        this case so that users can determine when the process has actually
        ended, in addition to knowing when bytes have been received via stderr.
    r   c                 C   s(   || _ tƒ | _|r| j| _n| j| _d S ©N)Údeferredr   ÚsÚerrReceivedIsGoodÚerrReceivedÚerrReceivedIsBad)r   r"   Úerrortoor   r   r   r   B   s
    
z_BackRelay.__init__c                 C   sF   | j d k	rBt ¡ | _t|| jƒ}| j  t |¡¡ d | _ | j 	¡  d S r!   )
r"   r   r   ÚonProcessEndedr   Úerrbackr   ZFailureÚ	transportZloseConnection)r   r   Úerrr   r   r   r&   J   s    

z_BackRelay.errReceivedIsBadc                 C   s   | j  |¡ d S r!   ©r#   Úwrite©r   r   r   r   r   r$   R   s    z_BackRelay.errReceivedIsGoodc                 C   s   | j  |¡ d S r!   r,   r.   r   r   r   ÚoutReceivedU   s    z_BackRelay.outReceivedc                 C   s8   | j d k	r| j  | j ¡ ¡ n| jd k	r4| j |¡ d S r!   )r"   Úcallbackr#   Úgetvaluer(   r)   ©r   Úreasonr   r   r   r   X   s    

z_BackRelay.processEndedN)r   )	r   r   r   r   r   r&   r$   r/   r   r   r   r   r   r    /   s   
r    c                    s   t ‡ fdd„| ||||ƒS )aé  
    Spawn a process and return its output as a deferred returning a L{bytes}.

    @param executable: The file name to run and get the output of - the
                       full path should be used.

    @param args: the command line arguments to pass to the process; a
                 sequence of strings. The first string should B{NOT} be the
                 executable's name.

    @param env: the environment variables to pass to the process; a
                dictionary of strings.

    @param path: the path to run the subprocess in - defaults to the
                 current directory.

    @param reactor: the reactor to use - defaults to the default reactor

    @param errortoo: If true, include stderr in the result.  If false, if
        stderr is received the returned L{Deferred} will errback with an
        L{IOError} instance with a C{processEnded} attribute.  The
        C{processEnded} attribute refers to a L{Deferred} which fires when the
        executed process ends.
    c                    s   t | ˆ d�S )N©r'   )r    )r   r4   r   r   Ú<lambda>y   ó    z"getProcessOutput.<locals>.<lambda>)r   )r   r   r   r   r	   r'   r   r4   r   ÚgetProcessOutput_   s    
     ÿr7   c                   @   s   e Zd Zdd„ Zdd„ ZdS )Ú_ValueGetterc                 C   s
   || _ d S r!   )r"   )r   r"   r   r   r   r   ~   s    z_ValueGetter.__init__c                 C   s   | j  |jj¡ d S r!   )r"   r0   ÚvalueÚexitCoder2   r   r   r   r   �   s    z_ValueGetter.processEndedN)r   r   r   r   r   r   r   r   r   r8   }   s   r8   c                 C   s   t t| ||||ƒS )z7Spawn a process and return its exit code as a Deferred.)r   r8   )r   r   r   r   r	   r   r   r   ÚgetProcessValue…   s    r;   c                   @   s&   e Zd Zddd„Zdd„ Zdd„ ZdS )	Ú_EverythingGetterNc                 C   s4   || _ tƒ | _tƒ | _| jj| _| jj| _|| _d S r!   )r"   r   ÚoutBufÚerrBufr-   r/   r%   Ú
stdinBytes)r   r"   r?   r   r   r   r   ‹   s    

z_EverythingGetter.__init__c                 C   s(   | j d k	r$| j d| j ¡ | j ¡  d S )Nr   )r?   r*   ZwriteToChildZ
closeStdin)r   r   r   r   ÚconnectionMade“   s    
z _EverythingGetter.connectionMadec                 C   sR   | j  ¡ }| j ¡ }|j}|j}|jr<| j |||jf¡ n| j |||f¡ d S r!   )	r=   r1   r>   r9   r:   Úsignalr"   r)   r0   )r   r3   Úoutr+   ÚeÚcoder   r   r   r   š   s    

z_EverythingGetter.processEnded)N)r   r   r   r   r@   r   r   r   r   r   r<   Š   s   
r<   c              	   C   s   t t| |||||fd�S )a.  Spawn a process and returns a Deferred that will be called back with
    its output (from stdout and stderr) and it's exit code as (out, err, code)
    If a signal is raised, the Deferred will errback with the stdout and
    stderr up to that point, along with the signal, as (out, err, signalNum)
    )r   )r   r<   )r   r   r   r   r	   r?   r   r   r   ÚgetProcessOutputAndValue¥   s    ùrE   c              	   C   s4   |D ]*}zt j |¡ W q tk
r,   Y qX q| S r!   )ÚwarningsÚfiltersÚremoveÚ
ValueError)ZpassthroughÚaddedFiltersÚfr   r   r   Ú_resetWarningFilters¸   s    rL   c           	      O   s    | D ]\}}t j||Ž qt jdt| ƒ… }z|||Ž}W n8 tk
rr   t ¡ }td|ƒ |d  |d ¡‚Y n*X t	|t
jƒrŽ| t|¡ n
td|ƒ |S dS )a}  
    Run the function I{f}, but with some warnings suppressed.

    This calls L{warnings.filterwarnings} to add warning filters before
    invoking I{f}. If I{f} returns a L{Deferred} then the added filters are
    removed once the deferred fires. Otherwise they are removed immediately.

    Note that the list of warning filters is a process-wide resource, so
    calling this function will affect all threads.

    @param suppressedWarnings:
        A list of arguments to pass to L{warnings.filterwarnings}, a sequence
        of (args, kwargs) 2-tuples.

    @param f: A callable, which may return a L{Deferred}.

    @param a: Positional arguments passed to I{f}

    @param kw: Keyword arguments passed to I{f}

    @return: The result of C{f(*a, **kw)}

    @seealso: L{twisted.python.util.runWithWarningsSuppressed}
        functions similarly, but doesn't handled L{Deferred}s.
    Né   é   )rF   ÚfilterwarningsrG   ÚlenÚBaseExceptionÚsysÚexc_inforL   Úwith_tracebackÚ
isinstancer   r   ZaddBoth)	ÚsuppressedWarningsrK   ÚaÚkwr   ÚkwargsrJ   ÚresultrS   r   r   r   ÚrunWithWarningsSuppressedÁ   s    

r[   c                    s   t ˆ ƒ‡ ‡fdd„ƒ}|S )zÜ
    Wrap C{f} in a callable which suppresses the indicated warnings before
    invoking C{f} and unsuppresses them afterwards.  If f returns a Deferred,
    warnings will remain suppressed until the Deferred fires.
    c                     s   t ˆˆ f| ž|ŽS r!   )r[   )rW   rX   ©rK   rV   r   r   ÚwarningSuppressingWrapperó   s    z3suppressWarnings.<locals>.warningSuppressingWrapperr   )rK   rV   r]   r   r\   r   ÚsuppressWarningsì   s    r^   )Nr   )r   rR   rF   Ú	functoolsr   Úior   r
   r   r   Ztwisted.pythonr   r   r   r   ZProcessProtocolr    r7   r8   r;   r<   rE   rL   r[   r^   Ú__all__r   r   r   r   Ú<module>   s<      ÿ
0    ÿ
	+û