B
    öÀ„\ºB  ã               @   s4  d 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lm	Z	 ddl
mZ ddlmZ ddlZddlmZmZmZmZ dd	lmZ dd
lmZ ddlmZ e dej¡Zdd„ Zdd„ ZG dd„ deƒZ G dd„ de!ƒZ"G dd„ dej#ej$ƒZ%G dd„ deƒZ&dd„ Z'dd„ Z(dd„ Z)dd „ Z*d!d"„ Z+d#d$„ Z,dS )%a[  
    sphinx.ext.inheritance_diagram
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    Defines a docutils directive for inserting inheritance diagrams.

    Provide the directive with one or more classes or modules (separated
    by whitespace).  For modules, all of the classes in that module will
    be used.

    Example::

       Given the following classes:

       class A: pass
       class B(A): pass
       class C(A): pass
       class D(B, C): pass
       class E(B): pass

       .. inheritance-diagram: D E

       Produces a graph like the following:

                   A
                  / \
                 B   C
                / \ /
               E   D

    The graph is inserted as a PNG+image map into HTML and a PDF in
    LaTeX.

    :copyright: Copyright 2007-2019 by the Sphinx team, see AUTHORS.
    :license: BSD, see LICENSE for details.
é    N)Úmd5)Únodes)Ú
directives)Ú	text_type)Úbuiltins)Úrender_dot_htmlÚrender_dot_latexÚrender_dot_texinfoÚfigure_wrapper)ÚModuleAnalyzer)Úforce_decode)ÚSphinxDirectivez‡^(?:([\w.]*)\.)?  # module names
                           (\w+)  \s* $          # class/final module name
                           c             C   s’   yt | ƒ tj | ¡S  ttfk
rŒ   t | ¡}|s:dS | ¡ \}}|dkrRdS yt |ƒ t	tj |¡|dƒS  ttfk
r†   dS X Y nX dS )záImport a object or module using *name* and *currentmodule*.
    *name* should be a relative name from *currentmodule* or
    a fully-qualified name.

    Returns imported object or module.  If failed, returns None value.
    N)
