U
    rÎ·h¥:  ã                   @   s„   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 d dlm	Z	 d dl
mZmZmZmZ G dd	„ d	e	ƒZG d
d„ deƒZdS )é    ©Úcopy)Ú
attrgetter)ÚStrict)ÚMinMax)ÚUniqueSequence)ÚSerialisable)Úrange_boundariesÚrange_to_tupleÚget_column_letterÚquote_sheetnamec                   @   s€  e Zd ZdZedded�Zedded�Zedded�Zedded�Z	dFdd„Z
ed	d
„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZedd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdGdd„Zd d!„ Zd"d#„ Zd$d%„ ZeZd&d'„ Zd(d)„ Zd*d+„ ZeZd,d-„ Zd.d/„ Z d0d1„ Z!d2d3„ Z"e"Z#d4d5„ Z$e$Z%d6d7„ Z&dHd8d9„Z'dId:d;„Z(ed<d=„ ƒZ)ed>d?„ ƒZ*ed@dA„ ƒZ+edBdC„ ƒZ,edDdE„ ƒZ-dS )JÚ	CellRangeaÜ  
    Represents a range in a sheet: title and coordinates.

    This object is used to perform operations on ranges, like:

    - shift, expand or shrink
    - union/intersection with another sheet range,

    We can check whether a range is:

    - equal or not equal to another,
    - disjoint of another,
    - contained in another.

    We can get:

    - the size of a range.
    - the range bounds (vertices)
    - the coordinates,
    - the string representation,

    é   ifG  )ÚminÚmaxÚexpected_typei   Nc                 C   s”   |d k	r6d|kr&t |ƒ\}\}}}}nt|ƒ\}}}}|| _|| _|| _|| _|| _||krrd}t|j||d�ƒ‚||kr�d}t|j||d�ƒ‚d S )Nú!z({max_col} must be greater than {min_col})Úmin_colÚmax_colz({max_row} must be greater than {min_row})Úmin_rowÚmax_row)	r
   r	   r   r   r   r   ÚtitleÚ
ValueErrorÚformat)ÚselfZrange_stringr   r   r   r   r   Úfmt© r   úA/tmp/pip-unpacked-wheel-49e_hfpc/openpyxl/worksheet/cell_range.pyÚ__init__0   s    zCellRange.__init__c                 C   s   | j | j| j| jfS )z2
        Vertices of the range as a tuple
        ©r   r   r   r   ©r   r   r   r   ÚboundsF   s    zCellRange.boundsc                 C   sB   d}| j | jkr | j| jkr d}|jt| j ƒ| jt| jƒ| jd�S )z9
        Excel-style representation of the range
        z%{min_col}{min_row}:{max_col}{max_row}z{min_col}{min_row}r   )r   r   r   r   r   r   ©r   r   r   r   r   ÚcoordN   s    
ÿüzCellRange.coordc                 #   s>   t | j| jd ƒD ]&‰ ‡ fdd„t | j| jd ƒD ƒV  qdS )z1
        Return cell coordinates as rows
        r   c                    s   g | ]}ˆ |f‘qS r   r   ©Ú.0Úcol©Úrowr   r   Ú
<listcomp>e   s     z"CellRange.rows.<locals>.<listcomp>N)Úranger   r   r   r   r    r   r'   r   Úrows_   s    zCellRange.rowsc                 #   s>   t | j| jd ƒD ]&‰ ‡ fdd„t | j| jd ƒD ƒV  qdS )z4
        Return cell coordinates as columns
        r   c                    s   g | ]}|ˆ f‘qS r   r   ©r%   r(   ©r&   r   r   r)   n   s     z"CellRange.cols.<locals>.<listcomp>N)r*   r   r   r   r   r    r   r-   r   Úcolsh   s    zCellRange.colsc                 C   s2   ddl m} |t| j| jd ƒt| j| jd ƒƒS )Nr   )Úproductr   )Ú	itertoolsr/   r*   r   r   r   r   )r   r/   r   r   r   Úcellsq   s    zCellRange.cellsc                 C   s8   t |tƒsttt|ƒƒƒ‚|jr4| j|jkr4tdƒ‚dS )z²
        Check whether comparisons between ranges are possible.
        Cannot compare ranges from different worksheets
        Skip if the range passed in has no title.
        z1Cannot work with ranges from different worksheetsN)Ú
