B
    d                 @   s  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 d dlm	Z	m
Z
 d dlmZ d dlmZ d dlmZmZ d dlmZ d	d
lmZ d	dlmZ d	dlmZ d	dlmZmZ e ZG dd deZe de dd Z!e"ej#ej$ej%ej&ej'ej(ej)ej*ej+ej,ej-gZ.d&ddZ/G dd dej0Z1dd Z2d'ddZ3G dd deZ4G dd deej0Z5G d d! d!e5Z6G d"d# d#e4Z7G d$d% d%e6eej8Z9dS )(    N)deepcopy)ma)UnitQuantity)color_print)MetaData)BaseColumnInfodtype_info_name)dtype_bytes_or_chars   )groups)pprint)fix_column_name)_ColumnGetitemShim_MaskedColumnGetitemShimc               @   s   e Zd ZdZdS )StringTruncateWarninga%  
    Warning class for when a string column is assigned a value
    that gets truncated because the base (numpy) string length
    is too short.

    This does not inherit from AstropyWarning because we want to use
    stacklevel=2 to show the user where the issue occurred in their code.
    N)__name__
__module____qualname____doc__ r   r   a/work/yifan.wang/ringdown/master-ringdown-env/lib/python3.7/site-packages/astropy/table/column.pyr      s   r   alwaysc                s"   ddl m   fddt| D S )Nr   )confc                s   g | ]}t  j|qS r   )strZauto_colnameformat).0i)r   r   r   
<listcomp>/   s    z_auto_names.<locals>.<listcomp>) r   range)Zn_colsr   )r   r   _auto_names-   s    r!   Tc             C   s|   t | tr|  S t| dr$|  nt| }d| jkrx| j|_|rx| jjrxt| jj|j_x|jjD ]}|| | qdW |S )a  
    Mixin-safe version of Column.copy() (with copy_data=True).

    Parameters
    ----------
    col : Column or mixin column
        Input column
    copy_indices : bool
        Copy the column ``indices`` attribute

    Returns
    -------
    col : Copy of input column
    copyinfo)	
isinstance
BaseColumnr"   hasattrr   __dict__r#   indicesreplace_col)colcopy_indicesZnewcolindexr   r   r   col_copy;   s    

r-   c               @   s    e Zd ZdZdd Zdd ZdS )
FalseArraya  
    Boolean mask array that is always False.

    This is used to create a stub ``mask`` property which is a boolean array of
    ``False`` used by default for mixin columns and corresponding to the mixin
    column data shape.  The ``mask`` looks like a normal numpy array but an
    exception will be raised if ``True`` is assigned to any element.  The
    consequences of the limitation are most obvious in the high-level table
    operations.

    Parameters
    ----------
    shape : tuple
        Data shape
    c             C   s   t j|td| }|S )N)dtype)npzerosboolview)clsshapeobjr   r   r   __new__k   s    zFalseArray.__new__c             C   s*   t |}t |r&td| jjd S )Nz*Cannot set any element of {} class to True)r0   asarrayany
ValueErrorr   	__class__r   )selfitemvalr   r   r   __setitem__o   s    

zFalseArray.__setitem__N)r   r   r   r   r7   r?   r   r   r   r   r.   [   s   r.   c             C   sd   | j jdkr`|tjjk	r`tj| }t| j }|r`||kr`| j j	| j j t
| }| |} | S )a  
    For string-dtype return a version of ``arr`` that is wide enough for ``values``.
    If ``arr`` is not string-dtype or does not need expansion then return ``arr``.

    Parameters
    ----------
    arr : np.ndarray
        Input array
    values : scalar or array-like
        Values for width comparison for string arrays

    Returns
    -------
    arr_expanded : np.ndarray

    )US)r/   kindr0   r   maskedcharstr_lenmaxr
   	byteorderr   Zastype)arrvaluesZvalues_str_lenZarr_str_lenZ	arr_dtyper   r   r   _expand_string_array_for_valuesv   s    

rJ   c                s  t jj t| drHt| dkrHt fdd| D rHt jj| |d}|S tjdd}tj	dt
d	d
 tj	dtdd
 yt j| |d}W nj t jjk
