o
    ҷh8o                     @  s   d dl mZ d dlmZmZmZmZmZ dd
dZdddZ	G dd dZ
G dd dZG dd dZG dd dZG dd dZG dd dZerjeeeeeeeef f  eeeeeeeeef f  f ZdS dS )    )annotations)TYPE_CHECKINGIteratorSequenceTupleUnionops_AnyOpList | Nonesrc_lenintdest_lenreturnlist[Editop]c           
      C  sF  | sg S t | d dkrt| || jS g }| D ]?}|\}}}||ks(||kr.d}t|||kr<|dkr<d}t|||krJ|dkrJd}t||dkrOq|t||| qtdt |d D ]>}	||	d  j||	 jk s|||	d  j	||	 j	k rd}t|||	d  j||	 jkr||	d  j	||	 j	krd	}t|qb|S )
Nr      List of edit operations invalidinsertdeleteequal   z$List of edit operations out of orderzDuplicated edit operation)
lenOpcodes
as_editops_editops
ValueErrorappendEditoprangesrc_posdest_pos)
r   r
   r   blocksop	edit_typer   r   msgi r$   T/var/www/html/venv/lib/python3.10/site-packages/rapidfuzz/distance/_initialize_py.py_list_to_editops	   s8   
00r&   list[Opcode]c              	   C  s  | r
t | d dkrt| || jS g }| D ]}|\}}}}}	||ks(|	|kr.d}
t|
||k s6|	|k r<d}
t|
|dv rR|| |	| ksL||krRd}
t|
|dkrd||ks^||	krdd}
t|
|dkrv||ksp||	krvd}
t|
|r|d j|kr|d j|kr|d j|kr||d _|	|d _q|t	|||||	 q|d j
dks|d jdkrd}
t|
|d j|ks|d j|krd	}
t|
tdt |d
 D ] }||d
  j
|| jks||d
  j|| jkrd}
t|
q|S )Nr      r   >   r   replacer   r   z4List of edit operations does not start at position 0z7List of edit operations does not end at the string endsr   z)List of edit operations is not continuous)r   Editops
as_opcodes_opcodesr   tagsrc_enddest_endr   Opcode	src_start
dest_startr   )r   r
   r   r   r    r!   r2   r/   r3   r0   r"   r#   r$   r$   r%   _list_to_opcodes8   sL    *

0r4   c                   @  sL   e Zd ZdZdddZdd	d
ZdddZdddZdddZdddZ	dS ) MatchingBlockz1
    Triple describing matching subsequences
    ar   bsizec                 C     || _ || _|| _d S Nr6   r7   r8   )selfr6   r7   r8   r$   r$   r%   __init__x      
zMatchingBlock.__init__r   c                 C     dS Nr(   r$   r<   r$   r$   r%   __len__}      zMatchingBlock.__len__otherobjectboolc                 C  X   z!t |dkr
W dS t|d | jko|d | jko|d | jkW S  ty+   Y dS w Nr(   Fr   r      )r   rF   r6   r7   r8   	TypeErrorr<   rD   r$   r$   r%   __eq__   s   0zMatchingBlock.__eq__r#   c                 C  6   |dv r| j S |dv r| jS |dv r| jS d}t|)N   r      r      rI   r*   z MatchingBlock index out of range)r6   r7   r8   
IndexErrorr<   r#   r"   r$   r$   r%   __getitem__      zMatchingBlock.__getitem__Iterator[int]c                 c      t dD ]}| | V  qd S r@   r   r<   r#   r$   r$   r%   __iter__      zMatchingBlock.__iter__strc                 C  s   d| j  d| j d| j dS )NzMatchingBlock(a=z, b=z, size=)r;   rA   r$   r$   r%   __repr__      zMatchingBlock.__repr__N)r6   r   r7   r   r8   r   r   r   rD   rE   r   rF   )r#   r   r   r   )r   rW   r   r]   
__name__
__module____qualname____doc__r=   rB   rL   rU   r[   r_   r$   r$   r$   r%   r5   s   s    



	
r5   c                   @  sL   e Zd ZdZdddZdd
dZdddZdddZdddZd ddZ	dS )!r   a  
    Tuple like object describing an edit operation.
    It is in the form (tag, src_pos, dest_pos)

    The tags are strings, with these meanings:

    +-----------+---------------------------------------------------+
    | tag       | explanation                                       |
    +===========+===================================================+
    | 'replace' | src[src_pos] should be replaced by dest[dest_pos] |
    +-----------+---------------------------------------------------+
    | 'delete'  | src[src_pos] should be deleted                    |
    +-----------+---------------------------------------------------+
    | 'insert'  | dest[dest_pos] should be inserted at src[src_pos] |
    +-----------+---------------------------------------------------+
    r.   r]   r   r   r   c                 C  r9   r:   r.   r   r   )r<   r.   r   r   r$   r$   r%   r=      r>   zEditop.__init__r   c                 C  r?   r@   r$   rA   r$   r$   r%   rB      rC   zEditop.__len__rD   rE   rF   c                 C  rG   rH   )r   rF   r.   r   r   rJ   rK   r$   r$   r%   rL      s   zEditop.__eq__r#   	int | strc                 C  rM   )NrN   rP   rR   zEditop index out of range)r.   r   r   rS   rT   r$   r$   r%   rU      rV   zEditop.__getitem__Iterator[int | str]c                 c  rX   r@   rY   rZ   r$   r$   r%   r[      r\   zEditop.__iter__c                 C  s   d| j d| j d| j dS )NzEditop(tag=z
