3

T'ícã
@s,dZddlZddlmZmZddlmZddlmZddl	m
Z
mZmZm
Z
ddlmZddlmZdd	lmZe
r€dd
lmZyddlZdZWnek
r¨dZYnXd
Zeee
edœdd„Zeeee
edœdd„Zeeedœdd„Zeeedœdd„Z Gdd„deƒZ!deeefdœdd„Z"dS) zHImplements the low-level algorithms Sphinx uses for versioning doctrees.éN)ÚproductÚzip_longest)Ú
itemgetter)Úpath)Ú
TYPE_CHECKINGÚAnyÚDictÚIterator)Úuuid4)ÚNode)ÚSphinxTransform)ÚSphinxTFéA)ÚdoctreeÚ	conditionÚreturnccs(x"|j|ƒD]}tƒj|_|VqWdS)aAdd a unique id to every node in the `doctree` which matches the
    condition and yield the nodes.

    :param doctree:
        A :class:`docutils.nodes.document` instance.

    :param condition:
        A callable which returns either ``True`` or ``False`` for a given node.
    N)Úfindallr
ÚhexÚuid)rrÚnode©rú3/tmp/pip-build-gk9425m9/sphinx/sphinx/versioning.pyÚadd_uidss

r)ÚoldÚnewrrccsÂ|j|ƒ}|j|ƒ}g}g}i}tƒ}xžt||ƒD]\}	}
|	dkrN|j|
ƒq2t|	ddƒsdtƒj|	_|
dkrx|j|	ƒq2t|	j	|
j	ƒ}|dkr¢|	j|
_|j
|
ƒq2|||	|
f<|j|	ƒ|j|
ƒq2Wxdt||ƒD]V\}	}
|
|ksÒ|	|
f|krðqÒt|	j	|
j	ƒ}|dkr|	j|
_|j
|
ƒqÒ|||	|
f<qÒWt|j
ƒtdƒd}xT|D]L\\}	}
}|
|krbqFn
|j
|
ƒ|tkr€|	j|
_ntƒj|
_|
VqFWx&t|ƒ|D]}
tƒj|
_|
Vq¤WdS)a1Merge the `old` doctree with the `new` one while looking at nodes
    matching the `condition`.

    Each node which replaces another one or has been added to the `new` doctree
    will be yielded.

    :param condition:
        A callable which returns either ``True`` or ``False`` for a given node.
    Nrré)Úkey)rÚsetrÚappendÚgetattrr
rrÚ	get_ratioZ	rawsourceÚaddrÚsortedÚitemsrÚVERSIONING_RATIO)rrrZold_iterZnew_iterZ	old_nodesZ	new_nodesZratiosÚseenÚold_nodeÚnew_nodeZratiorrrÚmerge_doctrees)sT













r()rrrcCsFt||gƒstStr,tj||ƒt|ƒdSt||ƒt|ƒdSdS)zšReturn a "similarity ratio" (in percent) representing the similarity
    between the two strings where 0 is equal and anything above less than equal.
    gY@N)Úallr$Ú
IS_SPEEDUPÚLevenshteinZdistanceÚlenÚlevenshtein_distance)rrrrrr ls
r )ÚaÚbrcCsÆ||krdSt|ƒt|ƒkr&||}}|s2t|ƒSttt|ƒdƒƒ}xvt|ƒD]j\}}|dg}xRt|ƒD]F\}}||dd}||d}	||||k}
|jt||	|
ƒƒqlW|}qPW|dS)zEReturn the Levenshtein edit distance between two strings *a* and *b*.rréÿÿÿÿ)r,ÚlistÚrangeÚ	enumeraterÚmin)r.r/Zprevious_rowÚiZcolumn1Zcurrent_rowÚjZcolumn2Z
insertionsZ	deletionsZ
substitutionsrrrr-ys 

r-c@s$eZdZdZdZeddœdd„ZdS)ÚUIDTransformz#Add UIDs to doctree for versioning.ipN)ÚkwargsrcKs¤|j}d}|jsdS|jrhy8tj|j|jdƒ}t|dƒ}tj	|ƒ}WdQRXWnt
k
rfYnX|jsx|dkrŒtt|j
|jƒƒntt||j
|jƒƒdS)Nz.doctreeÚrb)ÚenvZversioning_conditionZversioning_comparerÚjoinZ
doctreedirZdocnameÚopenÚpickleÚloadÚOSErrorr1rÚdocumentr()Úselfr8r:Zold_doctreeÚfilenameÚfrrrÚapply‘szUIDTransform.apply)Ú__name__Ú
__module__Ú__qualname__Ú__doc__Zdefault_priorityrrDrrrrr7sr7r
)ÚapprcCs|jtƒddddœS)NÚbuiltinT)ÚversionZparallel_read_safeZparallel_write_safe)Z
add_transformr7)rIrrrÚsetup§s
rL)#rHr=Ú	itertoolsrrÚoperatorrÚosrÚtypingrrrr	Úuuidr
Zdocutils.nodesrZsphinx.transformsrZsphinx.applicationr
r+r*ÚImportErrorr$rr(ÚstrÚfloatr Úintr-r7rLrrrrÚ<module>s,
C