o
    ^iGf                     @   sN  U d dl Z d dlmZmZ d dlmZ d dlmZ d dlm	Z	m
Z
m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mZmZ d dlmZ d d	lmZmZ eeef Zh d
Z e	e!d< ddhZ"e	e!d< h dZ#e	e!d< eej$ej%h Z&e	e!d< dZ'dZ(dZ)eG dd dZ*dededee fddZ+eddde,de-dede.e* fd d!Z/ded"e0ddfd#d$Z1d%e,dede,fd&d'Z2d(eded)ee3e0e0f  ddfd*d+Z4d,e*dede3e-e-e-f fd-d.Z5d,e*ded/e-d0e-de-f
d1d2Z6ded,e*d3e0dede-f
d4d5Z7d(eded)ee3e0e0f  de-fd6d7Z8d8e.e d,e*d3e0d0e-d)ee3e0e0f  deddfd9d:Z9ded,e*dedee fd;d<Z:d=ede
e fd>d?Z;d@edAede-fdBdCZ<d@edAede.e fdDdEZ=ded,e*dedee fdFdGZ>dHedede-fdIdJZ?dHedede-fdKdLZ@dMe.e de-fdNdOZAe e#B e"B fdPe,dQeBe, de-fdRdSZCdS )T    N)
CollectionIterator)	dataclass)	lru_cache)FinalOptionalUnion)ModePreview)
CLOSING_BRACKETSSTANDALONE_COMMENT	STATEMENT
WHITESPACEcontainer_offirst_leaf_ofis_type_comment_stringmake_simple_prefixpreceding_leafsyms)token)LeafNode>   	# fmt:off
# fmt: off# yapf: disableFMT_OFFz# fmt: skipz
# fmt:skipFMT_SKIP>   # fmt:on	# fmt: on# yapf: enableFMT_ON_COMPOUND_STATEMENTSz !:#'# ;c                   @   sB   e Zd ZU dZeed< eed< eed< eed< eed< eed< dS )	ProtoCommenta  Describes a piece of syntax that is a comment.

    It's not a :class:`blib2to3.pytree.Leaf` so that:

    * it can be cached (`Leaf` objects should not be reused more than once as
      they store their lineno, column, prefix, and parent information);
    * `newlines` and `consumed` fields are kept separate from the `value`. This
      simplifies handling of special marker comments like ``# fmt: off/on``.
    typevaluenewlinesconsumed	form_feedleading_whitespaceN)__name__
__module____qualname____doc__int__annotations__strbool r3   r3   S/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/black/comments.pyr$   '   s   
 
r$   leafmodereturnc                 c   sZ    d}t | j| jtjk|dD ]}|j}t|j|j}t	|j|j
|dV  qt| | dS )a  Clean the prefix of the `leaf` and generate comments from it, if any.

    Comments in lib2to3 are shoved into the whitespace prefix.  This happens
    in `pgen2/driver.py:Driver.parse_tokens()`.  This was a brilliant implementation
    move because it does away with modifying the grammar to include all the
    possible places in which comments can be placed.

    The sad consequence for us though is that comments don't "belong" anywhere.
    This is why this function generates simple parentless Leaf objects for
    comments.  We simply don't know what the correct parent should be.

    No matter though, we can live without this.  We really only need to
    differentiate between inline and standalone comments.  The latter don't
    share the line with any code.

    Inline comments are emitted as regular token.COMMENT leaves.  Standalone
    are emitted with a fake STANDALONE_COMMENT token identifier.
    r   is_endmarkerr6   )prefixN)list_commentsr:   r%   r   	ENDMARKERr(   r   r'   r)   r   r&   normalize_trailing_prefix)r5   r6   total_consumedpcr:   r3   r3   r4   generate_comments;   s   
r@   i   )maxsizer:   r9   c                C   s   g }| rd| vr
|S d}d}d}d}t td| D ]Z\}}	|t|	d 7 }td|	}
|
s0J |
 \}}|sB|d7 }d|	v rBd}|dsQ|d	rP|d7 }q||kr[|s[tj	}nt
}t||d
}|t||||||d d}d}q|S )zNReturn a list of :class:`ProtoComment` objects parsed from the given `prefix`.#r   Fz?
|   z^(\s*)(\S.*|)$T\r6   )r%   r&   r'   r(   r)   r*   )	enumerateresplitlenmatchgroups
startswithendswithr   COMMENTr   make_commentappendr$   )r:   r9   r6   resultr(   nlinesignored_linesr)   index	full_linerK   
whitespacelinecomment_typecommentr3   r3   r4   r;   X   sJ   


