3

T'ícªRã@szdZddlZddlZddlZddlZddlmZddlmZddlm	Z	m
Z
mZmZm
Z
mZmZddlmZmZddlmZmZmZmZmZddlmZdd	lmZmZejd
ƒZejdƒZejdƒZe e d
œdd„Z!ej"eej#dœdd„Z$d%ej"ej%ee dœdd„Z&e e dœdd„Z'Gdd„dƒZ(Gdd„dƒZ)Gdd„de)ƒZ*Gdd „d ej+ƒZ,Gd!d"„d"e)ƒZ-Gd#d$„d$ƒZ.dS)&z,Utilities parsing and analyzing Python code.éN)ÚOrderedDict)Ú	Signature)ÚDEDENTÚINDENTÚNAMEÚNEWLINEÚNUMBERÚOPÚSTRING)ÚCOMMENTÚNL)ÚAnyÚDictÚListÚOptionalÚTuple)Úast)ÚparseÚunparsez^\s*#: ?(.*)
?
?$z^\s*$z^\s*(#.*)?$)ÚcodeÚreturncCs|jddƒS)Núú )Úreplace)r©rú6/tmp/pip-build-gk9425m9/sphinx/sphinx/pycode/parser.pyÚfilter_whitespacesr)ÚnodercCst|tjƒr|jS|jgSdS)z3Get list of targets from Assign and AnnAssign node.N)Ú
isinstancerÚAssignÚtargetsÚtarget)rrrrÚget_assign_targetssr")rÚselfrcCs&|r
|j}|jj}|dkr*td|ƒ‚nø|dkrZ|dksD|j|krL|jgStd	|ƒ‚nÈ|dkr¤g}x8|jD].}y|jt||ƒƒWqntk
ršYqnXqnW|S|dkrð|jjjdkrâ|râ|jj|krâd
t|j	|ƒdgStd	|ƒ‚n2|dkr|gS|dkrt|j|ƒSt
d|ƒ‚dS)zÆConvert assignment-AST to variable names.

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

        ary[0] = 'foo'
        dic["bar"] = 'baz'
        # => TypeError
    ÚIndexÚNumÚSliceÚStrÚ	Subscriptz%r does not create new variableÚNameNz*The assignment %r is not instance variablerrÚ	Attributez%srÚstrÚStarredzUnexpected node name %r)r$r%r&r'r()rr)ÚargÚ	__class__Ú__name__Ú	TypeErrorÚidÚeltsÚextendÚget_lvar_namesÚvalueÚattrÚNotImplementedError)rr#Zself_idZ	node_nameÚmembersÚeltrrrr4 s4	



r4)ÚsrcCs:ddœdd„}||_tj|ƒ}|r2|jdƒjdƒSdSdS)z1Remove common leading indentation from docstring.N)rcSsdS)NrrrrrÚdummyLszdedent_docstring.<locals>.dummyz
Ú)Ú__doc__ÚinspectÚgetdocÚlstripÚrstrip)r:r;Ú	docstringrrrÚdedent_docstringJs
rCc@sfeZdZdZeeeeefeeefeddœdd„Zee	dœdd„Z
ee	d	œd
d„Zedœd
d„ZdS)ÚTokenz)Better token wrapper for tokenize module.N)Úkindr5ÚstartÚendÚsourcercCs"||_||_||_||_||_dS)N)rEr5rFrGrH)r#rEr5rFrGrHrrrÚ__init__[s
zToken.__init__)ÚotherrcCsft|tƒr|j|kSt|tƒr(|j|kSt|ttfƒrJ|j|jgt|ƒkS|dkrVdStd|ƒ‚dS)NFzUnknown value: %r)rÚintrEr+r5ÚlistÚtupleÚ
ValueError)r#rJrrrÚ__eq__cs



