B
    .Kc?                 @   s   d Z ddlmZmZmZmZmZmZmZ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mZ ddlmZ dd	lmZ dd
lmZ erddlmZ eeZeje dddZ!G dd dZ"G dd de"Z#G dd de#Z$G dd dZ%dS )zUtility code for "Doc fields".

"Doc fields" are reST field lists in object descriptions that will
be domain-specifically transformed to a more appealing presentation.
    )TYPE_CHECKINGAnyDictListTupleTypeUnioncast)nodes)Node)Inliner)addnodes)BuildEnvironment)__)logging)TextlikeNode)ObjectDescription)nodereturnc             C   sZ   t | dkrdS t | dkrBx$| dd D ]}t|tjs*dS q*W t| d tjrVdS dS )zCTrue if the node only contains one paragraph (and system messages).r   F   NT)len
isinstancer
   Zsystem_message	paragraph)r   Zsubnode r   4lib/python3.7/site-packages/sphinx/util/docfields.py_is_single_paragraph   s    r   c               @   s   e Zd ZdZdZdZdeeedf eeeedddd	Z	e
jddddfeeeee eeeeed
	ddZe
jddddfeeeee eeeeee d
	ddZeee eeee f dddZdeeee f eeeeeejdddZdS )Fielda  A doc field that is never grouped.  It can have an argument or not, the
    argument can be linked using a specified *rolename*.  Field should be used
    for doc fields that usually don't occur more than once.

    The body can be linked using a specified *bodyrolename* if the content is
    just a single inline or text node.

    Example::

       :returns: description of the return value
       :rtype: description of the return type
    Fr   NT.)namenameslabelhas_argrolenamebodyrolenamer   c             C   s(   || _ || _|| _|| _|| _|| _d S )N)r   r   r   r    r!   r"   )selfr   r   r   r    r!   r"   r   r   r   __init__5   s    zField.__init__)	r!   domaintarget	innernodecontnodeenvinlinerlocationr   c	             C   s   |d k	st |d k|d kks(t ||f|s:|p8|||S |||}	|	d ksZ|d kr|	d kr|d k	rtd}
tjt|
|||d tjd|d||d}||p|||7 }||| |S t	
|d }|	|||||i g \}}tj|df| S )Nz]Problem in %s domain: field is supposed to use role '%s', but that role is not in the domain.)r+    F)Z	refdomainZrefexplicitZreftypeZ	reftargetr   )AssertionErrorZ
get_domainroler   loggerZwarningr   Zpending_xrefZprocess_field_xrefr   Zget_source_liner
   inline)r#   r!   r%   r&   r'   r(   r)   r*   r+   r.   msgZrefnodelinenonsmessagesr   r   r   	make_xref>   s"    

zField.make_xrefc	       	   
   C   s   |  ||||||||gS )N)r5   )	r#   r!   r%   r&   r'   r(   r)   r*   r+   r   r   r   
make_xrefsX   s    zField.make_xrefs)fieldargcontentr   c             C   s   ||fS )Nr   )r#   r7   r8   r   r   r   
make_entry_   s    zField.make_entry)typesr%   itemr)   r*   r+   r   c             C   s   |\}}t d| j}	|rJ|	t d7 }	|	| j| j||t j|||d t|dkrt|d t jst|d t j	rt|d dkrt|d d t jr| j| j
||d  |d |||d}t dt jd| }
t d|	|
S )Nr,    )r)   r*   r+   r   r   )r(   r)   r*   r+   )r,   r,   )r
   
field_namer   Textextendr6   r!   r   r   r0   r"   astext
field_bodyr   field)r#   r:   r%   r;   r)   r*   r+   r7   r8   	fieldname	fieldbodyr   r   r   
make_fieldb   s      
zField.make_field)r   NTNN)NNN)__name__
__module____qualname____doc__
is_groupedis_typedstrr   boolr$   r   literal_emphasisr   r   r   r   r   r5   r   r6   r9   r   r
   rB   rE   r   r   r   r   r   %   s    $	(," r   c            	       sn   e Zd ZdZdZejZdee	edf eee
dd fdd	Zdeeee f ee	eeeejd
ddZ  ZS )GroupedFielda  
    A doc field that is grouped; i.e., all fields of that type will be
    transformed into one field with its body being a bulleted list.  It always
    has an argument.  The argument can be linked using the given *rolename*.
    GroupedField should be used for doc fields that can occur more than once.
    If *can_collapse* is true, this field will revert to a Field if only used
    once.

    Example::

       :raises ErrorClass: description when it is raised
    Tr   NF.)r   r   r   r!   can_collapser   c                s   t  |||d| || _d S )NT)superr$   rP   )r#   r   r   r   r!   rP   )	__class__r   r   r$      s    zGroupedField.__init__)r:   r%   itemsr)   r*   r+   r   c             C   s   t d| j}|  }x`|D ]X\}	}
t  }|| j| j||	tj	|||d |t 
d7 }||
7 }|t d|7 }qW t|dkr| jrtt j|d }t d|d }t d||S t d|}t d||S )Nr,   )r)   r*   r+   z -- r   r   )r
   r=   r   	list_typer   r?   r6   r!   r   literal_strongr>   	list_itemr   rP   r	   rA   rB   )r#   r:   r%   rS   r)   r*   r+   rC   Zlistnoder7   r8   parrV   rD   r   r   r   rE      s     zGroupedField.make_field)r   NNF)NNN)rF   rG   rH   rI   rJ   r
   Zbullet_listrT   rL   r   rM   r$   r   r   r   r   r   rB   rE   __classcell__r   r   )rR   r   rO   x   s    & rO   c            
       st   e Zd ZdZdZdeeedf eedf eeeedd fdd	Zde	ee
