a
    ߙfb                     @   sr   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mZ g dZej	dddZ
eg dZdd
dZdd ZdS )z-
Various utilities and cookbook-like things.
    N)Version)convert_to_writable_filelikestc_reference_framescoerce_range_list_paramFc                 c   sT  t | tr| ds|rlt| d6}tj|dd}|V  |  |  W d   dS 1 s`0    Y  n6t| ddd}|V  W d   dS 1 s0    Y  nt	| drHt
| jsJ |rtj| d} d	}z| d
 W n t y   d}Y n0 t	| dr| jdu rd}|r6td| V  |   n| V  |   dS tddS )a  
    Returns a writable file-like object suitable for streaming output.

    Parameters
    ----------
    fd : str or file-like
        May be:

            - a file path string, in which case it is opened, and the file
              object is returned.

            - an object with a :meth:``write`` method, in which case that
              object is returned.

    compressed : bool, optional
        If `True`, create a gzip-compressed file.  (Default is `False`).

    Returns
    -------
    fd : writable file-like
    z.gzwbutf8)encodingNZwtwrite)ZfileobjF Tr   zutf-8z/Can not be coerced to writable file-like object)
isinstancestrendswithgzipZGzipFileioTextIOWrapperflushopenhasattrcallabler	   	TypeErrorr   codecs	getwriter)fdZ
compressedZreal_fdZ
encoded_fdZneeds_wrapper r   6lib/python3.9/site-packages/astropy/io/votable/util.pyr      s:    
""

r   )+ZFK4ZFK5ZECLIPTICZICRSZGALACTICZ
GALACTIC_IZGALACTIC_IIZSUPER_GALACTICZAZ_ELZBODYZGEO_CZGEO_DZMAGZGSEZGSMZSMZHGCZHGSZHEEQZHRTNZHPCZHPRZHCCZHGIZ	MERCURY_CZVENUS_CZLUNA_CZMARS_CZJUPITER_C_IIIZSATURN_C_IIIZURANUS_C_IIIZNEPTUNE_C_IIIZPLUTO_CZ	MERCURY_GZVENUS_GZLUNA_GZMARS_GZJUPITER_G_IIIZSATURN_G_IIIZURANUS_G_IIIZNEPTUNE_G_IIIZPLUTO_GZUNKNOWNFrameTc                    s   fddfdddd }| du r,dS t | ttfrt| d	koP|| d
 }|rd| dd
 }n| dd }dfdd|D }t|}|r|dur| d
 |vrtd| d
  d|d| d
  7 }|d	7 }||fS t | trd}  sd| d }td| d | d | }	|	du r4td|  d|		 d }
|durn|
durn|
|vrntd|
 d| | 
d| 
d d	 fS zt|  t| d	fW S  ty   td|  dY n0 dS )a  
    Coerces and/or verifies the object *p* into a valid range-list-format parameter.

    As defined in `Section 8.7.2 of Simple
    Spectral Access Protocol
    <http://www.ivoa.net/documents/REC/DAL/SSA-20080201.html>`_.

    Parameters
    ----------
    p : str or sequence
        May be a string as passed verbatim to the service expecting a
        range-list, or a sequence.  If a sequence, each item must be
        either:

            - a numeric value

            - a named value, such as, for example, 'J' for named
              spectrum (if the *numeric* kwarg is False)

            - a 2-tuple indicating a range

            - the last item my be a string indicating the frame of
              reference

    frames : sequence of str, optional
        A sequence of acceptable frame of reference keywords.  If not
        provided, the default set in ``set_reference_frames`` will be
        used.

    numeric : bool, optional
        TODO

    Returns
    -------
    parts : tuple
        The result is a tuple:
            - a string suitable for passing to a service as a range-list
              argument

            - an integer counting the number of elements
    c                    s    | d u rdS  rt | } t| S )Nr
   )floatr   x)numericr   r   str_or_none   s
    z,coerce_range_list_param.<locals>.str_or_nonec                    s@   t | tr4t| dkr4 | d  d | d  S  | S d S )N   r   /   )r   tuplelenr   )r   r   r   numeric_or_range   s    z1coerce_range_list_param.<locals>.numeric_or_rangec                 S   s
   t | tS )N)r   r   r   r   r   r   is_frame_of_reference   s    z6coerce_range_list_param.<locals>.is_frame_of_referenceN)Nr   r"   ,c                    s   g | ]} |qS r   r   ).0r   )r%   r   r   
<listcomp>       z+coerce_range_list_param.<locals>.<listcomp>'z#' is not a valid frame of reference;z)([-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?)?(z)|([A-Z_]+)^z([,/]z )+(;(?P<frame>[<A-Za-z_0-9]+))?$z' is not a valid range listframe)r   r#   listr$   join
ValueErrorr   rematch	groupdictcountr   r   )pZframesr   r&   Zhas_frame_of_referenceZpointsoutZlengthZnumberr5   r0   r   )r   r%   r   r   r   c   sV    *

r   c                 C   s(   dd }|| }||}||k||k  S )z2
    Compare two VOTable version identifiers.
    c                 S   s$   | d   dkr| dd  } t| S )Nr   vr"   )lowerr   )r:   r   r   r   version_to_tuple   s    z)version_compare.<locals>.version_to_tupler   )abr<   avZbvr   r   r   version_compare   s    r@   )F)NT)__doc__r   
contextlibr   r4   r   Zpackaging.versionr   __all__contextmanagerr   setr   r   r@   r   r   r   r   <module>   s   @

h