o
    ›¨ÊhQ#  ã                   @   sn   d Z ddlmZ ddlmZ ddlmZmZ dZG dd„ dƒZ	G dd	„ d	e
ƒZG d
d„ dƒZG dd„ dƒZdS )z Dependency graph implementation.é    )ÚCounter)Údedent)Úbytes_to_strÚsafe_str)ÚDOTÚ
CycleErrorÚDependencyGraphÚGraphFormatterc                   @   s6   e Zd ZdZedƒZdZdZdZdZ	ddd	œZ
d
ZdS )r   z$Constants related to the dot format.z=
        {IN}{type} {id} {{
        {INp}graph [{attrs}]
    z{name}={value}z{INp}"{0}" [{attrs}]z {INp}"{0}" {dir} "{1}" [{attrs}]z, z--z->)ÚgraphÚdigraphz{IN}}}N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   ÚHEADÚATTRÚNODEÚEDGEÚATTRSEPÚDIRSÚTAIL© r   r   úD/var/www/html/env/lib/python3.10/site-packages/celery/utils/graph.pyr   
   s    
r   c                   @   s   e Zd ZdZdS )r   z)A cycle was detected in an acyclic graph.N)r   r   r   r   r   r   r   r   r      s    r   c                   @   s¶   e Zd ZdZd+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d„Zdd„ Zdd„ Zdd„ Zdd „ Zd!d"„ Zd#d$„ Ze ZZd%d&„ Zd-d)d*„ZdS ).r   a6  A directed acyclic graph of objects and their dependencies.

    Supports a robust topological sort
    to detect the order in which they must be handled.

    Takes an optional iterator of ``(obj, dependencies)``
    tuples to build the graph from.

    Warning:
        Does not support cycle detection.
    Nc                 C   s,   |pt ƒ | _i | _|d ur|  |¡ d S d S ©N)r	   Ú	formatterÚadjacentÚupdate)ÚselfÚitr   r   r   r   Ú__init__*   s
   ÿzDependencyGraph.__init__c                 C   s   | j  |g ¡ dS )zAdd an object to the graph.N)r   Ú
setdefault©r   Úobjr   r   r   Úadd_arc0   ó   zDependencyGraph.add_arcc                 C   s   | |   |¡ dS )z]Add an edge from object ``A`` to object ``B``.

        I.e. ``A`` depends on ``B``.
        N)Úappend)r   ÚAÚBr   r   r   Úadd_edge4   s   zDependencyGraph.add_edgec                 C   s   | j  |j ¡ dS )zAdd nodes from another graph.N)r   r   )r   r
   r   r   r   Úconnect;   r$   zDependencyGraph.connectc           	      C   s~   t ƒ }|  ¡ }dd„ |D ƒ}|D ]}| |¡ q| D ]}|| }| | D ]}|| }||kr4| ||¡ q$qdd„ | ¡ D ƒS )z�Sort the graph topologically.

        Returns:
            List: of objects in the order in which they must be handled.
        c                 S   s   i | ]
}|D ]}||“qqS r   r   )Ú.0Ú	componentÚnoder   r   r   Ú
<dictcomp>H   s
    ÿÿz+DependencyGraph.topsort.<locals>.<dictcomp>c                 S   s   g | ]}|d  ‘qS )r   r   )r*   Útr   r   r   Ú
<listcomp>S   s    z+DependencyGraph.topsort.<locals>.<listcomp>)r   Ú	_tarjan72r#   r(   Ú_khan62)	r   r
   Ú
componentsÚNCr+   r,   Únode_cÚ	successorÚsuccessor_cr   r   r   Útopsort?   s    ÿ€ýzDependencyGraph.topsortc                 C   sN   z	t | | ƒg}W n
 ty   Y dS w | | D ]
}| |  |¡¡ qt|ƒS )z5Return the valency (degree) of a vertex in the graph.r   )ÚlenÚKeyErrorr%   Ú
valency_ofÚsum)r   r"   Úlr,   r   r   r   r:   U   s   ÿzDependencyGraph.valency_ofc                 C   sH   t |ƒ}|D ]	\}}|  |¡ q|D ]\}}|D ]}|  ||¡ qqdS )z=Update graph with data from a list of ``(obj, deps)`` tuples.N)Úlistr#   r(   )r   r   Útupsr"   Ú_ÚdepsÚdepr   r   r   r   _   s   ÿÿzDependencyGraph.updatec                 C   s   dd„ |   ¡ D ƒS )z8Return generator that yields for all edges in the graph.c                 s   s   � | ]	\}}|r|V  qd S r   r   )r*   r"   Úadjr   r   r   Ú	<genexpr>j   s   € z(DependencyGraph.edges.<locals>.<genexpr>)Úitems©r   r   r   r   Úedgesh   r$   zDependencyGraph.edgesc                    sž   t ƒ ‰ g }| D ]}| | D ]
}ˆ |  d7  < qq‡ fdd„| D ƒ}|rI| ¡ }| |¡ | | D ]}ˆ |  d8  < ˆ | dkrF| |¡ q1|s$| ¡  |S )z‚Perform Khan's simple topological sort algorithm from '62.

        See https://en.wikipedia.org/wiki/Topological_sorting
        é   c                    s   g | ]}ˆ | s|‘qS r   r   )r*   r,   ©Úcountr   r   r/   w   s    z+DependencyGraph._khan62.<locals>.<listcomp>r   )r   Úpopr%   Úreverse)r   Úresultr,   r5   Úreadyr   rH   r   r1   l   s$   ÿ

