o
    ^iP                     @   s   d Z ddlZddlmZmZmZ ddlmZ 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 ddlmZmZ dee d	eeeef  fd
dZdeeef d	efddZdeeeef  ded	eeeef  fddZdeeeef  deded	eeeef  fddZdedeeeef  d	dfddZ ded	efddZ!G dd ded Z"dede#e d	dfdd Z$ded	dfd!d"Z%d#ee d$ed	dfd%d&Z&d'ed	efd(d)Z'd*e	eee f d	e#e fd+d,Z(eG d-d. d.Z)deded	ee) fd/d0Z*d1ed2ee) d3ed	efd4d5Z+dS )6z?Functions related to Black's formatting by line ranges feature.    N)
CollectionIteratorSequence)	dataclass)Union)	LNSTANDALONE_COMMENTLeafNodeVisitor
first_leaf furthest_ancestor_with_last_leaf	last_leafsyms)ASYNCNEWLINEline_rangesreturnc              	   C   s   g }| D ]9}| d}t|dkrtd|zt|d }t|d }W n ty5   td|d w |||f q|S )N-   z:Incorrect --line-ranges format, expect 'START-END', found r      z<Incorrect --line-ranges value, expect integer ranges, found )splitlen
ValueErrorintappend)r   lines	lines_strpartsstartend r!   Q/var/www/html/stock_analysis/be/venv/lib/python3.10/site-packages/black/ranges.pyparse_line_ranges   s.   
r#   r   c                 C   s   |  p
| d | d kS )z(Returns whether the line range is valid.r   r   r!   )r   r!   r!   r"   is_valid_line_range,   s   r$   src_contentsc                 C   sp   |sg S g }| d}|ds|d7 }| D ]\}}||krqt|d}||k r)qt||}|||f q|S )a  Returns the valid line ranges for the given source.

    This removes ranges that are entirely outside the valid lines.

    Other ranges are normalized so that the start values are at least 1 and the
    end values are at most the (1-based) index of the last source line.
    
r   )countendswithmaxminr   )r   r%   
good_linessrc_line_countr   r    r!   r!   r"   sanitized_lines1   s   




r-   original_sourcemodified_sourcec                 C   s   t ||}g }d}t| D ]R\}}t|||}t|||}	|}|t|ks+|	t|kr,q|| }
||	 }|
jr;|
j}n||
j |
j }|jrJ|j}n||j |j }||f}t|r_|	| q|S )a  Returns the adjusted line ranges based on edits from the original code.

    This computes the new line ranges by diffing original_source and
    modified_source, and adjust each range based on how the range overlaps with
    the diffs.

    Note the diff can contain lines outside of the original line ranges. This can
    happen when the formatting has to be done in adjacent to maintain consistent
    local results. For example:

    1. def my_func(arg1, arg2,
    2.             arg3,):
    3.   pass

    If it restricts to line 2-2, it can't simply reformat line 2, it also has
    to reformat line 1:

    1. def my_func(
    2.     arg1,
    3.     arg2,
    4.     arg3,
    5. ):
    6.   pass

    In this case, we will expand the line ranges to also include the whole diff
    block.

    Args:
      lines: a collection of line ranges.
      original_source: the original source.
      modified_source: the modified source.
    r   )