Ú
__import__ÚsysÚmodulesÚgetÚImportErrorÚ
ValueErrorÚmodule_sig_reÚmatchÚgroupsÚgetattr)ZobjnameZmatchedÚmodnameZattrname© r   ú=lib/python3.7/site-packages/sphinx/ext/inheritance_diagram.pyÚ
try_importD   s    
r   c             C   s¢   d}|rt |d |  ƒ}|dkr(t | ƒ}|dkr<td|  ƒ‚t |¡rL|gS t |¡r’g }x2|j ¡ D ]$}t |¡rf|j|jkrf| 	|¡ qfW |S td|  ƒ‚dS )z0Import a class using its fully-qualified *name*.NÚ.zECould not import class or module %r specified for inheritance diagramz=%r specified for inheritance diagram is not a class or module)
r   ÚInheritanceExceptionÚinspectZisclassZismoduleÚ__dict__ÚvaluesÚ
__module__Ú__name__Úappend)ÚnameÚ
currmoduleÚtargetÚclassesÚclsr   r   r   Úimport_classes`   s&    

r)   c               @   s   e Zd ZdS )r   N)r"   r!   Ú__qualname__r   r   r   r   r   €   s   r   c               @   sŽ   e Zd ZdZddddg fdd„Zdd„ Zd	d
„ Zd dd„Zdd„ ZdddœZ	ddddddœZ
dddœZdd„ Zdd„ Zi di i i fdd„ZdS )!ÚInheritanceGraphz¾
    Given a list of classes, determines the set of classes that they inherit
    from all the way to the root "object", and then is able to generate a
    graphviz dot graph from them.
    Fr   Nc       	      C   s:   || _ |  ||¡}|  ||||||¡| _| js6tdƒ‚dS )z£*class_names* is a list of child classes to show bases from.

        If *show_builtins* is True, then Python builtins will be shown
        in the graph.
        z(No classes found for inheritance diagramN)Úclass_namesÚ_import_classesÚ_class_infoÚ
class_infor   )	Úselfr,   r%   Úshow_builtinsÚprivate_basesÚpartsÚaliasesÚtop_classesr'   r   r   r   Ú__init__Š   s    zInheritanceGraph.__init__c             C   s&   g }x|D ]}|  t||ƒ¡ q
W |S )zImport a list of classes.)Úextendr)   )r0   r,   r%   r'   r$   r   r   r   r-   š   s    
z InheritanceGraph._import_classesc          	      sN   i ‰t tƒ ¡ ‰‡ ‡‡‡‡‡‡‡‡f	dd„‰x|D ]}ˆ|ƒ q2W tˆ ¡ ƒS )aY  Return name and bases for all classes that are ancestors of
        *classes*.

        *parts* gives the number of dotted name parts that is removed from the
        displayed node names.

        *top_classes* gives the name(s) of the top most ancestor class to traverse
        to. Multiple names can be specified separated by comma.
        c                s&  ˆs| ˆkrd S ˆs$| j  d¡r$d S ˆ | ˆˆ ¡}ˆ | dˆ ¡}d }yT| jr–t | j¡j}| j ¡  	d¡d }t
|tƒs‚t||ƒ}|r–d| dd¡ }W n tk
r¬   Y nX g }||||fˆ| < |ˆkrÎd S xR| jD ]H}ˆsè|ˆkrèqÖˆsú|j  d¡rúqÖ| ˆ |ˆˆ ¡¡ |ˆkrÖˆ|ƒ qÖW d S )NÚ_r   Ú
z"%s"ú"z\")r"   Ú
startswithÚ
class_nameÚ__doc__r   Z
for_moduler!   ÚencodingÚstripÚsplitÚ
isinstancer   r   ÚreplaceÚ	ExceptionÚ	__bases__r#   )r(   ÚnodenameÚfullnameÚtooltipÚencÚdocZbaselistÚbase)	r4   Úall_classesr3   r2   Úpy_builtinsÚrecurser0   r1   r5   r   r   rM   °   s:    

z-InheritanceGraph._class_info.<locals>.recurse)Úvarsr   r    Úlist)r0   r'   r1   r2   r3   r4   r5   r(   r   )	r4   rK   r3   r2   rL   rM   r0   r1   r5   r   r.   ¢   s    &
zInheritanceGraph._class_infoc             C   sl   |j }|dkr|j}nd||jf }|dkr2|}n| d¡}d || d… ¡}|dk	rh||krh|| S |S )z©Given a class object, return a fully-qualified name.

        This works for things I've tested in matplotlib so far, but may not be
        completely general.
        )Z__builtin__r   z%s.%sr   r   N)r!   r"   r@   Újoin)r0   r(   r3   r4   ÚmodulerF   ÚresultZ
name_partsr   r   r   r<   Û   s    
zInheritanceGraph.class_namec             C   s   dd„ | j D ƒS )z1Get all of the class names involved in the graph.c             S   s   g | ]\}}}}|‘qS r   r   )Ú.0r8   rF   r   r   r   ú
<listcomp>ó   s    z8InheritanceGraph.get_all_class_names.<locals>.<listcomp>)r/   )r0   r   r   r   Úget_all_class_namesð   s    z$InheritanceGraph.get_all_class_namesZLRz"8.0, 12.0")ZrankdirÚsizeZboxé
   g      Ð?zA"Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans"z"setlinewidth(0.5)")ÚshapeZfontsizeZheightZfontnameÚstyleg      à?)Z	arrowsizerY   c             C   s   d  dd„ t| ¡ ƒD ƒ¡S )Nú,c             S   s   g | ]}d | ‘qS )z%s=%sr   )rS   Úxr   r   r   rT   	  s    z7InheritanceGraph._format_node_attrs.<locals>.<listcomp>)rP   ÚsortedÚitems)r0   Úattrsr   r   r   Ú_format_node_attrs  s    z#InheritanceGraph._format_node_attrsc             C   s   d  dd„ t| ¡ ƒD ƒ¡S )NÚ c             S   s   g | ]}d | ‘qS )z%s=%s;
r   )rS   r[   r   r   r   rT     s    z8InheritanceGraph._format_graph_attrs.<locals>.<listcomp>)rP   r\   r]   )r0   r^   r   r   r   Ú_format_graph_attrs  s    z$InheritanceGraph._format_graph_attrsc          
   C   s0  | j  ¡ }| j ¡ }| j ¡ }	| |¡ | |¡ |	 |¡ |rj| |jj¡ | |jj¡ |	 |jj¡ g }
|
 	d| ¡ |
 	|  
|¡¡ xŽt| jƒD ]€\}}}}| ¡ }||krÌd||  |d< d|d< |rØ||d< |
 	d||  |¡f ¡ x&|D ]}|
 	d|||  |	¡f ¡ qöW q˜W |
 	d	¡ d
 |
¡S )aV  Generate a graphviz dot graph from the classes that were passed in
        to __init__.

        *name* is the name of the graph.

        *urls* is a dictionary mapping class names to HTTP URLs.

        *graph_attrs*, *node_attrs*, *edge_attrs* are dictionaries containing
        key/value pairs to pass on as graphviz properties.
        zdigraph %s {
z"%s"ZURLz"_top"r&   rG   z  "%s" [%s];
z  "%s" -> "%s" [%s];
z}
r`   )Údefault_graph_attrsÚcopyÚdefault_node_attrsÚdefault_edge_attrsÚupdateÚconfigÚinheritance_graph_attrsÚinheritance_node_attrsÚinheritance_edge_attrsr#   ra   r\   r/   r_   rP   )r0   r$   ÚurlsÚenvÚgraph_attrsZ
node_attrsZ
edge_attrsZg_attrsZn_attrsZe_attrsZresrF   ÚbasesrG   Zthis_node_attrsZ	base_namer   r   r   Úgenerate_dot  s8    







