o
    wvXj!$  ã                   @   sš   d Z ddlmZmZmZ ddlmZ ddlmZ ddl	m
Z
mZ ddlmZmZ dZG dd	„ d	ƒZG d
d„ deƒZeG dd„ deƒƒZG dd„ deƒZdS )z Dependency graph implementation.é    )Úabsolute_importÚprint_functionÚunicode_literals)ÚCounter)Údedent)Úbytes_to_strÚsafe_str)ÚitemsÚpython_2_unicode_compatible)Ú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   úO/var/www/html/myproject/venv/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__0   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_arc6   ó   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_edge:   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   ÚconnectA   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>N   s
    ÿÿz+DependencyGraph.topsort.<locals>.<dictcomp>c                 S   s   g | ]}|d  ‘qS )r   r   )r/   Útr   r   r   Ú
<listcomp>Y   s    z+DependencyGraph.topsort.<locals>.<listcomp>)r   Ú	_tarjan72r(   r-   Ú_khan62)	r"   r   Ú
componentsÚNCr0   r1   Únode_cÚ	successorÚsuccessor_cr   r   r   ÚtopsortE   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'   Úlr1   r   r   r   r?   [   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!   e   s   ÿÿzDependencyGraph.updatec                 C   s   dd„ t | ƒ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>p   s   € z(DependencyGraph.edges.<locals>.<genexpr>)r	   ©r"   r   r   r   Úedgesn   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/   r1   ©Úcountr   r   r4   }   s    z+DependencyGraph._khan62.<locals>.<listcomp>r   )r   Úpopr*   Úreverse)r"   Úresultr1   r:   Úreadyr   rL   r   r6   r   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   )r=   r*   ÚminÚtuple)r1   ÚnumÚ	stack_posr:   r0   Úitem©ÚlowrP   r"   ÚstackÚvisitr   r   rZ   ’   s"   

ûz(DependencyGraph._tarjan72.<locals>.visitr   ©r"   r1   r   rW   r   r5   Š   s
   
zDependencyGraph._tarjan72c                    s�   t ƒ ‰|p| j‰‡fdd„‰ ‡ ‡‡fdd„}ˆ ˆ ¡ ƒ t| ƒ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   Úheadr	   Úterminal_noder1   ÚedgeÚtail)r"   r_   r   rg   r'   r    Úreqr   )r`   re   r_   rf   r   Úto_dotª   s   
þzDependencyGraph.to_dotc                 C   s   | j r|   |¡S |S r   )r   r&   r   r   r   ÚformatÆ   ra   zDependencyGraph.formatc                 C   ó
   t | jƒS r   )Úiterr    rI   r   r   r   Ú__iter__É   ó   
zDependencyGraph.__iter__c                 C   s
   | j | S r   ©r    r[   r   r   r   Ú__getitem__Ì   rs   zDependencyGraph.__getitem__c                 C   rp   r   )r=   r    rI   r   r   r   Ú__len__Ï   rs   zDependencyGraph.__len__c                 C   s
   || j v S r   rt   r&   r   r   r   Ú__contains__Ò   rs   zDependencyGraph.__contains__c                 C   rp   r   )r	   r    rI   r   r   r   Ú_iterate_itemsÕ   rs   zDependencyGraph._iterate_itemsc                    s   d  ‡ fdd„ˆ D ƒ¡S )NÚ
c                 3   s   � | ]}ˆ   |¡V  qd S r   )Ú	repr_node)r/   ÚNrI   r   r   rH   Ú   s   € z+DependencyGraph.__repr__.<locals>.<genexpr>)ÚjoinrI   r   rI   r   Ú__repr__Ù   s   zDependencyGraph.__repr__rK   ú{0}({1})c                 C   s|   |  ||  |¡¡g}|| v r9| | D ]&}|  ||  |¡¡}| d| | ¡ | |  ||d ¡ d¡dd … ¡ qd |¡S )Nz     rK   ry   )ro   r?   r*   Úextendrz   Úsplitr|   )r"   r'   ÚlevelÚfmtÚoutputÚotherÚdr   r   r   rz   Ü   s   &
zDependencyGraph.repr_node©NNr   )rK   r~   )r   r   r   r   r$   r(   r-   r.   r<   r?   r!   rJ   r6   r5   rn   ro   rr   ru   rv   rw   rx   r	   Ú	iteritemsr}   rz   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_schemerb   )r"   rž   r    rŸ   ÚindentÚinwr¦   r   r   r   r$      s   

zGraphFormatter.__init__c                 C   s   d  |¡}| j| j||d�S )Nz"{0}")ÚnameÚvalue)ro   Ú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„t|ƒD ƒ¡S )Nc                 3   s$   � | ]\}}t ˆ  ||¡ƒV  qd S r   )r   r®   )r/   ÚkÚvrI   r   r   rH     s   € 
ÿz'GraphFormatter.attrs.<locals>.<genexpr>)r¥   r¦   Ú_attrsepr|   r	   )r"   r…   r¦   r   rI   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   ri     s   þzGraphFormatter.headc                 C   s   |   | j¡S r   )r¬   Ú_tailrI   r   r   r   rl     ó   zGraphFormatter.tailc                 C   s   |S r   r   r&   r   r   r   rb     s   zGraphFormatter.labelc                 K   ó   |   || j|¡S r   )Ú	draw_nodeÚnode_scheme©r"   r'   r²   r   r   r   r1   !  ó   zGraphFormatter.nodec                 K   r¶   r   )r·   Úterm_schemer¹   r   r   r   rj   $  rº   zGraphFormatter.terminal_nodec                 K   s   | j ||fi |¤ŽS r   )Ú	draw_edge)r"   ÚaÚbr²   r   r   r   rk   '  ra   zGraphFormatter.edgec                 C   s   |  dd¡S )Nzutf-8Úignore)Úencode)r"   r^   r   r   r   Ú_enc*  rµ   zGraphFormatter._encc              
   O   s$   |   |j|i t|| j| jd�¤Ž¡S )N)r£   r¤   )rÁ   ro   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¬   Ú_edgerb   r¢   r²   Úedge_scheme)r"   r½   r¾   r¦   r²   r   r   r   r¼   2  s   þzGraphFormatter.draw_edgec                 C   s    | j | j|  |¡|  ||¡d�S )N)r²   )r¬   Ú_noderb   r²   )r"   r'   r¦   r²   r   r   r   r·   8  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²   ri   rl   rb   r1   rj   rk   rÁ   r¬   r¼   r·   r   r   r   r   r   æ   sH    





üý


ÿ

r   N)r   Ú
__future__r   r   r   Úcollectionsr   Útextwrapr   Úkombu.utils.encodingr   r   Úcelery.fiver	   r
   Ú__all__r   Ú	Exceptionr   Úobjectr   r   r   r   r   r   Ú<module>   s    D