B
    Khh/                 @   s  U d Z ddlZddlmZmZ ddlmZmZmZm	Z	m
Z
mZmZmZ ejdk r^ddlmZ nddlmZ ddlmZmZ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m Z  eee f Z!e"Z#e"Z$e"Z%e"Z&d
Z'ee(d< dZ)ee(d< dZ*ee(d< dZ+ee(d< dZ,ee(d< dZ-ee(d< ej.dej/dej0dej1dej2dej3dej4dej5dej6dej7dej8dej9dej:dej;diZ<ee(d< dZ=ee(d < G d!d" d"e>Z?eG d#d$ d$Z@d0ee	e e&d%d&d'ZAd1ee	e e&d%d(d)ZBe!e&d*d+d,ZCe
e ee$ d-d.d/ZDdS )2z,Builds on top of nodes.py to track brackets.    N)	dataclassfield)DictIterableListOptionalSequenceSetTupleUnion)      )Final)
BRACKETCLOSING_BRACKETSCOMPARATORSLOGIC_OPERATORSMATH_OPERATORSOPENING_BRACKETSUNPACKING_PARENTSVARARGS_PARENTS	is_varargsyms)token)LeafNode   COMPREHENSION_PRIORITY   COMMA_PRIORITY   TERNARY_PRIORITY   LOGIC_PRIORITY   STRING_PRIORITY
   COMPARATOR_PRIORITY	   r               r      MATH_PRIORITIES   DOT_PRIORITYc               @   s   e Zd ZdZdS )BracketMatchErrorzLRaised when an opening bracket is unable to be matched to a closing bracket.N)__name__
__module____qualname____doc__ r6   r6   1/tmp/pip-install-vv81h98y/black/black/brackets.pyr1   <   s   r1   c               @   sD  e Zd ZU dZdZeed< eedZ	e
eeef ef ed< eedZe
eef ed< dZee ed< eedZee ed	< eedZee ed
< eedZee ed< eddddZedddZd#ee edddZd$eedddZeedddZeedddZ eedddZ!eeddd Z"ee dd!d"Z#dS )%BracketTrackerz"Keeps track of brackets on a line.r   depth)default_factorybracket_match
delimitersNprevious_for_loop_depths_lambda_argument_depths	invisible)leafreturnc          
   C   s  |j tjkrdS | jdkr:|j tkr:| j|j f| jkr:dS | | | | |j tkr|  jd8  _y| j| j|j f}W n2 t	k
r } zt
d| |W dd}~X Y nX ||_|js| j| | j|_| jdkr.t|| j}|r| jdk	r|| jt| j< n t|| j}|r.|| jt|< |j tkrr|| j| jt|j  f< |  jd7  _|jsr| j| || _| | | | dS )a  Mark `leaf` with bracket-related metadata. Keep track of delimiters.

        All leaves receive an int `bracket_depth` field that stores how deep
        within brackets a given leaf is. 0 means there are no enclosing brackets
        that started on this line.

        If a leaf is itself a closing bracket and there is a matching opening
        bracket earlier, it receives an `opening_bracket` field with which it forms a
        pair. This is a one-directional link to avoid reference cycles. Closing
        bracket without opening happens on lines continued from previous
        breaks, e.g. `) -> "ReturnType":` as part of a funcdef where we place
        the return type annotation on its own line of the previous closing RPAR.

        If a leaf is a delimiter (a token on which Black can split the line if
        needed) and it's on depth 0, its `id()` is stored in the tracker's
        `delimiters` field.
        Nr   r/   zDUnable to match a closing bracket to the following opening bracket: )typer   COMMENTr9   r   r;   'maybe_decrement_after_for_loop_variable&maybe_decrement_after_lambda_argumentspopKeyErrorr1   opening_bracketvaluer@   appendZbracket_depthis_split_before_delimiterr=   r<   idis_split_after_delimiterr   r    maybe_increment_lambda_arguments!maybe_increment_for_loop_variable)selfrA   rI   edelimr6   r6   r7   markL   sF    