zToken.__eq__)Ú
conditionsrcst‡fdd„|DƒƒS)Nc3s|]}ˆ|kVqdS)Nr)Ú.0Ú	candidate)r#rrú	<genexpr>pszToken.match.<locals>.<genexpr>)Úany)r#rPr)r#rÚmatchoszToken.match)rcCsdtj|j|jjƒfS)Nz<Token kind=%r value=%r>)ÚtokenizeÚtok_namerEr5Ústrip)r#rrrÚ__repr__rszToken.__repr__)
r/Ú
__module__Ú__qualname__r=rKr
rr+rIÚboolrOrUrYrrrrrDXsrDc@sReZdZeeddœdd„Zeedœdd„Zedœd	d
„Z	e
eedœdd
„ZdS)ÚTokenProcessorN)Úbuffersrcs2t|ƒ‰||_tj‡fdd„ƒ|_d|_d|_dS)NcstˆƒS)N)Únextr)ÚlinesrrÚ<lambda>{sz)TokenProcessor.__init__.<locals>.<lambda>)Úiterr^rVÚgenerate_tokensÚtokensÚcurrentÚprevious)r#r^r)r`rrIxs
zTokenProcessor.__init__)ÚlinenorcCs|j|dS)zReturns specified line.é)r^)r#rgrrrÚget_lineszTokenProcessor.get_line)rcCs>y|j|_tt|jƒŽ|_Wntk
r6d|_YnX|jS)z_Fetch the next token from source code.

        Returns ``None`` if sequence finished.
        N)rerfrDr_rdÚ
StopIteration)r#rrrÚfetch_tokenƒszTokenProcessor.fetch_token)Ú	conditionrcCs”g}xŠ|jƒrŽ|j|jƒ|j|kr(Pq|jtdgkrJ||jtdgƒ7}q|jtdgkrl||jtdgƒ7}q|jtdgkr||jtdgƒ7}qW|S)zlFetch tokens until specified token appeared.

        .. note:: This also handles parenthesis well.
        ú(ú)Ú{Ú}ú[ú])rkÚappendrer	Úfetch_until)r#rlrdrrrrts

zTokenProcessor.fetch_until)r/rZr[rr+rIrKrirDrkr
rtrrrrr]ws
r]csLeZdZdZeeddœ‡fdd„Zeedœdd„Zddœd	d
„Z	‡Z
S)ÚAfterCommentParserzÈPython 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.
    N)r`rcstƒj|ƒd|_dS)N)ÚsuperrIÚcomment)r#r`)r.rrrI«szAfterCommentParser.__init__)rcCsÊg}xÀ|jƒrÄ|j|jƒ|jtdgkr<||jtdgƒ7}q|jtdgkr^||jtdgƒ7}q|jtdgkr€||jtdgƒ7}q|jtkrš||jtƒ7}q|jtdgkr¬Pq|jjttt	t
fkrPqW|S)z%Fetch right-hand value of assignment.rmrnrorprqrrú;)rkrsrer	rtrrrErrr
)r#rdrrrÚfetch_rvalue¯s 

