o
    Uݢgy*                     @  sB  d Z ddlmZ ddlZddlZddlZddlmZmZ ddl	m
Z
mZmZmZ ddlmZ dDd	d
Ze ZdEddZdFddZedddGddZedHddZdddIddZdFddZedddJd!d"ZedKd$d"ZdddLd&d"Z		'		'	(dMdNd2d3ZdOd6d7ZedPd;d<ZedQd?d<ZdRd@d<ZdSdBdCZdS )TzHelper for functions for logging calls to subprocesses.

In addition to logging, these wrappers will also (on linux) set PDEATHSIG on
the child process, so that they are killed if the parent process dies.
    )annotationsN)CallableSequence)IOTYPE_CHECKINGLiteraloverload
ensure_strreturnCallable[[], None] | Nonec                    st   t jdr8dd l} dd l} ddlm} | | j	d| 
d | d| |d
 fdd	}|S d S )Nlinuxr   )SIGKILLc   r   Nonec                     s      dS )zWhen used as the preexec_fn argument for subprocess.Popen etc,.

            causes the subprocess to recieve SIGKILL if the parent process
            terminates.
            N)prctl ZPR_SET_PDEATHSIGlibcZsigkillzeror   d/oak/stanford/groups/akundaje/marinovg/programs/cellranger-9.0.1/lib/python/tenkit/log_subprocess.py_child_preexec_set_pdeathsig%   s   z6__make_pdeathsig.<locals>._child_preexec_set_pdeathsig)r   r   )sysplatform
startswithctypesctypes.utilsignalr   CDLLutilfind_libraryc_intc_ulong)r   r   r   r   r   r   __make_pdeathsig   s   