e f eeeeeejd
ddZ  ZS )
TypedFieldaa  
    A doc field that is grouped and has type information for the arguments.  It
    always has an argument.  The argument can be linked using the given
    *rolename*, the type using the given *typerolename*.

    Two uses are possible: either parameter and type description are given
    separately, using a field from *names* and one from *typenames*,
    respectively, or both are given using a field from *names*, see the example.

    Example::

       :param foo: description of parameter foo
       :type foo:  SomeClass

       -- or --

       :param SomeClass foo: description of parameter foo
    Tr   NF.)r   r   	typenamesr   r!   typerolenamerP   r   c                s$   t  ||||| || _|| _d S )N)rQ   r$   rZ   r[   )r#   r   r   rZ   r   r!   r[   rP   )rR   r   r   r$      s    zTypedField.__init__)r:   r%   rS   r)   r*   r+   r   c                s   t t tjd fdd}tdj}t|dkrZjrZ|d \}	}
||	|
}n0 }x&|D ]\}	}
|td||	|
7 }qhW t	d|}t
d||S )N)r7   r8   r   c                s   t  }|jj | tjd | kr|t d7 }| }t	|dkrt
|d t jr|d  }|jj |tjd n||7 }|t d7 }|t d7 }||7 }|S )N)r)   z (r   r   )r)   r*   r+   )z -- )r
   r   r?   r6   r!   r   rU   r>   popr   r   r@   r[   rN   )r7   r8   rW   	fieldtypetypename)r%   r)   r*   r+   r#   r:   r   r   handle_item   s     
z*TypedField.make_field.<locals>.handle_itemr,   r   r   )rL   r
   r   r=   r   r   rP   rT   rV   rA   rB   )r#   r:   r%   rS   r)   r*   r+   r`   rC   r7   r8   ZbodynoderD   r   )r%   r)   r*   r+   r#   r:   r   rE      s    "zTypedField.make_field)r   r   NNNF)NNN)rF   rG   rH   rI   rK   rL   r   rM   r$   r   r   r   r   r   r
   rB   rE   rX   r   r   )rR   r   rY      s     2 rY   c               @   s^   e Zd ZU dZeeeeef f e	d< dddddZ
ejddd	d
ZejddddZdS )DocFieldTransformerz
    Transforms field lists in "doc field" syntax into better-looking
    equivalents, using the field type definitions given on a domain.
    typemapr   N)	directiver   c             C   s   || _ | | _d S )N)rc   Zget_field_type_maprb   )r#   rc   r   r   r   r$      s    zDocFieldTransformer.__init__)r   r   c             C   s(   x"|D ]}t |tjr| | qW dS )z,Transform all field list children of a node.N)r   r
   
field_list	transform)r#   r   Zchildr   r   r   transform_all   s    
z!DocFieldTransformer.transform_allc       !   
   C   s  | j }g }i }i }xtttj |D ]}t|dks<tttj|d }ttj|d }y|	 
dd\}	}
W n" tk
r   |	 d }	}
Y nX ||	d\}}t|rttj|d }|j}n|j}|dks|jt|
kr|	dd  |	dd  }|
r|d|
 7 }t||d< || |r&|r&|r&t|dkr&t|d tjr&tt|}|d 	 }|j|j| jj||d | jjjjjd}t|rttj|d }|  | | q&|  |tjd| 7 }q&|j!}|rd	d
 |D }|r&||"|i |
< q&|j#r\y|
$dd\}}W n tk
r>   Y nX t|g|"|i |< |}
tj%|j&dd}|j'j|_|j'j(|_(|j'j)|_)||7 }|j*r ||krtt+t,tt-f |||  }n t|||< |g |f}|| |.|
|g}|d | q&|.|
|g}||||f q&W t/ }xt|D ]l}t|tjrL||7 }nN|\}}}||j!i }| jjjjj}| jjj0} ||j1|| jj||| |d7 }q0W |2| dS )z%Transform a single field list *node*.   r   r   Nr,   )NNr<   )r(   r)   c             S   s"   g | ]}t |tjtjfr|qS r   )r   r
   ZInliner>   ).0nr   r   r   
<listcomp>:  s    z1DocFieldTransformer.transform.<locals>.<listcomp>T)Ztranslatable)r)   r*   r+   )r,   r,   )3rb   r	   r   r
   rB   r   r-   r=   rA   r@   split
ValueErrorgetr   r   Zchildrenr    rM   upperr>   appendr   rY   r6   r[   rc   r%   stateZdocumentZsettingsr)   clearr?   r   
setdefaultrK   rsplitr0   Z	rawsourceparentsourcelinerJ   r   r   r   r9   rd   r*   rE   Zreplace_self)!r#   r   rb   entriesZgroupindicesr:   rB   r=   rA   Zfieldtype_namer7   ZtypedescZis_typefieldr   r8   Znew_fieldnameZtyped_fieldr&   Zxrefsr_   ZargtypeargnameZtranslatable_contentgroupZ	new_entryZnew_listentryr^   rS   r+   Z
fieldtypesr)   r*   r   r   r   re      s    












zDocFieldTransformer.transform)rF   rG   rH   rI   r   rL   r   r   rM   __annotations__r$   r   Zdesc_contentrf   r
   rd   re   r   r   r   r   ra      s
   
ra   N)&rI   typingr   r   r   r   r   r   r   r	   Zdocutilsr
   Zdocutils.nodesr   Zdocutils.parsers.rst.statesr   Zsphinxr   Zsphinx.environmentr   Zsphinx.localer   Zsphinx.utilr   Zsphinx.util.typingr   Zsphinx.directivesr   Z	getLoggerrF   r/   rA   rM   r   r   rO   rY   ra   r   r   r   r   <module>   s"   (
S,A