
    FeT                       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Zddlm	Z	 ddl
mZmZmZmZmZmZmZ ddlmZmZ ddlmZ ddlmZ  ej2                  d	      Z ej2                  d
      Z ej2                  d      ZddZddZdddZd dZ  G d d      Z! G d d      Z" G d de"      Z# G d dejH                        Z% G d de"      Z& G d d      Z'y)!z,Utilities parsing and analyzing Python code.    )annotationsN)	Signature)DEDENTINDENTNAMENEWLINENUMBEROPSTRING)COMMENTNL)Any)unparsez^\s*#: ?(.*)?
?$z^\s*$z^\s*(#.*)?$c                &    | j                  dd      S )N )replace)codes    6/usr/lib/python3/dist-packages/sphinx/pycode/parser.pyfilter_whitespacer      s    <<c""    c                h    t        | t        j                        r| j                  S | j                  gS )z3Get list of targets from Assign and AnnAssign node.)
isinstanceastAssigntargetstarget)nodes    r   get_assign_targetsr      s&    $

#||}r   c                   |r|j                   }| j                  j                  }|dv rt        d| z        |dk(  r,|| j                  k(  r| j                  gS t        d| z        |dv rRg }| j
                  D ]?  }t        j                  t              5  |j                  t        ||             ddd       A |S |dk(  ri| j                  j                  j                  dk(  r8|r6| j                  j                  k(  rdt        | j                  |      d	   z  gS t        d| z        |d
k(  r| gS |dk(  rt        | j                  |      S t        d|z        # 1 sw Y   xY w)zConvert assignment-AST to variable names.

    This raises `TypeError` if the assignment does not create new variable::

        ary[0] = 'foo'
        dic["bar"] = 'baz'
        # => TypeError
    )ConstantIndexSlice	Subscriptz%r does not create new variableNameNz*The assignment %r is not instance variable)TupleList	Attributez%sr   strStarredzUnexpected node name %r)arg	__class____name__	TypeErroridelts
contextlibsuppressextendget_lvar_namesvalueattrNotImplementedError)r   selfself_id	node_namememberselts         r   r4   r4   #   sm    ((''I??9D@AAF<477g-GG9H4OPP	'	'99 	:C$$Y/ :~c489: :	: 	k	!JJ  ))V3TZZ]]g- >$))T:1==>>H4OPP	e	v	i	djj$//!";i"GHH%: :s   EE&	c                    dd}| |_         t        j                  |      }|r |j                  d      j	                  d      S y)z1Remove common leading indentation from docstring.c                      y N r@   r   r   dummyzdedent_docstring.<locals>.dummyQ   s    r   z
 returnNone)__doc__inspectgetdoclstriprstrip)srA   	docstrings      r   dedent_docstringrM   O   s@     EMu%I'..v66r   c                  8    e Zd ZdZ	 	 	 	 ddZddZd	dZd