isinstancer   Ú	TypeErrorÚreprÚtyper   r   ©r   Úotherr   r   r   Ú_check_titlew   s    
zCellRange._check_titlec                 C   s&   d}| j rd}|j| jj| j | jd�S )Nz<{cls} {coord}>z<{cls} {title!r}!{coord}>)Úclsr   r#   )r   r   Ú	__class__Ú__name__r#   r"   r   r   r   Ú__repr__„   s    zCellRange.__repr__c                 C   s   t | j| j| j| jfƒS ©N)Úhashr   r   r   r   r    r   r   r   Ú__hash__‹   s    zCellRange.__hash__c                 C   s*   d}| j }|rd}t|ƒ}|j|| jd�S )Nz{coord}z{title}!{coord})r   r#   )r   r   r   r#   )r   r   r   r   r   r   Ú__str__�   s    zCellRange.__str__c                 C   s   | j | j| j| j| j| jd�S )N©r   r   r   r   r   )r:   r   r   r   r   r   r    r   r   r   Ú__copy__˜   s
     þzCellRange.__copy__r   c                 C   sh   | j | dks| j| dkr,td ||¡ƒ‚|  j |7  _ |  j|7  _|  j|7  _|  j|7  _dS )a{  
        Shift the focus of the range according to the shift values (*col_shift*, *row_shift*).

        :type col_shift: int
        :param col_shift: number of columns to be moved by, can be negative
        :type row_shift: int
        :param row_shift: number of rows to be moved by, can be negative
        :raise: :class:`ValueError` if any row or column index < 1
        r   z1Invalid shift value: col_shift={0}, row_shift={1}N)r   r   r   r   r   r   )r   Z	col_shiftZ	row_shiftr   r   r   Úshiftž   s    ÿzCellRange.shiftc                 C   sV   z|   |¡ W n tk
r$   Y dS X |j| jkpT| j|jkpT|j| jkpT| j|jkS )zÏ
        Test whether the ranges are not equal.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* != *other*.
        T)r8   r   r   r   r   r   r6   r   r   r   Ú__ne__²   s    
ÿ
þ
üzCellRange.__ne__c                 C   s   |   |¡ S )zË
        Test whether the ranges are equal.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* == *other*.
        )rD   r6   r   r   r   Ú__eq__Ç   s    zCellRange.__eq__c                 C   s   |   |¡ | | ¡S )zâ
        Test whether every cell in this range is also in *other*.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* <= *other*.
        ©r8   Ú_CellRange__supersetr6   r   r   r   ÚissubsetÒ   s    
zCellRange.issubsetc                 C   s   |   |¡o|  |¡S )zé
        Test whether *other* contains every cell of this range, and more.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* < *other*.
        )Ú__le__rD   r6   r   r   r   Ú__lt__á   s    zCellRange.__lt__c                 C   sT   | j |j   ko$|j  ko$| jkn  oR| j|j  koN|j  koN| jkS   S r=   )r   r   r   r   r6   r   r   r   Z
__supersetì   s    *(ýzCellRange.__supersetc                 C   s   |   |¡ |  |¡S )zõ
        Test whether every cell in *other* is in this range.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* >= *other* (or *other* in *range*).
        rF   r6   r   r   r   Ú
issupersetô   s    
zCellRange.issupersetc                 C   s   |   |¡}|  |¡S )zO
        Check whether the range contains a particular cell coordinate
        )r:   rG   ©r   r#   Úcrr   r   r   Ú__contains__  s    
zCellRange.__contains__c                 C   s   |   |¡o|  |¡S )zé
        Test whether this range contains every cell in *other*, and more.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range
        :return: ``True`` if *range* > *other*.
        )Ú__ge__rD   r6   r   r   r   Ú__gt__  s    zCellRange.__gt__c                 C   sD   |   |¡ | j|jkr ||  } }| j|jk pB| j|jk pB|j| jk S )aV  
        Return ``True`` if this range has no cell in common with *other*.
        Ranges are disjoint if and only if their intersection is the empty range.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range.
        :return: ``True`` if the range has no cells in common with other.
        )r8   r!   r   r   r   r   r6   r   r   r   Ú
isdisjoint  s    	


