B
    q\`                 @   sN  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Zd dlZd dlZd dlmZ d dlZddlmZmZmZmZmZmZmZmZmZmZ d dlmZm Z  d dl!m"Z"m#Z# d dl$m%Z% ddd	d
dddZ&dddddddZ'e(dZ)ej*ej*ej+ej*ej,dZ-dZ.dZ/dZ0dd Z1G dd dZ2dS )    N)reduce   )

isreadable
iswritableisfilefileobj_openfileobj_namefileobj_closedfileobj_mode_array_from_file_array_to_file_write_string)download_file_is_url)classpropertydeprecated_renamed_argument)AstropyUserWarningrbzrb+zab+wb)readonlycopyonwriteupdateappendostream	denywriter   r   r   r   )r   zrb+r   zwb+Zabzab+z^[rwa]((t?\+?)|(\+?t?))$)r   r   r   r   r   s   s   PKs   BZc             C   sP   | d k	rL| t krLt| r(td| t| }|t krHtd| |} | S )NzAText mode '{}' not supported: files must be opened in binary modezMode '{}' not recognized)IO_FITS_MODESTEXT_REmatch
ValueErrorformat
FILE_MODESget)modeZnew_mode r#   3lib/python3.7/site-packages/astropy/io/fits/file.py_normalize_fits_modeN   s    

r%   c               @   s   e Zd ZdZedddd9dd	Zd
d Zdd Zdd Zdd Z	d:ddZ
ddejdfddZdd Zdd Zdd Zdd Zd;dd Zd!d" Zd<d#d$Zd%d& Zd=d'd(Zd)d* Zd>d,d-Zd.d/ Zd0d1 Zd2d3 Zedd4d5d6 Zd7d8 ZdS )?_FilezM
    Represents a FITS file on disk (or in some other file-like object).
    Zclobber	overwritez2.0NFTc             C   s  t || _|d krdn|}|d krbd | _d| _d| _|| _|| _d | _d| _d| _	d| _
d| _d S d| _
t|tjr~t|}nt|trtdd | _|d k	r|tkrtd|t|rtt|}|d k	r||krtd|||}|d krd}t|tr(|dkr(t|r(t||d| _nBt|tjjr`|dkrPtd	|t |! }n
t"|| _d| _d| _|| _|| _d| _#d| _d | _d| _d| _	t|r| $||| n*t|tr| %||| n| &||| t| j| _t|t'j(rd
| _n*t|t)j*rd| _nt|t+j,r0d| _|dksL| jrT|dkrTd| _n"|dksp| jrv|dkrvd| _	|dks| jst-| jdsd| _.n0| j/ }| j0dd | j/ | _.| j0| | jr t| jsd| _n| js | j1s d| _d S )NTFz"names should be `str` not `bytes`.zMode '{}' not recognizedzGRequested FITS mode '{}' not compatible with open file handle mode '{}'r   )r   r   r   )cachez&Mode {} not supported for HTTPResponsegzipzipbzip2)r   r   r   r   r   r   seekr      )2boolZstrict_memmap_fileclosedZbinaryr"   memmapcompressionr   	writeonlyZsimulateonlyclose_on_error
isinstancepathlibZPathstrbytes	TypeError_mmapr   r   r   r   r%   r
   r   r   namehttpZclientZHTTPResponseioBytesIOreadr   	file_like_open_fileobj_open_filename_open_fileliker)   GzipFilezipfileZipFilebz2BZ2Filehasattrsizetellr,   _mmap_available)selffileobjr"   r1   r'   r(   Zobjmodeposr#   r#   r$   __init___   s    


	






z_File.__init__c             C   s   d | j| jj| jS )Nz
<{}.{} {}>)r   
__module__	__class____name__r/   )rM   r#   r#   r$   __repr__   s    z_File.__repr__c             C   s   | S )Nr#   )rM   r#   r#   r$   	__enter__   s    z_File.__enter__c             C   s   |    d S )N)close)rM   typevalue	tracebackr#   r#   r$   __exit__   s    z_File.__exit__c             C   s   | j r
dS t| jS )NF)r3   r   r/   )rM   r#   r#   r$   readable   s    z_File.readablec             C   sF   t | jdsty| j|S  tk
r@   | jdkr:dS  Y nX d S )Nr?   r)    )rI   r/   EOFErrorr?   OSErrorr2   )rM   rJ   r#   r#   r$   r?      s    
z
_File.readr   c          
   C   s  t | jdstt|tjs&t|}|rH||j dkrHtd||t|t	rX|f}|sp|spt