€ùzDependencyGraph._khan62c                    s:   g g i ‰‰‰ ‡ ‡‡‡‡fdd„‰ˆD ]}ˆ|ƒ qˆS )z©Perform Tarjan's algorithm to find strongly connected components.

        See Also:
            :wikipedia:`Tarjan%27s_strongly_connected_components_algorithm`
        c                    sª   | ˆ v rd S t ˆ ƒ}|ˆ | < t ˆƒ}ˆ | ¡ ˆ|  D ]}ˆ|ƒ tˆ |  ˆ | ƒˆ | < q|ˆ |  krQtˆ|d … ƒ}g ˆ|d …< ˆ |¡ |D ]
}t ˆƒˆ |< qHd S d S r   )r8   r%   ÚminÚtuple)r,   ÚnumÚ	stack_posr5   r+   Úitem©ÚlowrL   r   ÚstackÚvisitr   r   rV   Œ   s"   

ûz(DependencyGraph._tarjan72.<locals>.visitr   ©r   r,   r   rS   r   r0   „   s
   
zDependencyGraph._tarjan72c                    s�   t ƒ ‰|p| j‰‡fdd„‰ ‡ ‡‡fdd„}ˆ ˆ ¡ ƒ |  ¡ D ]\}}|s,|ˆj|ƒ |D ]}|ˆj|ƒ ˆ ˆ ||¡ƒ q.q ˆ ˆ ¡ ƒ dS )zñConvert the graph to DOT format.

        Arguments:
            fh (IO): A file, or a file-like object to write the graph to.
            formatter (celery.utils.graph.GraphFormatter): Custom graph
                formatter to use.
        c                    s   t t| ƒˆ d� d S )N)Úfile)Úprintr   )Ús)Úfhr   r   ÚP¯   ó   z!DependencyGraph.to_dot.<locals>.Pc                    s2   ˆ  |¡ˆvrˆ | |ƒƒ ˆ ˆ  |¡¡ d S d S r   )ÚlabelÚadd)Úfunr"   )r\   ÚdrawÚseenr   r   Úif_not_seen²   s   þz+DependencyGraph.to_dot.<locals>.if_not_seenN)Úsetr   ÚheadrD   Úterminal_noder,   ÚedgeÚtail)r   r[   r   rc   r"   r   Úreqr   )r\   ra   r[   rb   r   Úto_dot¤   s   
þzDependencyGraph.to_dotc                 C   s   | j r|   |¡S |S r   )r   r!   r   r   r   ÚformatÀ   r]   zDependencyGraph.formatc                 C   ó
   t | jƒS r   )Úiterr   rE   r   r   r   Ú__iter__Ã   ó   
zDependencyGraph.__iter__c                 C   s
   | j | S r   ©r   rW   r   r   r   Ú__getitem__Æ   ro   zDependencyGraph.__getitem__c                 C   rl   r   )r8   r   rE   r   r   r   Ú__len__É   ro   zDependencyGraph.__len__c                 C   s
   || j v S r   rp   r!   r   r   r   Ú__contains__Ì   ro   zDependencyGraph.__contains__c                 C   s
   | j  ¡ S r   )r   rD   rE   r   r   r   Ú_iterate_itemsÏ   ro   zDependencyGraph._iterate_itemsc                    s   d  ‡ fdd„ˆ D ƒ¡S )NÚ
c                 3   s   � | ]}ˆ   |¡V  qd S r   )Ú	repr_node)r*   ÚNrE   r   r   rC   Ô   s   € z+DependencyGraph.__repr__.<locals>.<genexpr>)ÚjoinrE   r   rE   r   Ú__repr__Ó   s   zDependencyGraph.__repr__rG   ú{0}({1})c                 C   s|   |  ||  |¡¡g}|| v r9| | D ]&}|  ||  |¡¡}| d| | ¡ | |  ||d ¡ d¡dd … ¡ qd |¡S )Nz     rG   ru   )rk   r:   r%   Úextendrv   Úsplitrx   )r   r"   ÚlevelÚfmtÚoutputÚotherÚdr   r   r   rv   Ö   s   &
zDependencyGraph.repr_node©NNr   )rG   rz   )r   r   r   r   r   r#   r(   r)   r7   r:   r   rF   r1   r0   rj   rk   rn   rq   rr   rs   rt   rD   Ú	iteritemsry   rv   r   r   r   r   r      s,    

	
 r   c                   @   sü   e Zd ZdZej ¡ Zej ¡ Z	ej
 ¡ Zej ¡ Zej ¡ ZejZeejƒZdddddœZddd	d