zAfterCommentParser.fetch_rvaluecCsTx$|jƒjtdgttƒs$|jst‚qW|jtdgkr<|jƒ|jtkrP|jj|_	dS)z3Parse the code and obtain comment after assignment.ú=N)
rkrUr	rrreÚAssertionErrorryr5rw)r#rrrrÃs
zAfterCommentParser.parse)r/rZr[r=rr+rIrDryrÚ
__classcell__rr)r.rru¤srucs¦eZdZdZeeeddœ‡fdd„Zeeeedœdd„Zeddœd	d
„Z	eddœdd„Z
ejdd
œdd„Z
eeddœdd„Zeejddœdd„Zeejedœdd„Zeejedœdd„Zeejdœdd„Zeedœdd „Zejdd!œ‡fd"d#„Zejdd!œd$d%„Zejdd!œd&d'„Zejdd!œd(d)„Zej dd!œd*d+„Z!ej"dd!œd,d-„Z#ej$dd!œd.d/„Z%ej&dd!œd0d1„Z'ejdd!œd2d3„Z(ej)dd!œd4d5„Z*‡Z+S)6ÚVariableCommentPickerz7Python source code parser to pick up variable comments.N)r^Úencodingrcsntjƒ|_||_||_g|_g|_d|_tƒ|_	i|_
d|_i|_g|_
i|_d|_d|_d|_tƒjƒdS)N)Ú	itertoolsÚcountÚcounterr^r~ÚcontextÚcurrent_classesÚcurrent_functionrÚcommentsÚannotationsrfÚ	defordersÚfinalsÚ	overloadsÚtypingÚtyping_finalÚtyping_overloadrvrI)r#r^r~)r.rrrIÔs 
zVariableCommentPicker.__init__)ÚnamercCsD|jr4|jr.|jddkr.|jdd…|gSdSn|j|gSdS)z;Get qualified name for given object as a list of string(s).rhrINéÿÿÿÿrŽ)r„rƒr‚)r#rrrrÚget_qualname_foræs
z&VariableCommentPicker.get_qualname_forcCs(|j|ƒ}|r$t|jƒ|jdj|ƒ<dS)NÚ.)rr_rr‡Újoin)r#rÚqualnamerrrÚ	add_entryñs
zVariableCommentPicker.add_entrycCs$|j|ƒ}|r |jjdj|ƒƒdS)Nr)rrˆrsr‘)r#rr’rrrÚadd_final_entryös
z%VariableCommentPicker.add_final_entry)ÚfuncrcCsBddlm}|j|jƒ}|r>|jjdj|ƒgƒ}|j||ƒƒdS)Nr)Úsignature_from_astr)Zsphinx.util.inspectr–rrr‰Ú
setdefaultr‘rs)r#r•r–r’r‰rrrÚadd_overload_entryûs
z(VariableCommentPicker.add_overload_entry)rrwrcCs2|j|ƒ}|r.dj|dd…ƒ}||j||f<dS)NrrhrŽ)rr‘r…)r#rrwr’ÚbasenamerrrÚadd_variable_comments
z*VariableCommentPicker.add_variable_comment)rÚ
annotationrcCs6|j|ƒ}|r2dj|dd…ƒ}t|ƒ|j||f<dS)NrrhrŽ)rr‘rr†)r#rr›r’r™rrrÚadd_variable_annotation	s
z-VariableCommentPicker.add_variable_annotation)Ú
decoratorsrcCshg}|jr|jd|jƒ|jr,|j|jƒx6|D].}yt|ƒ|krHdSWq2tk
r^Yq2Xq2WdS)Nz%s.finalTF)rŠrsr‹rr7)r#rÚfinalÚ	decoratorrrrÚis_finals

zVariableCommentPicker.is_finalcCshg}|jr|jd|jƒ|jr,|j|jƒx6|D].}yt|ƒ|krHdSWq2tk
r^Yq2Xq2WdS)Nz%s.overloadTF)rŠrsrŒrr7)r#rÚoverloadrŸrrrÚis_overloads

z!VariableCommentPicker.is_overload)rcCsJ|jr|jjjr|jjjdS|jrBt|jjddƒrB|jjjdSdSdS)z8Returns the name of the first argument if in a function.rÚposonlyargsN)r„ÚargsÚgetattrr£)r#rrrÚget_self/szVariableCommentPicker.get_self)rgrcCs|j|dS)zReturns specified line.rh)r^)r#rgrrrri:szVariableCommentPicker.get_line)rrcstƒj|ƒ||_dS)z(Updates self.previous to the given node.N)rvÚvisitrf)r#r)r.rrr§>szVariableCommentPicker.visitcCsrxl|jD]b}|j|jp|jƒ|jdkr8|jp2|j|_q|jdkrR|jpL|j|_q|jdkr|jpf|j|_qWdS)z8Handles Import node and record the order of definitions.rŠztyping.finalztyping.overloadN)Únamesr“ÚasnamerrŠr‹rŒ)r#rrrrrÚvisit_ImportCs