r   t | }Y nJ tk
r   yt| |}W n& tk
r   t}t j| |d}Y nX Y nX W dQ R X |jdks$|jdkr(t|dkr(| S t|dkrH|jjdkrH|S d}xztt|jD ]h}|dkrxd| d}nJ||jd krd| d| d|d  d}nd| d| d|d  d}q\W t jj| d}t||}|rt j|jtd}t j| td}	|jjdkrd}
n|jjdkr,d}
nd}
dd |jD }xRtj| D ]D}|	| }| krt|
|	|< d||< nt|trL|dkrLt}qLW |dkr|	 }	t jjt j|	|d|d}|S )a  Convert N-d sequence-like data to ndarray or MaskedArray.

    This is the core function for converting Python lists or list of lists to a
    numpy array. This handles embedded np.ma.masked constants in ``data`` along
    with the special case of an homogeneous list of MaskedArray elements.

    Considerations:

    - np.ma.array is about 50 times slower than np.array for list input. This
      function avoids using np.ma.array on list input.
    - np.array emits a UserWarning for embedded np.ma.masked, but only for int
      or float inputs. For those it converts to np.nan and forces float dtype.
      For other types np.array is inconsistent, for instance converting
      np.ma.masked to "0.0" for str types.
    - Searching in pure Python for np.ma.masked in ``data`` is comparable in
      speed to calling ``np.array(data)``.
    - This function may end up making two additional copies of input ``data``.

    Parameters
    ----------
    data : N-d sequence
        Input data, typically list or list of lists
    dtype : None or dtype-like
        Output datatype (None lets np.array choose)

    Returns
    -------
    np_data : np.ndarray or np.ma.MaskedArray

    __len__r   c             3   s$   | ]}t |tjjo| k	V  qd S )N)r$   r0   r   MaskedArray)r   r>   )np_ma_maskedr   r   	<genexpr>   s   z2_convert_sequence_data_to_array.<locals>.<genexpr>)r/   T)recordr   z.*converting a masked element.*)categorymessagez-.*Promotion of numbers and bools to strings.*N)r   fzd0 is ma_maskedzany(z for d0 in data)r   zany(dz is ma_masked for dz in d)z for d)Z	ma_maskeddatar@   r   rA       c             S   s   g | ]}t |qS r   )r    )r   dimr   r   r   r   
  s    z3_convert_sequence_data_to_array.<locals>.<listcomp>)mask)r0   r   rC   r&   lenallarraywarningscatch_warningsfilterwarningsUserWarningFutureWarningZ	MaskError	Exceptionr   objectndimr/   rB   reversedr    evalr1   r5   r2   	itertoolsproductr$   tolist)rT   r/   Znp_dataZwarnsZany_statementiicontextZ
has_maskedrW   Zdata_filledfillrangesZidxsr>   r   )rM   r   _convert_sequence_data_to_array   sn    

$&

"




rl   c               @   s,   e Zd ZdZejZdZd	ddZdd Z	dS )

ColumnInfoz
    Container for meta information like name, description, format.

    This is required when the object is used as a mixin column within a table,
    but can be used as a general way to store meta information.
    TwarnNc             C   s$   |  |||d}| jf d|i|S )a  
        Return a new Column instance which is consistent with the
        input ``cols`` and has ``length`` rows.

        This is intended for creating an empty column object whose elements can
        be set in-place for table operations like join or vstack.

        Parameters
        ----------
        cols : list
            List of input columns
        length : int
            Length of the output column object
        metadata_conflicts : str ('warn'|'error'|'silent')
            How to handle metadata conflicts
        name : str
            Output column name

        Returns
        -------
        col : Column (or subclass)
            New instance of this class consistent with ``cols``

        )metaunitr   descriptionlength)Zmerge_cols_attributesZ_parent_cls)r<   colsrr   Zmetadata_conflictsnameattrsr   r   r   new_like-  s    
zColumnInfo.new_likec             C   s   | j gS )z
        Return a list of arrays which can be lexically sorted to represent
        the order of the parent column.

        For Column this is just the column itself.

        Returns
        -------
        arrays : list of ndarray
        )_parent)r<   r   r   r   get_sortable_arraysK  s    zColumnInfo.get_sortable_arrays)rn   N)
r   r   r   r   r   
attr_namesZattrs_from_parentZ_supports_indexingrv   rx   r   r   r   r   rm   #  s
   
rm   c                   s  e Zd Ze ZdFddZedd	 Zed
d Zedd Z	e	j
dd Z	e ZdGddZdd Zdd Z fddZdH fdd	Zedd Zej
dd Zedd Zej
dd Zed d! Zd"d# Zd$d% Zed&d' ZdId(d)ZdJd*d+ZdKd,d-Zed.d/ Zej
d0d/ Zejd1d/ Zg fd2d3Zed4d5 Zd6d7 Zd8d9 Z d:d; Z!ed<d= Z"g fd>d?Z#d@dA Z$e%dBdC Z& fdDdEZ'  Z(S )Lr%   Nr   r   FTc             C   s  |d kr t j|f| |d}nt|trt|drt j|j||
d}|d krT|j}|d krf|pd|j}|d krt|j	}|	d kr|j
}	|d kr|j}nt|tr|d krt j|||
d}|j}nt||||
dj}d|jkr<|d kr|jj}|d kr|jj	}|	d kr<|jj
}	n,t |jdkr,| |}t j|||
d}|| }t||_d |_||_||_||_|	|_
|rtt|dg ng |_x|jD ]}||| qW |S )N)r/   _name)r/   r"   r#   rA   r(   )r0   r1   r$   r%   r&   rZ   rT   rq   rp   r   ro   rt   r   valuer'   r#   r/   rD   _encode_strr3   r   rz   _parent_table_formatr   getattrr(   r)   )r4   rT   rt   r/   r5   rr   rq   rp   r   ro   r"   r+   	self_datar<   r,   r   r   r   r7   ]  sP    