dZy)Tokenz)Better token wrapper for tokenize module.c                J    || _         || _        || _        || _        || _        y r?   )kindr5   startendsource)r8   rQ   r5   rR   rS   rT   s         r   __init__zToken.__init__`   s%    	

r   c                   t        |t              r| j                  |k(  S t        |t              r| j                  |k(  S t        |t
        t        f      r$| j                  | j                  gt        |      k(  S |yt        d|z        )NFzUnknown value: %r)r   intrQ   r)   r5   listtuple
ValueError)r8   others     r   __eq__zToken.__eq__h   sw    eS!99%%s#::&&e}-IItzz*d5k99]05899r   c                ,     t         fd|D              S )Nc              3  (   K   | ]	  }|k(    y wr?   r@   ).0	candidater8   s     r   	<genexpr>zToken.match.<locals>.<genexpr>u   s     A49$As   )any)r8   
conditionss   ` r   matchzToken.matcht   s    AjAAAr   c                z    dt         j                  | j                     d| j                  j	                         dS )Nz<Token kind=z value=>)tokenizetok_namerQ   r5   stripr8   s    r   __repr__zToken.__repr__w   s6    h//		:=WTZZEUEUEWDZZ[\\r   N)rQ   rW   r5   r   rR   tuple[int, int]rS   rl   rT   r)   rD   rE   )r[   r   rD   bool)rc   r   rD   rm   )rD   r)   )r-   
__module____qualname__rF   rU   r\   rd   rk   r@   r   r   rO   rO   ]   s+    3!%
:B]r   rO   c                  ,    e Zd ZddZddZddZd	dZy)
TokenProcessorc                    t        |      || _        t        j                  fd      | _        d | _        d | _        y )Nc                     t               S r?   )next)liness   r   <lambda>z)TokenProcessor.__init__.<locals>.<lambda>   s    tE{ r   )iterbuffersrg   generate_tokenstokenscurrentprevious)r8   rx   ru   s     @r   rU   zTokenProcessor.__init__|   s4    W../BC%)&*r   c                &    | j                   |dz
     S zReturns specified line.   rx   r8   linenos     r   get_linezTokenProcessor.get_line       ||FQJ''r   c                    	 | j                   | _        t        t        | j                         | _         | j                   S # t
        $ r d| _         Y | j                   S w xY w)z_Fetch the next token from source code.

        Returns ``None`` if sequence finished.
        N)r{   r|   rO   rt   rz   StopIterationrj   s    r   fetch_tokenzTokenProcessor.fetch_token   sU    
	  LLDM $t{{"34DL ||  	 DL||	 s   1? AAc                h   g }| j                         x}r|j                  |       ||k(  r	 |S |t        dgk(  r|| j                  t        dg      z  }nK|t        dgk(  r|| j                  t        dg      z  }n%|t        dgk(  r|| j                  t        dg      z  }| j                         x}r|S )zlFetch tokens until specified token appeared.

        .. note:: This also handles parenthesis well.
        (){}[])r   appendr
   fetch_until)r8   	conditionrz   r{   s       r   r   zTokenProcessor.fetch_until   s    
 ))++g+MM'")#  2s)#$**B955RI%$**B955RI%$**B955 ))++g+ r   N)rx   	list[str]rD   rE   r   rW   rD   r)   )rD   zToken | None)r   r   rD   list[Token])r-   rn   ro   rU   r   r   r   r@   r   r   rq   rq   {   s    +(r   rq   c                  4     e Zd ZdZd fdZddZddZ xZS )AfterCommentParserzPython source code parser to pick up comments after assignments.

    This parser takes code which starts with an assignment statement,
    and returns the comment for the variable if one exists.
    c                2    t         |   |       d | _        y r?   )superrU   commentr8   ru   r,   s     r   rU   zAfterCommentParser.__init__   s    #'r   c                   g }| j                         x}r|j                  |       |t        dgk(  r|| j                  t        dg      z  }n|t        dgk(  r|| j                  t        dg      z  }n}|t        dgk(  r|| j                  t        dg      z  }nW|t        k(  r|| j                  t
              z  }n5|t        dgk(  r	 |S |r%|j                  t        t        t        t        hvr	 |S | j                         x}r|S )z%Fetch right-hand value of assignment.r   r   r   r   r   r   ;)