zBracketTracker.mark)rB   c             C   s
   t | jS )zBReturn True if there is an yet unmatched open bracket on the line.)boolr;   )rQ   r6   r6   r7   any_open_brackets   s    z BracketTracker.any_open_bracketsr6   )excluderB   c                s   t  fdd| j D S )zReturn the highest priority of a delimiter found on the line.

        Values are consistent with what `is_split_*_delimiter()` return.
        Raises ValueError on no delimiters.
        c             3   s   | ]\}}| kr|V  qd S )Nr6   ).0kv)rW   r6   r7   	<genexpr>   s    z8BracketTracker.max_delimiter_priority.<locals>.<genexpr>)maxr<   items)rQ   rW   r6   )rW   r7   max_delimiter_priority   s    z%BracketTracker.max_delimiter_priority)priorityrB   c                s2   | j s
dS  p|   t fdd| j  D S )zReturn the number of delimiters with the given `priority`.

        If no `priority` is passed, defaults to max priority on the line.
        r   c             3   s   | ]}| krd V  qdS )r/   Nr6   )rX   p)r_   r6   r7   r[      s    z?BracketTracker.delimiter_count_with_priority.<locals>.<genexpr>)r<   r^   sumvalues)rQ   r_   r6   )r_   r7   delimiter_count_with_priority   s    z,BracketTracker.delimiter_count_with_priorityc             C   s:   |j tjkr6|jdkr6|  jd7  _| j| j dS dS )zIn a for loop, or comprehension, the variables are often unpacks.

        To avoid splitting on the comma in this situation, increase the depth of
        tokens between `for` and `in`.
        forr/   TF)rC   r   NAMErJ   r9   r>   rK   )rQ   rA   r6   r6   r7   rP      s
    z0BracketTracker.maybe_increment_for_loop_variablec             C   sL   | j rH| j d | jkrH|jtjkrH|jdkrH|  jd8  _| j   dS dS )z>See `maybe_increment_for_loop_variable` above for explanation.inr/   TF)r>   r9   rC   r   re   rJ   rG   )rQ   rA   r6   r6   r7   rE      s    

z6BracketTracker.maybe_decrement_after_for_loop_variablec             C   s:   |j tjkr6|jdkr6|  jd7  _| j| j dS dS )zIn a lambda expression, there might be more than one argument.

        To avoid splitting on the comma in this situation, increase the depth of
        tokens between `lambda` and `:`.
        lambdar/   TF)rC   r   re   rJ   r9   r?   rK   )rQ   rA   r6   r6   r7   rO      s
    z/BracketTracker.maybe_increment_lambda_argumentsc             C   sB   | j r>| j d | jkr>|jtjkr>|  jd8  _| j   dS dS )z=See `maybe_increment_lambda_arguments` above for explanation.rf   r/   TF)r?   r9   rC   r   COLONrG   )rQ   rA   r6   r6   r7   rF      s    
z5BracketTracker.maybe_decrement_after_lambda_argumentsc             C   s   | j | jd tjfS )z7Return the most recent opening square bracket (if any).r/   )r;   getr9   r   RSQB)rQ   r6   r6   r7   get_open_lsqb   s    zBracketTracker.get_open_lsqb)r6   )r   )$r2   r3   r4   r5   r9   int__annotations__r   dictr;   r   r
   DepthNodeTyper   r<   LeafIDPriorityr=   r   listr>   r   r?   r@   rT   rU   rV   r   r^   rc   rP   rE   rO   rF   rl   r6   r6   r6   r7   r8   @   s"   
