o
    KK&h=                     @   sp   d dl 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mZ edZG dd	 d	ZG d
d dZdS )    N)	getLogger   )
RouteGroup)Line)REGEX_PARAM_NAMEREGEX_PARAM_NAME_EXTalphaextslugz
sanic.rootc                	   @   s`  e Zd Z						d/dededdfddZdefd	d
ZdefddZedefddZ	ede
fddZdd Zd0ddZdejeje eje f fddZdejeje eje eje f fddZd1ddZdd ZedefddZed d! Zd"d# Zd$d% Zd&d' Zdejeee
e
e
eef fd(d)Zdeje
d*f fd+d,Zed-d. ZdS )2Node FNpartrootreturnc                 C   sv   || _ || _|| _|| _i | _i | _d| _d| _d| _g | _	d| _
d| _d| _d| _d| _d| _d| _|| _|| _d S )Nr   F)r   r   parentparam	_childrenchildrenlevelbase_indentoffsetgroupsdynamicfirstlastchildren_basketedchildren_param_injectedhas_deferredequality_checkunquoterouter)selfr   r   r   r    r   r    r"   E/var/www/html/venv/lib/python3.10/site-packages/sanic_routing/tree.py__init__   s&   	
zNode.__init__c                    s$   d  fdddD }d| dS )Nz, c                 3   s6    | ]}t  |s|d v r| dt  | V  qdS ))r   =N)getattr).0propr!   r"   r#   	<genexpr>,   s    zNode.__str__.<locals>.<genexpr>)r   r   r   r   z<Node: >)join)r!   	internalsr"   r)   r#   __str__+   s   zNode.__str__c                 C   s   t | S N)strr)   r"   r"   r#   __repr__3   s   zNode.__repr__c                 C   s.   | j r| j js| j j dnd}| | j S )N.r   )r   r   identidx)r!   prefixr"   r"   r#   r3   6   s   z
Node.identc                 C   s&   | j sdS t| j j | jd S )Nr   )r   listr   keysindexr   r)   r"   r"   r#   r4   ?   s   zNode.idxc                 C   st   dd t | j | jdD | _| jr6t| j }d| j|d  _d| j|d  _| j	 D ]}|
  q/dS dS )z
        Sort the children (if any), and set properties for easy checking
        # they are at the beginning or end of the line.
        c                 S   s   i | ]\}}||qS r"   r"   )r'   kvr"   r"   r#   
<dictcomp>J   s    
z*Node.finalize_children.<locals>.<dictcomp>keyTr   N)sortedr   items_sortingr   r6   r7   r   r   valuesfinalize_children)r!   r7   childr"   r"   r#   rC   E   s   
zNode.finalize_childrenc                 C   s4   t d| j t|   | j D ]}|  qdS )z5
        Visual display of the tree of nodes
        z    N)loggerinfor   r0   r   rB   displayr!   rD   r"   r"   r#   rG   U   s   
zNode.displayc                 C   sX   g }g }g }| j s|  \}}}| j D ]}| \}}||7 }||7 }q|| |fS r/   )r   to_srcr   rB   render)r!   srcdelayedfinalrD   ofr"   r"   r#   rJ   ]   s   
zNode.renderc                 C   s  | j r| j jni }d }| jstt| }| j r't| jdkp!| j| j j nd| _| j}g }g }g }|	t
d| |	t
d| j d| j | | j}|d }| j }	d}
d}| jrm| j| j jkrfdnd	}
|
dk| _|	t
| d
|
 d| d| |d7 }| jr| ||| |d7 }nD| js| jr| js|r|j| _d}| js| jsd| j nd}|  jt|O  _|	t
| d| d| j d| d| |  jd7  _| jrS||	 }d}|}| js| jrdnd}d}
|	t
| d
|
 d| d| |d7 }t| j| jdD ]G}d}|jrd}| ||| | |jr/| ||| | |d7 }|dkrGt|jdkrGd}| ||| | | ||| || q|||fS )Nr   r   r   z# node=z	 // part=r+   ifz==z>=z num  z:  # CHECK 1z and num == z parts[z] == ""z:  # CHECK 4elifz:  # CHECK 5r<   	route_idx)r   r   r   nextiterrB   boolr   r   appendr   r3   r   r   r   depthr   _inject_param_checkr?   _group_sortingrequirements_inject_requirementsregex_inject_regexlenroutes_inject_method_check_inject_return)r!   siblingsfirst_siblingindentrL   rM   rK   r   r4   return_bump	operationconditionalif_stmt	len_checkreturn_indentrT   locationgroup
group_bumpr"   r"   r#   rI   o   s    





zNode.to_srcrD   c                 C   s   || j |j< d S r/   )r   r   rH   r"   r"   r#   	add_child   s   zNode.add_childc              	   C   s   t d|t d| d| jjj d| d|d t d|t d|d t d	|g}| jrB| | jjrB|t d| d
| d|d  |  jd7  _|| dS )z6
        Try and cast relevant path segments.
        ztry:zbasket['__matches__'][z] = z(parts[z])r   zexcept ValueError:passelse:z"] = unquote(basket['__matches__'][N)	r   r   cast__name__r   _cast_as_strrX   r   extend)r!   rm   rf   r4   linesr"   r"   r#   rZ     s0   zNode._inject_param_checkc                 C   s(   t | d}| ttttfv p|tu S )Nr   )tget_type_hintsgetr0   r	   r
   r   )rs   return_type_hintr"   r"   r#   ru     s   zNode._cast_as_strc                 C   sx   t |jD ]%\}}|dkrdnd}| t| d|j d|td| |d g q| td|td	|d g d
S )zY
        Sometimes we need to check the routing methods inside the generated src
        r   rP   rS   z method in :route_idx = r   rr   zraise NoMethodN)	enumeratera   rv   r   methods)rm   rf   rn   irouterj   r"   r"   r#   rb   #  s   	zNode._inject_method_checkc                 C   sb   |j rdnd}|jjrdnd| d}|td| j |td| d|j d| d|g d	S )
z=
        The return statement for the node if needed
        regex_routesdynamic_routesr   []z	# Return zreturn router.z, basketN)r^   r    stackingrv   r   r3   segments)r!   rm   rf   rT   rn   ra   route_returnr"   r"   r#   rc   :  s   zNode._inject_returnc              
   C   s~   t |D ])\}}|dkrdnd}|t| d|j d|j d|td| |d g q|td	|td
|d g dS )z
        Check any extra checks needed for a route. In path routing, for exampe,
        this is used for matching vhosts.
        r   rP   rS   z
 extra == z and method in r|   r}   r   rr   zraise NotFoundN)r~   rv   r   r\   r   )r!   rm   rf   rn   r9   r   ri   r"   r"   r#   r]   M  s"   zNode._inject_requirementsc                 C   s4   | td|j d|td|td|d g dS )z
        For any path matching that happens in the course of the tree (anything
        that has a path matching--<path:path>--or similar matching with regex
        delimiter)
        zmatch = router.matchers[z].match(path)z	if match:z(basket['__params__'] = match.groupdict()r   N)rv   r   pattern_idx)r!   rm   rf   rn   r"   r"   r#   r_   h  s   zNode._inject_regexc              	   C   s`   |\}}d}|j r|jj}t|j|j |d |jd t|jt|jo+tdd |jD  |fS )zW
        Primarily use to sort nodes to determine the order of the nested tree
        r   r>   c                 s       | ]}|j V  qd S r/   )r^   )r'   rn   r"   r"   r#   r*         z Node._sorting.<locals>.<genexpr>)	r   r   priorityrW   r   rY   r`   r   any)r!   itemr=   rD   type_r"   r"   r#   rA     s   zNode._sorting.c                    s     fdd}t t||j}|S )z
        When multiple RouteGroups terminate on the same node, we want to
        evaluate them based upon the priority of the param matching types
        c                    s   d}|  dr@| dd }d|v r@|dd\}}zt jj |}W |d S  ty?   tt jj }Y |d S w |d S )Nr   <r   r>   r|   )	