r   r   r
   r   r   r   rQ   r   r	   r   )r8   rz   r{   s      r   fetch_rvaluezAfterCommentParser.fetch_rvalue   s   ))++g+MM'"2s)#$**B955RI%$**B955RI%$**B955F"$**622RI%  W\\"dFF1KK ))++g+ r   c                n   | j                         x}rY|j                  t        dgt        t              s8|sJ | j                         x}r"|j                  t        dgt        t              s8|J |t        dgk(  r | j                          | j                  }|J |t        k(  r|j                  | _        yy)z3Parse the code and obtain comment after assignment.=N)	r   rd   r
   r   r   r   r{   r5   r   )r8   toks     r   parsezAfterCommentParser.parse   s     &&((s(#))RIwPW2XJ3 &&((s(#))RIwPW2X 2s),,C?"?'>99DL r   ru   r   rD   rE   )rD   r   rC   )r-   rn   ro   rF   rU   r   r   __classcell__r,   s   @r   r   r      s    ((%r   r   c                       e Zd ZdZd f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Zd  f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 xZS )*VariableCommentPickerz7Python source code parser to pick up variable comments.c                   t        j                         | _        || _        || _        g | _        g | _        d | _        i | _        i | _	        d | _
        i | _        g | _        i | _        d | _        d | _        d | _        t"        | I          y r?   )	itertoolscountcounterrx   encodingcontextcurrent_classescurrent_functioncommentsr   r|   	defordersfinals	overloadstypingtyping_finaltyping_overloadr   rU   )r8   rx   r   r,   s      r   rU   zVariableCommentPicker.__init__   s     ( "$*,8<4679(,)+!#57"&(,+/r   c                    | j                   r2| j                  r%| j                  d   dk(  r| j                  dd |gz   S y| j                  |gz   S )z;Get qualified name for given object as a list of string(s).rU   N)r   r   r   )r8   names     r   get_qualname_forz&VariableCommentPicker.get_qualname_for   sP      ##R(8J(F||CR(D611<<4&((r   c                    | j                  |      }|r2t        | j                        | j                  dj	                  |      <   y y N.)r   rt   r   r   joinr8   r   qualnames      r   	add_entryzVariableCommentPicker.add_entry   s:    ((.15dll1CDNN388H-. r   c                    | j                  |      }|r+| j                  j                  dj                  |             y y r   )r   r   r   r   r   s      r   add_final_entryz%VariableCommentPicker.add_final_entry   s5    ((.KKsxx12 r   c                    ddl m} | j                  |j                        }|rC| j                  j                  dj                  |      g       }|j                   ||             y y )Nr   )signature_from_astr   )sphinx.util.inspectr   r   r   r   
setdefaultr   r   )r8   funcr   r   r   s        r   add_overload_entryz(VariableCommentPicker.add_overload_entry  sT    :((311#((82DbII/56 r   c                v    | j                  |      }|r&dj                  |d d       }|| j                  ||f<   y y Nr   r   )r   r   r   )r8   r   r   r   basenames        r   add_variable_commentz*VariableCommentPicker.add_variable_comment
  sA    ((.xx".H.5DMM8T*+ r   c                    | j                  |      }|r/dj                  |d d       }t        |      | j                  ||f<   y y r   )r   r   ast_unparser   )r8   r   
annotationr   r   s        r   add_variable_annotationz-VariableCommentPicker.add_variable_annotation  sH    ((.xx".H1<Z1HDh-. r   c                    g }| j                   r|j                  d| j                   z         | j                  r|j                  | j                         |D ]  }	 t        |      |v r y y# t        $ r Y !w xY w)Nz%s.finalTF)r   r   r   r   r7   )r8   
decoratorsfinal	decorators       r   is_finalzVariableCommentPicker.is_final  s    ;;LLdkk12LL**+# 	Iy)U2 3	  '    A,,	A87A8c                    g }| j                   r|j                  d| j                   z         | j                  r|j                  | j                         |D ]  }	 t        |      |v r y y# t        $ r Y !w xY w)Nz%s.overloadTF)r   r   r   r   r7   )r8   r   overloadr   s       r   is_overloadz!VariableCommentPicker.is_overload&  s    ;;OOMDKK78OOD001# 	Iy)X5 6	  ' r   c                @   | j                   rC| j                   j                  j                  r#| j                   j                  j                  d   S | j                   rC| j                   j                  j                  r#| j                   j                  j                  d   S y)z8Returns the name of the first argument if in a function.r   N)r   argsposonlyargsrj   s    r   get_selfzVariableCommentPicker.get_self6  sy      T%:%:%?%?%D%D((--22155  T%:%:%?%?%K%K((--99!<<r   c                &    | j                   |dz
     S r~   r   r   s     r   r   zVariableCommentPicker.get_line>  r   r   c                2    t         |   |       || _        y)z(Updates self.previous to the given node.N)r   visitr|   )r8   r   r,   s     r   r   zVariableCommentPicker.visitB  s    dr   c                   |j                   D ]  }| j                  |j                  xs |j                         |j                  dk(  r |j                  xs |j                  | _        [|j                  dk(  r |j                  xs |j                  | _        |j                  dk(  s|j                  xs |j                  | _         y)8Handles Import node and record the order of definitions.r   ztyping.finalztyping.overloadN)namesr   asnamer   r   r   r   r8   r   r   s      r   visit_Importz"VariableCommentPicker.visit_ImportG  s    JJ 	@DNN4;;3$))4yyH$"kk6TYYn,$(KK$<499!//'+{{'?dii$	@r   c                r   |j                   D ]  }| j                  |j                  xs |j                         |j                  dk(  r/|j                  dk(  r |j                  xs |j                  | _        j|j                  dk(  sz|j                  dk(  s|j                  xs |j                  | _         y)r   r   r   r   N)r   r   r   r   moduler   r   r   s      r   visit_ImportFromz&VariableCommentPicker.visit_ImportFromS  s    JJ 	@DNN4;;3$))4{{h&499+?$(KK$<499!(TYY*-D'+{{'?dii$	@r   c           
     H   	 t        |      }t        |D cg c]  }t        || j                                c}g       }| j	                  |j
                        }t        |d      r0|j                  r$|D ]  }| j                  ||j                           n;t        |d      r/|j                  r#|D ]  }| j                  ||j                           t        ||j                  d g| j                  |j
                  d z         }|j                          |j                  rht         j#                  |j                        rI|D ]C  }| j%                  |t         j'                  d|j                               | j)                  |       E yt*        j#                  |d|j                         rg }t-        |j
                  dz
        D ]_  }	| j	                  |j
                  dz
  |	z
        }