zBaseColumn.__new__c             C   s   |  tjS )N)r3   r0   ndarray)r<   r   r   r   rT     s    zBaseColumn.datac             C   s   | j S )N)rT   )r<   r   r   r   r{     s    zBaseColumn.valuec             C   s    t | dd d krd S |  S d S )Nr}   )r   r}   )r<   r   r   r   parent_table  s    zBaseColumn.parent_tablec             C   s    |d krd | _ nt|| _ d S )N)r}   weakrefref)r<   tabler   r   r   r     s    Cc             C   sd   |dkr| j }|r||}|| j}||  | jdk	rD| j|_t| trV|j|_| 	| |S )am  
        Return a copy of the current instance.

        If ``data`` is supplied then a view (reference) of ``data`` is used,
        and ``copy_data`` is ignored.

        Parameters
        ----------
        order : {'C', 'F', 'A', 'K'}, optional
            Controls the memory layout of the copy. 'C' means C-order,
            'F' means F-order, 'A' means 'F' if ``a`` is Fortran contiguous,
            'C' otherwise. 'K' means match the layout of ``a`` as closely
            as possible. (Note that this function and :func:numpy.copy are very
            similar, but have different default values for their order=
            arguments.)  Default is 'C'.
        data : array, optional
            If supplied then use a view of ``data`` instead of the instance
            data.  This allows copying the instance attributes and meta.
        copy_data : bool, optional
            Make a copy of the internal numpy array instead of using a
            reference.  Default is True.

        Returns
        -------
        col : Column or MaskedColumn
            Copy of the current column (same type as original)
        N)
rT   r"   r3   r;   __array_finalize__ro   r$   MaskedColumnZ_mask_copy_groups)r<   orderrT   Z	copy_dataoutr   r   r   r"     s    




zBaseColumn.copyc             C   sx   d}dd t ||d D }|dd }t| tjr:tjntj}|| | x | D ]\}}t| || qVW d| _	dS )z
        Restore the internal state of the Column/MaskedColumn for pickling
        purposes.  This requires that the last element of ``state`` is a
        5-tuple that has Column-specific state values.
        )rz   _unitr~   rq   ro   r(   c             S   s   i | ]\}}||qS r   r   )r   rt   r>   r   r   r   
<dictcomp>  s    z+BaseColumn.__setstate__.<locals>.<dictcomp>N)
zipr$   r   rL   r0   r   __setstate__itemssetattrr}   )r<   statenamesru   super_classrt   r>   r   r   r   r     s    zBaseColumn.__setstate__c             C   sX   t | tjrtjntj}|| \}}}| j| j| j| j	| j
| jf}||f }|||fS )z
        Return a 3-tuple for pickling a Column.  Use the super-class
        functionality but then add in a 5-tuple of Column-specific values
        that get used in __setstate__.
        )r$   r   rL   r0   r   
__reduce__rt   rp   r   rq   ro   r(   )r<   r   Zreconstruct_funcZreconstruct_func_argsr   Zcolumn_stater   r   r   r     s    
zBaseColumn.__reduce__c                sH   |d krd S t t jr$t | d | _t| ds:g | _| | d S )Nr(   )callablesuperr   r   r&   r(   _copy_attrs)r<   r6   )r;   r   r   r     s    
zBaseColumn.__array_finalize__c                sJ   t  ||}| j|jks8t|trB|dk	rB|d tkrB|jd S |S dS )a  
        __array_wrap__ is called at the end of every ufunc.

        Normally, we want a Column object back and do not have to do anything
        special. But there are two exceptions:

        1) If the output shape is different (e.g. for reduction ufuncs
           like sum() or mean()), a Column still linking to a parent_table
           makes little sense, so we return the output viewed as the
           column content (ndarray or MaskedArray).
           For this case, we use "[()]" to select everything, and to ensure we
           convert a zero rank array to a scalar. (For some reason np.sum()
           returns a zero rank scalar array while np.mean() returns a scalar;
           So the [()] is needed for this case.

        2) When the output is created by any function that returns a boolean
           we also want to consistently return an array rather than a column
           (see #1446 and #1685)
        Nr   r   )r   __array_wrap__r5   r$   r%   _comparison_functionsrT   )r<   Zout_arrri   )r;   r   r   r     s    

zBaseColumn.__array_wrap__c             C   s   | j S )z*
        The name of this column.
        )rz   )r<   r   r   r   rt   9  s    zBaseColumn.namec             C   s2   t |}| jd k	r(| j}|j| j| || _d S )N)r   r   columnsZ_rename_columnrt   rz   )r<   r>   r   r   r   r   rt   @  s
    
c             C   s   | j S )zE
        Format string for displaying values in this column.
        )r~   )r<   r   r   r   r   J  s    zBaseColumn.formatc          
   C   sh   t | dd }|| _y| jdd W n@ tk
