o
    Df0S                  	   @   s  d Z g dZddlZddlZddlZddlZddlZddlZddlZddl	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 ddlmZmZmZmZ ddlmZ zddlZW n eyg   dZY nw z
dd	lmZmZ W n ey   dZdZY nw zddl Z e!e d
sej"dkre#e d
d W n ey   dZ Y nw e
$dZ%e%& re'e%( Z)ndZ)zddlm*Z* W n ey   dd Z*Y nw de'fddZ+de'ddfddZ,de-de.fddZ/G dd deZ0G dd de0Z1G dd de0Z2G d d! d!e2Z3G d"d# d#e1Z4G d$d% d%e2Z5G d&d' d'e1Z6d(e-defd)d*Z7d(e-defd+d,Z8d(e-defd-d.Z9d/d0 Z:d(e-fd1d2Z;d3e-dee- fd4d5Z<d3e-dee- fd6d7Z=	8		d=d(e-d9ee' d:ee' defd;d<Z>dS )>z&
Open compressed files transparently.
)xopenPipedGzipWriterPipedGzipReader__version__    N)ABCabstractmethod)PopenPIPEDEVNULL)OptionalTextIOAnyStrIO   )version)igzip	isal_zlibF_SETPIPE_SZlinuxi  z/proc/sys/fs/pipe-max-size)fspathc                 C   sD   t | dr	|  S td urt| tjrt| S t| ts td| S )N
__fspath__zpath must be a string)hasattrr   pathlib
isinstancePathstr	TypeError)path r   W/var/www/html/software/conda/envs/catlas/lib/python3.10/site-packages/xopen/__init__.pyr   8   s   

r   returnc               	   C   s   zt tdW S  ty   Y nw ddl} z:td}| }W d   n1 s*w   Y  | d|}|rOtt	|
ddddd	}|dkrO|W S W n	 tyY   Y nw z	ddl}| W S  ttfyo   Y dS w )
z
    Number of available virtual or physical CPUs on this system
    Adapted from http://stackoverflow.com/a/1006301/715090
    r   Nz/proc/self/statusz(?m)^Cpus_allowed:\s*(.*)$r   ,    1)lenossched_getaffinityAttributeErrorreopenreadsearchbinintgroupreplacecountOSErrormultiprocessing	cpu_countImportErrorNotImplementedError)r)   fstatusmresr3   r   r   r   _available_cpu_countD   s2   

"
r;   fdc                 C   s>   t tdrts	dS zt| tjt W dS  ty   Y dS w )z
    Set pipe size to maximum on platforms that support it.
    :param fd: The file descriptor to increase the pipe size for.
    r   N)r   fcntl_MAX_PIPE_SIZEr   r2   )r<   r   r   r   _set_pipe_size_to_max_   s   r?   programc              	   C   s   t jddd\}}zWt|d}|tdtd  W d   n1 s'w   Y  ztj| dd	|gd
ttd}|j	dkW W t
| t
| S  tjy`   Y W t
| t
| dS w t
| t
| w )zt
    Check if a concatenated gzip file can be read properly. Not all deflate
    programs handle this properly.
    .gzzxopen.)suffixprefixwbs   ABs   CDNz-cz-dT)checkstderrstdouts   ABCDF)tempfilemkstempr*   writegzipcompress
subprocessrunr	   rG   r&   closeremoveCalledProcessError)r@   r<   Z	temp_path	temp_fileresultr   r   r   _can_read_concatenated_gzl   s&   


rT   c                   @   s4   e Zd ZdZdd Zdd Zdd Zedd	 Zd
S )Closingzl
    Inherit from this class and implement a close() method to offer context
    manager functionality.
    c                 C      | S Nr   selfr   r   r   	__enter__      zClosing.__enter__c                 G   s   |    d S rW   )rO   )rY   exc_infor   r   r   __exit__      zClosing.__exit__c                 C   s$   z|    W d S  ty   Y d S w rW   )rO   	ExceptionrX   r   r   r   __del__   s
   zClosing.__del__c                 C      d S rW   r   rX   r   r   r   rO      s   zClosing.closeN)	__name__
__module____qualname____doc__rZ   r]   r`   r   rO   r   r   r   r   rU      s    rU   c                
   @   s   e Zd ZdZ				ddedee dedee fdd	Zd
