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

ÿ	+