zInheritanceGraph.generate_dot)r   N)r"   r!   r*   r=   r6   r-   r.   r<   rU   rb   rd   re   r_   ra   ro   r   r   r   r   r+   „   s(   9
r+   c               @   s   e Zd ZdZdS )Úinheritance_diagramzN
    A docutils node to use as a placeholder for the inheritance diagram.
    N)r"   r!   r*   r=   r   r   r   r   rp   ?  s   rp   c               @   s>   e Zd ZdZdZdZdZdZej	ej
ejejdœZdd„ Zd	S )
ÚInheritanceDiagramzJ
    Run when the inheritance_diagram directive is first encountered.
    Fé   r   T)r3   zprivate-basesÚcaptionztop-classesc          
   C   sf  t ƒ }| jj|_| jd  ¡ }| j d¡ d¡}| j 	dd¡|d< d 
|¡|d< g |d< x6| j 	dd¡ d	¡D ]}| ¡ }|rn|d  |¡ qnW y4t|| jj 	d
¡|d d| jk| jj|d d}W n< tk
r  } z|jjj|jd | jdgS d }~X Y nX x6| ¡ D ]*}|dd| |d| jƒ\}}	| |¡ qW ||d< | j 	d¡}
|
r`t| ||
ƒ}|gS )Nr   ÚpyÚclassr3   z, Úcontentztop-classesr`   rZ   z	py:modulezprivate-bases)r3   r2   r4   r5   )Úlinez:class:`%s`Úgraphrs   )rp   ÚstateZdocumentZ	argumentsr@   rl   Z
get_domainZroleZoptionsr   rP   r?   r#   r+   Zref_contextrg   Úinheritance_aliasr   ZreporterZwarningÚargsÚlinenorU   r7   r
   )r0   Únoder,   Z