r;   r>   c                 C   sL   | j |d }d|vr!|d}d|v o|d}t||| _ dS d| _ dS )zNormalize the prefix that's left over after generating comments.

    Note: don't use backslashes for formatting or you'll lose your voting rights.
    NrE   
rD    )r:   countrN   r   )r5   r>   	remaindernl_countr)   r3   r3   r4   r=      s   

r=   contentc                 C   s   |   } | sdS | drt| r| S | d dkr| dd } | r9| d dkr9td|   |ds9d| dd  } tj|v r^| r^d| vr^td|  |dr^| d	d\}}| d
 |  } | rj| d t	vrjd|  } d|  S )a  Return a consistently formatted comment from the given `content` string.

    All comments (except for "##", "#!", "#:", '#'") should have a single
    space between the hash sign and the content.

    If `content` didn't start with a hash sign, one is provided.

    Comments containing fmt directives are preserved exactly as-is to respect
    user intent (e.g., `#no space # fmt: skip` stays as-is).
    rB   r   rC   N    r"   rF    :z: )
rstriprM   _contains_fmt_directiver   lstripr
   standardize_type_commentsrI   stripCOMMENT_EXCEPTIONS)r`   r6   	type_part
value_partr3   r3   r4   rP      s6   
rP   nodelinesc                 C   s    d}|rt | ||}|sdS dS )zJConvert content between `# fmt: off`/`# fmt: on` into standalone comments.TN)convert_one_fmt_off_pair)rl   r6   rm   	try_againr3   r3   r4   normalize_fmt_off   s   rp   rZ   c                 C   s@   t | jt}t | jt}|s|sdS |r|jtv rdS d||fS )zsCheck if comment should be processed for fmt handling.

    Returns (should_process, is_fmt_off, is_fmt_skip).
    )FFFT)re   r&   r   r   r%   r   )rZ   r5   
is_fmt_offis_fmt_skipr3   r3   r4   _should_process_fmt_comment   s   
rs   rq   rr   c                 C   sP   | j tkrdS t|}|sdS |r|j tvr|j tkrdS |r&|j tv r&dS dS )zCheck if comment is a valid standalone fmt directive.

    We only want standalone comments. If there's no previous leaf or if
    the previous leaf is indentation, it's a standalone comment in disguise.
    TF)r%   r   r   r   )rZ   r5   rq   rr   prevr3   r3   r4    _is_valid_standalone_fmt_comment   s   
ru   previous_consumedc              	   C   s  t | jd|d}d}d}t|D ] \}}|du r|jtv r|}|dur0||kr0|jtv r0|} nq|du s9|du r;dS || }|| }	| j}
|j}|	j}|
|| }|jd | }|drd|dd }|
d| d|j  }|
	|jd }d|v r|	dd }||7 }|
|	jd | _| j
}|dusJ dd}t|jD ]\}}|| u r|} nq|dusJ d||tt||dd	 d
S )zvHandle fmt:off/on blocks that contain only comments.

    Returns True if a block was converted, False otherwise.
    Fr8   Nr[   r   z2INTERNAL ERROR: fmt: on/off handling (prefix only)z1INTERNAL ERROR: fmt: on/off handling (leaf index)r:   fmt_pass_converted_first_leafT)r;   r:   rG   r&   r   r    r(   rN   r'   rI   parentchildreninsert_childr   r   )r5   rZ   rv   r6   all_commentsfmt_off_idx
fmt_on_idxidxcfmt_on_commentoriginal_prefix	start_posend_poscontent_between_and_fmt_onhidden_valuestandalone_comment_prefixfmt_off_prefixrz   leaf_idxchildr3   r3   r4   _handle_comment_only_fmt_block   s^   

	r   c           
   	   C   s   |   D ]O}d}t|jd|dD ]B}t||\}}}|s |j}qt||||s+|j}qtt|||}	|	sC|rCt||||rB  dS q|	sFqt	|	|||||   dS qdS )zConvert content of a single `# fmt: off`/`# fmt: on` into a standalone comment.

    Returns True if a pair was converted.
    r   Fr8   T)
