
    j                     d    d dl Z ddlmZ  e j        d          Ze G d d                      ZdS )    N   )str_coerciblez!^[A-Za-z0-9_]+(\.[A-Za-z0-9_]+)*$c                       e Zd ZdZd Zed             Zd Zd Zd Z	d Z
d Zd	 Zd
 Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd Zd ZdS )Ltreea  
    Ltree class wraps a valid string label path. It provides various
    convenience properties and methods.

    ::

        from sqlalchemy_utils import Ltree

        Ltree('1.2.3').path  # '1.2.3'


    Ltree always validates the given path.

    ::

        Ltree(None)  # raises TypeError

        Ltree('..')  # raises ValueError


    Validator is also available as class method.

    ::

        Ltree.validate('1.2.3')
        Ltree.validate(None)  # raises TypeError


    Ltree supports equality operators.

    ::

        Ltree('Countries.Finland') == Ltree('Countries.Finland')
        Ltree('Countries.Germany') != Ltree('Countries.Finland')


    Ltree objects are hashable.


    ::

        assert hash(Ltree('Finland')) == hash('Finland')


    Ltree objects have length.

    ::

        assert len(Ltree('1.2')) == 2
        assert len(Ltree('some.one.some.where'))  # 4


    You can easily find subpath indexes.

    ::

        assert Ltree('1.2.3').index('2.3') == 1
        assert Ltree('1.2.3.4.5').index('3.4') == 2


    Ltree objects can be sliced.


    ::

        assert Ltree('1.2.3')[0:2] == Ltree('1.2')
        assert Ltree('1.2.3')[1:] == Ltree('2.3')


    Finding longest common ancestor.


    ::

        assert Ltree('1.2.3.4.5').lca('1.2.3', '1.2.3.4', '1.2.3') == '1.2'
        assert Ltree('1.2.3.4.5').lca('1.2', '1.2.3') == '1'


    Ltree objects can be concatenated.

    ::

        assert Ltree('1.2') + Ltree('1.2') == Ltree('1.2.1.2')
    c                    t          |t                    r|j        | _        d S t          |t                    r|                     |           || _        d S t          d                    t          |          j                            )Nz7Ltree() argument must be a string or an Ltree, not '{}')	
isinstancer   pathstrvalidate	TypeErrorformattype__name__)selfpath_or_ltrees     k/lsinfo/ai/hellotax_ai/base_platform/venv/lib/python3.11/site-packages/sqlalchemy_utils/primitives/ltree.py__init__zLtree.__init___   s    mU++ 	%*DIIIs++ 		MM-(((%DIIII''0       c                 `    t                               |          t          d| d          d S )N'z' is not a valid ltree path.)path_matchermatch
ValueError)clsr	   s     r   r   zLtree.validatem   s>    d##+6D666   ,+r   c                 P    t          | j                            d                    S N.)lenr	   splitr   s    r   __len__zLtree.__len__t   s    49??3''(((r   c                    t          |          j                            d          }| j                            d          }t          |          D ]'\  }}||t	          |          |z            |k    r|c S (t          d          )Nr   zsubpath not found)r   r	   r   	enumerater   r   )r   othersubpathpartsindex_s         r   r'   zLtree.indexw   s    ,,#))#..	$$!%(( 	 	HE1U3w<<%//0G;; <,---r   c                 V    | dt          t          |                             }||k    S )z
        is left argument a descendant of right (or equal)?

        ::

            assert Ltree('1.2.3.4.5').descendant_of('1.2.3')
        N)r   r   r   r$   r%   s      r   descendant_ofzLtree.descendant_of   s-     )E%LL)))*%r   c                 V    t          |          dt          |                    }|| k    S )z
        is left argument an ancestor of right (or equal)?

        ::

            assert Ltree('1.2.3').ancestor_of('1.2.3.4.5')
        N)r   r   r*   s      r   ancestor_ofzLtree.ancestor_of   s(     ,,zD		z*$r   c                    t          |t                    r-t          | j                            d          |                   S t          |t
                    r@t          d                    | j                            d          |                             S t          d                    |j	        j
                            )Nr   z&Ltree indices must be integers, not {})r   intr   r	   r   slicejoinr   r   	__class__r   )r   keys     r   __getitem__zLtree.__getitem__   s    c3 	>--c2333U## 	>$)//#"6"6s";<<===4;;& 
 
 	
r   c                 &   d |D             }| j                             d          t                    D ]W\  t          fd|D                       r5dk    r dS t	          d                    d                             c S XdS )z
        Lowest common ancestor, i.e., longest common prefix of paths

        ::

            assert Ltree('1.2.3.4.5').lca('1.2.3', '1.2.3.4', '1.2.3') == '1.2'
        c                 \    g | ])}t          |          j                            d           *S )r   )r   r	   r   ).0r$   s     r   
<listcomp>zLtree.lca.<locals>.<listcomp>   s/    HHHuU||(..s33HHHr   r   c              3      K   | ]<}|         k    p+t          |          d z   k    pt                    d z   k    V  =dS )   N)r   )r7   r$   elementr'   r&   s     r   	<genexpr>zLtree.lca.<locals>.<genexpr>   sp          e' (E

eai'(E

eai'     r   r   N)r	   r   r#   anyr   r1   )r   othersother_partsr;   r'   r&   s      @@@r   lcaz	Ltree.lca   s     IHHHH	$$'.. 		7 		7NE7       )	     7 A::44SXXeAeGn55666667		7 		7r   c                 Z    t          | j        dz   t          |          j        z             S r   )r   r	   r   r$   s     r   __add__zLtree.__add__   s$    TY_uU||'88999r   c                 &    t          |          | z   S N)r   rB   s     r   __radd__zLtree.__radd__   s    U||d""r   c                     t          |t                    r| j        |j        k    S t          |t                    r| j        |k    S t          S rE   )r   r   r	   r
   NotImplementedrB   s     r   __eq__zLtree.__eq__   sH    eU## 	"9
**s## 	"9%%!!r   c                 *    t          | j                  S rE   )hashr	   r    s    r   __hash__zLtree.__hash__   s    DIr   c                     | |k     S rE    rB   s     r   __ne__zLtree.__ne__   s    EM""r   c                 0    | j         j         d| j        dS )N())r2   r   r	   r    s    r   __repr__zLtree.__repr__   s     .)::DI::::r   c                     | j         S rE   r	   r    s    r   __unicode__zLtree.__unicode__   s
    yr   c                 :    || j                             d          v S r   )r	   r   )r   labels     r   __contains__zLtree.__contains__   s    	,,,,r   c                 "    | j         |j         k    S rE   rU   rB   s     r   __gt__zLtree.__gt__       y5:%%r   c                 "    | j         |j         k     S rE   rU   rB   s     r   __lt__zLtree.__lt__   r\   r   c                 "    | j         |j         k    S rE   rU   rB   s     r   __ge__zLtree.__ge__       yEJ&&r   c                 "    | j         |j         k    S rE   rU   rB   s     r   __le__zLtree.__le__   ra   r   N)r   
__module____qualname____doc__r   classmethodr   r!   r'   r+   r-   r4   r@   rC   rF   rI   rL   rO   rS   rV   rY   r[   r^   r`   rc   rN   r   r   r   r      sY       S Sj     [) ) ). . .	  	  	 	 	 		
 	
 	
7 7 7*: : :# # #" " "  # # #; ; ;  - - -& & && & &' ' '' ' ' ' 'r   r   )reutilsr   compiler   r   rN   r   r   <module>rk      sz    				 ! ! ! ! ! !rz>?? S' S' S' S' S' S' S' S' S' S'r   