_calculate_lines_mappingssorted_find_lines_mapping_indexr   is_changed_blockmodified_startoriginal_startmodified_endr$   r   )r   r.   r/   lines_mappings	new_linescurrent_mapping_indexr   r    start_mapping_indexend_mapping_indexstart_mappingend_mapping	new_startnew_end	new_ranger!   r!   r"   adjusted_linesM   sB   
%
rA   src_nodec                 C   sL   t  }|D ]\}}|t||d  qt|}t|| }t| | dS )a  Converts unchanged lines to STANDALONE_COMMENT.

    The idea is similar to how `# fmt: on/off` is implemented. It also converts the
    nodes between those markers as a single `STANDALONE_COMMENT` leaf node with
    the unformatted code as its value. `STANDALONE_COMMENT` is a "fake" token
    that will be formatted as-is with its prefix normalized.

    Here we perform two passes:

    1. Visit the top-level statements, and convert them to a single
       `STANDALONE_COMMENT` when unchanged. This speeds up formatting when some
       of the top-level statements aren't changed.
    2. Convert unchanged "unwrapped lines" to `STANDALONE_COMMENT` nodes line by
       line. "unwrapped lines" are divided by the `NEWLINE` token. e.g. a
       multi-line statement is *one* "unwrapped line" that ends with `NEWLINE`,
       even though this statement itself can span multiple lines, and the
       tokenizer only sees the last '\n' as the `NEWLINE` token.

    NOTE: During pass (2), comment prefixes and indentations are ALWAYS
    normalized even when the lines aren't changed. This is fixable by moving
    more formatting to pass (1). However, it's hard to get it correct when
    incorrect indentations are used. So we defer this to future optimizations.
    r   N)setupdaterange_TopLevelStatementsVisitorlistvisit_convert_unchanged_line_by_line)rB   r   	lines_setr   r    visitor_r!   r!   r"   convert_unchanged_lines   s   rM   nodec                 C   s2   t | tr
| jtkS | jD ]	}t|r dS qdS )NTF)
isinstancer	   typer   children_contains_standalone_comment)rN   childr!   r!   r"   rR      s   


rR   c                   @   sN   e Zd ZdZdee fddZdeded fdd	Z	deded fd
dZ
dS )rF   a  
    A node visitor that converts unchanged top-level statements to
    STANDALONE_COMMENT.

    This is used in addition to _convert_unchanged_line_by_line, to
    speed up formatting when there are unchanged top-level
    classes/functions/statements.
    rJ   c                 C   s
   || _ d S N)
_lines_set)selfrJ   r!   r!   r"   __init__   s   
z#_TopLevelStatementsVisitor.__init__rN   r   Nc                 c   s^    g E d H  t |}|sd S |jtksJ d|j t|}t|| js-t| d S d S )NzUnexpectedly found leaf.type=)r   rP   r   r   _get_line_rangeintersectionrU   #_convert_node_to_standalone_comment)rV   rN   newline_leafancestorr!   r!   r"   visit_simple_stmt   s   

z,_TopLevelStatementsVisitor.visit_simple_stmtc                 c   sn    g E d H  t |rd S |j}|d ur!|jd ur!|jjtkr!|j}|d ur3t|| js5t| d S d S d S rT   )	rR   parentprev_siblingrP   r   rX   rY   rU   rZ   )rV   rN   semantic_parentr!   r!   r"   visit_suite   s$   


z&_TopLevelStatementsVisitor.visit_suite)__name__
__module____qualname____doc__rC   r   rW   r
   r   r]   ra   r!   r!   r!   r"   rF      s
    	rF   rJ   c                 C   sX  |   D ]}|jtkrq|jr6|jjtjkr6g }|j}|r(|d| |j}|st|	|s5t
||d q|jr|jjtjkr|jj}g }|r_|jtjkr_|d| |j}|r_|jtjksN|jj}|dury|jdury|jjtkry|d|j t|	|st
||d qt|}|jtjkr|jr|jjtjkr|j}t|	|st| qdS )z6Converts unchanged to STANDALONE_COMMENT line by line.r   )newlineN)leavesrP   r   r^   r   
match_stmtr_   insertrX   rY   $_convert_nodes_to_standalone_commentsuiter   r   	decorator
decoratorsrZ   )rN   rJ   leafnodes_to_ignorer_   parent_siblinggrandparentr\   r!   r!   r"   rI      sV   