d Zdedee dede	de
f
ddZdeddfddZdddZdd Zdd ZdS )PipedCompressionWriterzS
    Write Compressed files by running an external process and piping into it.
    wtNr@   compresslevelthreads_flagthreadsc                 C   s   |dvrt d|t||| _d| _|| _|| _|| _|| _|du r*t	t
 d}|| _z| |||| j| _W n tyF   | j   w | jjdusOJ t| jj  d|vret| jj| _dS | jj| _dS )a)  
        mode -- one of 'w', 'wt', 'wb', 'a', 'at', 'ab'
        compresslevel -- compression level
        threads_flag -- which flag is used to denote the number of threads in the program.
            If set to none, program will be called without threads flag.
        threads (int) -- number of threads. If this is set to None, a reasonable default is
            used. At the moment, this means that the number of available CPU cores is used, capped
            at four to avoid creating too many threads. Use 0 to use all available cores.
        )wrg   rD   aatabz?Mode is '{}', but it must be 'w', 'wt', 'wb', 'a', 'at' or 'ab'FN   b)
ValueErrorformatr*   outfileclosedname_mode_program_threads_flagminr;   _threads_open_processprocessr2   rO   stdinr?   filenoioTextIOWrapper_file)rY   r   r@   moderh   ri   rj   r   r   r   __init__   s4   


zPipedCompressionWriter.__init__c                 C      d | jj| j| j| j| jS Nz-{}('{}', mode='{}', program='{}', threads={})rr   	__class__rb   ru   rv   rw   rz   rX   r   r   r   __repr__      zPipedCompressionWriter.__repr__r   rs   r    c           	      C   s   | j g}|dkr| jd ur|| jt|g7 }g }d|v r)|d ur)|dt| g7 }tt|td}tjdkr9d|d< t|| fi |}|S )Nr   rk   -)r}   rG   rF   win32T	close_fds)	rw   rx   r   dictr	   r
   sysplatformr   )	rY   r   rh   rj   rs   program_args
extra_argskwargsr|   r   r   r   r{      s   
z$PipedCompressionWriter._open_processargc                 C   s   | j | d S rW   )r   rJ   )rY   r   r   r   r   rJ      s   zPipedCompressionWriter.writec                 C   sL   | j rd S d| _ | j  | j }| j  |dkr$td| j|d S )NTr   z.Output {} process terminated with exit code {})	rt   r   rO   r|   waitrs   r2   rr   rw   )rY   retcoder   r   r   rO      s   


zPipedCompressionWriter.closec                 C   rV   rW   r   rX   r   r   r   __iter__   s   zPipedCompressionWriter.__iter__c                 C   s
   t d)Nznot readable)r   UnsupportedOperationrX   r   r   r   __next__      
zPipedCompressionWriter.__next__)rg   NNNr    N)rb   rc   rd   re   r   r   r.   r   r   r   r   r{   r   rJ   rO   r   r   r   r   r   r   rf      s:    
*	

rf   c                
   @   s   e Zd ZdZ			d(dededee dee fdd	Zd
d Zd)ddZ	dd Z
defddZd*deddfddZdefddZdd ZdefddZdefddZd+defd d!Zdefd"d#Zdefd$d%Zd)d&d'ZdS ),PipedCompressionReaderzA
    Open a pipe to a process for reading a compressed file.
    rNr@   r   ri   rj   c                 C   s   |dvrt d||| _|d|g}|dur%|du rd}||t|g7 }|| _t|ttd| _|| _| jj	dus;J t