rb } z"|| _td| j|jd W d d }~X Y nX d S )Nr~   r   )	max_linesz^Invalid format for column '{}': could not display values in this column using this format ({})r   )r   r~   pformatr`   r:   r   rt   args)r<   format_stringZprev_formaterrr   r   r   r   R  s    c             C   s   | j | jj| jdd fS )zArray-interface compliant full description of the column.

        This returns a 3-tuple (name, type, shape) that can always be
        used in a structured array dtype definition.
        r   N)rt   r/   r   r5   )r<   r   r   r   descrd  s    zBaseColumn.descrc             c   s0   | j j}x"|| ddddi dD ]
}|V  qW dS )z
        Return an iterator that yields the string-formatted values of this
        column.

        Returns
        -------
        str_vals : iterator
            Column values formatted as strings
        r   F)	show_name	show_unit
show_dtypeoutsN)
_formatter_pformat_col_iter)r<   r   Zstr_valr   r   r   iter_str_valsm  s    zBaseColumn.iter_str_valsc                s2   t  tstdd}t fdd|D }|S )ax  Compare the column attributes of ``col`` to this object.

        The comparison attributes are: ``name``, ``unit``, ``dtype``,
        ``format``, ``description``, and ``meta``.

        Parameters
        ----------
        col : Column
            Comparison column

        Returns
        -------
        equal : bool
            True if all attributes are equal
        z8Comparison `col` must be a Column or MaskedColumn object)rt   rp   r/   r   rq   ro   c             3   s"   | ]}t |t  |kV  qd S )N)r   )r   x)r*   r<   r   r   rN     s    z)BaseColumn.attrs_equal.<locals>.<genexpr>)r$   r%   r:   rY   )r<   r*   ru   equalr   )r*   r<   r   attrs_equal~  s
    
zBaseColumn.attrs_equalc             C   s   | j d krtS | j jS )N)r   	FORMATTER	formatter)r<   r   r   r   r     s    zBaseColumn._formatterc       	      C   s$   | j j}|| |||||d\}}|S )a  Return a list of formatted string representation of column values.

        If no value of ``max_lines`` is supplied then the height of the
        screen terminal is used to set ``max_lines``.  If the terminal
        height cannot be determined then the default will be
        determined using the ``astropy.conf.max_lines`` configuration
        item. If a negative value of ``max_lines`` is supplied then
        there is no line limit applied.

        Parameters
        ----------
        max_lines : int
            Maximum lines of output (header + data rows)

        show_name : bool
            Include column name. Default is True.

        show_unit : bool
            Include a header row for unit. Default is False.

        show_dtype : bool
            Include column dtype. Default is False.

        html : bool
            Format the output as an HTML table. Default is False.

        Returns
        -------
        lines : list
            List of lines with header and formatted column values

        )r   r   r   html)r   _pformat_col)	r<   r   r   r   r   r   r   linesr   r   r   r   r     s
    "zBaseColumn.pformatc             C   s\   | j j}|| ||||d\}}|d }x0t|D ]$\}	}
|	|k rLt|
d q0t|
 q0W dS )a   Print a formatted string representation of column values.

        If no value of ``max_lines`` is supplied then the height of the
        screen terminal is used to set ``max_lines``.  If the terminal
        height cannot be determined then the default will be
        determined using the ``astropy.conf.max_lines`` configuration
        item. If a negative value of ``max_lines`` is supplied then
        there is no line limit applied.

        Parameters
        ----------
        max_lines : int
            Maximum number of values in output

        show_name : bool
            Include column name. Default is True.

        show_unit : bool
            Include a header row for unit. Default is False.

        show_dtype : bool
            Include column dtype. Default is True.
        )r   r   r   n_headerredN)r   r   	enumerater   print)r<   r   r   r   r   r   r   r   r   r   liner   r   r   r     s    
zBaseColumn.pprintc             C   s   | j j}|| |||d dS )a  Interactively browse column with a paging interface.

        Supported keys::

          f, <space> : forward one page
          b : back one page
          r : refresh same page
          n : next row
          p : previous row
          < : go to beginning
          > : go to end
          q : quit browsing
          h : print this help

        Parameters
        ----------
        max_lines : int
            Maximum number of lines in table output.

        show_name : bool
            Include a header row for column names. Default is True.

        show_unit : bool
            Include a header row for unit. Default is False.

        )r   r   r   N)r   _more_tabcol)r<   r   r   r   r   r   r   r   more  s    zBaseColumn.morec             C   s   | j S )a  
        The unit associated with this column.  May be a string or a
        `astropy.units.UnitBase` instance.

        Setting the ``unit`` property does not change the values of the
        data.  To perform a unit conversion, use ``convert_unit_to``.
        )r   )r<   r   r   r   rp     s    	zBaseColumn.unitc             C   s"   |d krd | _ nt|dd| _ d S )NZsilent)Zparse_strict)r   r   )r<   rp   r   r   r   rp     s    c             C   s
   d | _ d S )N)r   )r<   r   r   r   rp     s    c             C   s:   | j dkrtd| j j|| j|d| jdd< || _ dS )a  
        Converts the values of the column in-place from the current
        unit to the given unit.

        To change the unit associated with this column without
        actually changing the data values, simply set the ``unit``
        property.

        Parameters
        ----------
        new_unit : str or `astropy.units.UnitBase` instance
            The unit to convert to.

        equivalencies : list of tuple
           A list of equivalence pairs to try if the unit are not
           directly convertible.  See :ref:`unit_equivalencies`.

        Raises
        ------
        astropy.units.UnitsError
            If units are inconsistent
        NzNo unit set on column)equivalencies)rp   r:   torT   )r<   Znew_unitr   r   r   r   convert_unit_to  s
    
