o
    DfQ#                     @   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   K/home/ubuntu/webapp/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__*   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 )zSort 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 )zPerform 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 )zPerform 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 )zConvert 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