B
    q\+                 @   s   d dl Z d dlZd dlmZ dddgZG dd deZG dd	 d	eZd
d Z	dddZ
dd Zdd Zdd Zdd Zdd ZG dd deZdd ZdS )    N)OrderedDictget_header_from_yamlget_yaml_from_headerget_yaml_from_tablec                   s    e Zd ZdZ fddZ  ZS )ColumnOrderListzq
    List of tuples that sorts in a specific order that makes sense for
    astropy table column attributes.
    c                s   t    ddddddg}t| }g }x&|D ]}||kr,|||| f q,W x&| D ]\}}||krT|||f qTW | d d = | | d S )Nnameunitdatatypeformatdescriptionmeta)supersortdictappendextend)selfargskwargsZcolumn_keysZin_dictZout_listkeyval)	__class__ 1lib/python3.7/site-packages/astropy/table/meta.pyr      s    


zColumnOrderList.sort)__name__
__module____qualname____doc__r   __classcell__r   r   )r   r   r   	   s   r   c                   s    e Zd ZdZ fddZ  ZS )
ColumnDictz
    Specialized dict subclass to represent attributes of a Column
    and return items() in a preferred order.  This is only for use
    in generating a YAML map representation that has a fixed order.
    c                s   t t  S )zt
        Return items as a ColumnOrderList, which sorts in the preferred
        way for column attributes.
        )r   r   items)r   )r   r   r   r    *   s    zColumnDict.items)r   r   r   r   r    r   r   r   )r   r   r   #   s   r   c       	   	   c   s   ddl }t }|V  t||js>|jd|jd|j|jx|j	D ]}t||j
st|jd|jd|j|jt|j	dkr|jd|jdt|j	|j|j	d \}}| |}| |}|||< qFW dS )a  
    Construct OrderedDict from !!omap in yaml safe load.

    Source: https://gist.github.com/weaver/317164
    License: Unspecified

    This is the same as SafeConstructor.construct_yaml_omap(),
    except the data type is changed to OrderedDict() and setitem is
    used instead of append in the loop

    Examples
    --------
    ::

      >>> yaml.load('''  # doctest: +SKIP
      ... !!omap
      ... - foo: bar
      ... - mumble: quux
      ... - baz: gorp
      ... ''')
      OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')])

      >>> yaml.load('''!!omap [ foo: bar, mumble: quux, baz : gorp ]''')  # doctest: +SKIP
      OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')])
    r   Nz!while constructing an ordered mapz!expected a sequence, but found {}z,expected a mapping of length 1, but found {}   z2expected a single mapping item, but found {} items)yamlr   
isinstanceSequenceNodeconstructorZConstructorErrorZ
start_markr
   idvalueMappingNodelenZconstruct_object)	loadnoder"   ZomapZsubnodeZkey_nodeZ
value_noder   r'   r   r   r   _construct_odict2   s,    


r,   c             C   s   ddl }g }|j|||d}| jdk	r2|| j| j< d}x>|D ]6\}}	| ||	i}
t|
|jrd|
jrhd}||
 q<W |dkr| j	dk	r| j	|_
n||_
|S )z
    This is the same code as BaseRepresenter.represent_sequence(),
    but the value passed to dump.represent_data() in the loop is a
    dictionary instead of a tuple.

    Source: https://gist.github.com/weaver/317164
    License: Unspecified
    r   N)
flow_styleTF)r"   r$   	alias_keyrepresented_objectsrepresent_datar#   
ScalarNodestyler   default_flow_styler-   )dumptagZsequencer-   r"   r'   r+   
best_styler   r   itemr   r   r   _repr_pairsh   s     	


r8   c             C   s   t | d| S )a  
    Represent OrderedDict in yaml dump.

    Source: https://gist.github.com/weaver/317164
    License: Unspecified

    >>> data = OrderedDict([('foo', 'bar'), ('mumble', 'quux'), ('baz', 'gorp')])
    >>> yaml.dump(data, default_flow_style=False)  # doctest: +SKIP
    '!!omap\n- foo: bar\n- mumble: quux\n- baz: gorp\n'
    >>> yaml.dump(data, default_flow_style=True)  # doctest: +SKIP
    '!!omap [foo: bar, mumble: quux, baz: gorp]\n'
    ztag:yaml.org,2002:omap)r8   r    )dumperdatar   r   r   _repr_odict   s    r;   c             C   s   |  d|S )z
    Represent ColumnDict in yaml dump.

    This is the same as an ordinary mapping except that the keys
    are written in a fixed order that makes sense for astropy table
    columns.
    ztag:yaml.org,2002:map)represent_mapping)r9   r:   r   r   r   _repr_column_dict   s    r=   c             C   s   t  }| jj|d< | jjjj}|dr,d}|drB|dd }||d< xjdd	d
 tfddd
 dfddd
 dfddd
 dffD ]2\}}}t	| j|}||r|r||n|||< qW |S )zw
    Extract information from a column (apart from the values) that is required
    to fully serialize the column.
    r   )bytesstrstring_Nr	   r   c             S   s   | d k	S )Nr   )xr   r   r   <lambda>   s    z%_get_col_attributes.<locals>.<lambda>r
   c             S   s   | d k	S )Nr   )rC   r   r   r   rD      s    r   c             S   s   | d k	S )Nr   )rC   r   r   r   rD      s    r   c             S   s   | S )Nr   )rC   r   r   r   rD      s    )
