o
    b!                     @   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g dZdS ) z
Utility methods.
    Nwraps)BytesIO)deferprotocol)failure c           	      C   sL   |d u r
ddl m} t }| |g|R  }||||ft| || |S )Nr   )reactor)twisted.internetr	   r   DeferredspawnProcesstuple)	r   
executableargsenvpathr	   	protoArgsdpr   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| || _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| _d S | j| _d S N)deferredr   serrReceivedIsGooderrReceivederrReceivedIsBad)r   r#   errortoor   r   r   r   B   s
   z_BackRelay.__init__c                 C   sJ   | j d ur#t | _t|| j}| j t| d | _ | j	  d S d S r"   )
r#   r   r   onProcessEndedr   errbackr   Failure	transportloseConnection)r   r   errr   r   r   r'   J   s   

z_BackRelay.errReceivedIsBadc                 C      | j | d S r"   r$   writer   r   r   r   r   r%   R      z_BackRelay.errReceivedIsGoodc                 C   r/   r"   r0   r2   r   r   r   outReceivedU   r3   z_BackRelay.outReceivedc                 C   s>   | j d ur| j | j  d S | jd ur| j| d S 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%   r4   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   r9   r   r   <lambda>y   s    z"getProcessOutput.<locals>.<lambda>)r   )r   r   r   r   r	   r(   r   r9   r   getProcessOutput_   s   r;   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#   r5   valueexitCoder7   r   r   r   r      s   z_ValueGetter.processEndedN)r   r   r   r   r   r   r   r   r   r<   }   s    r<   c                 C   s   t t| ||||S )z7Spawn a process and return its exit code as a Deferred.)r   r<   )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errBufr1   r4   r&   
stdinBytes)r   r#   rC   r   r   r   r      s   


z_EverythingGetter.__init__c                 C   s,   | j d ur| jd| j  | j  d S d S )Nr   )rC   r,   writeToChild
closeStdin)r   r   r   r   connectionMade   s   
z _EverythingGetter.connectionMadec                 C   sT   | j  }| j }|j}|j}|jr| j|||jf d S | j|||f d S r"   )	rA   r6   rB   r=   r>   signalr#   r*   r5   )r   r8   outr.   ecoder   r   r   r      s   

z_EverythingGetter.processEndedr"   )r   r   r   r   rF   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	   rC   r   r   r   getProcessOutputAndValue   s   rK   c              	   C   s0   |D ]}zt j| W q ty   Y qw | S r"   )warningsfiltersremove
ValueError)passthroughaddedFiltersfr   r   r   _resetWarningFilters   s   rS   c           	      O   s   | D ]\}}t j|i | qt jdt|  }z	||i |}W n ty:   t }td| |d |d w t	|t
jrI|t| |S t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      )rL   filterwarningsrM   lenBaseExceptionsysexc_inforS   with_traceback
isinstancer   r   addBoth)	suppressedWarningsrR   akwr   kwargsrQ   resultrZ   r   r   r   runWithWarningsSuppressed   s   

rc   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  g| R i |S r"   )rc   )r_   r`   rR   r^   r   r   warningSuppressingWrapper   s   z3suppressWarnings.<locals>.warningSuppressingWrapperr   )rR   r^   re   r   rd   r   suppressWarnings   s   rf   )rc   rf   r;   r?   rK   )Nr   )r    rY   rL   	functoolsr   ior   r
   r   r   twisted.pythonr   r   r   r   ProcessProtocolr!   r;   r<   r?   r@   rK   rS   rc   rf   __all__r   r   r   r   <module>   s*   
0

	+