t         j#                  |
      r&|j/                  t         j'                  d|
             _ n |rNt1        dj3                  t5        |                  }|D ]%  }| j%                  ||       | j)                  |       ' y|D ]  }| j)                  |        yc c}w # t        $ r Y yw xY w)z3Handles Assign node and pick up a variable comment.rj   Nr   type_commentz\1r   
)r   sumr4   r   r   r   r.   hasattrr   r   r   r   
col_offsetrx   r   r   
comment_rerd   r   subr   	indent_reranger   rM   r   reversed)r8   r   r   tvarnamescurrent_linevarnameparsercomment_linesibefore_liner   s               r   visit_Assignz"VariableCommentPicker.visit_Assign]  sW   	(.G"%BIJQ8JB#H  ==5L
 4&4??# G,,WdooFGT>*t/@/@# 0,,T..00
 $\$//2B%C$D$(LL$>%? @>>j..v~~># ())':>>%3XYw'(  ??<(89:M4;;?+ "mmDKK!Oa,?@##K0!(({)KL *499Xm5L+MN' ,G--gw?NN7+,    	$GNN7#	$W K  		s!   J "J#J J 	J! J!c                &    | j                  |       y)z6Handles AnnAssign node and pick up a variable comment.N)r   r8   r   s     r   visit_AnnAssignz%VariableCommentPicker.visit_AnnAssign  s    $r   c                   t        | j                  t        j                  t        j                  f      rt        |j
                  t        j                        rt        |j
                  j
                  t              r	 t        | j                        }t        |d   | j                               }|D ]  }t        |j
                  j
                  t              r|j
                  j
                  }n3|j
                  j
                  j                  | j                  xs d      }| j                  |t        |             | j                  |        yyyy# t         $ r Y yw xY w)z2Handles Expr node and pick up a comment if string.r   utf-8N)r   r|   r   r   	AnnAssignr5   r!   r)   r   r4   r   decoder   r   rM   r   r.   )r8   r   r   r   r   rL   s         r   
