U
    e»{jG  ã                   @   sn   d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlZ	dgZ
G dd„ deƒZG dd„ de jd�ZdS )	é    N)ÚOrderedDict)Ú
itemgetterÚIORegistryErrorc                   @   s   e Zd ZdZdS )r   z"Custom error for registry clashes.N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__© r	   r	   úW/var/www/html/bwave/python/venv/lib/python3.8/site-packages/astropy/io/registry/base.pyr      s   c                   @   s~   e Zd ZdZdd„ Zedd„ ƒZddd„Zej	d	d
„ ƒZ
ddd„Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )Ú_UnifiedIORegistryBasea�  Base class for registries in Astropy's Unified IO.

    This base class provides identification functions and miscellaneous
    utilities. For an example how to build a registry subclass we suggest
    :class:`~astropy.io.registry.UnifiedInputRegistry`, which enables
    read-only registries. These higher-level subclasses will probably serve
    better as a baseclass, for instance
    :class:`~astropy.io.registry.UnifiedIORegistry` subclasses both
    :class:`~astropy.io.registry.UnifiedInputRegistry` and
    :class:`~astropy.io.registry.UnifiedOutputRegistry` to enable both
    reading from and writing to files.

    .. versionadded:: 5.0

    c                 C   s4   t ƒ | _tƒ | _tddd�| jd< d| _tƒ | _d S )NÚ_identifierszAuto-identify)ÚattrÚcolumnÚidentify)r   )r   r   ÚdictÚ_registriesÚ_registries_orderÚsetÚ_delayed_docs_classes©Úselfr	   r	   r
   Ú__init__)   s
    z_UnifiedIORegistryBase.__init__c                 C   s
   | j  ¡ S )zUAvailable registries.

        Returns
        -------
        ``dict_keys``
        )r   Úkeysr   r	   r	   r
   Úavailable_registries7   s    z+_UnifiedIORegistryBase.available_registriesNc              	      s  ddl m} d‡fdd„ˆjD ƒd˜}| d¡}| d¡}| ˆjˆjd  d ¡‰| d¡}tƒ }ˆj ¡ d	h D ] }	|ttˆˆj|	 d
 ƒƒO }qtt|t	dƒd�}
g }|
D ]‚\‰‰ |dk	rÎˆ 
|ˆ |
¡sÎq®‡ ‡‡fdd„ˆj ¡ D ƒ‰dˆ ˆ f}||
k�rdnd}| ˆ jˆf‡fdd„ˆjD ƒ|f˜¡ q®t|ƒ ¡ ˆjk�rpˆj t|ƒ ¡ ¡‰‡‡fdd„|D ƒ}n|dk	�rŒtdˆj› d�ƒ‚|�r°ttt|t	|||ƒd�Ž ƒ}nd}t ¡ �@ tjdtd� |||d�}t |d jdk¡�sø| d¡ W 5 Q R X |S )a{  
        Get the list of registered formats as a `~astropy.table.Table`.

        Parameters
        ----------
        data_class : class or None, optional
            Filter readers/writer to match data class (default = all classes).
        filter_on : str or None, optional
            Which registry to show. E.g. "identify"
            If None search for both.  Default is None.

        Returns
        -------
        format_table : :class:`~astropy.table.Table`
            Table of available I/O formats.

        Raises
        ------
        ValueError
            If ``filter_on`` is not None nor a registry name.
        r   )ÚTableú
Data classÚFormatc                    s   g | ]}ˆ j | d  ‘qS )r   )r   )Ú.0Úkr   r	   r
   Ú
<listcomp>]   s     z6_UnifiedIORegistryBase.get_formats.<locals>.<listcomp>Ú
Deprecatedr   r   r   ©ÚkeyNc                    s0   i | ](\}}|ˆˆ ft ˆ|d  ƒkr(dnd“qS )r   ÚYesZNo)Úgetattr)r   r   Úv)ÚclsÚfmtr   r	   r
   Ú
