
    c                        d Z ddlmZ ddlZddlZddlZddlZddlZddlm	Z	 ddl
mZ dd
Z G d d          ZddZ	 d d!dZd"dZdS )#z^Graph manipulation utilities.

(dot generation adapted from pypy/translator/tool/make_dot.py)
    )annotationsN)Sequence)Anyfilenamestrreturntuple[str, str, str]c                   t           j                            |           }t           j                            t           j                            |                     }t           j                            |           d         dd         }|||fS )zDTransforms /some/path/foo.png into ('/some/path', 'foo.png', 'png').   N)ospathbasenamedirnameabspathsplitext)r   r   storedirtargets       ,lib/python3.11/site-packages/pylint/graph.pytarget_info_from_filenamer      sh    w))Hwrwx8899HWh''+ABB/FXv%%    c                  j    e Zd ZdZ	 	 	 	 	 	 dd dZd!dZ ee          Z	 d"d#dZd$dZ	d%dZ
d&dZdS )'
DotBackendzDot File back-end.Nutf-8dot	graphnamer   rankdir
str | Nonesizer   ratiocharsetrendereradditional_paramdict[str, Any] | Noner   Nonec                *   |i }|| _         || _        g | _        d | _        |                     dt          |           d           |r|                     d|            |r|                     d|            |r|                     d| d           |r<|                                dv sJ d|             |                     d	| d           |                                D ]*}|                     d
                    |                     +d S )Nzdigraph z {zrankdir=zratio=zsize="">   
iso-8859-1latin1r   zunsupported charset z	charset="=)	r   r"   lines_sourceemitnormalize_node_idloweritemsjoin)	selfr   r   r   r    r!   r"   r#   params	            r   __init__zDotBackend.__init__    sh     	"!"  "
#'		>.y99>>>??? 	,II***+++ 	(II&u&&''' 	(II&t&&&''' 	.==?? '  0 0 0g//	0 0 0
 II,',,,---%++-- 	' 	'EIIchhuoo&&&&	' 	'r   c                    | j         6|                     d           d                    | j                  | _         | `| j         S )zReturns self._source.Nz}

)r,   r-   r1   r+   )r2   s    r   
get_sourcezDotBackend.get_sourceA   s@    < 	IIe99TZ00DL
|r   
outputfilemapfilec                0   d}| j         }|[d}t          j        d|          \  }}t          j        d|          \  }}t          j        |           t          j        |           nRt          |          \  }	}	}|s
d}|dz   |z   }||vr-t          j        d|          \  }}t          j        |           n|}t          j        |dd	          5 }
|
                    | j	                   ddd           n# 1 swxY w Y   ||vrt          j        | j                  t          d
| d| j         d          |r%t          j        | j        dd|d||d|g	d           n!t          j        | j        d||d|gd           t          j        |           |S )a+  Generates a graph file.

        :param str outputfile: filename and path [defaults to graphname.png]
        :param str mapfile: filename and path

        :rtype: str
        :return: a path to the generated file
        :raises RuntimeError: if the executable for rendering was not found
        )r   gvNpngz.gvz.png.wutf8)encodingzCannot generate `z` because 'zg' executable not found. Install graphviz, or specify a `.gv` outputfile to produce the DOT source code.z-Tcmapxz-oz-TT)check)r   tempfilemkstempr   closer   codecsopenwritesourceshutilwhichr"   RuntimeError
subprocessrununlink)r2   r8   r9   graphviz_extensionsnamer   pdotdot_sourcepathppng_files              r   generatezDotBackend.generateK   sB    ,~ 	,F#+#3E4#@#@ D.'/==D*HTNNNHTNNNN4Z@@LAq& 7'#-6
00 ,'/'7t'D'D$n!+[v>>> 	$$JJt{###	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$ 	$,, 	&|DM** "A
 A At} A A A  
  !&"
      ]D&.$