leavesr;   r:   rs   r(   ru   listgenerate_ignored_nodesr   _handle_regular_fmt_block)
rl   r6   rm   r5   rv   rZ   should_processrq   rr   ignored_nodesr3   r3   r4   rn   A  sD   
(rn   r   c              	      sl  | d }|j }|j}|jtv r||jd |_|rd|_|}	n|d| d|j  }	ddd | D }
|j|j  |jtv rpd}t|dkret	 fdd|D se|
|jd }d|v re|
dd }|	|7 }	|jd |
 }
|rz|
|j|j 7 }
|
dr|
dd }
d}| D ]}| }|du r|}q|dusJ d	|dusJ d
||tt|
|	t|d dS )z(Handle fmt blocks with actual AST nodes.r   Nr\   r[   c                 s   s    | ]}t |V  qd S N)r1   ).0nr3   r3   r4   	<genexpr>      z,_handle_regular_fmt_block.<locals>.<genexpr>c                 3   s0    | ]}|d     ko|d kn  V  qdS )r   rC   Nr3   )r   rX   comment_linenor3   r4   r     s     
rw   z(INTERNAL ERROR: fmt: on/off handling (1)z(INTERNAL ERROR: fmt: on/off handling (2)rx   )rz   r:   r&   r   r(   r'   joinlinenorJ   anyrI   r*   rN   remover|   r   r   r   )r   rZ   rv   rr   rm   r5   firstrz   r:   r   r   r   	first_idxignoredrU   r3   r   r4   r   u  sT   	


r   c                 c   s:   t |jtrt| ||E dH  dS t| }|dur|jtjkrt||dr(dS t	||drxt
|jD ]C\}}t|trMt||drM|jtv rJ|V   dS |jtjkrj|t|jd k rjt	|j|d  |drj dS t	||drs dS |V  q3n|jtjkr|jdu rdS |V  |j}|dur|jtjks dS dS dS dS )zStarting from the container of `leaf`, generate all leaves until `# fmt: on`.

    If comment is skip, returns leaf only.
    Stops at the end of the block.
    NrF   rC   )re   r&   r   %_generate_ignored_nodes_from_fmt_skipr   r%   r   r<   	is_fmt_onchildren_contains_fmt_onrG   r{   
isinstancer   r   INDENTrJ   DEDENTnext_sibling)r5   rZ   r6   	containerrU   r   r3   r3   r4   r     s@   

	$r   rz   c                 C   sd   | j tjkrdS t| jtsdS | jj tjkr(t| jjtr(| jjj tv r(| jS | jj tv r0| S dS )a  Return the body node of a compound statement if we should respect fmt: skip.

    This handles one-line compound statements like:
        if condition: body  # fmt: skip

    When Black expands such statements, they temporarily look like:
        if condition:
            body  # fmt: skip

    In both cases, we want to return the body node (either the simple_stmt directly
    or the suite containing it).
    N)r%   r   simple_stmtr   rz   r   suiter!   )rz   r3   r3   r4    _find_compound_statement_context  s   r   	body_nodesimple_stmt_parentc                 C   sb   |   D ]*}|jtjkr.| jtjkr(dd | jD }t|dko%|d |u   S | |u   S qdS )zCheck if a compound statement should be kept on one line.

    Returns True only for compound statements with semicolon-separated bodies,
    like: if True: print("a"); print("b")  # fmt: skip
    c                 S   s   g | ]
}|j tjkr|qS r3   )r%   r   r   )r   r   r3   r3   r4   
<listcomp>  s    
z:_should_keep_compound_statement_inline.<locals>.<listcomp>rC   r   F)r   r%   r   SEMIr   r   r{   rJ   )r   r   r5   simple_stmtsr3   r3   r4   &_should_keep_compound_statement_inline  s   	r   c                 C   s   t | |sg S | j}|du s|jtvrg S g }|jD ]$}|| u r# |S t|tr7|jtjtj	fvr6|
| q||  q|S )zJGet header nodes for a compound statement that should be preserved inline.N)r   rz   r%   r!   r{   r   r   r   NEWLINEr   rQ   extendr   )r   r   compound_stmtheader_leavesr   r3   r3   r4   _get_compound_statement_header)  s    



