U
    H$xe                     @   s   d dl Z d dlZd dlZd dlmZmZmZmZ d dlZd dl	m	Z	 d dl
mZ zd dlZW n ek
rt   dZY nX edddZdd	 Zd
d ZG dd dZG dd dZG dd dZG dd dZdS )    N)BinaryIOOptionalDictTuplexopen)logger)pathc                 C   s(   d}t t| |dd}td| || |S )z
    Open a (possibly compressed) file for reading in binary mode, trying to avoid the
    "Too many open files" problem using `open_raise_limit`.
    rbr   )threads1Opening '%s', mode '%s' with xopen resulted in %s)open_raise_limitr   r   debug)r	   modef r   -lib/python3.8/site-packages/cutadapt/files.pyxopen_rb_raise_limit   s    r   c              
   O   sb   z| ||}W nN t k
r\ } z0|jtjkrJtd td | ||}n W 5 d}~X Y nX |S )z
    Run 'func' (which should be some kind of open() function) and return its result.
    If "Too many open files" occurs, increase limit and try again.
    z3Too many open files, attempting to raise soft limit   N)OSErrorerrnoZEMFILEr   r   raise_open_files_limit)funcargskwargsr   er   r   r   r      s    
r   c                 C   s@   t d krd S t t j\}}t||  |}t t j||f d S N)resourceZ	getrlimitZRLIMIT_NOFILEminZ	setrlimit)nZsoftZhardr   r   r   r   .   s
    r   c                   @   sV   e Zd Zdeee dddZdd Zdd	 Zeee d
ddZ	dd Z
dd ZdS )
FileOpener   Ncompression_levelr   c                 C   s   || _ || _dS )z
        threads -- no. of external compression threads.
            0: write in-process
            None: min(cpu_count(), 4)
        Nr"   )selfr#   r   r   r   r   __init__7   s    zFileOpener.__init__c                 C   s:   d|kr| j nd}tt||| j|d}td||| |S )Nwr   )Zcompresslevelr   r   )r   r   r   r#   r   r   )r$   r	   r   r   r   r   r   r   r   @   s        zFileOpener.xopenc                 C   s   |dkrdS |  ||S )z.Return opened file or None if the path is NoneNr   )r$   r	   r   r   r   r   xopen_or_noneH   s    zFileOpener.xopen_or_none)path1path2c                 C   s8   |d kr|d k	rt d| ||}| ||}||fS )NzWWhen giving paths for paired-end files, only providing the second file is not supported)
ValueErrorr'   )r$   r(   r)   r   Zfile1Zfile2r   r   r   
xopen_pairN   s    zFileOpener.xopen_pairc                 O   sB   | j |d< tj||}t|d tjs>td|d |d | |S )NZopenerr   z/Opening %r, mode '%s' with dnaio resulted in %sr   )r   dnaioopen
isinstanceioBytesIOr   r   )r$   r   r   r   r   r   r   
dnaio_openX   s    
zFileOpener.dnaio_openc                 O   s   t | jf||S )z
        Open a FASTA/FASTQ file for writing. If it fails because the number of open files
        would be exceeded, try to raise the soft limit and re-try.
        )r   r1   )r$   r   r   r   r   r   dnaio_open_raise_limitd   s    z!FileOpener.dnaio_open_raise_limit)r!   N)__name__
__module____qualname__intr   r%   r   r'   strr+   r1   r2   r   r   r   r   r    6   s   	
r    c                   @   s8   e Zd ZddeedddZdd Zdd	d
dZdS )
InputFilesFinterleaved)filesr:   c                G   s(   || _ || _| j D ]}|d k	stqd S r   )_filesr:   AssertionError)r$   r:   r;   r   r   r   r   r%   m   s    
zInputFiles.__init__c                 C   s   t j| j| jddS )Nr)r:   r   )r,   r-   r<   r:   )r$   r   r   r   r-   w   s    zInputFiles.openNreturnc                 C   s   | j D ]}|  qd S r   )r<   close)r$   filer   r   r   rA   z   s    
zInputFiles.close)r3   r4   r5   r   boolr%   r-   rA   r   r   r   r   r8   l   s   
r8   c                   @   s0   e Zd ZddeedddZedddZd	S )

InputPathsFr9   pathsr:   c                G   s   || _ || _d S r   rE   )r$   r:   rF   r   r   r   r%      s    zInputPaths.__init__r?   c                 C   s    dd | j D }t|d| jiS )Nc                 S   s   g | ]}t |qS r   )r   ).0r	   r   r   r   
<listcomp>   s     z#InputPaths.open.<locals>.<listcomp>r:   )rF   r8   r:   )r$   r;   r   r   r   r-      s    zInputPaths.openN)r3   r4   r5   r7   rC   r%   r8   r-   r   r   r   r   rD      s   rD   c                   @   s   e Zd ZdZdee ee ee ee ee ee ee ee ee ee ee eeeef  eeeef  eeeeef ef  eeeeef ef  ee	 dddZ
dd Zd dd	d
ZddddZdS )OutputFilesz
    The attributes are either None or open file-like objects except for demultiplex_out
    and demultiplex_out2, which are dictionaries that map an adapter name
    to a file-like object.
    Noutout2	untrimmed
untrimmed2	too_short
too_short2too_long	too_long2inforestwildcarddemultiplex_outdemultiplex_out2combinatorial_outcombinatorial_out2force_fastac                 C   sd   || _ || _|| _|| _|| _|| _|| _|| _|	| _|
| _	|| _
|| _|| _|| _|| _|| _d S r   rJ   )r$   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   rZ   r   r   r   r%      s     zOutputFiles.__init__c                 c   s   | j | j| j| j| j| j| j| j| j| j	| j
fD ]}|d k	r0|V  q0| j| j| j| jfD ],}|d k	rX| D ]}|d k	s|t|V  qlqXd S r   )rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rV   rW   rX   rY   valuesr=   )r$   r   Zoutsr   r   r   __iter__   s.    zOutputFiles.__iter__r?   c                 C   s   t | jd}dD ]"}t| |dk	rt||t  qdD ]J}t| |dk	r8t||t  t| | D ]\}}t t|||< qfq8|S )zl
        Create a new OutputFiles instance that has BytesIO instances for each non-None output file
        )rZ   )rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   N)rV   rW   rX   rY   )rI   rZ   getattrsetattrr/   r0   dictitems)r$   resultattrkvr   r   r   
as_bytesio   s    zOutputFiles.as_bytesioc                 C   s.   | D ]$}|t jks|t jjkr q|  qdS )z*Close all output files that are not stdoutN)sysstdoutbufferrA   )r$   r   r   r   r   rA      s    zOutputFiles.close)NNNNNNNNNNNNNNNN)r3   r4   r5   __doc__r   r   r   r7   r   rC   r%   r\   re   rA   r   r   r   r   rI      sL                   $ rI   )r   r/   rf   typingr   r   r   r   r,   r   Zcutadapt.utilsr   r   ImportErrorr7   r   r   r   r    r8   rD   rI   r   r   r   r   <module>   s"   
6