<dictcomp>w   s   ÿ z6_UnifiedIORegistryBase.get_formats.<locals>.<dictcomp>zascii.r#   Ú c                    s   g | ]}ˆ | ‘qS r	   r	   )r   Ún)Úhas_r	   r
   r   ‡   s     c                    s    g | ]}|ˆ ˆ  d kr|‘qS )r#   r	   )r   Úrow)Ú
i_regstartÚindexr	   r
   r   �   s      z5unrecognized value for "filter_on": {0}.
Allowed are z
 and None.Úignore)ÚactionÚcategory)Únames)r   r   )r    )Zastropy.tabler   r   r.   r   r   r   r$   Úsortedr   Ú_is_best_matchÚitemsÚappendr   ÚstrÚlowerÚ
ValueErrorÚlistÚzipÚwarningsÚcatch_warningsÚsimplefilterÚFutureWarningÚnpÚanyÚdataÚremove_column)r   Ú
data_classÚ	filter_onr   ÚcolnamesZi_dataclassZi_formatZi_deprecatedÚregsr   Úformat_classesÚrowsZascii_format_classÚ
deprecatedrB   Úformat_tabler	   )r&   r'   r+   r-   r.   r   r
   Úget_formatsA   sp      þ ü

ÿ
  ÿþþüÿ

ÿÿ
z"_UnifiedIORegistryBase.get_formatsc                 c   sD   | j  |¡ dV  | j  |¡ | j ¡ dh D ]}|  ||¡ q.dS )až  Contextmanager to disable documentation updates when registering
        reader and writer. The documentation is only built once when the
        contextmanager exits.

        .. versionadded:: 1.3

        Parameters
        ----------
        cls : class
            Class for which the documentation updates should be delayed.

        Notes
        -----
        Registering multiple readers and writers can cause significant overhead
        because the documentation of the corresponding ``read`` and ``write``
        methods are build every time.

        Examples
        --------
        see for example the source code of ``astropy.table.__init__``.
        Nr   )r   ÚaddÚdiscardr   r   Ú_update__doc__)r   r&   Úmethodr	   r	   r
   Údelay_doc_updates¬   s
    z(_UnifiedIORegistryBase.delay_doc_updatesFc                 C   s>   ||f| j ks|r"|| j ||f< ntd|›d|j›d�ƒ‚dS )an  
        Associate an identifier function with a specific data type.

        Parameters
        ----------
        data_format : str
            The data format identifier. This is the string that is used to
            specify the data type when reading/writing.
        data_class : class
            The class of the object that can be written.
        identifier : function
            A function that checks the argument specified to `read` or `write` to
            determine whether the input can be interpreted as a table of type
            ``data_format``. This function should take the following arguments:

               - ``origin``: A string ``"read"`` or ``"write"`` identifying whether
                 the file is to be opened for reading or writing.
               - ``path``: The path to the file.
               - ``fileobj``: An open file object to read the file's contents, or
                 `None` if the file could not be opened.
               - ``*args``: Positional arguments for the `read` or `write`
                 function.
               - ``**kwargs``: Keyword arguments for the `read` or `write`
                 function.

            One or both of ``path`` or ``fileobj`` may be `None`.  If they are
            both `None`, the identifier will need to work from ``args[0]``.

            The function should return True if the input can be identified
            as being of format ``data_format``, and False otherwise.
        force : bool, optional
            Whether to override any existing function if already present.
            Default is ``False``.

        Examples
        --------
        To set the identifier based on extensions, for formats that take a
        filename as a first argument, you can do for example

        .. code-block:: python

            from astropy.io.registry import register_identifier
            from astropy.table import Table
            def my_identifier(*args, **kwargs):
                return isinstance(args[0], str) and args[0].endswith('.tbl')
            register_identifier('ipac', Table, my_identifier)
            unregister_identifier('ipac', Table)
        zIdentifier for format ú and class z is already definedN)r   r   r   )r   Údata_formatrD   Ú