, src_pos=z, dest_pos=r^   ri   rA   r$   r$   r%   r_      r`   zEditop.__repr__N)r.   r]   r   r   r   r   ra   rb   r#   r   r   rj   r   rk   rc   rd   r$   r$   r$   r%   r      s    




r   c                   @  s   e Zd ZdZ			d?d@d	d
ZedAddZdBddZdCddZdDddZ	dEddZ
dEddZdFddZdGd#d$ZedHd%d&ZejdId(d&ZedHd)d*ZejdId+d*ZdJd/d0ZdHd1d2ZdKd5d6ZdLd8d9ZdMd;d<ZdNd=d>ZdS )Or+   zH
    List like object of Editops describing how to turn s1 into s2.
    Nr   editopsr	   r
   r   r   c                 C     || _ || _t|||| _d S r:   )_src_len	_dest_lenr&   r   )r<   rn   r
   r   r$   r$   r%   r=         zEditops.__init__opcodesr   r   c                 C     |  S )z
        Create Editops from Opcodes

        Parameters
        ----------
        opcodes : Opcodes
            opcodes to convert to editops

        Returns
        -------
        editops : Editops
            Opcodes converted to Editops
        )r   )clsrs   r$   r$   r%   from_opcodes      zEditops.from_opcodesc           	   	   C  s  t t }| j|_| j|_g }d}d}d}|t| jk r|| j| jk s,|| j| jk rK|t	d|| j| j|| j| j | j| j}| j| j}|}|}| j| j
}|t| jk r| j| j
|kr|| j| jkr|| j| jkr|dkr|d7 }|d7 }n|dkr|d7 }n|dkr|d7 }|d7 }|t| jk r| j| j
|kr|| j| jkr|| j| jkst|t	||||| |t| jk s|| jk s|| jk r|t	d|| j|| j ||_|S )z
        Convert to Opcodes

        Returns
        -------
        opcodes : Opcodes
            Editops converted to Opcodes
        r   r   r)   r   r   r   )r   __new__rp   rq   r   r   r   r   r   r1   r.   r
   r   r-   )	r<   xr   r   r   r#   	src_begin
dest_beginr.   r$   r$   r%   r,      sZ   
	 

	

#zEditops.as_opcodeslist[MatchingBlock]c                 C  s  g }d}d}| D ]K}||j k s||jk r2t|j | |j| }|dkr,|t||| |j }|j}|jdkr@|d7 }|d7 }q|jdkrJ|d7 }q|jdkrS|d7 }q|| jk s^|| jk rvt| j| | j| }|dkrv|t||| |t| j| jd |S )z
        Convert to matching blocks

        Returns
        -------
        matching blocks : list[MatchingBlock]
            Editops converted to matching blocks
        r   r)   r   r   r   )r   r   minr   r5   r.   r
   r   )r<   r   r   r   r    lengthr$   r$   r%   as_matching_blocks/  s0   	




zEditops.as_matching_blocksr   c                 C     dd | j D S )zr
        Convert Editops to a list of tuples.

        This is the equivalent of ``[x for x in editops]``
        c                 S     g | ]}t |qS r$   tuple.0r    r$   r$   r%   
<listcomp>Y      z#Editops.as_list.<locals>.<listcomp>r   rA   r$   r$   r%   as_listS  s   zEditops.as_listc                 C  .   t t }| j|_| j|_| jdd |_|S )z*
        performs copy of Editops
        N)r+   rx   rp   rq   r   r<   ry   r$   r$   r%   copy[  
   
zEditops.copyc                 C  sh   g }| D ]}|j }|dkrd}n|dkrd}|t||j|j qtt}| j|_| j	|_
||_|S )a  
        Invert Editops, so it describes how to transform the destination string to
        the source string.

        Returns
        -------
        editops : Editops
            inverted Editops

        Examples
        --------
        >>> from rapidfuzz.distance import Levenshtein
        >>> Levenshtein.editops('spam', 'park')
        [Editop(tag=delete, src_pos=0, dest_pos=0),
         Editop(tag=replace, src_pos=3, dest_pos=2),
         Editop(tag=insert, src_pos=4, dest_pos=3)]

        >>> Levenshtein.editops('spam', 'park').inverse()
        [Editop(tag=insert, src_pos=0, dest_pos=0),
         Editop(tag=replace, src_pos=2, dest_pos=3),
         Editop(tag=delete, src_pos=3, dest_pos=4)]
        r   r   )r.   r   r   r   r   r+   rx   r   rp   r
   rq   r   r<   r   r    r.   ry   r$   r$   r%   inversee  s   
zEditops.inversesubsequenceNonec                 C  sZ  t t }| j|_| j|_t|t| krd}t|dgt| t|  |_d}d}d}|D ]W}|t| krc|| j| krc| j| ||< ||  j|7  _|d7 }|d7 }|t| krc|| j| ks>|t| krod}t||jdkry|d7 }n	|jdkr|d8 }|d7 }q/|t| kr| j| ||< ||  j|7  _|d7 }|d7 }|t| ks|S )a#  
        remove a subsequence

        Parameters
        ----------
        subsequence : Editops
            subsequence to remove (has to be a subset of editops)

        Returns
        -------
        sequence : Editops
            a copy of the editops without the subsequence
        z subsequence is not a subsequenceNr   r   r   r   )	r+   rx   rp   rq   r   r   r   r   r.   )r<   r   resultr"   offsetop_pos
result_possopr$   r$   r%   remove_subsequence  s@   




zEditops.remove_subsequencesource_stringr]   destination_stringc                 C  s   d}d}| j D ]=}||jk r||| 7 }|d7 }||jk s|jdkr.|||j 7 }|d7 }q|jdkr;|||j 7 }q|jdkrD|d7 }q|t|k r[||| 7 }|d7 }|t|k sK|S )at  
        apply editops to source_string

        Parameters
        ----------
        source_string : str | bytes
            string to apply editops to
        destination_string : str | bytes
            string to use for replacements / insertions into source_string

        Returns
        -------
        mod_string : str
            modified source_string

         r   r   r)   r   r   )r   r   r.   r   r   )r<   r   r   res_strr   r    r$   r$   r%   apply  s(   






zEditops.applyc                 C     | j S r:   rp   rA   r$   r$   r%   r
        zEditops.src_lenvaluec                 C  
   || _ d S r:   r   r<   r   r$   r$   r%   r
        
c                 C  r   r:   rq   rA   r$   r$   r%   r     r   zEditops.dest_lenc                 C  r   r:   r   r   r$   r$   r%   r     r   rD   rE   rF   c                 C  2   t |tsdS | j|jko| j|jko| j|jkS NF)
isinstancer+   r   r
   r   rK   r$   r$   r%   rL        
$zEditops.__eq__c                 C  
   t | jS r:   )r   r   rA   r$   r$   r%   rB        
zEditops.__len__keyint | slicec                 C  s   | j |= d S r:   r   )r<   r   r$   r$   r%   __delitem__  s   zEditops.__delitem__Editops | Editopc                 C  sn   t |tr
| j| S |t| j\}}}|dk rd}t|tt}| j|_| j	|_	| j||| |_|S )Nr   z6step sizes below 0 lead to an invalid order of editops)
r   r   r   indicesr   r   r+   rx   rp   rq   )r<   r   startstopstepr"   ry   r$   r$   r%   rU   
  s   


zEditops.__getitem__Iterator[Editop]c                 c      | j E d H  d S r:   r   rA   r$   r$   r%   r[        zEditops.__iter__c                 C  .   dd dd | D  d| j d| j d S )Nz	Editops([, c                 s      | ]}t |V  qd S r:   reprr   r$   r$   r%   	<genexpr>      z#Editops.__repr__.<locals>.<genexpr>], src_len=, dest_len=r^   joinr
   r   rA   r$   r$   r%   r_        ,zEditops.__repr__Nr   r   )rn   r	   r
   r   r   r   )rs   r   r   r+   r   r   r   r|   )r   r   r   r+   )r   r+   r   r   r   r]   r   r]   r   r]   ra   r   r   r   r   rb   )r   r   r   r   )r   r   r   r   )r   r   rc   )re   rf   rg   rh   r=   classmethodrv   r,   r   r   r   r   r   r   propertyr
   setterr   rL   rB   r   rU   r[   r_   r$   r$   r$   r%   r+      s:    


9
$



'
9)




r+   c                   @  sL   e Zd ZdZdd	d
ZdddZdddZd ddZd!ddZd"ddZ	dS )#r1   ai  
    Tuple like object describing an edit operation.
    It is in the form (tag, src_start, src_end, dest_start, dest_end)

    The tags are strings, with these meanings:

    +-----------+-----------------------------------------------------+
    | tag       | explanation                                         |
    +===========+=====================================================+
    | 'replace' | src[src_start:src_end] should be                    |
    |           | replaced by dest[dest_start:dest_end]               |
    +-----------+-----------------------------------------------------+
    | 'delete'  | src[src_start:src_end] should be deleted.           |
    |           | Note that dest_start==dest_end in this case.        |
    +-----------+-----------------------------------------------------+
    | 'insert'  | dest[dest_start:dest_end] should be inserted        |
    |           | at src[src_start:src_start].                        |
    |           | Note that src_start==src_end in this case.          |
    +-----------+-----------------------------------------------------+
    | 'equal'   | src[src_start:src_end] == dest[dest_start:dest_end] |
    +-----------+-----------------------------------------------------+

    Note
    ----
    Opcode is compatible with the tuples returned by difflib's SequenceMatcher to make them
    interoperable
    r.   r]   r2   r   r/   r3   r0   c                 C  "   || _ || _|| _|| _|| _d S r:   r.   r2   r/   r3   r0   )r<   r.   r2   r/   r3   r0   r$   r$   r%   r=   ?  s
   
zOpcode.__init__r   c                 C  r?   Nr   r$   rA   r$   r$   r%   rB   F  rC   zOpcode.__len__rD   rE   rF   c                 C  t   z/t |dkr
W dS t|d | jko-|d | jko-|d | jko-|d | jko-|d | jkW S  ty9   Y dS w Nr   Fr   r   rI   r(      )r   rF   r.   r2   r/   r3   r0   rJ   rK   r$   r$   r%   rL   I      zOpcode.__eq__r#   rj   c                 C  R   |dv r| j S |dv r| jS |dv r| jS |dv r| jS |dv r#| jS d}t|N>   r   >   r   >   rI   rO   >   r(   rQ   >   r   r*   zOpcode index out of range)r.   r2   r/   r3   r0   rS   rT   r$   r$   r%   rU   X     zOpcode.__getitem__rk   c                 c  rX   r   rY   rZ   r$   r$   r%   r[   g  r\   zOpcode.__iter__c                 C  s.   d| j d| j d| j d| j d| j dS )NzOpcode(tag=, src_start=
, src_end=, dest_start=, dest_end=r^   r   rA   r$   r$   r%   r_   k  s   zOpcode.__repr__N)
r.   r]   r2   r   r/   r   r3   r   r0   r   ra   rb   rl   rm   rc   rd   r$   r$   r$   r%   r1   "  s    




r1   c                   @  s   e Zd ZdZ			d9d:d	d
Zed;ddZd<ddZd=ddZd>ddZ	d?ddZ
d?ddZd@dd ZedAd!d"ZejdBd%d"ZedAd&d'ZejdBd(d'ZdCd,d-ZdAd.d/ZdDd2d3ZdEd5d6ZdFd7d8ZdS )Gr   a  
    List like object of Opcodes describing how to turn s1 into s2.
    The first Opcode has src_start == dest_start == 0, and remaining tuples
    have src_start == the src_end from the tuple preceding it,
    and likewise for dest_start == the previous dest_end.
    Nr   rs   r	   r
   r   r   c                 C  ro   r:   )rp   rq   r4   r-   )r<   rs   r
   r   r$   r$   r%   r=   z  rr   zOpcodes.__init__rn   r+   r   c                 C  rt   )z
        Create Opcodes from Editops

        Parameters
        ----------
        editops : Editops
            editops to convert to opcodes

        Returns
        -------
        opcodes : Opcodes
            Editops converted to Opcodes
        )r,   )ru   rn   r$   r$   r%   from_editops  rw   zOpcodes.from_editopsc              	   C  s   t t }| j|_| j|_g }| D ]]}|jdkr3t|j|j D ]}|t	d|j| |j
|  q q|jdkrQt|j|j
 D ]}|t	d|j|j
|  q@q|jdkrnt|j|j D ]}|t	d|j| |j
 q^q||_|S )z
        Convert Opcodes to Editops

        Returns
        -------
        editops : Editops
            Opcodes converted to Editops
        r)   r   r   )r+   rx   rp   rq   r.   r   r/   r2   r   r   r3   r0   r   )r<   ry   r   r    jr$   r$   r%   r     s&   
	
 

zOpcodes.as_editopsr|   c                 C  sj   g }| D ]#}|j dkr't|j|j |j|j }|dkr'|t|j|j| q|t| j| j	d |S )z
        Convert to matching blocks

        Returns
        -------
        matching blocks : list[MatchingBlock]
            Opcodes converted to matching blocks
        r   r   )
r.   r}   r/   r2   r0   r3   r   r5   r
   r   )r<   r   r    r~   r$   r$   r%   r     s   	
zOpcodes.as_matching_blocksr'   c                 C  r   )z
        Convert Opcodes to a list of tuples, which is compatible
        with the opcodes of difflibs SequenceMatcher.

        This is the equivalent of ``[x for x in opcodes]``
        c                 S  r   r$   r   r   r$   r$   r%   r     r   z#Opcodes.as_list.<locals>.<listcomp>r-   rA   r$   r$   r%   r     s   zOpcodes.as_listc                 C  r   )z*
        performs copy of Opcodes
        N)r   rx   rp   rq   r-   r   r$   r$   r%   r     r   zOpcodes.copyc              	   C  sp   g }| D ]!}|j }|dkrd}n|dkrd}|t||j|j|j|j qtt}| j	|_
| j|_||_|S )a  
        Invert Opcodes, so it describes how to transform the destination string to
        the source string.

        Returns
        -------
        opcodes : Opcodes
            inverted Opcodes

        Examples
        --------
        >>> from rapidfuzz.distance import Levenshtein
        >>> Levenshtein.opcodes('spam', 'park')
        [Opcode(tag=delete, src_start=0, src_end=1, dest_start=0, dest_end=0),
         Opcode(tag=equal, src_start=1, src_end=3, dest_start=0, dest_end=2),
         Opcode(tag=replace, src_start=3, src_end=4, dest_start=2, dest_end=3),
         Opcode(tag=insert, src_start=4, src_end=4, dest_start=3, dest_end=4)]

        >>> Levenshtein.opcodes('spam', 'park').inverse()
        [Opcode(tag=insert, src_start=0, src_end=0, dest_start=0, dest_end=1),
         Opcode(tag=equal, src_start=0, src_end=2, dest_start=1, dest_end=3),
         Opcode(tag=replace, src_start=2, src_end=3, dest_start=3, dest_end=4),
         Opcode(tag=delete, src_start=3, src_end=4, dest_start=4, dest_end=4)]
        r   r   )r.   r   r1   r3   r0   r2   r/   r   rx   r   rp   r
   rq   r-   r   r$   r$   r%   r     s    
zOpcodes.inverser   r]   r   c                 C  sR   d}| j D ]!}|jdkr|||j|j 7 }q|jdv r&|||j|j 7 }q|S )at  
        apply opcodes to source_string

        Parameters
        ----------
        source_string : str | bytes
            string to apply opcodes to
        destination_string : str | bytes
            string to use for replacements / insertions into source_string

        Returns
        -------
        mod_string : str
            modified source_string

        r   r   >   r   r)   )r-   r.   r2   r/   r3   r0   )r<   r   r   r   r    r$   r$   r%   r     s   


zOpcodes.applyc                 C  r   r:   r   rA   r$   r$   r%   r
     r   zOpcodes.src_lenr   r   c                 C  r   r:   r   r   r$   r$   r%   r
     r   c                 C  r   r:   r   rA   r$   r$   r%   r   "  r   zOpcodes.dest_lenc                 C  r   r:   r   r   r$   r$   r%   r   &  r   rD   rE   rF   c                 C  r   r   )r   r   r   r
   r-   rK   r$   r$   r%   rL   *  r   zOpcodes.__eq__c                 C  r   r:   )r   r-   rA   r$   r$   r%   rB   0  r   zOpcodes.__len__r   r1   c                 C  s    t |tr
| j| S d}t|)NzExpected index)r   r   r-   rJ   )r<   r   r"   r$   r$   r%   rU   3  s   

zOpcodes.__getitem__Iterator[Opcode]c                 c  r   r:   r   rA   r$   r$   r%   r[   :  r   zOpcodes.__iter__c                 C  r   )Nz	Opcodes([r   c                 s  r   r:   r   r   r$   r$   r%   r   ?  r   z#Opcodes.__repr__.<locals>.<genexpr>r   r   r^   r   rA   r$   r$   r%   r_   =  r   zOpcodes.__repr__r   )rs   r	   r
   r   r   r   )rn   r+   r   r   r   r   )r   r'   r   r   ra   r   rb   )r   r   r   r1   )r   r   rc   )re   rf   rg   rh   r=   r   r   r   r   r   r   r   r   r   r
   r   r   rL   rB   rU   r[   r_   r$   r$   r$   r%   r   r  s6    	




	


)



r   c                   @  sL   e Zd ZdZdd	d
ZdddZdddZd ddZd!ddZd"ddZ	dS )#ScoreAlignmentz
    Tuple like object describing the position of the compared strings in
    src and dest.

    It indicates that the score has been calculated between
    src[src_start:src_end] and dest[dest_start:dest_end]
    scoreint | floatr2   r   r/   r3   r0   c                 C  r   r:   r   r2   r/   r3   r0   )r<   r   r2   r/   r3   r0   r$   r$   r%   r=   L  s
   
zScoreAlignment.__init__r   c                 C  r?   r   r$   rA   r$   r$   r%   rB   Z  rC   zScoreAlignment.__len__rD   rE   rF   c                 C  r   r   )r   rF   r   r2   r/   r3   r0   rJ   rK   r$   r$   r%   rL   ]  r   zScoreAlignment.__eq__r#   c                 C  r   r   )r   r2   r/   r3   r0   rS   rT   r$   r$   r%   rU   l  r   zScoreAlignment.__getitem__Iterator[int | float]c                 c  rX   r   rY   rZ   r$   r$   r%   r[   {  r\   zScoreAlignment.__iter__r]   c                 C  s.   d| j  d| j d| j d| j d| j dS )NzScoreAlignment(score=r   r   r   r   r^   r   rA   r$   r$   r%   r_     s   zScoreAlignment.__repr__N)
r   r   r2   r   r/   r   r3   r   r0   r   ra   rb   )r#   r   r   r   )r   r   rc   rd   r$   r$   r$   r%   r   C  s    




r   N)r   r	   r
   r   r   r   r   r   )r   r	   r
   r   r   r   r   r'   )
__future__r   typingr   r   r   r   r   r&   r4   r5   r   r+   r1   r   r   r]   r   
_AnyOpListr$   r$   r$   r%   <module>   s(   

/;):  NP RC