o
    ˷e29                     @   sp   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m	Z	m
Z
mZ G dd deZG dd	 d	eZd
S )    )copy)Strict)MinMaxSequence)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			dDd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dEd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d.d/ Z d0d1 Z!e!Z"d2d3 Z#e#Z$d4d5 Z%dFd6d7Z&dFd8d9Z'ed:d; Z(ed<d= Z)ed>d? Z*ed@dA Z+edBdC Z,dS )G	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 urd|v rt |\}\}}}}nt|\}}}}|| _|| _|| _|| _|| _||kr9d}t|j||d||krHd}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)selfrange_stringr   r   r   r   r   fmt r   T/var/www/ideatree/venv/lib/python3.10/site-packages/openpyxl/worksheet/cell_range.py__init__/   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   boundsE   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   coordM   s   zCellRange.coordc                 #   @    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>d       z"CellRange.rows.<locals>.<listcomp>N)ranger   r   r   r   r   r   r'   r   rows^      $zCellRange.rowsc                 #   r#   )z4
        Return cell coordinates as columns
        r   c                    s   g | ]}| fqS r   r   r%   r(   r&   r   r   r)   m   r*   z"CellRange.cols.<locals>.<listcomp>N)r+   r   r   r   r   r   r   r/   r   colsg   r-   zCellRange.colsc                 C   s2   ddl m} |t| j| jd t| j| jd S )Nr   )productr   )	itertoolsr1   r+   r   r   r   r   )r   r1   r   r   r   cellsp   s   &zCellRange.cellsc                 C   s<   t |tsttt||jr| j|jkrtddS 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_titlev   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*   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   	col_shift	row_shiftr   r   r   shift   s   zCellRange.shiftc                 C   sT   z|  | W n
 ty   Y dS w |j| jkp)| j|jkp)|j| jkp)| 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)r:   r   r   r   r   r   r8   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*.
        )rE   r8   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*.
        r:   _CellRange__supersetr8   r   r   r   issubset      

zCellRange.issubsetc                 C      |  |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__rE   r8   r   r   r   __lt__      zCellRange.__lt__c                 C   sT   | j |j   ko|j  ko| jkn  o)| j|j  ko'|j  ko'| jkS   S N)r   r   r   r   r8   r   r   r   
__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*).
        rG   r8   r   r   r   
issuperset   rJ   zCellRange.issupersetc                 C   s   |  |}| |S )zO
        Check whether the range contains a particular cell coordinate
        )r<   rH   r   r"   crr   r   r   __contains__   s   

zCellRange.__contains__c                 C   rK   )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__rE   r8   r   r   r   __gt__  rN   zCellRange.__gt__c                 C   sD   |  | | j|jkr|| } }| j|jk p!| j|jk p!|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.
        )r:   r    r   r   r   r   r8   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   )
rW   r   r   r   r   r   r   r   r   r   r   r9   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*.
        r@   )	r:   r   r   r   r   r   r   r   r   rX   r   r   r   union=  s   

zCellRange.unionc                 c   s0    | 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__S  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   rightdownleftupr   r   r   expand^     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 bottown by this number of cells
        Nr   )r   r`   bottomrb   topr   r   r   shrinkq  re   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   r0   r,   r   r   r   size  s   
zCellRange.sizec                         fddt  j jd D S )z=A list of cell coordinates that comprise the top of the rangec                       g | ]} j |fqS r   )r   r$   r   r   r   r)         z!CellRange.top.<locals>.<listcomp>r   r+   r   r   r   r   r   r   rg         zCellRange.topc                    rk   )z@A list of cell coordinates that comprise the bottom of the rangec                    rl   r   )r   r$   r   r   r   r)     rm   z$CellRange.bottom.<locals>.<listcomp>r   rn   r   r   r   r   rf     ro   zCellRange.bottomc                    rk   )zCA list of cell coordinates that comprise the left-side of the rangec                       g | ]}| j fqS r   )r   r.   r   r   r   r)     rm   z"CellRange.left.<locals>.<listcomp>r   r+   r   r   r   r   r   r   rb     ro   zCellRange.leftc                    rk   )zDA list of cell coordinates that comprise the right-side of the rangec                    rp   r   )r   r.   r   r   r   r)     rm   z#CellRange.right.<locals>.<listcomp>r   rq   r   r   r   r   r`     ro   zCellRange.right)NNNNNN)r   r   )r   r   r   r   )-r=   
__module____qualname____doc__r   intr   r   r   r   r   propertyr    r"   r,   r0   r3   r:   r>   r?   rA   rD   rE   rF   rI   rL   rM   rH   rQ   rU   rT   rV   rW   rY   __and__rZ   __or__r_   rd   rh   rj   rg   rf   rb   r`   r   r   r   r   r      sh    





	






r   c                   @   s|   e Zd ZeedZdddZdd Zdd Zd	d
 Z	e	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   r   c                 C   s&   t |trdd | D }|| _d S )Nc                 S      g | ]}t |qS r   )r   r%   rr   r   r   r)     r*   z+MultiCellRange.__init__.<locals>.<listcomp>)r4   strsplitrangesr   r   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)r4   r}   r   r   )r   r"   r|   r   r   r   rT     s   

zMultiCellRange.__contains__c                 C   s&   d dd | jD }d| jj|S )N c                 S   rz   r   r}   r{   r   r   r   r)     r*   z+MultiCellRange.__repr__.<locals>.<listcomp>z<{0} [{1}]>)joinr   r   r<   r=   r   r   r   r   r>     s   zMultiCellRange.__repr__c                 C   s   d dd | jD }|S )Nr   c                 S   rz   r   r   r{   r   r   r   r)     r*   z*MultiCellRange.__str__.<locals>.<listcomp>)r   r   r   r   r   r   r?     s   zMultiCellRange.__str__c                 C   sF   |}t |trt|}n	t |tstd|| vr!| j| dS dS )z4
        Add a cell coordinate or CellRange
        zYou can only add CellRangesN)r4   r}   r   r   r   appendrR   r   r   r   add  s   


zMultiCellRange.addc                 C   s   |  | | S rO   )r   r   r"   r   r   r   __iadd__  s   
zMultiCellRange.__iadd__c                 C   s    t |tr
| |}| j|jkS rO   )r4   r}   r<   r   r8   r   r   r   rF     s   

zMultiCellRange.__eq__c                 C   s
   | |k S rO   r   r8   r   r   r   rE        
zMultiCellRange.__ne__c                 C   s
   t | jS rO   )boolr   r   r   r   r   __bool__  r   zMultiCellRange.__bool__c                 C   s"   t |ts	t|}| j| d S rO   )r4   r   r   remover   r   r   r   r     s   
zMultiCellRange.removec                 c   s    | j D ]}|V  qd S rO   )r   )r   rS   r   r   r   r_     s   
zMultiCellRange.__iter__c                 C   s&   t  }| jD ]
}|jt| q|S rO   )ry   r   r   r   )r   nr|   r   r   r   rA     s   
zMultiCellRange.__copy__N)r   )r=   rr   rs   r   r   r   r   rT   r>   r?   r   r   rF   rE   r   r   r_   rA   r   r   r   r   ry     s    

	ry   N)r   openpyxl.descriptorsr   r   r   !openpyxl.descriptors.serialisabler   openpyxl.utilsr   r   r	   r
   r   ry   r   r   r   r   <module>   s      