zBaseColumn.convert_unit_toc             C   s   t | dst| | _| jS )N_groups)r&   r   ColumnGroupsr   )r<   r   r   r   r   8  s    
zBaseColumn.groupsc             C   s   t | |S )a  
        Group this column by the specified ``keys``

        This effectively splits the column into groups which correspond to
        unique values of the ``keys`` grouping object.  The output is a new
        `Column` or `MaskedColumn` which contains a copy of this column but
        sorted by row according to ``keys``.

        The ``keys`` input to ``group_by`` must be a numpy array with the
        same length as this column.

        Parameters
        ----------
        keys : numpy array
            Key grouping object

        Returns
        -------
        out : Column
            New column with groups attribute set accordingly
        )r   Zcolumn_group_by)r<   keysr   r   r   group_by>  s    zBaseColumn.group_byc             C   sL   | j r*t| j drHtj|| j jjd|_nt| drHtj|| jjd|_dS )zA
        Copy current groups into a copy of self ``out``
        r   )r(   N)r   r&   r   r   r   Z_indices)r<   r   r   r   r   r   V  s
    
zBaseColumn._copy_groupsc             C   s   t |  S )N)r0   r8   __repr__)r<   r   r   r   r   c  s    zBaseColumn.__repr__c             C   s   t | | jd| jdddS )z
        A view of this table column as a `~astropy.units.Quantity` object with
        units given by the Column's `unit` parameter.
        FAT)r"   r/   r   Zsubok)r   rp   r/   )r<   r   r   r   quantityf  s    	zBaseColumn.quantityc             K   s   | j ||S )a~  
        Converts this table column to a `~astropy.units.Quantity` object with
        the requested units.

        Parameters
        ----------
        unit : unit-like
            The unit to convert to (i.e., a valid argument to the
            :meth:`astropy.units.Quantity.to` method).
        equivalencies : list of tuple
            Equivalencies to use for this conversion.  See
            :meth:`astropy.units.Quantity.to` for more details.

        Returns
        -------
        quantity : `~astropy.units.Quantity`
            A quantity object with the contents of this column in the units
            ``unit``.
        )r   r   )r<   rp   r   kwargsr   r   r   r   q  s    zBaseColumn.toc             C   sD   x$dD ]}t ||d}t| || qW t |dd}|r@| | _dS )zA
        Copy key column attributes from ``obj`` to self
        )rt   rp   r~   rq   Nro   )r   r   r"   ro   )r<   r6   attrr>   Zobj_metar   r   r   r     s    
zBaseColumn._copy_attrsc             C   s~   t | tr| d} ndt | tsz| tjjkr.nLt| }|jj	dkrvtj	j|dd}t | tjj
rvtjj|| jdd}|} | S )zm
        Encode anything that is unicode-ish as utf-8.  This method is only
        called for Py3+.
        zutf-8r@   )encodingF)rW   r"   )r$   r   encodebytesr0   r   rC   r8   r/   rD   rL   rZ   rW   )r{   rH   r   r   r   r|     s    