identifierÚforcer	   r	   r
   Úregister_identifierÎ   s
    1ÿz*_UnifiedIORegistryBase.register_identifierc                 C   s:   ||f| j kr | j  ||f¡ ntd|›d|j›�ƒ‚dS )zõ
        Unregister an identifier function

        Parameters
        ----------
        data_format : str
            The data format identifier.
        data_class : class
            The class of the object that can be read/written.
        z!No identifier defined for format rR   N)r   Úpopr   r   )r   rS   rD   r	   r	   r
   Úunregister_identifier  s
    ÿz,_UnifiedIORegistryBase.unregister_identifierc           
      C   sP   g }| j D ]@\}}	|  ||	| j ¡r
| j ||	f |||f|ž|Žr
| |¡ q
|S )a  Loop through identifiers to see which formats match.

        Parameters
        ----------
        origin : str
            A string ``"read`` or ``"write"`` identifying whether the file is to be
            opened for reading or writing.
        data_class_required : object
            The specified class for the result of `read` or the class that is to be
            written.
        path : str or path-like or None
            The path to the file or None.
        fileobj : file-like or None.
            An open file object to read the file's contents, or ``None`` if the
            file could not be opened.
        args : sequence
            Positional arguments for the `read` or `write` function. Note that
            these must be provided as sequence.
        kwargs : dict-like
            Keyword arguments for the `read` or `write` function. Note that this
            parameter must be `dict`-like.

        Returns
        -------
        valid_formats : list
            List of matching formats.
        )r   r4   r6   )
r   ÚoriginZdata_class_requiredÚpathÚfileobjÚargsÚkwargsÚvalid_formatsrS   rD   r	   r	   r
   Úidentify_format  s      ÿÿÿz&_UnifiedIORegistryBase.identify_formatc                 C   s,   |   ||¡}| d¡ d |jdd�¡}|S )z9``get_formats()``, without column "Data class", as a str.r   Ú
éÿÿÿÿ)Ú	max_lines)rL   rC   ÚjoinÚpformat)r   rD   rE   rK   Úformat_table_strr	   r	   r
   Ú_get_format_table_strC  s    
z,_UnifiedIORegistryBase._get_format_table_strc                 C   sD   t ||ƒr@dd„ |D ƒ}|jD ] }||kr0 dS ||kr dS qdS )a€  
        Determine if class2 is the "best" match for class1 in the list
        of classes.  It is assumed that (class2 in classes) is True.
        class2 is the the best match if:

        - ``class1`` is a subclass of ``class2`` AND
        - ``class2`` is the nearest ancestor of ``class1`` that is in classes
          (which includes the case that ``class1 is class2``)
        c                 S   s   h | ]\}}|’qS r	   r	   )r   r'   r&   r	   r	   r
   Ú	<setcomp>U  s     z8_UnifiedIORegistryBase._is_best_match.<locals>.<setcomp>TF)Ú
issubclassÚ__mro__)r   Zclass1Zclass2rH   ÚclassesÚparentr	   r	   r
   r4   J  s    


z%_UnifiedIORegistryBase._is_best_matchc           	      C   sb   |   ||||||¡}t|ƒdkr@|  || ¡ ¡}td|› �ƒ‚nt|ƒdkrZ|  |||¡S |d S )z”
        Returns the first valid format that can be used to read/write the data in
        question.  Mode can be either 'read' or 'write'.
        r   z‚Format could not be identified based on the file name or contents, please provide a 'format' argument.
The available formats are:
é   )r_   Úlenrf   Ú
capitalizer   Ú_get_highest_priority_format)	r   Úmoder&   rZ   r[   r\   r]   r^   re   r	   r	   r
   Ú_get_valid_format]  s    ÿz(_UnifiedIORegistryBase._get_valid_formatc              	   C   sÈ   |dkr| j }d}n|dkr&| j}d}g }tj }|D ]\}z|||f \}	}