visit_Exprz VariableCommentPicker.visit_Expr  s   t}}szz3==&AB4::s||4DJJDTDTVY9Z,T]];)'!*dmmoF' ,G!$**"2"2C8$(JJ$4$4	$(JJ$4$4$;$;DMM<TW$U	--g7G	7RSNN7+,	 :[4 C  s   ?CE 	E"!E"c                    |j                   D ]  }| j                  |        |j                  D ]  }| j                  |        y)zHandles Try node and processes body and else-clause.

        .. note:: pycode parser ignores objects definition in except-clause.
        N)bodyr   orelse)r8   r   subnodes      r   	visit_TryzVariableCommentPicker.visit_Try  sB    
 yy 	 GJJw	 {{ 	 GJJw	 r   c                   | j                   j                  |j                         | j                  |j                         | j	                  |j
                        r| j                  |j                         | j                  j                  |j                         || _        |j                  D ]  }| j                  |        | j                  j                          | j                   j                          y)z&Handles ClassDef node and set context.N)r   r   r   r   r   decorator_listr   r   r|   r  r   popr8   r   childs      r   visit_ClassDefz$VariableCommentPicker.visit_ClassDef  s    ##DII.tyy!==,,-  +DII&YY 	EJJu	  "r   c                   | j                   | j                  |j                         | j                  |j                        r| j                  |j                         | j                  |j                        r| j                  |       | j                  j                  |j                         || _         |j                  D ]  }| j                  |        | j                  j                          d| _         yy)z)Handles FunctionDef node and set context.N)r   r   r   r   r  r   r   r   r   r   r  r   r  r  s      r   visit_FunctionDefz'VariableCommentPicker.visit_FunctionDef  s      (NN499%}}T001$$TYY/ 3 34''-LL		*$(D! "

5!"LL$(D! )r   c                &    | j                  |       y)z.Handles AsyncFunctionDef node and set context.N)r  r   s     r   visit_AsyncFunctionDefz,VariableCommentPicker.visit_AsyncFunctionDef  s    t$r   )rx   r   r   r)   rD   rE   )r   r)   rD   zlist[str] | None)r   r)   rD   rE   )r   ast.FunctionDefrD   rE   )r   r)   r   r)   rD   rE   )r   r)   r   ast.ASTrD   rE   )r   list[ast.expr]rD   rm   )rD   ast.arg | Noner   )r   r  rD   rE   )r   z
ast.ImportrD   rE   )r   zast.ImportFromrD   rE   )r   z
ast.AssignrD   rE   )r   zast.AnnAssignrD   rE   )r   zast.ExprrD   rE   )r   zast.TryrD   rE   )r   zast.ClassDefrD   rE   )r   r  rD   rE   )r   zast.AsyncFunctionDefrD   rE   )r-   rn   ro   rF   rU   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r
  r  r  r  r   r   s   @r   r   r      st    A$	)D
3
76I  (

@@1$f $ #)%r   r   c                  D     e Zd ZdZd fdZddZd	dZd
dZd	dZ xZ	S )DefinitionFinderzXPython source code parser to detect location of functions,
    classes and methods.
    c                \    t         |   |       d | _        g | _        g | _        i | _        y r?   )r   rU   r   r   indentsdefinitionsr   s     r   rU   zDefinitionFinder.__init__  s-    '+"$AC<>r   c                v    | j                   r| j                   d   d   dk(  r	|d   dk(  ry|| j                  |<   y)zAdd a location of definition.r   r   defN)r  r  )r8   r   entrys      r   add_definitionzDefinitionFinder.add_definition  s<    <<DLL,Q/58U1X=N%*DT"r   c                   	 | j                         }|y|t        k(  rn|t        dgk(  rN| j                  .| j                  j	                  t
        t        t        t              r| j                  || _	        n|j	                  t        dg      r| j                  d       ng|j	                  t        dg      r| j                  d       n>|t        k(  r| j                  j                  d       n|t        k(  r| j                          )z1Parse the code to obtain location of definitions.N@classr  )r[   NN)r   r   r
   r|   rd   r   r   r   r   r   r   parse_definitionr  r   finalize_block)r8   tokens     r   r   zDefinitionFinder.parse  s    $$&E}2s)#)>)-)<)<Wb&RX)Y>>)%*DNdG_-%%g.dE]+%%e,&##$9:&##%# r   c                z   | j                         }| j                  j                  |j                         dj	                  | j                        }| j
                  r!| j
                  j                  d   }d| _        n|j                  d   }| j                  t        dg       | j                         j                  t        t              r4| j                  t               | j                  j                  |||f       y| j                  ||||j                  d   f       | j                  j!                          y)zParse AST of definition.r   r   N:)r   r   r   r5   r   r   rR   r   r
   rd   r   r   r   r  r!  rS   r  )r8   typr   funcname	start_poss        r   r%  z!DefinitionFinder.parse_definition  s    !DJJ'88DLL)>>,,Q/I!DN