startswithsplitr6   r    regex_typesr7   r8   
ValueErrorr`   )segmentr   r=   
param_typer)   r"   r#   get_type  s   
z%Node._group_sorting.<locals>.get_type)tuplemapparts)r!   r   r   r   r"   r)   r#   r[     s   zNode._group_sortingc                 C   s$   | j s| jS tdd | j  D S )Nc                 s   r   r/   )rY   )r'   rD   r"   r"   r#   r*     r   zNode.depth.<locals>.<genexpr>)r   r   maxrB   r)   r"   r"   r#   rY     s   z
Node.depth)r   FNNNFr   N)rD   r   r   N)rt   
__module____qualname__r0   rW   r$   r.   r1   propertyr3   intr4   rC   rG   rx   TupleListr   rJ   rI   rp   rZ   staticmethodru   rb   rc   r]   r_   rA   r[   rY   r"   r"   r"   r#   r      sL    

$, 

"r   c                   @   sT   e Zd ZdddZdeje ddfddZddd	Zdej	e
 fd
dZdd ZdS )Treer   Nc                 C   s    t d|d| _d| j_|| _d S )NT)r   r    r   )r   r   r   r    )r!   r    r"   r"   r#   r$     s   
zTree.__init__r   c           	   	   C   s   |D ]f}| j }|jp|j|_t|jD ]N\}}d}|d}|r?t|s1t|s1td| d|j	| j
 }|j	| }||jvrWt||| j||jd}||_|| |j| }|d |_q|j| qdS )zb
        Arrange RouteGroups into hierarchical nodes and arrange them into
        a tree
        Nr   zInvalid declaration: z__dynamic__:)r   r   r    r   r   r   )r   r   r~   r   r   r   matchr   r   paramslabelr   r   r    r   rp   r   r   rX   )	r!   r   rn   currentr   r   r   r   rD   r"   r"   r#   generate  s:   




zTree.generatec                 C   s   | j   dS )z9
        Debug tool to output visual of the tree
        N)r   rG   r)   r"   r"   r#   rG     s   zTree.displayc                 C   s   | j  \}}|| S r/   )r   rJ   )r!   rN   rO   r"   r"   r#   rJ     s   zTree.renderc                 C   s   | j   d S r/   )r   rC   r)   r"   r"   r#   finalize  s   zTree.finalizer   )rt   r   r   r$   rx   Iterabler   r   rG   r   r   rJ   r   r"   r"   r"   r#   r     s    

!r   )typingrx   loggingr   rn   r   liner   patternsr   r   r   r	   r
   rE   r   r   r"   r"   r"   r#   <module>   s       (