zBaseColumn._encode_strc                s.   | j jdkr tjj| dd S t  S d S )NrA   zutf-8)r   )r/   rB   r0   Z	chararraydecoderg   r   )r<   )r;   r   r   rg     s    zBaseColumn.tolist)NNNr   r   NNNNFT)r   NT)N)NTFFF)NTFF)NTF))r   r   r   r   ro   r7   propertyrT   r{   r   setterrm   r#   r"   r   r   r   r   rt   r   r   r   r   r   r   r   r   rp   deleterr   r   r   r   r   r   r   r   staticmethodr|   rg   __classcell__r   r   )r;   r   r%   Y  sP      
4

3
	 
'
#
r%   c                   s   e Zd ZdZd# fdd	Z f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 fddZedZedZedZedZedZed Zd%d!d"ZejZejZejZejZejZejZejZejZejZ  ZS )&Columna  Define a data column for use in a Table object.

    Parameters
    ----------
    data : list, ndarray, or None
        Column data values
    name : str
        Column name and key for reference within Table
    dtype : `~numpy.dtype`-like
        Data type for column
    shape : tuple or ()
        Dimensions of a single row element in the column data
    length : int or 0
        Number of row elements in column data
    description : str or None
        Full description of column
    unit : str or None
        Physical unit
    format : str, None, or callable
        Format string for outputting column values.  This can be an
        "old-style" (``format % value``) or "new-style" (`str.format`)
        format specification string or a function or any callable object that
        accepts a single value and returns a string.
    meta : dict-like or None
        Meta-data associated with the column

    Examples
    --------
    A Column can be created in two different ways:

    - Provide a ``data`` value but not ``shape`` or ``length`` (which are
      inferred from the data).

      Examples::

        col = Column(data=[1, 2], name='name')  # shape=(2,)
        col = Column(data=[[1, 2], [3, 4]], name='name')  # shape=(2, 2)
        col = Column(data=[1, 2], name='name', dtype=float)
        col = Column(data=np.array([1, 2]), name='name')
        col = Column(data=['hello', 'world'], name='name')

      The ``dtype`` argument can be any value which is an acceptable
      fixed-size data-type initializer for the numpy.dtype() method.  See
      `<https://numpy.org/doc/stable/reference/arrays.dtypes.html>`_.
      Examples include:

      - Python non-string type (float, int, bool)
      - Numpy non-string type (e.g. np.float32, np.int64, np.bool\_)
      - Numpy.dtype array-protocol type strings (e.g. 'i4', 'f8', 'S15')

      If no ``dtype`` value is provide then the type is inferred using
      ``np.array(data)``.

    - Provide ``length`` and optionally ``shape``, but not ``data``

      Examples::

        col = Column(name='name', length=5)
        col = Column(name='name', dtype=int, length=10, shape=(3,4))

      The default ``dtype`` is ``np.float64``.  The ``shape`` argument is the
      array shape of a single cell in the column.
    Nr   r   FTc                sF   t |trt|jrtdt j| |||||||||	|
|d}|S )Nz;Cannot convert a MaskedColumn with masked value to a Column)rT   rt   r/   r5   rr   rq   rp   r   ro   r"   r+   )r$   r   r0   r9   rW   	TypeErrorr   r7   )r4   rT   rt   r/   r5   rr   rq   rp   r   ro   r"   r+   r<   )r;   r   r   r7     s    
zColumn.__new__c                s   t | ts|dkrtdt || |dkr~t| jjtj	r~y| j
| }W n tk
rd   Y nX || k	r~| j
| j| d S )NrW   z5cannot set mask value to a column in non-masked Tablerp   )r$   r   AttributeErrorr   __setattr__
issubclassr/   typer0   numberr   Z_convert_col_for_tableZreplace_columnrt   )r<   r=   r{   Z	converted)r;   r   r   r     s    zColumn.__setattr__c          	   C   s  | j dkrt|  S | jjg}| jd kr.d nt| j}| j dkrFd n| jdd  }xfd| jfdt	| j
fd|fd|fd| jfd| jfd	t| ffD ]$\}}|d k	r|| d
| qW dd| d }|rddlm} ||}| jj| ddd|d\}	}
|d|	 }|S )Nr   r   rt   r/   r5   rp   r   rq   rr   =< z>
)
xml_escapeF)r   r   Zshow_lengthr   
)rb   reprr=   r;   r   rp   r   r5   rt   r	   r/   r   rq   rX   appendjoinZastropy.utils.xml.writerr   r   r   )r<   r   Z
descr_valsrp   r5   r   r>   r   r   Z
data_linesr   r   r   r   r   _base_repr_  s,    


zColumn._base_repr_c             C   s   | j ddS )NT)r   )r   )r<   r   r   r   _repr_html_,  s    zColumn._repr_html_c             C   s   | j ddS )NF)r   )r   )r<   r   r   r   r   /  s    zColumn.__repr__c             C   s0   | j dkrt|  S | j| \}}d|S )Nr   r   )rb   r   r=   r   r   r   )r<   r   r   r   r   r   __str__2  s    
zColumn.__str__c             C   s   t | dS )Nzutf-8)r   r   )r<   r   r   r   	__bytes__:  s    zColumn.__bytes__c             C   s\   t j|| jjd}|jdkr dS t j| }t| j}||krXt	j
d|tdd dS )z{
        Emit a warning if any elements of ``value`` will be truncated when
        ``value`` is assigned to self.
        )r/   r   NzLtruncated right side string(s) longer than {} character(s) during assignment   )
stacklevel)r0   
asanyarrayr/   r   sizerD   rE   rF   r
   r[   rn   r   r   )r<   r{   Zvalue_str_lenZself_str_lenr   r   r   _check_string_truncate=  s    

zColumn._check_string_truncatec             C   sR   | j jdkr| |}t| j jtjr0| | | j	||t
|  || j|< d S )NrA   )r/   rD   r|   r   r   r0   	characterr   r#   adjust_indicesrX   rT   )r<   r,   r{   r   r   r   r?   T  s    

zColumn.__setitem__c                s*   ddddddd   fdd	}|S )
z
        Make comparison methods which encode the ``other`` object to utf-8
        in the case of a bytestring dtype for Py3+.
        __eq____ne____lt____gt____le____ge__)r   r   r   r   r   r   c                sx   }t | tr>| jjdkr>t |tr>|jjdkr>||  } }}| jjdkrT| |}tt ||}t |trt|j	S |S )Nr@   rA   )
r$   r   r/   rB   rD   r|   r   r   r   rT   )r<   otheropresult)r;   operswapped_operr   r   _compareo  s    