W n tk
rj   tj }
Y nX |
|kr€| |¡ q6|
|kr6|g}|
}q6t|ƒdkrÀtdd t	|t
dƒd	�¡› �ƒ‚|d S )
zh
        Returns the reader or writer with the highest priority. If it is a tie,
        error.
        ÚreadÚreaderÚwriteÚwriterrl   z#Format is ambiguous - options are: z, r   r!   )Ú_readersÚ_writersr@   ÚinfÚKeyErrorr6   rm   r   rc   r3   r   )r   rp   r&   r^   Zformat_dictZmode_loaderZbest_formatsZcurrent_priorityÚformatÚ_Úpriorityr	   r	   r
   ro   q  s.    ÿz3_UnifiedIORegistryBase._get_highest_priority_formatc                    sŠ  t ||ƒsdS ddlm} d‰ t||ƒ}t|jtƒs8dS |j ¡ }‡ fdd„t|ƒD ƒ}|rp|d }|d|… }dd„ |dd… D ƒ}d	t	d
d„ |D ƒƒ ‰|  
|| ¡ ¡}	|	 d¡ |	jddd�}
t dd|
d ¡}||
d< |
 d|¡ |
 |¡ d|	jk�r|
 dddg¡ ˆ dg|
 }
| ‡fdd„|
D ƒ¡ t||ƒ�rPd |¡|j_n6zd |¡|_W n$ tk
�r„   d |¡|j_Y nX dS )zò
        Update the docstring to include all the available readers / writers for
        the ``data_class.read``/``data_class.write`` functions (respectively).
        Don't update if the data_class does not have the relevant method.
        Nrl   )ÚUnifiedReadWritez#The available built-in formats are:c                    s   g | ]\}}ˆ |kr|‘qS r	   r	   )r   ÚiiÚline)ÚFORMATS_TEXTr	   r
   r   ­  s      z9_UnifiedIORegistryBase._update__doc__.<locals>.<listcomp>r   c                 S   s   g | ]}t  d |¡‘qS )z(\S))ÚreÚsearch©r   r   r	   r	   r
   r   ´  s     ú c                 s   s   | ]}|r|  ¡ V  qd S )N)Ústart)r   Úmatchr	   r	   r
   Ú	<genexpr>µ  s      z8_UnifiedIORegistryBase._update__doc__.<locals>.<genexpr>r   ra   éP   )rb   Ú	max_widthú-ú=r    r)   zZDeprecated format names like ``aastex`` will be removed in a future version. Use the full z%name (e.g. ``ascii.aastex``) instead.c                    s   g | ]}ˆ | ‘qS r	   r	   rƒ   )Úleft_indentr	   r
   r   Ð  s     r`   )ÚhasattrZ	interfacer}   r$   Ú
isinstancer   r7   Ú
splitlinesÚ	enumerateÚminrL   rn   rC   rd   r�   ÚsubÚinsertr6   rF   Úextendrc   Ú	__class__ÚAttributeErrorÚ__func__)r   rD   Z	readwriter}   Zclass_readwrite_funcÚlinesZsep_indicesZ
chop_indexÚmatchesrK   Ú	new_linesZtable_rst_sepr	   )r€   rŒ   r
   rO   ”  sH    




üÿ	z%_UnifiedIORegistryBase._update__doc__)NN)F)r   r   r   r   r   Úpropertyr   rL   Ú
contextlibÚcontextmanagerrQ   rV   rX   r_   rf   r4   rq   ro   rO   r	   r	   r	   r
   r      s   
	
k
!
9)#r   )Ú	metaclass)Úabcrœ   r�   r<   Úcollectionsr   Úoperatorr   Únumpyr@   Ú__all__Ú	Exceptionr   ÚABCMetar   r	   r	   r	   r
   Ú<module>   s   	