"<r8   )rA   r=   rB   c             C   s   | j tjkrtS dS )zReturn the priority of the `leaf` delimiter, given a line break after it.

    The delimiter priorities returned here are from those delimiters that would
    cause a line break after themselves.

    Higher numbers are higher priority.
    r   )rC   r   COMMAr   )rA   r=   r6   r6   r7   rN      s    rN   c             C   s8  t | ttB drdS | jtjkrP| jrP| jjtjtj	hkrP|dksL|jt
krPtS | jtkr~| jr~| jjtjtjhkr~t| j S | jtkrtS | jtjkr|dk	r|jtjkrtS | jtjtjhkrdS | jdkr| jr| jjtjtjhks| jtjkrt| jtr| jjdkrtS | jdkrF| jrF| jjtjtjhkrFtS | jdkrn| jrn| jjtjkrnt S | jdkr~tS | jd	kr| jr| jjtj!tj"hkr|dk	r|jtjkr|jd
kstS | jd
kr| jr| jjtj!kr|dk	r|jtjkr|jdkstS | jt#kr4| jr4t$S dS )zReturn the priority of the `leaf` delimiter, given a line break before it.

    The delimiter priorities returned here are from those delimiters that would
    cause a line break before themselves.

    Higher numbers are higher priority.
    )Zwithinr   Nrd   asyncif>   rw   elseisrg   not)%r   r   r   rC   r   DOTparentr   Zimport_fromZdotted_namer   r0   r   ZfactorZ	star_exprr.   r   r'   STRINGr%   re   ZASYNCrJ   Zcomp_forZold_comp_for
isinstanceZprev_siblingr   r   Zcomp_ifZold_comp_iftestr!   Zcomp_opZ
comparisonr   r#   )rA   r=   r6   r6   r7   rL      sf    



$

rL   )noderB   c             C   s   | j tjkrdS | jd }| jd }|j tjkr<|j tjks@dS t }xH| jdd D ]6}t|t	rp|
| qVx| D ]}|
| qzW qVW y| S  tk
r   dS X dS )zReturn maximum delimiter priority inside `node`.

    This is specific to atoms with contents contained in a pair of parentheses.
    If `node` isn't an atom or there are no enclosing parentheses, returns 0.
    r   rf   r/   N)rC   r   Zatomchildrenr   LPARRPARr8   r~   r   rT   leavesr^   
ValueError)r   firstlastZbtcrA   r6   r6   r7   max_delimiter_priority_in_atomG  s     


r   )r   rB   c       	      C   s   yt dd t| D }W n tk
r0   t S X g }t }xt|t| D ]}| | }|jtkrv|t	|j |f |jt
krL|r|j|d d kr| \}}x,t||d D ]}|t| |  qW qLP qLW |S )zReturn leaves that are inside matching brackets.

    The input `leaves` can have non-matching brackets at the head or tail parts.
    Matching brackets are included.
    c             s   s    | ]\}}|j tkr|V  qd S )N)rC   r   )rX   ilr6   r6   r7   r[   l  s    z6get_leaves_inside_matching_brackets.<locals>.<genexpr>rf   r   r/   )next	enumerateStopIterationsetrangelenrC   r   rK   r   r   rG   addrM   )	r   start_indexZbracket_stackidsr   rA   _startjr6   r6   r7   #get_leaves_inside_matching_bracketsc  s$    

r   )N)N)Er5   sysZdataclassesr   r   typingr   r   r   r   r   r	   r
   r   version_infoZtyping_extensionsr   Zblack.nodesr   r   r   r   r   r   r   r   r   r   Zblib2to3.pgen2r   Zblib2to3.pytreer   r   LNrm   rp   rr   rq   rs   r   rn   r   r!   r#   r%   r'   VBAR
CIRCUMFLEXAMPER	LEFTSHIFT
RIGHTSHIFTPLUSMINUSSTARSLASHDOUBLESLASHPERCENTATTILDE
DOUBLESTARr.   r0   	Exceptionr1   r8   rN   rL   r   r   r6   r6   r6   r7   <module>   sT   (
0 `