r   infor   Zdtypetyper   
startswithendswithr?   getattr)colZattrsZ	type_nameattrZ
nontrivialZxformZcol_attrr   r   r   _get_col_attributes   s     

rL   c             C   s*   dt | j i}| jr"| j|d< t|S )a/  
    Return lines with a YAML representation of header content from the ``table``.

    Parameters
    ----------
    table : `~astropy.table.Table` object
        Table for which header content is output

    Returns
    -------
    lines : list
        List of text lines with YAML header content
    colsr   )listcolumnsvaluesr   r   )tableheaderr   r   r   r      s    
c                s   yddl  W n tk
r(   tdY nX ddlm} G  fddd|}|tt |tt t		| } dd | d	 D | d
< | d	=  j
| |dd }|S )a  
    Return lines with a YAML representation of header content from a Table.

    The ``header`` dict must contain these keys:

    - 'cols' : list of table column objects (required)
    - 'meta' : table 'meta' attribute (optional)

    Other keys included in ``header`` will be serialized in the output YAML
    representation.

    Parameters
    ----------
    header : dict
        Table header content

    Returns
    -------
    lines : list
        List of text lines with YAML header content
    r   NzN`import yaml` failed, PyYAML package is required for serializing mixin columns)AstropyDumperc                   s   e Zd ZdZd fdd	ZdS )z)get_yaml_from_header.<locals>.TableDumperzP
        Custom Dumper that represents OrderedDict as an !!omap object.
        Nc                s  g } j |||d}| jdk	r*|| j| j< d}t|dr~| }t|drT|  n*t|}yt|}W n tk
r|   Y nX x^|D ]V\}}| 	|}	| 	|}
t
|	 jr|	jrd}t
|
 jr|
jrd}||	|
f qW |dkr| jdk	r| j|_n||_|S )a|  
            This is a combination of the Python 2 and 3 versions of this method
            in the PyYAML library to allow the required key ordering via the
            ColumnOrderList object.  The Python 3 version insists on turning the
            items() mapping into a list object and sorting, which results in
            alphabetical order for the column keys.
            )r-   NTr    r   F)r(   r.   r/   hasattrr    r   rN   sorted	TypeErrorr0   r#   r1   r2   r   r3   r-   )r   r5   mappingr-   r'   r+   r6   Zitem_keyZ
item_valueZnode_keyZ
node_value)r"   r   r   r<      s6    








z;get_yaml_from_header.<locals>.TableDumper.represent_mapping)N)r   r   r   r   r<   r   )r"   r   r   TableDumper   s   rX   c             S   s   g | ]}t |qS r   )rL   ).0rJ   r   r   r   
<listcomp>  s    z(get_yaml_from_header.<locals>.<listcomp>rM   r	      )ZDumperwidth)r"   ImportErrorastropy.io.misc.yamlrS   Zadd_representerr   r;   r   r=   copyr4   
splitlines)rR   rS   rX   linesr   )r"   r   r      s    ,
c               @   s   e Zd ZdS )YamlParseErrorN)r   r   r   r   r   r   r   rb   &  s   rb   c          
   C   s   yddl }W n tk
r(   tdY nX ddlm} G dd d|}|dt td| }y|j	||d	}W n. t
k
r } ztt|W dd}~X Y nX |S )
aS  
    Get a header dict from input ``lines`` which should be valid YAML.  This
    input will typically be created by get_yaml_from_header.  The output is a
    dictionary which describes all the table and column meta.

    The get_cols() method in the io/ascii/ecsv.py file should be used as a
    guide to using the information when constructing a table using this
    header dict information.

    Parameters
    ----------
    lines : list
        List of text lines with YAML header content

    Returns
    -------
    header : dict
        Dictionary describing table and column meta

    r   NzN`import yaml` failed, PyYAML package is required for serializing mixin columns)AstropyLoaderc               @   s   e Zd ZdZdS )z)get_header_from_yaml.<locals>.TableLoaderz
        Custom Loader that constructs OrderedDict from an !!omap object.
        This does nothing but provide a namespace for adding the
        custom odict constructor.
        N)r   r   r   r   r   r   r   r   TableLoaderH  s   rd   ztag:yaml.org,2002:omap
)Loader)r"   r]   r^   rc   Zadd_constructorr,   textwrapdedentjoinr*   	Exceptionrb   r?   )ra   r"   rc   rd   Zheader_yamlrR   errr   r   r   r   *  s    )N)rg   r_   collectionsr   __all__rN   r   r   r   r,   r8   r;   r=   rL   r   r   rj   rb   r   r   r   r   r   <module>   s   
6
U