r$   argsSequence[str] | Sequence[bytes]	list[str]c                 C  s    t | trdd | D S td)Nc                 S  s   g | ]}t |qS r   r	   ).0xr   r   r   
<listcomp>7   s    z_str_args.<locals>.<listcomp>zCommand must be a sequence.)
isinstancer   
ValueError)r%   r   r   r   	_str_args5   s   
r-   intc                 O  B   t t jddt|  d|vrt|d< tj| g|R i |S )zSee `subprocess.check_call`.zsubprocess check_call: %s 
preexec_fn)logginglogINFOjoinr-   child_preexec_set_pdeathsig
subprocess
check_callr%   Zwargskwargsr   r   r   r8   <      r8   )encodingr<   r   bytesc                K     d S Nr   r%   r<   r:   r   r   r   check_outputE      rA   strc                K  r>   r?   r   r@   r   r   r   rA   N   rB   
str | Nonestr | bytesc                K  @   t t jddt|  d|vrt|d< tj| fd|i|S )zSee `subprocess.check_output`.zsubprocess check_output: %sr0   r1   r<   )r2   r3   r4   r5   r-   r6   r7   rA   r@   r   r   r   rA   W   s   c                 O  r/   )zSee `subprocess.call`.zsubprocess call: %sr0   r1   )r2   r3   r4   r5   r-   r6   r7   callr9   r   r   r   rG   b   r;   rG   subprocess.Popen[bytes]c                K  r>   r?   r   r@   r   r   r   Popenk   rB   rI   subprocess.Popen[str]c                K  r>   r?   r   r@   r   r   r   rI   t   rB   /subprocess.Popen[bytes] | subprocess.Popen[str]c                K  rF   )zSee `subprocess.Popen`.subprocess Popen: %sr0   r1   r<   )r2   r3   r4   r5   r-   r6   r7   rI   r@   r   r   r   rI   }   s   FTcmds)Sequence[Sequence[str] | Sequence[bytes]]stdinNone | str | bytes | IO[bytes]close_inputboolstdoutclose_outputr3   c                 C  sn   t | tsJ t| dksJ tdd | D sJ |r,ttjdddd | D  t| ||||d dS )	a  Run a series of commands, piping output from each one to the next.

    The commands given as arguments to this method must be lists of arguments.
    In general, this will be much safer than using `check_call` with `shell=True`
    to pipe output between processes.  For example,

    .. code-block:: python

       from subprocess import call
       filename = input("What file would you like to search?\n")
       # imagine the user enters `non_existent; rm -rf / #`
       call("cat {} | grep predicate".format(filename), shell=True)  # Uh oh...

    While it _is_ possible to make sure the arguments in such an expression are
    properly quoted, there are a lot of tricky edge cases to watch out for.

    As compared to `pipes.Template()`, this method makes it easier to safely
    include commands in the pipeline which include untrusted arguments, and also
    offers more flexibility in terms of inputs and outputs.

    Args:
        cmds (list of list): A list of commands to execute.  Must have at least
                             one element.
        stdin (file or str): A filename or file object to pass as input to the
                             first process in the pipeline.  This file will be
                             closed once the subprocess is launched.  If not
                             provided, input will not be redirected.
        close_input (bool): If true, close the input file after launching the
                            first process.  This value is ignored if
                            `input_file` is not a file-like object.
        stdout (file or str): The name of the file to which to write the output
                              of the final command in the pipeline.  If not
                              provided, the final process's output will not be
                              redirected.
        close_output (bool): If true, close the output file after launching the
                             final process.  This value is ignored if
                             `output_file` is not a file-like object.
        log (bool): If true, write the pipeline (as if it were a bash command)
                    to the log.
    r   c                 s  s    | ]}t |tV  qd S r?   )r+   listr(   cmdr   r   r   	<genexpr>   s    zpipeline.<locals>.<genexpr>rL   z | c                 s  s    | ]
}d  t|V  qdS )r0   N)r5   r-   rV   r   r   r   rX      s    
input_filerQ   output_filerT   N)	r+   rU   lenallr2   r3   r4   r5   	_pipeline)rM   rO   rQ   rS   rT   r3   r   r   r   pipeline   s    0
r_   rZ   r[   c                 C  s   t | d ||||t| dk}z%zt| dkr%t| dd  |jd||d W n   |   W | }n| }w |rDt|| d d S )Nr   r   TrY   )_get_pipeline_procr\   r^   rS   killwaitr7   CalledProcessError)rM   rZ   rQ   r[   rT   procresultr   r   r   r^      s,   	
r^   obj	IO[bytes]Literal[True]c                 C  r>   r?   r   rf   r   r   r   _is_file_handle      rj   str | bytes | intLiteral[False]c                 C  r>   r?   r   ri   r   r   r   rj      rk   c                 C  s   t | do	t | dS )Nfilenoclose)hasattrri   r   r   r   rj      s   $bytes | int | str | IO[bytes] | Nonec                 C  s&  |rt |strt|trJ t|d}d}tr#|dur#t|ts#J d}z|sTtj| |tjtd}|W |rQ|rRt |rSz|	  W S    |rP|
  |   S S S |rjt |sjtrct|trcJ t|d}d}trw|durwt|tswJ zPtj| ||td}|W |r|rt |rz|	  W n   ttjd |r|
  |   W |r|rt |rz|	  W S    |r|
  |   S S S |r|rt |rz|	  W w    ttjd |r|
  |   w w w |r|rt |rz|	  W w    |r|
  |   w w w )zStarts a command with the given input and output.

    Handles all of the details around opening files and closing them if need be,
    even when stuff fails.
    rbTN)rO   rS   r1   wbzfailed to close output file)rj   r   r+   r   openr7   rI   PIPEr6   ro   ra   rb   r2   r3   r4   )rW   rZ   rQ   r[   rT   finalrd   r   r   r   r`      s   


r`   )r   r   )r%   r&   r   r'   )r%   r&   r   r.   )r%   r&   r<   r   r   r=   )r%   r&   r<   rC   r   rC   )r%   r&   r<   rD   r   rE   )r%   r&   r<   r   r   rH   )r%   r&   r<   rC   r   rJ   )r%   r&   r<   rD   r   rK   )NFNFT)rM   rN   rO   rP   rQ   rR   rS   rP   rT   rR   r3   rR   )
rM   rN   rZ   rP   rQ   rR   r[   rP   rT   rR   )rf   rg   r   rh   )rf   rl   r   rm   )r   rR   )
rZ   rq   rQ   rR   r[   rq   rT   rR   r   rH   )__doc__
__future__r   r2   r7   r   collections.abcr   r   typingr   r   r   r   sixr
   r$   r6   r-   r8   rA   rG   rI   r_   r^   rj   r`   r   r   r   r   <module>   sP   


		
		
E 
