
    HR-eG                         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e          Z G d de j                  ZdS )	    N)OrderedDict)
itemgetterIORegistryErrorc                       e Zd ZdZdS )r   z"Custom error for registry clashes.N)__name__
__module____qualname____doc__     8lib/python3.11/site-packages/astropy/io/registry/base.pyr   r      s        ,,Dr   c                       e Zd ZdZd Zed             ZddZej	        d             Z
ddZd	 Zd
 Zd Zd Zd Zd Z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                     t                      | _        t                      | _        t          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selfs    r   __init__z_UnifiedIORegistryBase.__init__)   sR    'MM  66'+'X'X'X$!.
 &)UU"""r   c                 4    | j                                         S )zUAvailable registries.

        Returns
        -------
        ``dict_keys``
        )r   keysr   s    r   available_registriesz+_UnifiedIORegistryBase.available_registries7   s     $$&&&r   Nc                     ddl m} ddg fd j        D             dR }|                    d          }|                    d          }|                     j         j        d                  d                   |                    d          }t                      } j                                        dhz
  D ]3}	|t          t            j        |	         d	                             z  }4t          |t          d          
          }
g }|
D ]\  | 
                    ||
          s fd j                                        D             dz   f}||
v rdnd}|                    j        gfd j        D             |R            t          |                                           j        v rI j                            t          |                                                    fd|D             }n|t!          d j         d          |r5t#          t%          t          |t          |||          
                     }nd}t'          j                    5  t'          j        dt,                      |||          }t/          j        |d         j        dk              s|                    d           ddd           n# 1 swxY w Y   |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                 6    g | ]}j         |         d          S )r   )r   ).0kr   s     r   
<listcomp>z6_UnifiedIORegistryBase.get_formats.<locals>.<listcomp>]   s&    LLLdq!(+LLLr   
Deprecatedr   r   r   keyNc           	      T    i | ]$\  }}|ft          |d                    v rdnd%S )r   YesNo)getattr)r%   r&   vclsfmtr   s      r   
<dictcomp>z6_UnifiedIORegistryBase.get_formats.<locals>.<dictcomp>w   sO       Aq S#J'$&	*B*BBB55  r   zascii.r,    c                      g | ]
}|         S r   r   )r%   nhas_s     r   r'   z6_UnifiedIORegistryBase.get_formats.<locals>.<listcomp>   s    >>>!d1g>>>r   c                 2    g | ]}|z            d k    |S )r,   r   )r%   row
i_regstartindexs     r   r'   z6_UnifiedIORegistryBase.get_formats.<locals>.<listcomp>   s-    LLLC3zE/A+Be+K+KC+K+K+Kr   z5unrecognized value for "filter_on": {0}.
Allowed are z
 and None.ignore)actioncategory)names)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!   colnamesi_dataclassi_formati_deprecatedregsr&   format_classesrowsascii_format_class
deprecatedrO   format_tabler0   r1   r6   r9   r:   s   `               @@@@@r   get_formatsz"_UnifiedIORegistryBase.get_formatsA   s   , 	(''''' 
 MLLLT5KLLL
 	
 
 nn\22>>(++^^T3A67A
 

  ~~l33 uu!&&((J<7 	D 	DACd&6q&9&&ABBCCCDD*Q--888 & 	 	HC%d.A.AC/ /%       ,2244  D #+S.#!6"4"F"FBJ KKL ?>>>t'=>>> 	     y>>!!T%;;;*00Y1E1E1G1GHHELLLLL4LLLDD"B#5B B B    	VDjlH&U&UVVVW DD D
 $&& 	9 	9!MJJJJ 5X666L6,|49UBCC 9**<888	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 	9 s   7A!K$$K(+K(c              #      K   | j                             |           dV  | j                             |           | j                                        dhz
  D ]}|                     ||           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   r0   methods      r   delay_doc_updatesz(_UnifiedIORegistryBase.delay_doc_updates   s      . 	"&&s+++"**3///&++--< 	- 	-FV,,,,	- 	-r   Fc                 n    ||f| j         vs|r|| j         ||f<   dS t          d|d|j        d          )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_formatrQ   
identifierforces        r   register_identifierz*_UnifiedIORegistryBase.register_identifier   sm    b Z(D,====;ED{J7888!? ? ?'? ? ?  r   c                     ||f| j         v r| j                             ||f           dS t          d|d|j                  )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 re   N)r   popr   r   )r   rf   rQ   s      r   unregister_identifierz,_UnifiedIORegistryBase.unregister_identifier  sl     $(999!!;
";<<<<<!,K , ,', ,  r   c                     g }| j         D ]Q\  }}	|                     ||	| j                   r0 | j         ||	f         |||g|R i |r|                    |           R|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   rA   rC   )
r   origindata_class_requiredpathfileobjargskwargsvalid_formatsrf   rQ   s
             r   identify_formatz&_UnifiedIORegistryBase.identify_format  s    8 '+'8 	6 	6#K""#6
DDUVV 6?4$k:%>?D',0  4:  6 "((555r   c                     |                      ||          }|                    d           d                    |                    d                    }|S )z9``get_formats()``, without column "Data class", as a str.r"   
)	max_lines)r]   rP   joinpformat)r   rQ   rR   r\   format_table_strs        r   _get_format_table_strz,_UnifiedIORegistryBase._get_format_table_strC  sT    ''
I>>""<00099\%9%9B%9%G%GHHr   c                 n    t          ||          r$d |D             }|j        D ]}||u r dS ||v r dS dS )aw  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                     h | ]\  }}|S r   r   )r%   r1   r0   s      r   	<setcomp>z8_UnifiedIORegistryBase._is_best_match.<locals>.<setcomp>U  s    :::xsCs:::r   TF)
issubclass__mro__)r   class1class2rX   classesparents         r   rA   z%_UnifiedIORegistryBase._is_best_matchJ  sh     ff%% 	!::>:::G . ! !V##44W$$ 55 %ur   c                 4   |                      ||||||          }t          |          dk    r:|                     ||                                          }t	          d|           t          |          dk    r|                     |||          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   zFormat could not be identified based on the file name or contents, please provide a 'format' argument.
The available formats are:
   )ru   lenr}   
capitalizer   _get_highest_priority_format)	r   moder0   rp   rq   rr   rs   rt   r|   s	            r   _get_valid_formatz(_UnifiedIORegistryBase._get_valid_format]  s    
 ,,T3gtVTT}""#99#t?P?PQQ!B 0@B B   !##44T3NNNQr   c                    |dk    r
| j         }d}n|dk    r	| j        }d}g }t          j         }|D ]U}	 |||f         \  }	}
n# t          $ r t          j         }
Y nw xY w|
|k    r|                    |           J|
|k    r|g}|
}Vt          |          dk    rAt          dd                    t          |t          d          	                               |d         S )
zh
        Returns the reader or writer with the highest priority. If it is a tie,
        error.
        readreaderwritewriterr   z#Format is ambiguous - options are: z, r   r)   )_readers_writersrM   infKeyErrorrC   r   r   rz   r@   r   )r   r   r0   rt   format_dictmode_loaderbest_formatscurrent_priorityformat_prioritys              r   r   z3_UnifiedIORegistryBase._get_highest_priority_formatq  s5   
 6>>-K"KKW__-K"KF7# 	, 	,F#)63-888 # # # F7#
 +++##F++++,,, &x#+ |q  !JIIf]
1FFFGGJ J   As   AAAc                 N   t          ||          sdS ddlm} dt          ||          }t	          |j        t                    sdS |j                                        }fdt          |          D             }|r|d         }|d|         }d |dd         D             }dt          d	 |D                       z  | 
                    ||                                          }	|	                    d
           |	                    dd          }
t          j        dd|
d                   }||
d<   |
                    d|           |
                    |           d|	j        v r|
                    g d           dg|
z   }
|                    fd|
D                        t	          ||          r!d                    |          |j        _        dS 	 d                    |          |_        dS # t,          $ r# d                    |          |j        _        Y dS w xY w)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.
        Nr   )UnifiedReadWritez#The available built-in formats are:c                 "    g | ]\  }}|v 	|S r   r   )r%   iilineFORMATS_TEXTs      r   r'   z9_UnifiedIORegistryBase._update__doc__.<locals>.<listcomp>  s'    SSShb$ld>R>Rr>R>R>Rr   r   c                 8    g | ]}t          j        d |          S )z(\S))research)r%   r   s     r   r'   z9_UnifiedIORegistryBase._update__doc__.<locals>.<listcomp>  s$    BBB29Wd++BBBr    c              3   B   K   | ]}||                                 V  d S )N)start)r%   matchs     r   	<genexpr>z8_UnifiedIORegistryBase._update__doc__.<locals>.<genexpr>  s/      LL%eLLLLLLLr   r"   rx   P   )ry   	max_width-=r(   )r3   zZDeprecated format names like ``aastex`` will be removed in a future version. Use the full z%name (e.g. ``ascii.aastex``) instead.r3   c                     g | ]}|z   S r   r   )r%   r   left_indents     r   r'   z9_UnifiedIORegistryBase._update__doc__.<locals>.<listcomp>  s    ???TkD(???r   rw   )hasattr	interfacer   r.   
isinstancer
   rD   
splitlines	enumerateminr]   r   rP   r{   r   subinsertrC   rS   extendrz   	__class__AttributeError__func__)r   rQ   	readwriter   class_readwrite_funclinessep_indices
chop_indexmatchesr\   	new_linestable_rst_sepr   r   s               @@r   ra   z%_UnifiedIORegistryBase._update__doc__  s    z9-- 	F//////<  'z9==.6<< 	 F$,7799 TSSS)E*:*:SSS 	'$QJ+:+&E CBabb	BBBCLL7LLLLLL ''
I4H4H4J4JKK""<000 !((2(DD	sC166$	!M***''' <000     "2&2	????Y???@@@ *,<== 	I59YYu5E5E *222I/3yy/?/?$,,,! I I I8<		%8H8H$-5555Is   G7 7)H$#H$)NN)F)r   r   r	   r
   r   propertyr   r]   
contextlibcontextmanagerrc   ri   rl   ru   r}   rA   r   r   ra   r   r   r   r   r      s         + + + ' ' X'i i i iV - - -B7 7 7 7r  &$ $ $R       &     (! ! !FFI FI FI FI FIr   r   )	metaclass)abcr   r   rI   collectionsr   operatorr   numpyrM   __all__	Exceptionr   ABCMetar   r   r   r   <module>r      s    


     				  # # # # # #          
	 	 	 	 	i 	 	 	BI BI BI BI BIs{ BI BI BI BI BI BIr   