| jj	  || _d|vrSt| jj	| _n| jj	| _| jjdus`J t| jj| _d| _td	 |   dS )
z@
        Raise an OSError when pigz could not be found.
        )r   rtrbz.Mode is '{}', but it must be 'r', 'rt' or 'rb'z-cdNr   )rG   rF   rp   Fg{Gz?)rq   rr   rw   r   rz   r   r	   r|   ru   rG   r?   r~   rv   r   r   r   rF   _stderrrt   timesleep_raise_if_error)rY   r   r@   r   ri   rj   r   r   r   r   r     s,   


zPipedCompressionReader.__init__c                 C   r   r   r   rX   r   r   r   r   1  r   zPipedCompressionReader.__repr__r    c                 C   sd   | j rd S d| _ | j }|d u r| j  d}nd}| j  | j  | j|d | j  d S )NTF)allow_sigterm)	rt   r|   poll	terminater   r   rO   r   r   )rY   r   r   r   r   r   rO   :  s   



zPipedCompressionReader.closec                 C   rV   rW   r   rX   r   r   r   r   J  r[   zPipedCompressionReader.__iter__c                 C   
   | j  S rW   )r   r   rX   r   r   r   r   M  r   zPipedCompressionReader.__next__Fr   c                 C   sh   | j  }|dur.|dkr0|r|tj ks2| j  }| j  | j  t	d
||dS dS dS )z
        Raise IOError if process is not running anymore and the exit code is
        nonzero. If allow_sigterm is set and a SIGTERM exit code is
        encountered, no error is raised.
        Nr   z{} (exit code {}))r|   r   signalSIGTERMr   r+   stripr   rO   r2   rr   )rY   r   r   messager   r   r   r   P  s   


z&PipedCompressionReader._raise_if_errorc                 G      | j j| S rW   )r   r+   rY   argsr   r   r   r+   `  r^   zPipedCompressionReader.readc                 G   r   rW   )r   readintor   r   r   r   r   c  r^   zPipedCompressionReader.readintoc                 G   r   rW   )r   readliner   r   r   r   r   f  r^   zPipedCompressionReader.readlinec                 C   r   rW   )r   seekablerX   r   r   r   r   i  r   zPipedCompressionReader.seekablenc                 C   s   | j |S rW   )r   peek)rY   r   r   r   r   r   l  r^   zPipedCompressionReader.peekc                 C   r   rW   )r   readablerX   r   r   r   r   o  r   zPipedCompressionReader.readablec                 C   r   rW   )r   writablerX   r   r   r   r   r  r   zPipedCompressionReader.writablec                 C   ra   rW   r   rX   r   r   r   flushu  r[   zPipedCompressionReader.flushr   NNr   )FrW   )rb   rc   rd   re   r   r   r.   r   r   rO   r   r   r   boolr   r+   r   r   r   r   r   r   r   r   r   r   r   r      s6    
.
	r   c                       0   e Zd ZdZddedee f fddZ  ZS )	r   z
    Open a pipe to pigz for reading a gzipped file. Even though pigz is mostly
    used to speed up writing by using many compression threads, it is
    also faster when reading, even when forced to use a single thread
    (ca. 2x speedup).
    r   Nr   rj   c              
      sD   zt  |d|d| W d S  ty!   t  |d|d | Y d S w )Npigz-prK   )superr   r2   )rY   r   r   rj   r   r   r   r     s
   zPipedGzipReader.__init__)r   N	rb   rc   rd   re   r   r   r.   r   __classcell__r   r   r   r   r   y  s    $r   c                       s>   e Zd ZdZ			d	dedee dee f fddZ  ZS )
r   a  
    Write gzip-compressed files by running an external gzip or pigz process and
    piping into it. pigz is tried first. It is fast because it can compress using
    multiple cores. Also it is more efficient on one core.
    If pigz is not available, a gzip subprocess is used. On Python 3, gzip.GzipFile is on
    par with gzip itself, but running an external gzip can still reduce wall-clock
    time because the compression happens in a separate process.
    rg   Nr   rh   rj   c                    sf   |dur|t ddvrtdzt |d||d| W dS  ty2   t |d||d| Y dS w )a  
        mode -- one of 'w', 'wt', 'wb', 'a', 'at', 'ab'
        compresslevel -- compression level
        threads (int) -- number of pigz threads. If this is set to None, a reasonable default is
            used. At the moment, this means that the number of available CPU cores is used, capped
            at four to avoid creating too many threads. Use 0 to let pigz use all available cores.
        Nr   
   z%compresslevel must be between 1 and 9r   r   rK   )rangerq   r   r   r2   )rY   r   r   rh   rj   r   r   r   r     s   zPipedGzipWriter.__init__)rg   NNr   r   r   r   r   r     s    r   c                       s(   e Zd ZdZddef fddZ  ZS )PipedIGzipReadera  
    Uses igzip for reading of a gzipped file. This is much faster than either
    gzip or pigz which were written to run on a wide array of systems. igzip
    can only run on x86 and ARM architectures, but is able to use more
    architecture-specific optimizations as a result.
    r   r   c                    s$   t dstdt |d| d S )Nr   zThis version of igzip does not support reading concatenated gzip files and is therefore not safe to use. See: https://github.com/intel/isa-l/issues/143)rT   rq   r   r   )rY   r   r   r   r   r   r     s
   zPipedIGzipReader.__init__)r   )rb   rc   rd   re   r   r   r   r   r   r   r   r     s    r   c                       r   )	PipedIGzipWritera  
    Uses igzip for writing a gzipped file. This is much faster than either
    gzip or pigz which were written to run on a wide array of systems. igzip
    can only run on x86 and ARM architectures, but is able to use more
    architecture-specific optimizations as a result.

    Threads are supported by a flag, but do not add any speed. Also on some
    distro version (isal package in debian buster) the thread flag is not
    present. For these reason threads are omitted from the interface.
    Only compresslevel 0-3 are supported and these output slightly different
    filesizes from their pigz/gzip counterparts.
    See: https://gist.github.com/rhpvorderman/4f1201c3f39518ff28dde45409eb696b
    rg   Nr   rh   c                    s4   |d ur|t ddvrtdt |d|| d S )Nr   ro   z%compresslevel must be between 0 and 3r   )r   rq   r   r   )rY   r   r   rh   r   r   r   r     s   zPipedIGzipWriter.__init__)rg   Nr   r   r   r   r   r     s    $r   r   c                 C   s*   t tjtjd| d  }t| | ddS )N)r   rk   r   F)r   closefd)r   r   r}   rG   r*   r~   )r   Zstdr   r   r   _open_stdin_or_out  s   r   c                 C   s   t | |S rW   )bz2r*   filenamer   r   r   r   	_open_bz2  r^   r   c                 C   s   t d u rtdt | |S )NzPCannot open xz files: The lzma module is not available (use Python 3.3 or newer))lzmar5   r*   r   r   r   r   _open_xz  s
   r   c              	   C   sp   d|v rzt | |W S  ttfy   t| ||d Y S w zt| ||W S  ttfy7   t| |||d Y S w )Nr   )rj   )r   r2   rq   r   r   r   r   r   rh   rj   r   r   r   _open_gz_external  s   