z&Column._make_compare.<locals>._comparer   )r   r   )r;   )r   r   r   _make_comparec  s    zColumn._make_comparer   r   r   r   r   r   c             C   s^   | j jdkr(tj| |d|d}|||< nt| |}tj||||d}|| j}||  |S )a  
        Insert values before the given indices in the column and return
        a new `~astropy.table.Column` object.

        Parameters
        ----------
        obj : int, slice or sequence of int
            Object that defines the index or indices before which ``values`` is
            inserted.
        values : array-like
            Value(s) to insert.  If the type of ``values`` is different from
            that of the column, ``values`` is converted to the matching type.
            ``values`` should be shaped so that it can be broadcast appropriately.
        axis : int, optional
            Axis along which to insert ``values``.  If ``axis`` is None then
            the column array is flattened before insertion.  Default is 0,
            which will insert a row.

        Returns
        -------
        out : `~astropy.table.Column`
            A copy of column with ``values`` and ``mask`` inserted.  Note that the
            insertion does not occur in-place: a new column is returned.
        ON)axis)r/   rB   r0   insertrJ   r3   r;   r   )r<   r6   rI   r   rT   Zself_for_insertr   r   r   r   r     s    


zColumn.insert)NNNr   r   NNNNFT)F)r   ) r   r   r   r   r7   r   r   r   r   r   r   r   r?   r   r   r   r   r   r   r   r   r%   rt   rp   r"   r   r   r   r   r   r   r   r   r   )r;   r   r     s<   ?   
 (
(r   c                   sF   e Zd ZdZejdhB ZdZejj	Z
d	 fdd	Z fddZ  ZS )
MaskedColumnInfoa  
    Container for meta information like name, description, format.

    This is required when the object is used as a mixin column within a table,
    but can be used as a general way to store meta information.  In this case
    it just adds the ``mask_val`` attribute.
    serialize_methodrT   Fc                s$   t  | |r ddddd| _d S )N
null_value	data_mask)ZfitsZecsvZhdf5N)r   __init__r   )r<   bound)r;   r   r   r     s    zMaskedColumnInfo.__init__c                s^   t   }| j}| j| j }|dkrH|jj|d< t|jrZ|j|d< n|dkrRnt	d|S )Nr   rT   rW   r   z;serialize method must be either "data_mask" or "null_value")
r   _represent_as_dictrw   r   Z_serialize_contextrT   r0   r9   rW   r:   )r<   r   r*   method)r;   r   r   r     s    
z#MaskedColumnInfo._represent_as_dict)F)r   r   r   r   rm   ry   Z_represent_as_dict_primary_datar0   r   rC   Zmask_valr   r   r   r   r   )r;   r   r     s   r   c                   s   e Zd ZdZe ZdddZed	d
 Zej	dd
 Zedd Z
d fdd	ZdddZdd Zdd ZejZejZejZejZejZejZ  ZS )r   a
  Define a masked data column for use in a Table object.

    Parameters
    ----------
    data : list, ndarray, or None
        Column data values
    name : str
        Column name and key for reference within Table
    mask : list, ndarray or None
        Boolean mask for which True indicates missing or invalid data
    fill_value : float, int, str, or None
        Value used when filling masked column elements
    dtype : `~numpy.dtype`-like
        Data type for column
    shape : tuple or ()
        Dimensions of a single row element in the column data
    length : int or 0
        Number of row elements in column data
    description : str or None
        Full description of column
    unit : str or None
        Physical unit
    format : str, None, or callable
        Format string for outputting column values.  This can be an
        "old-style" (``format % value``) or "new-style" (`str.format`)
        format specification string or a function or any callable object that
        accepts a single value and returns a string.
    meta : dict-like or None
        Meta-data associated with the column

    Examples
    --------
    A MaskedColumn is similar to a Column except that it includes ``mask`` and
    ``fill_value`` attributes.  It can be created in two different ways:

    - Provide a ``data`` value but not ``shape`` or ``length`` (which are
      inferred from the data).

      Examples::

        col = MaskedColumn(data=[1, 2], name='name')
        col = MaskedColumn(data=[1, 2], name='name', mask=[True, False])
        col = MaskedColumn(data=[1, 2], name='name', dtype=float, fill_value=99)

      The ``mask`` argument will be cast as a boolean array and specifies
      which elements are considered to be missing or invalid.

      The ``dtype`` argument can be any value which is an acceptable
      fixed-size data-type initializer for the numpy.dtype() method.  See
      `<https://numpy.org/doc/stable/reference/arrays.dtypes.html>`_.
      Examples include:

      - Python non-string type (float, int, bool)
      - Numpy non-string type (e.g. np.float32, np.int64, np.bool\_)
      - Numpy.dtype array-protocol type strings (e.g. 'i4', 'f8', 'S15')

      If no ``dtype`` value is provide then the type is inferred using
      ``np.array(data)``.  When ``data`` is provided then the ``shape``
      and ``length`` arguments are ignored.

    - Provide ``length`` and optionally ``shape``, but not ``data``

      Examples::

        col = MaskedColumn(name='name', length=5)
        col = MaskedColumn(name='name', dtype=int, length=10, shape=(3,4))

      The default ``dtype`` is ``np.float64``.  The ``shape`` argument is the
      array shape of a single cell in the column.
    Nr   r   FTc             C   s   |d kr4t |j}|tj jkr&d}qN|rN| }n|tj jkrFd}nt|}t||||||	|