1I"c###GW5V$LLh	 :; !$i! =?LLr   c                   | j                   j                         }|d   dk7  r|\  }}}| j                  j                  d   dz
  }t        j                  | j                  |            r*|dz  }t        j                  | j                  |            r*| j                  ||||f       | j                  j                          yy)zFinalize definition block.r   r[   r   N)	r  r  r{   rS   emptyline_rerd   r   r!  r   )r8   
definitionr*  r+  r,  end_poss         r   r&  zDefinitionFinder.finalize_block  s    \\%%'
a=G#'1$C9ll&&q)A-G$$T]]7%;<1 $$T]]7%;< 3	7*CDLL $r   r   )r   r)   r   ztuple[str, int, int]rD   rE   rC   )r*  r)   rD   rE   )
r-   rn   ro   rF   rU   r!  r   r%  r&  r   r   s   @r   r  r    s!    ?+&*,
r   r  c                  2    e Zd ZdZdddZd	dZd	dZd	dZy)
ParserzyPython source code parser to pick up variable comments.

    This is a better wrapper for ``VariableCommentPicker``.
    c                    t        |      | _        || _        i | _        i | _        i | _        i | _        g | _        i | _        y r?   )	r   r   r   r   r   r   r  r   r   )r8   r   r   s      r   rU   zParser.__init__#  sA    %d+	 7946)+<>!#57r   c                D    | j                          | j                          y)zParse the source code.N)parse_commentsr%  rj   s    r   r   zParser.parse-  s    r   c                p   t        j                  | j                  d      }t        | j                  j	                  d      | j
                        }|j                  |       |j                  | _        |j                  | _        |j                  | _	        |j                  | _
        |j                  | _        y)z$Parse the code and pick up comments.T)type_commentsN)r   r   r   r   
splitlinesr   r   r   r   r   r   r   )r8   treepickers      r   r5  zParser.parse_comments2  s    yy$7&tyy';';D'A4==QT!--))mm))r   c                    t        | j                  j                  d            }|j                          |j                  | _        y)z0Parse the location of definitions from the code.TN)r  r   r8  r   r  )r8   r   s     r   r%  zParser.parse_definition=  s2    !$))"6"6t"<=!--r   N)r  )r   r)   r   r)   rD   rE   rC   )r-   rn   ro   rF   rU   r   r5  r%  r@   r   r   r2  r2    s    
8 
	*.r   r2  )r   r)   rD   r)   )r   r  rD   r  r?   )r   r  r8   r  rD   r   )rK   r)   rD   r)   )(rF   
__future__r   r   r1   rG   r   rerg   r   r'  r   r   r   r   r	   r
   r   r   r   r   r   sphinx.pycode.astr   r   compiler   r   r.  r   r   r4   rM   rO   rq   r   NodeVisitorr   r  r2  r@   r   r   <module>rA     s    2 " 
    	   C C C    4RZZ./
BJJx 	rzz.)#)IX] ]<* *Z-% -%`v%COO v%rI~ IX$. $.r   