U
    W[                     @   s  d Z ddlmZmZ ddlZddlZddlmZ ddlm	Z	m
Z
 ddlmZ ddl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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.
    )divisionabsolute_importNwraps)protocoldefer)failure)reraise)BytesIOc                 C   sD   |d krddl m} t }| |}||||ft| || |S )Nr   )reactor)twisted.internetr   r   DeferredZspawnProcesstuple)r   
executableargsenvpathr   dp r   8/usr/lib/python3/dist-packages/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|f  || _d S )Nzgot stderr: %r)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   E   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FailureZ	transportZloseConnection)r   r   errr   r   r   r(   M   s    

z_BackRelay.errReceivedIsBadc                 C   s   | j | d S r#   r%   writer   r   r   r   r   r&   U   s    z_BackRelay.errReceivedIsGoodc                 C   s   | j | d S r#   r-   r/   r   r   r   outReceivedX   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   [   s    

z_BackRelay.processEndedN)r   )	r   r   r    r!   r   r(   r&   r0   r   r   r   r   r   r"   2   s   
r"   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   r5   r   r   <lambda>}   s    z"getProcessOutput.<locals>.<lambda>)r   )r   r   r   r   r   r)   r   r5   r   getProcessOutputc   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$   r1   valueexitCoder3   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 Zdd ZdS )_EverythingGetterc                 C   s.   || _ t | _t | _| jj| _| jj| _d S r#   )r$   r
   outBuferrBufr.   r0   r'   r9   r   r   r   r      s
    
z_EverythingGetter.__init__c                 C   sR   | j  }| j }|j}|j}|jr<| j|||jf n| j|||f d S r#   )	r@   r2   rA   r:   r;   signalr$   r+   r1   )r   r4   outr,   ecoder   r   r   r      s    

z_EverythingGetter.processEndedNr<   r   r   r   r   r?      s   r?   c                 C   s   t t| ||||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   getProcessOutputAndValue   s    rF   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    rM   c           	      O   s   | D ]\}}t j|| qt jdt|  }z|||}W n0   t }td| t|d |d  Y n*X t|t	j
r|t| n
td| |S dS )a%  Run the function C{f}, but with some warnings suppressed.

    @param suppressedWarnings: A list of arguments to pass to filterwarnings.
                               Must be a sequence of 2-tuples (args, kwargs).
    @param f: A callable, followed by its arguments and keyword arguments
    N      )rG   filterwarningsrH   lensysexc_inforM   r	   
isinstancer   r   ZaddBoth)	suppressedWarningsrL   akwr   kwargsrK   resultrS   r   r   r   runWithWarningsSuppressed   s    

rZ   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#   )rZ   )rV   rW   rL   rU   r   r   warningSuppressingWrapper   s    z3suppressWarnings.<locals>.warningSuppressingWrapperr   )rL   rU   r\   r   r[   r   suppressWarnings   s    r]   )N)r!   Z
__future__r   r   rR   rG   	functoolsr   r   r   r   Ztwisted.pythonr   Ztwisted.python.compatr	   ior
   r   r   r   ZProcessProtocolr"   r7   r8   r>   r?   rF   rM   rZ   r]   __all__r   r   r   r   <module>   s8   
1
 	
	   