class_roler(   rx   Úerrr$   Zrefnodesr[   rs   r   r   r   ÚrunU  s<    
zInheritanceDiagram.runN)r"   r!   r*   r=   Zhas_contentZrequired_argumentsZoptional_argumentsZfinal_argument_whitespacer   Znonnegative_intÚflagZ	unchangedZunchanged_requiredZoption_specr   r   r   r   r   rq   F  s   
rq   c             C   s.   | d t | d ƒ  d¡}t|ƒ ¡ dd … S )Nrv   r3   zutf-8iöÿÿÿ)ÚstrÚencoder   Z	hexdigest)r}   Zencodedr   r   r   Úget_graph_hashƒ  s    rƒ   c       
   
   C   s  |d }t |ƒ}d| }| jjjj ¡ }| jj| jj }i }xš|D ]’}| d¡dk	rˆ|dkrtd| d¡ ||d < qÔ| d¡||d < qB| d¡dk	rB|dkr¾d| d	 | d¡ ||d < qBd	| d¡ ||d < qBW |j	||| jjd
}	t
| ||	i ddd|d  d tj‚dS )zZ
    Output the graph for HTML.  This will insert a PNG with clickable
    image map.
    rx   zinheritance%sZrefuriNZSVGz../ZreftitleZrefidú#)rl   ÚinheritancezInheritance diagram of rv   )Zalt)rƒ   Úbuilderrl   rg   Úgraphviz_output_formatÚupperZcurrent_docnameZ
out_suffixr   ro   r   r   ÚSkipNode)
r0   r}   rx   Ú
graph_hashr$   r‡   Zcurrent_filenamerk   ZchildÚdotcoder   r   r   Úhtml_visit_inheritance_diagram‰  s&    
 rŒ   c             C   sJ   |d }t |ƒ}d| }|j|| jjddid}t| ||i dƒ tj‚dS )z>
    Output the graph for LaTeX.  This will insert a PDF.
    rx   zinheritance%srV   z	"6.0,6.0")rl   rm   r…   N)rƒ   ro   r†   rl   r   r   r‰   )r0   r}   rx   rŠ   r$   r‹   r   r   r   Úlatex_visit_inheritance_diagramª  s    r   c             C   sJ   |d }t |ƒ}d| }|j|| jjddid}t| ||i dƒ tj‚dS )z@
    Output the graph for Texinfo.  This will insert a PNG.
    rx   zinheritance%srV   z	"6.0,6.0")rl   rm   r…   N)rƒ   ro   r†   rl   r	   r   r‰   )r0   r}   rx   rŠ   r$   r‹   r   r   r   Ú!texinfo_visit_inheritance_diagramº  s    rŽ   c             C   s
   t j‚d S )N)r   r‰   )r0   r}   r   r   r   ÚskipÊ  s    r   c             C   s„   |   d¡ | jttd ftd ftd ftd ftd fd |  dt¡ |  	di d¡ |  	di d¡ |  	di d¡ |  	di d¡ t
jd	d
œS )Nzsphinx.ext.graphviz)ZlatexZhtmlÚtextZmanZtexinfozinheritance-diagramrh   Fri   rj   rz   T)ÚversionZparallel_read_safe)Zsetup_extensionZadd_noderp   r   rŒ   r   rŽ   Zadd_directiverq   Zadd_config_valueÚsphinxZ__display_version__)Zappr   r   r   ÚsetupÏ  s    
r“   )-r=   r   Úrer   Zhashlibr   Zdocutilsr   Zdocutils.parsers.rstr   Zsixr   Z	six.movesr   r’   Zsphinx.ext.graphvizr   r   r	   r
   Zsphinx.pycoder   Zsphinx.utilr   Zsphinx.util.docutilsr   ÚcompileÚVERBOSEr   r   r)   rC   r   Úobjectr+   ZGeneralZElementrp   rq   rƒ   rŒ   r   rŽ   r   r“   r   r   r   r   Ú<module>%   s8   	
  <=!