r   c                 c   sh   | j }| j}g }t| jd|d}|r|j|d jkrdS |dur| j|jd | _tj|vrV|g}d|jvrO|j durO|j }|d| d|jvrO|j dus<|E dH  dS |}|g}|j du rh|jdurh|j}d|jvr|j durt	|j 
 }	|	r|	d n|}|jtjtjfv rd|_n|d| |j du r|jdur|j}d|jvr|j dusrtj|v rt|trt|}
|
durt|
|}|r|| }|E dH  dS |dur.|jtjkr0| jtjkr2d| _|j }|dur|jtjkr|d| |j }|dur|jtjks|j}|dur%|j dur%|j jtjkr%|d|j  t|E dH  dS dS dS dS )zLGenerate all leaves that should be ignored by the `# fmt: skip` from `leaf`.Fr8   r   Nr[   rw   r\   )prev_siblingrz   r;   r:   r&   r(   r
   fix_fmt_skip_in_one_linersinsertr   r   r%   r   r   r   r   r   r   r   r   r   ASYNCiter)r5   rZ   r6   r   rz   r   commentssiblingscurrent_node
leaf_nodesr   header_nodesparent_siblinggrandparentr3   r3   r4   r   B  s   




r   r   c                 C   s<   d}t | jd|dD ]}|jtv rd}q
|jtv rd}q
|S )zDetermine whether formatting is switched on within a container.
    Determined by whether the last `# fmt:` comment is `on` or `off`.
    Fr8   T)r;   r:   r&   r    r   )r   r6   fmt_onrZ   r3   r3   r4   r     s   

r   c                 C   s2   | j D ]}t|}|durt||dr dS qdS )z2Determine if children have formatting switched on.NrF   TF)r{   r   r   )r   r6   r   r5   r3   r3   r4   r     s   
r   comment_listc                 C   s    | D ]}|j dr dS qdS )z
    Returns:
        True iff one of the comments in @comment_list is a pragma used by one
        of the more common static analysis tools for python (e.g. mypy, flake8,
        pylint).
    )z# type:z# noqaz	# pylint:TF)r&   rM   )r   rZ   r3   r3   r4   contains_pragma_comment  s
   r   comment_line
directivesc                    sR   | gdd |  tdd D dd | t tD }t fdd|D S )a  
    Checks if the given comment contains format directives, alone or paired with
    other comments.

    Defaults to checking all directives (skip, off, on, yapf), but can be
    narrowed to specific ones.

    Matching styles:
      # foobar                    <-- single comment
      # foobar # foobar # foobar  <-- multiple comments
      # foobar; foobar            <-- list of comments (; separated)
    c                 S      g | ]}t |  qS r3   _COMMENT_PREFIXrh   r   rZ   r3   r3   r4   r         
z+_contains_fmt_directive.<locals>.<listcomp>rC   Nc                 S   r   r3   r   r   r3   r3   r4   r     r   c                 3   s    | ]}| v V  qd S r   r3   r   r   r3   r4   r     r   z*_contains_fmt_directive.<locals>.<genexpr>)rI   r   rh   _COMMENT_LIST_SEPARATORr   )r   r   semantic_comment_blocksr3   r   r4   re     s   
re   )DrH   collections.abcr   r   dataclassesr   	functoolsr   typingr   r   r   
black.moder	   r
   black.nodesr   r   r   r   r   r   r   r   r   r   blib2to3.pgen2r   blib2to3.pytreer   r   LNr   r0   r   r    except_clause
case_blockr!   ri   r   r   r$   r@   r1   r2   r   r;   r/   r=   rP   tuplerp   rs   ru   r   rn   r   r   r   r   r   r   r   r   r   setre   r3   r3   r3   r4   <module>   s  
 0 /)
	


L
4
@
1)


]