ÿ
þzCellRange.isdisjointc                 C   sb   |   |¡rtd | |¡ƒ‚t| j|jƒ}t| j|jƒ}t| j|jƒ}t| j|jƒ}t	||||d�S )aN  
        Return a new range with cells common to this range and *other*

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range.
        :return: the intersecting sheet range.
        :raise: :class:`ValueError` if the *other* range doesn't intersect
            with this range.
        zRange {0} doesn't intersect {0}r   )
rQ   r   r   r   r   r   r   r   r   r   ©r   r7   r   r   r   r   r   r   r   Úintersection*  s    

ÿzCellRange.intersectionc                 C   sV   |   |¡ t| j|jƒ}t| j|jƒ}t| j|jƒ}t| j|jƒ}t||||| jd�S )a�  
        Return the minimal superset of this range and *other*. This new range
        will contain all cells from this range, *other*, and any additional
        cells required to form a rectangular ``CellRange``.

        :type other: openpyxl.worksheet.cell_range.CellRange
        :param other: Other sheet range.
        :return: a ``CellRange`` that is a superset of this and *other*.
        rA   )	r8   r   r   r   r   r   r   r   r   rR   r   r   r   ÚunionB  s    

 ÿzCellRange.unionc                 c   s.   | j D ]"}|dkrqt| |ƒ}||fV  qdS )zC
        For use as a dictionary elsewhere in the library.
        r   N)Ú	__attrs__Úgetattr)r   ÚxÚvr   r   r   Ú__iter__X  s
    

zCellRange.__iter__c                 C   s<   |  j |8  _ |  j|8  _|  j|7  _|  j|7  _dS )a¦  
        Expand the range by the dimensions provided.

        :type right: int
        :param right: expand range to the right by this number of cells
        :type down: int
        :param down: expand range down by this number of cells
        :type left: int
        :param left: expand range to the left by this number of cells
        :type up: int
        :param up: expand range up by this number of cells
        Nr   )r   ÚrightZdownÚleftZupr   r   r   Úexpandc  s    zCellRange.expandc                 C   s<   |  j |7  _ |  j|7  _|  j|8  _|  j|8  _dS )a¿  
        Shrink the range by the dimensions provided.

        :type right: int
        :param right: shrink range from the right by this number of cells
        :type down: int
        :param down: shrink range from the top by this number of cells
        :type left: int
        :param left: shrink range from the left by this number of cells
        :type up: int
        :param up: shrink range from the bottom by this number of cells
        Nr   )r   rZ   Úbottomr[   Útopr   r   r   Úshrinkv  s    zCellRange.shrinkc                 C   s*   | j d | j }| jd | j }||dœS )zC Return the size of the range as a dictionary of rows and columns. r   )Úcolumnsr+   )r   r   r   r   )r   r.   r+   r   r   r   Úsize‰  s    zCellRange.sizec                    s    ‡ fdd„t ˆ jˆ jd ƒD ƒS )z=A list of cell coordinates that comprise the top of the rangec                    s   g | ]}ˆ j |f‘qS r   )r   r$   r    r   r   r)   ”  s     z!CellRange.top.<locals>.<listcomp>r   ©r*   r   r   r    r   r    r   r^   ‘  s    zCellRange.topc                    s    ‡ fdd„t ˆ jˆ jd ƒD ƒS )z@A list of cell coordinates that comprise the bottom of the rangec                    s   g | ]}ˆ j |f‘qS r   )r   r$   r    r   r   r)   š  s     z$CellRange.bottom.<locals>.<listcomp>r   rb   r    r   r    r   r]   —  s    zCellRange.bottomc                    s    ‡ fdd„t ˆ jˆ jd ƒD ƒS )zCA list of cell coordinates that comprise the left-side of the rangec                    s   g | ]}|ˆ j f‘qS r   )r   r,   r    r   r   r)      s     z"CellRange.left.<locals>.<listcomp>r   ©r*   r   r   r    r   r    r   r[   �  s    zCellRange.leftc                    s    ‡ fdd„t ˆ jˆ jd ƒD ƒS )zDA list of cell coordinates that comprise the right-side of the rangec                    s   g | ]}|ˆ j f‘qS r   )r   r,   r    r   r   r)   ¦  s     z#CellRange.right.<locals>.<listcomp>r   rc   r    r   r    r   rZ   £  s    zCellRange.right)NNNNNN)r   r   )r   r   r   r   )r   r   r   r   ).r;   Ú