S    In%%%s   C77C;>C;linec                :    | j                             |           dS )zAdds <line> to final output.N)r+   append)r2   rW   s     r   r-   zDotBackend.emit   s    
$r   name1name2propsc                    d |                                 D             }t          |          t          |          }}|                     | d| dd                    t	          |                     d           dS )z}Emit an edge from <name1> to <name2>.

        For edge properties: see https://www.graphviz.org/doc/info/attrs.html
        c                $    g | ]\  }}| d | dS z="r'    .0propvalues      r   
<listcomp>z(DotBackend.emit_edge.<locals>.<listcomp>   -    FFFuD$$E$$$FFFr   z ->  [, ];N)r0   r.   r-   r1   sorted)r2   rZ   r[   r\   attrsn_fromn_tos          r   	emit_edgezDotBackend.emit_edge   s}    
 GFFFF(//1B51I1I		VEEEE6%==)A)AEEEFFFFFr   rP   c           	         d |                                 D             }|                     t          |           dd                    t	          |                     d           dS )zzEmit a node with given properties.

        For node properties: see https://www.graphviz.org/doc/info/attrs.html
        c                $    g | ]\  }}| d | dS r_   r`   ra   s      r   re   z(DotBackend.emit_node.<locals>.<listcomp>   rf   r   rg   rh   ri   N)r0   r-   r.   r1   rj   )r2   rP   r\   rk   s       r   	emit_nodezDotBackend.emit_node   sd    
 GFFFF		&t,,LL		&--0H0HLLLMMMMMr   )NNNr   r   N)r   r   r   r   r   r   r    r   r!   r   r"   r   r#   r$   r   r%   )r   r   )NN)r8   r   r9   r   r   r   )rW   r   r   r%   )rZ   r   r[   r   r\   r   r   r%   )rP   r   r\   r   r   r%   )__name__
__module____qualname____doc__r4   r7   propertyrH   rV   r-   rn   rq   r`   r   r   r   r      s        
 #26' ' ' ' 'B    Xj!!F DH= = = = =~       G G G GN N N N N Nr   r   nidc                    d|  dS )z)Returns a suitable DOT node id for `nid`.r'   r`   )rw   s    r   r.   r.      s    s:::r   
graph_dictdict[str, set[str]]verticeslist[str] | NoneSequence[list[str]]c                    | sdS g }|!t          |                                           }|D ]!}t          | g t                      ||           "|S )zReturn a list of detected cycles based on an ordered graph (i.e. keys are
    vertices and values are lists of destination vertices representing edges).
    r`   )listkeys_get_cyclesset)ry   r{   resultvertices       r   
get_cyclesr      sf      r F +
))** < <JCEE67;;;;Mr   r   	list[str]visitedset[str]r   list[list[str]]r   r%   c                   ||v r|g}|ddd         D ] }||k    r n|                     d|           !t          |          }|                    |          }||d         |d|         z   }||vr|                    |           dS |                    |           	 | |         D ].}||vr(t	          | ||||           |                    |           /n# t          $ r Y nw xY w|                                 dS )z6Recursive function doing the real work for get_cycles.Nr   r   )insertminindexrY   r   addKeyErrorpop)	ry   r   r   r   r   cyclenode
start_fromr   s	            r   r   r      sK    $ 	2J 	" 	"Dw LLD!!!!ZZ
J''effag. 	!MM%   KKw' 	" 	"D7" "JgvtDDDD!!!		"
    HHJJJJJs   7C 
C#"C#)r   r   r   r	   )rw   r   r   r   )N)ry   rz   r{   r|   r   r}   )ry   rz   r   r   r   r   r   r   r   r   r   r%   )ru   
__future__r   rE   r   rI   rL   rB   collections.abcr   typingr   r   r   r.   r   r   r`   r   r   <module>r      s  
 
 # " " " " "  				       $ $ $ $ $ $      & & & &@N @N @N @N @N @N @N @NF    CG          r   