z"VariableCommentPicker.visit_ImportcCslxf|jD]\}|j|jp|jƒ|jdkrB|jdkrB|jp<|j|_q|jdkr|jdkr|jp`|j|_qWdS)z8Handles Import node and record the order of definitions.rŠržr¡N)r¨r“r©rÚmoduler‹rŒ)r#rrrrrÚvisit_ImportFromOsz&VariableCommentPicker.visit_ImportFromcsÜy0t|ƒ}t‡fdd„|Dƒgƒ}ˆj|jƒ}Wntk
rDdSXt|dƒrt|jrtxH|D]}ˆj||jƒq\Wn,t|dƒr |jr x|D]}ˆj||jƒqŠWt	||j
d…gˆj|jd…ƒ}|jƒ|j
oÜtj|j
ƒrx,|D]$}ˆj|tjd|j
ƒƒˆj|ƒqæWdStj|d|j
…ƒr¾g}xNt|jdƒD]<}ˆj|jd|ƒ}	tj|	ƒrt|jtjd|	ƒƒnPq<W|r¾tdjt|ƒƒƒ}
x$|D]}ˆj||
ƒˆj|ƒqšWdSx|D]}ˆj|ƒqÄWdS)	z3Handles Assign node and pick up a variable comment.csg|]}t|ˆjƒd‘qS))r#)r4r¦)rQÚt)r#rrú
<listcomp>]sz6VariableCommentPicker.visit_Assign.<locals>.<listcomp>Nr›Útype_commentz\1rhÚ
)r"Úsumrirgr0Úhasattrr›rœr¯ruÚ
col_offsetr^rrwÚ
comment_rerUršÚsubr“Ú	indent_reÚrangersrCr‘Úreversed)r#rr ÚvarnamesÚcurrent_lineÚvarnameÚparserZ
comment_linesÚiZbefore_linerwr)r#rÚvisit_AssignYsF




z"VariableCommentPicker.visit_AssigncCs|j|ƒdS)z6Handles AnnAssign node and pick up a variable comment.N)r¾)r#rrrrÚvisit_AnnAssign‰sz%VariableCommentPicker.visit_AnnAssigncCs°t|jtjtjfƒr¬t|jtjƒr¬ytt|jƒ}t|d|j	ƒƒ}xR|D]J}t|jj
tƒrb|jj
}n|jj
j|j
prdƒ}|j|t|ƒƒ|j|ƒqFWWntk
rªYnXdS)z2Handles Expr node and pick up a comment if string.rzutf-8N)rrfrrÚ	AnnAssignr5r'r"r4r¦r:r+Údecoder~ršrCr“r0)r#rr r¹r»rBrrrÚ
visit_Exprs


z VariableCommentPicker.visit_ExprcCs8x|jD]}|j|ƒqWx|jD]}|j|ƒq"WdS)z‹Handles Try node and processes body and else-clause.

        .. note:: pycode parser ignores objects definition in except-clause.
        N)Úbodyr§Zorelse)r#rZsubnoderrrÚ	visit_TryŸszVariableCommentPicker.visit_TrycCsx|jj|jƒ|j|jƒ|j|jƒr2|j|jƒ|jj|jƒ||_x|j	D]}|j
|ƒqNW|jjƒ|jjƒdS)z&Handles ClassDef node and set context.N)rƒrsrr“r Údecorator_listr”r‚rfrÃr§Úpop)r#rÚchildrrrÚvisit_ClassDef©s
z$VariableCommentPicker.visit_ClassDefcCs†|jdkr‚|j|jƒ|j|jƒr.|j|jƒ|j|jƒrD|j|ƒ|jj	|jƒ||_x|j
D]}|j|ƒq`W|jjƒd|_dS)z)Handles FunctionDef node and set context.N)
r„r“rr rÅr”r¢r˜r‚rsrÃr§rÆ)r#rrÇrrrÚvisit_FunctionDef¶s


z'VariableCommentPicker.visit_FunctionDefcCs|j|ƒdS)z.Handles AsyncFunctionDef node and set context.N)rÉ)r#rrrrÚvisit_AsyncFunctionDefÅsz,VariableCommentPicker.visit_AsyncFunctionDef),r/rZr[r=rr+rIrrr“r”rÚFunctionDefr˜ršÚASTrœÚexprr\r r¢r-r¦rKrir§ÚImportrªÚ
ImportFromr¬rr¾rÀr¿ÚExprrÂÚTryrÄÚClassDefrÈrÉÚAsyncFunctionDefrÊr|rr)r.rr}Ñs,
0

r}csteZdZdZeeddœ‡fdd„Zeeeeefddœdd„Z	dd	œd
d„Z
eddœd
d„Zdd	œdd„Z‡Z
S)ÚDefinitionFinderzXPython source code parser to detect location of functions,
    classes and methods.
    N)r`rcs(tƒj|ƒd|_g|_g|_i|_dS)N)rvrIrŸr‚ÚindentsÚdefinitions)r#r`)r.rrrIÏs