__module__Ú__qualname__Ú__doc__r   Úintr   r   r   r   r   Úpropertyr!   r#   r+   r.   r1   r8   r<   r?   r@   rB   rC   rD   rE   rH   rI   rJ   rG   rK   rO   rN   rP   rQ   rS   Ú__and__rT   Ú__or__rY   r\   r_   ra   r^   r]   r[   rZ   r   r   r   r   r      sl         ÿ





	






r   c                   @   sŒ   e Zd Zeed�Zeƒ f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d„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdS )ÚMultiCellRange)r   c                 C   s*   t |tƒrdd„ | ¡ D ƒ}t|ƒ| _d S )Nc                 S   s   g | ]}t |ƒ‘qS r   )r   ©r%   Úrr   r   r   r)   ±  s     z+MultiCellRange.__init__.<locals>.<listcomp>)r2   ÚstrÚsplitÚsetÚranges©r   rq   r   r   r   r   ¯  s    
zMultiCellRange.__init__c                 C   s0   t |tƒrt|ƒ}| jD ]}||kr dS qdS )NTF)r2   rn   r   rq   )r   r#   rm   r   r   r   rN   µ  s    

zMultiCellRange.__contains__c                 C   s.   d  dd„ |  ¡ D ƒ¡}d| jj› d|› d�S )Nú c                 S   s   g | ]}t |ƒ‘qS r   ©rn   rl   r   r   r   r)   ¿  s     z+MultiCellRange.__repr__.<locals>.<listcomp>ú<z [z]>)ÚjoinÚsortedr:   r;   rr   r   r   r   r<   ¾  s    zMultiCellRange.__repr__c                 C   s   d  dd„ |  ¡ D ƒ¡}|S )Nrs   c                 S   s   g | ]}t |ƒ‘qS r   rt   rl   r   r   r   r)   Ä  s     z*MultiCellRange.__str__.<locals>.<listcomp>)rv   rw   rr   r   r   r   r@   Ã  s    zMultiCellRange.__str__c                 C   s   t t| ƒƒS r=   )r>   rn   r    r   r   r   r?   È  s    zMultiCellRange.__hash__c                 C   s   t | jtddddƒd�S )z/
        Return a sorted list of items
        r   r   r   r   )Úkey)rw   rq   r   r    r   r   r   rw   Ì  s    zMultiCellRange.sortedc                 C   sB   |}t |tƒrt|ƒ}nt |tƒs*tdƒ‚|| kr>| j |¡ dS )z4
        Add a cell coordinate or CellRange
        zYou can only add CellRangesN)r2   rn   r   r   rq   ÚaddrL   r   r   r   ry   Ó  s    


zMultiCellRange.addc                 C   s   |   |¡ | S r=   )ry   ©r   r#   r   r   r   Ú__iadd__à  s    
zMultiCellRange.__iadd__c                 C   s    t |tƒr|  |¡}| j|jkS r=   )r2   rn   r:   rq   r6   r   r   r   rE   å  s    

zMultiCellRange.__eq__c                 C   s
   | |k S r=   r   r6   r   r   r   rD   ë  s    zMultiCellRange.__ne__c                 C   s
   t | jƒS r=   )Úboolrq   r    r   r   r   Ú__bool__ï  s    zMultiCellRange.__bool__c                 C   s"   t |tƒst|ƒ}| j |¡ d S r=   )r2   r   rq   Úremoverz   r   r   r   r~   ó  s    
zMultiCellRange.removec                 c   s   | j D ]
}|V  qd S r=   )rq   )r   rM   r   r   r   rY   ù  s    
zMultiCellRange.__iter__c                 C   s   dd„ | j D ƒ}t|ƒS )Nc                 S   s   h | ]}t |ƒ’qS r   r   rl   r   r   r   Ú	<setcomp>ÿ  s     z*MultiCellRange.__copy__.<locals>.<setcomp>)rq   rk   rr   r   r   r   rB   þ  s    zMultiCellRange.__copy__N)r;   rd   re   r   r   rq   rp   r   rN   r<   r@   r?   rw   ry   r{   rE   rD   r}   r~   rY   rB   r   r   r   r   rk   ©  s   
	rk   N)r   Úoperatorr   Zopenpyxl.descriptorsr   r   Zopenpyxl.descriptors.sequencer   Z!openpyxl.descriptors.serialisabler   Zopenpyxl.utilsr	   r
   r   r   r   rk   r   r   r   r   Ú<module>   s      