œZdddœZdddœZddiZ		d/dd„Zdd„ Zd0d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$d1d+d,„Z%d1d-d.„Z&dS )2r	   zFormat dependency graphs.ÚboxÚveeÚfilledÚHelveticaNeue)ÚshapeÚ	arrowheadÚstyleÚfontnameÚdarkseagreen4Úblackgffffffæ?)ÚcolorÚ
arrowcolorÚ	arrowsizeÚ
palegreen3Ú
palegreen4)Ú	fillcolorrŽ   Ú
palegreen1Ú
palegreen2ÚbgcolorÚ	mintcreamNr   ú    c                 K   sr   |pd| _ || _|pd| _| j| j | _||pd | _| j| | _t| jfi |¤Ž| _t| j	|  
| j¡d�| _	d S )NÚdependenciesr   r   )Úroot)Úidrš   ÚtypeÚ_dirsÚ	directionÚINÚINpÚdictÚschemeÚgraph_schemer^   )r   rš   rœ   r›   ÚindentÚinwr¢   r   r   r   r   ú   s   

zGraphFormatter.__init__c                 C   s   d|› d�}| j | j||d�S )Nú")ÚnameÚvalue)ÚFMTÚ_attr)r   r§   r¨   r   r   r   Úattr  s   zGraphFormatter.attrc                    sH   t ˆ jfi |rt |fi |pi ¤Žn|¤Ž}ˆ j ‡ fdd„| ¡ D ƒ¡S )Nc                 3   s$   � | ]\}}t ˆ  ||¡ƒV  qd S r   )r   r«   )r*   ÚkÚvrE   r   r   rC     s   € 
ÿz'GraphFormatter.attrs.<locals>.<genexpr>)r¡   r¢   Ú_attrseprx   rD   )r   r�   r¢   r   rE   r   Úattrs	  s   *ÿzGraphFormatter.attrsc                 K   s"   | j | j| j| j|  || j¡d�S )N)r›   rœ   r¯   )r©   Ú_headr›   rœ   r¯   r£   )r   r¯   r   r   r   re     s   þzGraphFormatter.headc                 C   s   |   | j¡S r   )r©   Ú_tailrE   r   r   r   rh     ó   zGraphFormatter.tailc                 C   s   |S r   r   r!   r   r   r   r^     s   zGraphFormatter.labelc                 K   ó   |   || j|¡S r   )Ú	draw_nodeÚnode_scheme©r   r"   r¯   r   r   r   r,     ó   zGraphFormatter.nodec                 K   r³   r   )r´   Úterm_schemer¶   r   r   r   rf     r·   zGraphFormatter.terminal_nodec                 K   s   | j ||fi |¤ŽS r   )Ú	draw_edge)r   ÚaÚbr¯   r   r   r   rg   !  r]   zGraphFormatter.edgec                 C   s   |  dd¡S )Nzutf-8Úignore)Úencode)r   rZ   r   r   r   Ú_enc$  r²   zGraphFormatter._encc              
   O   s$   |   |j|i t|| j| jd�¤Ž¡S )N)rŸ   r    )r¾   rk   r¡   rŸ   r    )r   r~   ÚargsÚkwargsr   r   r   r©   '  s
   ÿÿzGraphFormatter.FMTc              	   C   s.   | j | j|  |¡|  |¡| j|  || j¡d�S )N)Údirr¯   )r©   Ú_edger^   rž   r¯   Úedge_scheme)r   rº   r»   r¢   r¯   r   r   r   r¹   ,  s   þzGraphFormatter.draw_edgec                 C   s    | j | j|  |¡|  ||¡d�S )N)r¯   )r©   Ú_noder^   r¯   )r   r"   r¢   r¯   r   r   r   r´   2  s   ÿzGraphFormatter.draw_node)NNNr   r˜   r   r‚   )'r   r   r   r   r   r   Ústriprª   r   rÄ   r   rÂ   r   r°   r   r±   r   r®   r¡   r   r�   r¢   rÃ   rµ   r¸   r£   r   r«   r¯   re   rh   r^   r,   rf   rg   r¾   r©   r¹   r´   r   r   r   r   r	   à   sH    





üý


ÿ

r	   N)r   Úcollectionsr   Útextwrapr   Úkombu.utils.encodingr   r   Ú__all__r   Ú	Exceptionr   r   r	   r   r   r   r   Ú<module>   s     D