dt d}|r|s||j f}|r|rt||j }||krtd|||n||k rtd|||| j }z | jr| jdkrt| j }| jdd ytj| j d|dd	| _W nl tk
r } zL|jtjkr| jd
krt
dt tj| j dtd dd	| _n W dd}~X Y nX tj|||| jdS ttj|}	| j| t| j||	}
||
_|
S W d| j| X dS )a*  
        Similar to file.read(), but returns the contents of the underlying
        file as a numpy array (or mmap'd array if memmap=True) rather than a
        string.

        Usually it's best not to use the `size` argument with this method, but
        it's provided for compatibility.
        r?   r   zsize {} not a multiple of {}z?No size or shape given to readarray(); assuming a shape of (1,))r   z-size {} is too few bytes for a {} array of {}z.size {} is too many bytes for a {} array of {}N)accessoffsetr   zCould not memory map array with mode='readonly', falling back to mode='denywrite', which means that the array will be read-onlyr   )shapedtyper`   buffer)rI   r/   r]   r5   nprb   itemsizer   r   intwarningswarnr   ZprodrK   r1   r:   MEMMAP_MODESr"   r,   mmapfilenor^   errnoZENOMEMZndarrayr   operatormulr   ra   )rM   rJ   r`   rb   ra   Z
actualsizeZfileposZaccess_modeexccountdatar#   r#   r$   	readarray   s`    




	

z_File.readarrayc             C   s   | j r
dS t| jS )NF)r   r   r/   )rM   r#   r#   r$   writable[  s    z_File.writablec             C   s   t | jdrt| j| d S )Nwrite)rI   r/   r   )rM   stringr#   r#   r$   rt   `  s    z_File.writec             C   s   t | jdrt|| j dS )z
        Similar to file.write(), but writes a numpy array instead of a string.

        Also like file.write(), a flush() or close() may be needed before
        the file on disk reflects the data written.
        rt   N)rI   r/   r   )rM   Zarrayr#   r#   r$   
writearrayd  s    z_File.writearrayc             C   s   t | jdr| j  d S )Nflush)rI   r/   rw   )rM   r#   r#   r$   rw   o  s    z_File.flushc             C   sR   t | jdsd S | j|| | j }| jrN|| jkrNtd| j|t d S )Nr,   z\File may have been truncated: actual file length ({}) is smaller than the expected size ({}))	rI   r/   r,   rK   rJ   rg   rh   r   r   )rM   r`   whencerO   r#   r#   r$   r,   s  s    
z
_File.seekc             C   s   t | jdst| j S )NrK   )rI   r/   r]   rK   )rM   r#   r#   r$   rK   }  s    z
_File.tellc             C   s   t | jdr| j| d S )Ntruncate)rI   r/   ry   )rM   rJ   r#   r#   r$   ry     s    z_File.truncatec             C   s4   t | jdr| j  |   d| _d| _d| _dS )z1
        Close the 'physical' FITS file.
        rV   NTF)rI   r/   rV   _maybe_close_mmapr:   r0   r4   )rM   r#   r#   r$   rV     s    
z_File.closec             C   s2   | j dk	r.t| j d| kr.| j   d| _ dS )z
        When mmap is in use these objects hold a reference to the mmap of the
        file (so there is only one, shared by all HDUs that reference this
        file).

        This will close the mmap if there are no arrays referencing it.
        Nr-   )r:   sysgetrefcountrV   )rM   Zrefcount_deltar#   r#   r$   rz     s    	

z_File._maybe_close_mmapc             C   s   | j rt|dr|jdks:tj| jrtj| jdkr|rt| j rZt|drZ|d q|sf|	  t
| j ntd| jdS )zOverwrite an existing file if ``overwrite`` is ``True``, otherwise
        raise an OSError.  The exact behavior of this method depends on the
        _File object state and is only meant for use within the ``_open_*``
        internal methods.
        lenr   ry   zFile {!r} already exists.N)r@   rI   r}   ospathexistsr;   getsizery   rV   remover^   r   )rM   r'   rN   r0   r#   r#   r$   _overwrite_existing  s     z_File._overwrite_existingr\   c             C   s   |dks| trb|dkr"tdtt| d}t|trD||d< n||d< tjf || _	d| _
np|dkst| tr| | j| d	| _
nH|d
ks| tr|dkrtd|dkrdnd}tj||d| _	d| _
| j
dk	S )z4Attempt to determine if the given file is compressedz.gzr   zH'append' mode is not supported with gzip files.Use 'update' mode instead)r"   filenamerN   r)   z.zipr*   z.bz2)r   r   z:update and append modes are not supported with bzip2 filesr   wrr+   N)
startswith
GZIP_MAGICr^   dictr   r5   r7   r)   rD   r/   r2   PKZIP_MAGIC_open_zipfiler;   BZIP2_MAGICrG   rH   )rM   Zobj_or_namemagicr"   extkwargsZ
bzip2_moder#   r#   r$   _try_read_compressed  s&    