r   c                 C   s   |dkrzt | |||W S  ty   Y nw d|v r*td ur$t| |S t| |S td urKztj| ||d u r=tjdW S |dW S  tyJ   Y nw tj| ||d u rWddS |dS )Nr   r   )rh      )r   r2   r   r*   rK   r   ZISAL_DEFAULT_COMPRESSIONrq   r   r   r   r   _open_gz  s4   
r   r   c                 C   s   zJt t | jrEt| d}|d}W d   n1 sw   Y  |dd dkr/W dS |dd dkr:W d	S |dd d
krHW dS W dS W dS  tyT   Y dS w )z
    Attempts to detect file format from the content by reading the first
    6 bytes. Returns None if no format could be detected.
    r   r   N   s   gz   s   BZhr   s   7zXZ xz)statS_ISREGr&   st_moder*   r+   r2   )r   fhbsr   r   r   _detect_format_from_content
  s&   r   c                 C   s.   |  drdS |  drdS |  drdS dS )zv
    Attempts to detect file format from the filename extension.
    Returns None if no format could be detected.
    z.bz2r   z.xzr   rA   r   N)endswith)r   r   r   r   _detect_format_from_extension"  s   


r   r   rh   rj   c                 C   s   |dv r|d7 }|dvrt d|t| } | dkrt|S t| }|du r/d|vr/t| }|dkr:t| |||S |d	krCt| |S |d
krLt| |S t	| |S )a  
    A replacement for the "open" function that can also read and write
    compressed files transparently. The supported compression formats are gzip,
    bzip2 and xz. If the filename is '-', standard output (mode 'w') or
    standard input (mode 'r') is returned.

    The file type is determined based on the filename: .gz is gzip, .bz2 is bzip2, .xz is
    xz/lzma and no compression assumed otherwise.

    mode can be: 'rt', 'rb', 'at', 'ab', 'wt', or 'wb'. Also, the 't' can be omitted,
    so instead of 'rt', 'wt' and 'at', the abbreviations 'r', 'w' and 'a' can be used.

    In Python 2, the 't' and 'b' characters are ignored.

    Append mode ('a', 'at', 'ab') is not available with BZ2 compression and
    will raise an error.

    compresslevel is the compression level for writing to gzip files.
    This parameter is ignored for the other compression formats. If set to
    None (default), level 6 is used.

    threads only has a meaning when reading or writing gzip files.

    When threads is None (the default), reading or writing a gzip file is done with a pigz
    (parallel gzip) subprocess if possible. See PipedGzipWriter and PipedGzipReader.

    When threads = 0, no subprocess is used.
    )r   rk   rl   t)r   r   rg   rD   rm   rn   zMode '{}' not supportedr   Nrk   r   r   r   )
rq   rr   r   r   r   r   r   r   r   r*   )r   r   rh   rj   Zdetected_formatr   r   r   r   1  s"   "


r   r   )?re   __all__rK   r   r   r&   r   r   r   r   r   rM   rH   abcr   r   r   r	   r
   typingr   r   r   r   _versionr   r   r   r5   Zisalr   r   r=   r   r   setattrr   Z_MAX_PIPE_SIZE_PATHexistsr.   	read_textr>   r   r;   r?   r   r   rT   rU   rf   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   s    
d{