zDefinitionFinder.__init__)rÚentryrcCs4|jr&|jdddkr&|ddkr&n
||j|<dS)zAdd a location of definition.rhrÚdefNrŽ)rÕrÖ)r#rr×rrrÚadd_definitionÖs$zDefinitionFinder.add_definition)rcCs¼x¶|jƒ}|dkrPq|tkr q|tdgkrZ|jdksH|jjttttƒrZ|j	dkr´||_	q|jt
dgƒrt|jdƒq|jt
dgƒrŽ|jdƒq|tkr¤|jj
dƒq|tkr|jƒqWdS)z1Parse the code to obtain location of definitions.Nú@ÚclassrØrJ)rJNN)rkrr	rfrUrrrrrŸrÚparse_definitionrÕrsÚfinalize_block)r#ÚtokenrrrrÞs$
zDefinitionFinder.parse)ÚtyprcCs¨|jƒ}|jj|jƒdj|jƒ}|jr<|jjd}d|_n
|jd}|jtdgƒ|jƒj	t
tƒr‚|jtƒ|j
j|||fƒn"|j||||jdfƒ|jjƒdS)zParse AST of definition.rrNú:)rkr‚rsr5r‘rŸrFrtr	rUrrrrÕrÙrGrÆ)r#rßrÚfuncnameÚ	start_posrrrrÜós

z!DefinitionFinder.parse_definitioncCsn|jjƒ}|ddkrj|\}}}|jjdd}xtj|j|ƒƒrL|d8}q2W|j||||fƒ|jjƒdS)zFinalize definition block.rrJrhN)	rÕrÆrerGÚemptyline_rerUrirÙr‚)r#Z
definitionrßrárâZend_posrrrrÝs

zDefinitionFinder.finalize_block)r/rZr[r=rr+rIrrKrÙrrÜrÝr|rr)r.rrÔÊsrÔc@sNeZdZdZdeeddœdd„Zddœdd	„Zddœd
d„Zddœdd
„ZdS)ÚParserzyPython source code parser to pick up variable comments.

    This is a better wrapper for ``VariableCommentPicker``.
    úutf-8N)rr~rcCs8t|ƒ|_||_i|_i|_i|_i|_g|_i|_dS)N)	rrr~r†r…r‡rÖrˆr‰)r#rr~rrrrIs
zParser.__init__)rcCs|jƒ|jƒdS)zParse the source code.N)Úparse_commentsrÜ)r#rrrr%szParser.parsecCsTt|jƒ}t|jjdƒ|jƒ}|j|ƒ|j|_|j|_|j|_|j	|_	|j
|_
dS)z$Parse the code and pick up comments.TN)rrr}Ú
splitlinesr~r§r†r…r‡rˆr‰)r#ÚtreeZpickerrrrræ*s

zParser.parse_commentscCs$t|jjdƒƒ}|jƒ|j|_dS)z0Parse the location of definitions from the code.TN)rÔrrçrrÖ)r#r¼rrrrÜ5szParser.parse_definition)rå)	r/rZr[r=r+rIrrærÜrrrrräs

rä)N)/r=r>rÚrerVÚcollectionsrrrÞrrrrrr	r
rrrŠr
rrrrZsphinx.pycode.astrrrÚcompiler´r¶rãr+rrÌrÍr"r-r4rCrDr]ruÚNodeVisitorr}rÔrärrrrÚ<module>s2$


*--zK