z_File._try_read_compressedc          	   C   s   t |}t|pt| }|dkr.| ||| |s:|| _nt|rTt| jt| | _y0|dkrj| jd | j	d}| jd W n t
t
fk
r   dS X | ||| dS )zAOpen a FITS file from a file object (including compressed files).r   )r   r   r      N)r	   r
   r   r   r/   r   r   r;   r,   r?   r^   r   )rM   rN   r"   r'   r0   Zfmoder   r#   r#   r$   rA     s     z_File._open_fileobjc             C   s   d| _ || _t|r"td|t|tjr>| || dS t	| jdrVt	| jds`d | _
}|dkrv| ||d | j
dkrt	| jd	std
| j
| j
dkrt	| jdstd| j
dS )zgOpen a FITS file from a file-like object, i.e. one that has
        read and/or write methods.
        Tz;Cannot read from/write to a closed file-like object ({!r}).Nr,   rK   r   F)r   r   r   rt   zHFile-like object does not have a 'write' method, required for mode '{}'.r?   zGFile-like object does not have a 'read' method, required for mode {!r}.)r@   r/   r	   r^   r   r5   rE   rF   r   rI   r"   r   )rM   rN   r"   r'   r#   r#   r$   rC     s(    


z_File._open_filelikec          	   C   s   |dkr|  |dd tj| jrHt| jd}|d}W dQ R X nd}tj| jd }| j| j|||dst| jt	| | _
d| _t| j
tjr|dks| j
d	 dS )
z(Open a FITS file from a filename string.r   NTr   r       r   )r   r   )r   r~   r   r   r;   r   r?   splitextr   r   r/   r4   r5   rG   rH   r,   )rM   r   r"   r'   fr   r   r#   r#   r$   rB     s    z_File._open_filename)Zlazyc          
   C   s   t  \}}zt|d t| ytj|dtjd}W n: tk
rt } zt	d
t|t ~dS d}~X Y nX z2y|  W n  tk
r   t	dt dS X W d|  X W dt| t| X dS )	a  Tests that mmap, and specifically mmap.flush works.  This may
        be the case on some uncommon platforms (see
        https://github.com/astropy/astropy/issues/968).

        If mmap.flush is found not to work, ``self.memmap = False`` is
        set and a warning is issued.
            r   )r_   z4Failed to create mmap: {}; mmap use will be disabledFNzYmmap.flush is unavailable on this platform; using mmap in writeable mode will be disabledT)tempfileZmkstempr~   rt   fsyncrj   ACCESS_WRITEr^   rg   rh   r   r7   r   rw   rV   r   )clsZtmpfdZtmpnameZmmro   r#   r#   r$   rL   4  s*    



z_File._mmap_availablec             C   s   |dkrt dt|tjs,t|}d}n|}d}| }t|dkrPt dtjdd| _| j	|
|d	  |r|  | jd	 d
S )zLimited support for zipfile.ZipFile objects containing a single
        a file.  Allows reading only for now by extracting the file to a
        tempfile.
        )r   r   z7Writing to zipped fits files is not currently supportedTFr   z2Zip files with multiple members are not supported.z.fits)suffixr   N)r^   r5   rE   rF   namelistr}   r   ZNamedTemporaryFiler/   rt   r?   rV   r,   )rM   rN   r"   ZzfilerV   r   r#   r#   r$   r   Y  s"    
z_File._open_zipfile)NNNFT)N)r   )N)r   )r\   )rS   rQ   __qualname____doc__r   rP   rT   rU   rZ   r[   r?   rd   Zuint8rr   rs   rt   rv   rw   r,   rK   ry   rV   rz   r   r   rA   rC   rB   r   rL   r   r#   r#   r#   r$   r&   Z   s4   
 {
b




!&%r&   )3rG   r)   rl   Zhttp.clientr<   rj   rm   r6   r=   r~   r{   r   rg   rE   re	functoolsr   Znumpyrd   utilr   r   r   r   r   r	   r
   r   r   r   Zastropy.utils.datar   r   Zastropy.utils.decoratorsr   r   Zastropy.utils.exceptionsr   r   r    compiler   ZACCESS_COPYr   ZACCESS_READri   r   r   r   r%   r&   r#   r#   r#   r$   <module>   sN   0	