||||d}t jj| ||d}|d krt	|dd d k	rt
|j|jd }||_d |_x|jD ]}||| qW |S )NF)
r/   r5   rr   rt   rp   r   rq   ro   r"   r+   )rT   rW   
fill_valuer   )r   rL   rW   r0   nomaskr"   r   r%   r7   r   rZ   r   r/   r   r(   r)   )r4   rT   rt   rW   r   r/   r5   rr   rq   rp   r   ro   r"   r+   r   r<   r,   r   r   r   r7   P  s(    

zMaskedColumn.__new__c             C   s   |   S )N)Zget_fill_value)r<   r   r   r   r     s    zMaskedColumn.fill_valuec             C   s   d| _ | | dS )zSet fill value both in the masked column view and in the parent table
        if it exists.  Setting one or the other alone doesn't work.N)Z_fill_valueZset_fill_value)r<   r>   r   r   r   r     s    c             C   s   |  tjj}tj|_|S )z/The plain MaskedArray data held by this column.)r3   r0   r   rL   r   Z
_baseclass)r<   r   r   r   r   rT     s    zMaskedColumn.datac                sV   |dkr| j }t |}| jdk	r,| jjnt}|| j|| j| j| jt	| j
d}|S )a  Return a copy of self, with masked values filled with a given value.

        Parameters
        ----------
        fill_value : scalar; optional
            The value to use for invalid entries (`None` by default).  If
            `None`, the ``fill_value`` attribute of the array is used
            instead.

        Returns
        -------
        filled_column : Column
            A copy of ``self`` with masked entries replaced by `fill_value`
            (be it the function argument or the attribute of ``self``).
        N)rt   rT   rp   r   rq   ro   )r   r   filledr   r   rt   rp   r   rq   r   ro   )r<   r   rT   Z
column_clsr   )r;   r   r   r    s    zMaskedColumn.filledc       
      C   s   | j }| jjdkr0tj|j |d|d}|||< nt||}tj|j |||d}|dkrt|dtjj}|tjjkr| jjdkrd}ntj	t
|td}tj|j|||d}tjj||dd}|| j}	d|	_g |	_|	|  | j|	_|	S )a  
        Insert values along the given axis before the given indices and return
        a new `~astropy.table.MaskedColumn` object.

        Parameters
        ----------
        obj : int, slice or sequence of int
            Object that defines the index or indices before which ``values`` is
            inserted.
        values : array-like
            Value(s) to insert.  If the type of ``values`` is different from
            that of the column, ``values`` is converted to the matching type.
            ``values`` should be shaped so that it can be broadcast appropriately.
        mask : bool or array-like
            Mask value(s) to insert.  If not supplied, and values does not have
            a mask either, then False is used.
        axis : int, optional
            Axis along which to insert ``values``.  If ``axis`` is None then
            the column array is flattened before insertion.  Default is 0,
            which will insert a row.

        Returns
        -------
        out : `~astropy.table.MaskedColumn`
            A copy of column with ``values`` and ``mask`` inserted.  Note that the
            insertion does not occur in-place: a new masked column is returned.
        r   N)r   rW   F)r/   )rW   r"   )rT   r/   rB   r0   r   rJ   r   r   r  r1   r5   r2   rW   rZ   r3   r;   r   r(   r   r   )
r<   r6   rI   rW   r   Zself_maZnew_dataZnew_maskZnew_mar   r   r   r   r     s(    


zMaskedColumn.insertc             C   s2   |j | j kr.d |_|j| jkr$g |_||  |S )N)r;   r   r(   r   )r<   r   r   r   r   _copy_attrs_slice  s    
zMaskedColumn._copy_attrs_slicec             C   sr   | j jdkr| |}t| j jtjrJtjj|| j jd}| 	|
d | j||t|  tj| || d S )NrA   )r/   r   )r/   rD   r|   r   r   r0   r   r   r   r   r  r#   r   rX   rL   r?   )r<   r,   r{   r   r   r   r?     s    
zMaskedColumn.__setitem__)NNNNNr   r   NNNNFT)N)Nr   )r   r   r   r   r   r#   r7   r   r   r   rT   r  r   r  r?   r%   rt   r"   r   r   r   r   r   r   r   )r;   r   r     s&   F   
2

;r   )T)N):re   r[   r   r"   r   numpyr0   r   Zastropy.unitsr   r   Zastropy.utils.consoler   Zastropy.utils.metadatar   Zastropy.utils.data_infor   r	   Zastropy.utils.miscr
   r   r   r   Znp_utilsr   Z_column_mixinsr   r   ZTableFormatterr   r^   r   simplefilterr!   setZgreaterZgreater_equallessZ
less_equal	not_equalr   isfiniteisinfisnansignZsignbitr   r-   r   r.   rJ   rl   rm   r%   r   r   rL   r   r   r   r   r   <module>   sL   
  
 6    Z  B