rI   c              	   C   s   | j }|sdS t| }t| }|r|sdS ||u rdS |j}d|_|  }|durU| jtjkr?t| t	s6J | 
dttd t| dd }|
|tt|||d dS dS )z@Convert node to STANDALONE_COMMENT by modifying the tree inline.N r   r&   prefixfmt_pass_converted_first_leaf)r^   r   r   ru   removerP   r   	decoratedrO   r
   insert_childr	   r   strr   )rN   r^   firstlastru   indexvaluer!   r!   r"   rZ   3  s6   rZ   nodesrf   c             	   C   s   | sdS | d j }t| d }|r|sdS |j}d|_ddd | D }|jr0||j7 }d|_| d  }| dd D ]}|  q<|durU||tt|||d dS dS )zAConvert nodes to STANDALONE_COMMENT by modifying the tree inline.Nr   rr   c                 s   s    | ]}t |V  qd S rT   )rz   ).0rN   r!   r!   r"   	<genexpr>r  s    z7_convert_nodes_to_standalone_comment.<locals>.<genexpr>r   rt   )r^   r   ru   joinrw   ry   r	   r   )r   rf   r^   r{   ru   r~   r}   rN   r!   r!   r"   rj   h  s4   


rj   rn   c                 C   s$   | j tkr| jS | jt| d S )z5Returns the line number of the leaf node's last line.r&   )rP   r   linenorz   r'   )rn   r!   r!   r"   _leaf_line_end  s   
r   node_or_nodesc                 C   s   t | tr/| }|st S t|d }t|d }|r,|r,|j}t|}tt||d S t S | }t |trBtt|jt|d S t|}t|}|rZ|rZtt|jt|d S t S )z5Returns the line range of this node or list of nodes.r   rs   r   )	rO   rG   rC   r   r   r   r   rE   r	   )r   r   r{   r|   
line_startline_endrN   r!   r!   r"   rX     s&   

rX   c                   @   s:   e Zd ZU dZeed< eed< eed< eed< eed< dS )_LinesMappingz1-based lines mapping from original source to modified source.

    Lines [original_start, original_end] from original source
    are mapped to [modified_start, modified_end].

    The ranges are inclusive on both ends.
    r5   original_endr4   r6   r3   N)rb   rc   rd   re   r   __annotations__boolr!   r!   r!   r"   r     s   
 r   c              
   C   s   t d| jdd|jdd}| }g }t|D ]c\}}|dkr:|jdks+|jdkr9|td|jd|jdd n ||d  }|t|j|j	 d |j|j|j	 d |jdd |t
|d k r||t|jd |j|j	 |jd |j|j	 dd q|S )a  Returns a sequence of _LinesMapping by diffing the sources.

    For example, given the following diff:
        import re
      - def func(arg1,
      -   arg2, arg3):
      + def func(arg1, arg2, arg3):
          pass
    It returns the following mappings:
      original -> modified
       (1, 1)  ->  (1, 1), is_changed_block=False (the "import re" line)
       (2, 3)  ->  (2, 2), is_changed_block=True (the diff)
       (4, 4)  ->  (3, 3), is_changed_block=False (the "pass" line)

    You can think of this visually as if it brings up a side-by-side diff, and tries
    to map the line ranges from the left side to the right side:

      (1, 1)->(1, 1)    1. import re          1. import re
      (2, 3)->(2, 2)    2. def func(arg1,     2. def func(arg1, arg2, arg3):
                        3.   arg2, arg3):
      (4, 4)->(3, 3)    4.   pass             3.   pass

    Args:
      original_source: the original source.
      modified_source: the modified source.
    NT)keependsr   r   F)r5   r   r4   r6   r3   )difflibSequenceMatcher
splitlinesget_matching_blocks	enumerateabr   r   sizer   )r.   r/   matchermatching_blocksr7   iblockprevious_blockr!   r!   r"   r0     sT   


	

	r0   original_liner7   start_indexc                 C   sL   |}|t |k r$|| }|j|   kr|jkr|S  |d7 }|t |k s|S )zGReturns the original index of the lines mappings for the original line.r   )r   r5   r   )r   r7   r   r}   mappingr!   r!   r"   r2     s   r2   ),re   r   collections.abcr   r   r   dataclassesr   typingr   black.nodesr   r   r	   r
   r   r   r   r   r   blib2to3.pgen2.tokenr   r   rz   rG   tupler   r#   r   r$   r-   rA   rM   rR   rF   rC   rI   rZ   rj   r   rX   r   r0   r2   r!   r!   r!   r"   <module>   sf    ,"

"P 
665"	
O