o
    g:                     @   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'dHd:d;Z(ed<d= Z)ed>d? Z*ed@dA Z+edBdC Z,edDdE Z-dS )I	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   W/var/www/html/api-tag/env/lib/python3.10/site-packages/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                 #   @    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       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+   n   r,   z"CellRange.cols.<locals>.<listcomp>N)r-   r   r   r   r   r!   r   r1   r   colsh   r/   zCellRange.colsc                 C   s2   ddl m} |t| j| jd t| j| jd S )Nr   )productr   )	itertoolsr3   r-   r   r   r   r   )r   r3   r   r   r   cellsq   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_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   	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   r:   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*.
        )rJ   r:   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__supersetr:   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__rJ   r:   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 rA   )r   r   r   r   r:   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*).
        rL   r:   r   r   r   
issuperset   rO   zCellRange.issupersetc                 C   s   |  |}| |S )zO
        Check whether the range contains a particular cell coordinate
        )r>   rM   r   r$   crr   r   r   __contains__  s   

zCellRange.__contains__c                 C   rP   )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__rJ   r:   r   r   r   __gt__  rS   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   r:   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    )
r[   r   r   r   r   r   r   r   r   r   r   r;   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*.
        rE   )	r<   r   r   r   r   r   r   r   r   r\   r   r   r   unionB  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__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   rightdownleftupr   r   r   expandc     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   rd   bottomrf   topr   r   r   shrinkv  ri   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   r2   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   rk         zCellRange.topc                    ro   )z@A list of cell coordinates that comprise the bottom of the rangec                    rp   r   )r   r&   r!   r   r   r+     rq   z$CellRange.bottom.<locals>.<listcomp>r   rr   r!   r   r!   r   rj     rs   zCellRange.bottomc                    ro   )zCA list of cell coordinates that comprise the left-side of the rangec                       g | ]}| j fqS r   )r   r0   r!   r   r   r+     rq   z"CellRange.left.<locals>.<listcomp>r   r-   r   r   r!   r   r!   r   rf     rs   zCellRange.leftc                    ro   )zDA list of cell coordinates that comprise the right-side of the rangec                    rt   r   )r   r0   r!   r   r   r+     rq   z#CellRange.right.<locals>.<listcomp>r   ru   r!   r   r!   r   rd     rs   zCellRange.right)NNNNNN)r   r   )r   r   r   r   ).r?   
__module____qualname____doc__r   intr   r   r   r   r   propertyr"   r$   r.   r2   r5   r<   r@   rC   rD   rF   rI   rJ   rK   rN   rQ   rR   rM   rU   rY   rX   rZ   r[   r]   __and__r^   __or__rc   rh   rl   rn   rk   rj   rf   rd   r   r   r   r   r      sj    





	






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      g | ]}t |qS r   )r   r'   rr   r   r   r+     r,   z+MultiCellRange.__init__.<locals>.<listcomp>)r6   strsplitset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)r6   r   r   r   )r   r$   r   r   r   r   rX     s   

zMultiCellRange.__contains__c                 C   s.   d dd |  D }d| jj d| dS )N c                 S   r~   r   r   r   r   r   r   r+     r,   z+MultiCellRange.__repr__.<locals>.<listcomp><z [z]>)joinsortedr>   r?   r   r   r   r   r@     s   zMultiCellRange.__repr__c                 C   s   d dd |  D }|S )Nr   c                 S   r~   r   r   r   r   r   r   r+     r,   z*MultiCellRange.__str__.<locals>.<listcomp>)r   r   r   r   r   r   rD     s   zMultiCellRange.__str__c                 C   s   t t| S rA   )rB   r   r!   r   r   r   rC     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)r   r   r   r!   r   r   r   r     s   zMultiCellRange.sortedc                 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)r6   r   r   r   r   addrV   r   r   r   r     s   


zMultiCellRange.addc                 C   s   |  | | S rA   )r   r   r$   r   r   r   __iadd__  s   
zMultiCellRange.__iadd__c                 C   s    t |tr
| |}| j|jkS rA   )r6   r   r>   r   r:   r   r   r   rK     s   

zMultiCellRange.__eq__c                 C   s
   | |k S rA   r   r:   r   r   r   rJ        
zMultiCellRange.__ne__c                 C   s
   t | jS rA   )boolr   r!   r   r   r   __bool__  r   zMultiCellRange.__bool__c                 C   s"   t |ts	t|}| j| d S rA   )r6   r   r   remover   r   r   r   r     s   
zMultiCellRange.removec                 c   s    | j D ]}|V  qd S rA   )r   )r   rW   r   r   r   rc     s   
zMultiCellRange.__iter__c                 C   s   dd | j D }t|S )Nc                 S   s   h | ]}t |qS r   r   r   r   r   r   	<setcomp>  r,   z*MultiCellRange.__copy__.<locals>.<setcomp>)r   r}   r   r   r   r   rF     s   zMultiCellRange.__copy__N)r?   rv   rw   r   r   r   r   r   rX   r@   rD   rC   r   r   r   rK   rJ   r   r   rc   rF   r   r   r   r   r}     s     
	r}   N)r   operatorr   openpyxl.descriptorsr   r   openpyxl.descriptors.sequencer   !openpyxl.descriptors.serialisabler   openpyxl.utilsr	   r
   r   r   r   r}   r   r   r   r   <module>   s      