o
    bE                     @   s  d Z ddlZddlZddl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 ddlmZ ddlmZmZ d	Zg d
Zg dZejdk rLed g dZg dZg dZdZeejejejgZ ejejfZ!dZ"dZ#dZ$dZ%dZ&dZ'e&e%e'gZ(e&e%gZ)dddddddddd d!d"d#ej*ifd$d%d&d'd(g d)ifd*d+d,Z+d-d. Z,d/d0 Z-d1d2 Z.d3d4 Z/d5d6 Z0d7d8 Z1d9d: Z2G d;d< d<Z3d=Z4d>Z5d?Z6d@Z7dAZ8dBZ9dCZ:e4dDe5dEe6dFe7dGe8dHiZ;dIZ<dJdK Z=dLdM Z>G dNdO dOZ?G dPdQ dQZ@G dRdS dSeZAdTdU ZBdVdW ZCdS )XzPython code format's checker.

By default try to follow Guido's style guide :

https://www.python.org/doc/essays/styleguide/

Some parts of the process_token method is based from The Tab Nanny std module.
    N)reduce)nodes)ITokenCheckerIAstroidCheckerIRawChecker)BaseTokenChecker)check_messages)WarningScope
OPTION_RGXasync)elifexceptforifwhiledefclasswith)assertdelr   r   r   r   innotraisereturnr   yieldr   )   r   print)==<>!=z<><=>=z+=z-=z*=z**=z/=z//=z&=z|=z^=z%=z>>=z<<=)([{))]}         zdict-separatorztrailing-commaz
empty-line)zLine too long (%s/%s)line-too-longz=Used when a line is longer than a given number of characters.)z Too many lines in module (%s/%s)too-many-linesz@Used when a module has too many lines, reducing its readability.)zTrailing whitespacetrailing-whitespacezHUsed when there is whitespace between the end of a line and the newline.)zFinal newline missingmissing-final-newlinez7Used when the last line in a file is missing a newline.)zTrailing newlinestrailing-newlinesz3Used when there are trailing blank lines in a file.)z)Bad indentation. Found %s %s, expected %sbad-indentationzUUsed when an unexpected number of indentation's tabulations or spaces has been found.)zWrong %s indentation%s%s.
%s%sbad-continuationTODO)z)Found indentation with %ss instead of %ssmixed-indentationz;Used when there are some mixed tabs and spaces in a module.)zUnnecessary semicolonunnecessary-semicolonzeUsed when a statement is ended by a semi-colon (";"), which isn't necessary (that's python, not C ;).z(More than one statement on a single linemultiple-statementsz<Used when more than on statement are found on the same line.scope)z#Unnecessary parens after %r keywordsuperfluous-parenszLUsed when a single item in parentheses follows an if, for, or other keyword.z%s space %s %s %s
%sbad-whitespacezWUsed when a wrong number of spaces is used around an operator, bracket or block opener.Z	old_names))ZC0323zno-space-after-operator)ZC0324zno-space-after-comma)ZC0322zno-space-before-operator)zMixed line endings LF and CRLFmixed-line-endingsz@Used when there are mixed (LF and CRLF) newline signs in a file.)zEUnexpected line ending format. There is '%s' while it should be '%s'.unexpected-line-ending-formatz3Used when there is different newline than expected.)ZC0301ZC0302ZC0303ZC0304ZC0305ZW0311ZC0330ZW0312ZW0301ZC0321ZC0325ZC0326ZC0327ZC0328c                 C   sT   | d d | d d  }| d d }| d }|d dkr |d7 }|d|  d|  S )	Nr   r*   r+      
 ^ )tokenlengthoffsetZreferenced_linerA   rA   U/var/www/secure340b-portal/env/lib/python3.10/site-packages/pylint/checkers/format.py_underline_token   s   rF   c                 C   sZ   | |krdS |d | d k r|| } }| d d |d d kr!d S |d d | d d  S )Nr   r   r+   r*   rA   )Ztoken1Ztoken2rA   rA   rE   _column_distance   s   
rG   c                 C   sH   |dkr|  |d |kp#|dko#|  |d |ko#| |d tjkS )Nr   r*   r+   )rB   typetokenizeCOMMENT)tokensline_endrB   rA   rA   rE   _last_token_on_line_is   s   rM   c                 C   s<   |  |d tjkp|  |d tjko|  |d tjkS )Nr*   r+   )rH   rI   NLrJ   )rK   positionrA   rA   rE   _token_followed_by_eol   s   rP   c                 C   s(   d}| D ]}|dv r||7 }q |S |S )z.Return the indention string of the given line.  	rA   lineresultcharrA   rA   rE   _get_indent_string   s   
rW   c                 C   s:   d}| D ]}|dkr|d7 }q|dkr|t 7 }q |S |S )z?Return the length of the indentation on the given token's line.r   r?   r*   	)_TAB_LENGTHrS   rA   rA   rE   _get_indent_length  s   

rZ   c           
      C   s   | sdS dd | D } t |}d}dd | D }t|dkr?|d d }t|| }||kr0dnd	}t|||dkr;d
ndf }||df |  dg|d d d  }|D ]\}}	|	||< qWd||fS )zCReturn a line with |s for each of the positions in the given lists.)rQ   rQ   c                 S   s   g | ]}t |qS rA   )rZ   ).0indentrA   rA   rE   
<listcomp>      z)_get_indent_hint_line.<locals>.<listcomp>rQ   c                 S   s   g | ]}|d fqS )|rA   )r[   posrA   rA   rE   r]     r^   r*   r   addremovesr@   r?   r=   )rZ   lenabs_CONTINUATION_HINT_MESSAGEappendsortjoin)
Zbar_positionsZbad_positiondelta_messagemarkersZexpected_positiondelta	directionrT   rO   markerrA   rA   rE   _get_indent_hint_line  s*   
ro   c                   @   s   e Zd ZdZdd ZdS )_ContinuedIndent)valid_outdent_stringsvalid_continuation_stringscontext_typerB   rO   c                 C   s"   || _ || _|| _|| _|| _d S N)rq   rr   rs   rO   rB   )selfrs   rB   rO   rq   rr   rA   rA   rE   __init__5  s
   
z_ContinuedIndent.__init__N)__name__
__module____qualname__	__slots__rv   rA   rA   rA   rE   rp   ,  s    rp   z
dict-valuehangingzhanging-block	continuedzcontinued-blocksingleZmulti)r{   z in dict value)r{   rQ   )r{    before block)r|   rQ   )r|   r~   z (%s %d space%s)c                  G   s   dd | D S )z/Valid indentation strings for a continued line.c                 S   s   i | ]}|d qS rt   rA   )r[   arA   rA   rE   
<dictcomp>`  s    z!_Indentations.<locals>.<dictcomp>rA   )argsrA   rA   rE   _Indentations^     r   c                 C   s   | t |tiS )a  Valid alternative indentation strings for continued lines before blocks.

    :param int single: Valid indentation string for statements on a single logical line.
    :param int with_body: Valid indentation string for statements on several lines.

    :returns: A dictionary mapping indent offsets to a string representing
        whether the indent if for a line or block.
    :rtype: dict
    )SINGLE_LINE	WITH_BODY)r}   Z	with_bodyrA   rA   rE   _BeforeBlockIndentationsc  s   
r   c                   @   sP   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dd ZdS )TokenWrapperz3A wrapper for readable access to token information.c                 C   s
   || _ d S rt   _tokens)ru   rK   rA   rA   rE   rv   s  s   
zTokenWrapper.__init__c                 C      | j | d S )Nr*   r   ru   idxrA   rA   rE   rB   v     zTokenWrapper.tokenc                 C   r   Nr   r   r   rA   rA   rE   rH   y  r   zTokenWrapper.typec                 C      | j | d d S )Nr+   r   r   r   rA   rA   rE   
start_line|     zTokenWrapper.start_linec                 C   r   )Nr+   r*   r   r   rA   rA   rE   	start_col  r   zTokenWrapper.start_colc                 C   r   )Nr<   r   r   rA   rA   rE   rT     r   zTokenWrapper.linec                 C   s   t | |S )zPGet the string of TABs and Spaces used for indentation of the line of this token)rW   rT   r   rA   rA   rE   line_indent  r   zTokenWrapper.line_indentc                 C   s$   |  |}|d| |t|   S )a  Get an indentation string for hanging indentation, consisting of the line-indent plus
        a number of spaces to fill up to the column of this token.

        e.g. the token indent for foo
        in "<TAB><TAB>print(foo)"
        is "<TAB><TAB>      "
        r?   )r   r   rd   )ru   r   r   rA   rA   rE   token_indent  s   
zTokenWrapper.token_indentN)rw   rx   ry   __doc__rv   rB   rH   r   r   rT   r   r   rA   rA   rA   rE   r   p  s    r   c                   @   s   e Zd ZdZdd Zedd Zedd Zedd	 Zed
d Z	dd Z
dd Zdd Zdd Zdd Zdd Zdd Zdd Zdd ZdS )ContinuedLineStatez8Tracker for continued indentation inside a logical line.c                 C   s,   d| _ g | _d| _g | _|| _t|| _d S )Nr=   F)_line_start_cont_stack_is_block_openerretained_warnings_configr   r   )ru   rK   configrA   rA   rE   rv     s   zContinuedLineState.__init__c                 C   s
   t | jS rt   )boolr   ru   rA   rA   rE   has_content  s   
zContinuedLineState.has_contentc                 C   s   | j jddS )N\trX   )r   indent_stringreplacer   rA   rA   rE   _block_indent_string  s   z'ContinuedLineState._block_indent_stringc                 C   s   | j d | jj S r   )r   r   indent_after_parenr   rA   rA   rE   _continuation_string     z'ContinuedLineState._continuation_stringc                 C   s   | j jS rt   )r   r   r   rA   rA   rE   _continuation_size  s   z%ContinuedLineState._continuation_sizec                 C   sF   | j dkrdS |}| j|tkr|d7 }| j|tv | _|| _ dS )z7Record the first non-junk token at the start of a line.r=   Nr*   )r   r   rB   _ASYNC_TOKEN_CONTINUATION_BLOCK_OPENERSr   )ru   r`   Zcheck_token_positionrA   rA   rE   handle_line_start  s   

z$ContinuedLineState.handle_line_startc                 C   s   d| _ d| _dS )z2Prepares the tracker for a new physical line (NL).r=   FN)r   r   r   rA   rA   rE   next_physical_line  s   
z%ContinuedLineState.next_physical_linec                 C   s   |    g | _g | _dS )zPrepares the tracker for a new logical line (NEWLINE).

        A new logical line only starts with block indentation.
        N)r   r   r   r   rA   rA   rE   next_logical_line  s   
z$ContinuedLineState.next_logical_linec                 C   s   | j |||f d S rt   )r   rg   )ru   Ztoken_positionstatevalid_indentationsrA   rA   rE   add_block_warning  s   z$ContinuedLineState.add_block_warningc                 C   s\   d}| j |dv r| jd jdkrd}| j| }| j |tv r%|j}n|j}|| fS )z>Returns the valid offsets for the token at the given position.r=   )r(   r   :)r   rB   r   _CLOSING_BRACKETSrq   rr   copy)ru   r   Z	stack_topr\   r   rA   rA   rE   get_valid_indentations  s   
z)ContinuedLineState.get_valid_indentationsc              
   C   s   | j |}| jr(| j| jkr(tt||t|| j |t|| j || jd  S |dkrQ| j	d j
}| j	d j }t| }d||d | j < tt||||S tt||t||| j t|| j S )ab  Extracts indentation information for a hanging indent

        Case of hanging indent after a bracket (including parenthesis)

        :param str bracket: bracket in question
        :param int position: Position of bracket in self._tokens

        :returns: the state and valid positions for hanging indentation
        :rtype: _ContinuedIndent
        r+   r   r=   Tr   )r   r   r   r   r   rp   HANGING_BLOCKr   r   r   rq   rr   r   listkeysHANGING_DICT_VALUEHANGING)ru   bracketrO   indentationZparen_alignZ
next_alignZnext_align_keysrA   rA   rE   _hanging_indent_after_bracket  s<   


z0ContinuedLineState._hanging_indent_after_bracketc              	   C   sv   | j |}| j |}| j |d }| jr.||| j kr.tt||t|t||| j	 S tt
||t||t|S )z8Extracts indentation information for a continued indent.r*   )r   r   r   r   r   rp   CONTINUED_BLOCKr   r   r   	CONTINUED)ru   r   rO   r   r   Znext_token_indentrA   rA   rE   _continuation_inside_bracket  s.   
	z/ContinuedLineState._continuation_inside_bracketc                 C   s   | j   d S rt   )r   popr   rA   rA   rE   	pop_token,  r   zContinuedLineState.pop_tokenc                 C   s<   t | j|r| j| || dS | j| || dS )a  Pushes a new token for continued indentation on the stack.

        Tokens that can modify continued indentation offsets are:
          * opening brackets
          * 'lambda'
          * : inside dictionaries

        push_token relies on the caller to filter out those
        interesting tokens.

        :param int token: The concrete token
        :param int position: The position of the token in the stream.
        N)rP   r   r   rg   r   r   )ru   rB   rO   rA   rA   rE   
push_token/  s   zContinuedLineState.push_tokenN)rw   rx   ry   r   rv   propertyr   r   r   r   r   r   r   r   r   r   r   r   r   rA   rA   rA   rE   r     s(    



	3r   c                   @   s  e Zd ZdZeeefZdZe	Z
ddddddfd	d
ddddfddddddfddddddfddededede d e d e d dfddddd dfd!d"d#d$d%dfd&ddd'd(dfd)d*d+d,g d-d.d/ff	Zdfd1d2Zd3d4 Zd5d6 Zd7d8 Zd9d: Zd;d< Zd=d> Zd?d@ ZdAdB ZdCdD ZdEdF ZdGdH ZdIdJ ZdKdL ZdMdN Z dOdP Z!dQdR Z"dSdT Z#dUdV Z$dWdX Z%dYdZ Z&d[d\ Z'e(d]d^d_ Z)d`da Z*dbdc Z+ddde Z,d0S )gFormatCheckerz]checks for :
    * unauthorized constructions
    * strict indentation
    * line length
    formatzmax-line-lengthd   intz<int>z.Maximum number of characters on a single line.)defaultrH   metavarhelpzignore-long-linesregexpz<regexp>z^\s*(# )?<?https?://\S+>?$z>Regexp for a line that is allowed to be longer than the limit.)rH   r   r   r   zsingle-line-if-stmtFZynz<y_or_n>zOAllow the body of an if to be on the same line as the test if there is no else.zsingle-line-class-stmtzfAllow the body of a class to be on the same line as the declaration if body contains single statement.zno-space-check,Zmultiple_choicezHList of optional constructs for which whitespace checking is disabled. `zB` is used to allow tabulation in dicts, etc.: {1  : 1,\n222: 2}. `z<` allows a space between comma and closing bracket: (a, ). `z` allows space-only lines.)r   r   rH   choicesr   zmax-module-linesi  z$Maximum number of lines in a module.zindent-stringz    Znon_empty_stringz<string>zSString used as indentation unit. This is usually "    " (4 spaces) or "\t" (1 tab).zindent-after-parenr<   zGNumber of spaces of indent required inside a hanging or continued line.zexpected-line-ending-formatchoicez<empty or LF or CRLF>rQ   )rQ   LFCRLFzIExpected format of line ending, e.g. empty (any line ending), LF or CRLF.)rH   r   r   r   r   Nc                 C   s$   t | | d | _d | _d g| _d S rt   )r   rv   _lines_visited_lines_bracket_stack)ru   linterrA   rA   rE   rv     s   zFormatChecker.__init__c                 C   s   | j   | j  d S rt   )r   r   _current_liner   r   rA   rA   rE   
_pop_token  s   
zFormatChecker._pop_tokenc                 C   s   | j | | j|| d S rt   )r   rg   r   r   )ru   rB   r   rA   rA   rE   _push_token  s   zFormatChecker._push_tokenc                 C   sf   t ||dr| jd||d ||}||}||tvr+|dd | j|< | || dS )z8a new line has been encountered, process it if necessary;r5   rT   r>   r   N)	rM   add_messager   rT   rH   _JUNK_TOKENSsplitr   check_lines)ru   rK   rL   
line_startline_numrT   rA   rA   rE   new_line  s   

zFormatChecker.new_linec                 C   s&   t  | _d|jv r| jd d S d S )Nprint_functionr   )set_keywords_with_parensZfuture_importsra   )ru   modulerA   rA   rE   process_module  s   
zFormatChecker.process_modulec           	      C   s  |  dr|| d dkr|   ||d  d dkrdS d}d}t|| d }|| d d }t|t|d D ]}|| }|d tjkrJ dS |d dkrU|d7 }q:|d d	kr|d8 }|rbq:||d  d d
v s|||d  d tjtjtj	fv r||d kr dS |dkr|s| j
d||d  dS |dv r| j
d||d  dS || jvr|s| j
d||d  dS |dkr|d dkr dS |d dv rd}q:|d dkr dS |d dkr dS q:dS )a  Check that there are not unnecessary parens after a keyword.

        Parens are unnecessary if there is exactly one balanced outer pair on a
        line, and it is followed by a colon, and contains no commas (i.e. is not a
        tuple).

        Args:
        tokens: list of Tokens; the entire list of Tokens.
        start: int; the position of the keyword in the token list.
        r   r*   r   r#   NFr   r+   r&   )r   r&   r'   r(   r   r   r8   rT   r   )r   r   r   )andorTr   )_inside_bracketsr   strrangerd   rI   rN   NEWLINE	ENDMARKERrJ   r   r   )	ru   rK   startZfound_and_ordepthZkeyword_tokenr   irB   rA   rA   rE   _check_keyword_parentheses  sj   

z(FormatChecker._check_keyword_parenthesesc                 C   s   |  || d | || d dkr||d  d dkrd S |dkrM||d  d tjkr8t||d  d rB||d  d tv rM| ||ttf d S | ||ttf d S )Nr*   r$   r   r   )	r   rI   NAMEkeyword	iskeywordr   _check_space	_MUST_NOT_IGNOREru   rK   r   rA   rA   rE   _opening_bracket(  s   $zFormatChecker._opening_bracketc                 C   s   |  dr	|   |   ||d  d dkr!|| d dkr!d S t}|| d tv r=||d  d dkr=t| jjv r=t}| |||tf d S )Nr   r*   r'   r   )	r   r   r   r   _TRAILING_COMMAr   no_space_checkr   r   )ru   rK   r   Zpolicy_beforerA   rA   rE   _closing_bracket7  s   
$$zFormatChecker._closing_bracketc                 C   s   |  dsdS d}||d dd D ]L}|d dkr dS |d dkr& dS |d d	kr1|d7 }q|d d
kr<|d8 }q|d dkrH|sG dS q|d dv rOq|d tjtjtjfvr^ dS qdS )z,Extended check of PEP-484 type hint presencer#   Fr   r*   Nr=   r   Tr'   r$   r   ).z...)r   rI   r   STRINGrN   )ru   rK   r   Zbracket_levelrB   rA   rA   rE   _has_valid_type_annotationE  s,   


z(FormatChecker._has_valid_type_annotationc                 C   sb   |  ||r| ||ttf dS | ds| dr&| ||ttf dS | ||ttf dS )z*Check the spacing of a single equals sign.r#   lambdaN)r   r   _MUSTr   r   r   rA   rA   rE   _check_equals_spacing_  s
   z#FormatChecker._check_equals_spacingc                 C   s   |  d| d S )Nr   )r   r   rA   rA   rE   _open_lambdah  s   zFormatChecker._open_lambdac                 C   sx   |  drd S |  drt| jjv rttf}nttf}| ||| |  dr-|   d S |  dr:| 	d| d S d S )Nr$   r%   r   r   )
r   _DICT_SEPARATORr   r   r   r   r  r   r   r   )ru   rK   r   policyrA   rA   rE   _handle_colonk  s   



zFormatChecker._handle_colonc                 C   sT   ||d  d t v r| ||ttf n	| ||ttf | dr(|   d S d S )Nr*   r   )r   r   r   r   r  r   r   r   rA   rA   rE   _handle_commaz  s   
zFormatChecker._handle_commac                 C   s   |  ||ttf dS )z@Check that a binary operator is surrounded by exactly one space.N)r   r  r   rA   rA   rE   _check_surrounded_by_space  s   z(FormatChecker._check_surrounded_by_spacec              
      s`  dd } fdd}ddg}|| }||d  |f|||d  fg}t t||D ].\}	\}
}||	 d tv s;|
tkr<q)t| }|d u rEq)|
tkrM|dkpT|
tkoT|dk||	< q)g }t|sp|d |d krp||d df nt||d	D ]\}}
}|s||
|f qv|D ]&\}
}||}||
\}} j	d
|d d ||||t
|f|d d d qd S )Nc                 S   s   | t krdS dS )N)zExactly onerequired)ZNoallowed)r  )r  rA   rA   rE   _policy_string  s   z2FormatChecker._check_space.<locals>._policy_stringc                    sR   | d dkrdS | d dkrdS | d dv rdS | d dv r dS   d	r'd
S dS )Nr*   r   commar   z()[]{}r   )r   r   r!   r"   r    r   Z
comparisonr#   zkeyword argument assignmentZ
assignment)r   )rB   r   rA   rE   _name_construct  s   
z3FormatChecker._check_space.<locals>._name_constructTr*   r   Zaround)beforeafterr9   r+   )rT   r   
col_offset)	enumeratezip_EOLr   rG   r  r   anyrg   r   rF   )ru   rK   r   Zpoliciesr  r  Z
good_spacerB   pairsZ	other_idxr  Z
token_pairZdistancewarningsokrO   	constructcountr   rA   r   rE   r     s>    

zFormatChecker._check_spacec                 C   s   | j d |kS )Nr=   )r   )ru   leftrA   rA   rE   r     r   zFormatChecker._inside_bracketsc              	   C   st   t | jft| jft| jfdg| jft| jfdg| j	fdg| j
fdg| jfg}i }|D ]\}}|D ]}|||< q0q*|S )N=r   r   r   )_KEYWORD_TOKENSr   _OPENING_BRACKETSr   r   r   r  _SPACED_OPERATORSr  r  r  r  )ru   rawdispatchrK   handlerrB   rA   rA   rE   _prepare_token_dispatcher  s   




z'FormatChecker._prepare_token_dispatcherc              	   C   s  dg| _ dg}d}d}i | _i | _|  }d| _d}t|| j| _t|D ]\}\}}	}
}}|
d |krV|
d }|t	j
krK| t||d |d  n| t||d | |t	jkrqd}| t|| | j  | |	| nd|t	j
krd}| |	|d d | ||d d  nH|t	jkrd}t|dkr|d= n7|t	jkr|ds|}| t||d  | j  n|t	jt	jfvr| j| |rd}| ||d | |t	jkr|	dr| jd	|d
 z||	 }W n	 ty   Y q%w ||| q%|d8 }|| jj kr/| j!j"#dd }|j$df}t%t&dt'| j!j(j)|d}| jd|| jj f|d ||krB|dkrD| jd|d
 dS dS dS )a=  process tokens and search for :

         _ non strict indentation (i.e. not always using the <indent> parameter as
           indent unit)
         _ too long lines (i.e. longer than <max_chars>)
         _ optionally bad construct (if given, bad_construct must be a compiled
           regular expression).
        Nr   Fr*   Tr=   
lzlowercase-l-suffixr   r-   r   rT   r0   )*r   r   r   r"  _last_line_endingr   r   r   r  rI   INDENTr   r   r   _process_retained_warningsr   _check_line_endingcheck_indent_levelrg   DEDENTrd   rN   strip_check_continued_indentationr   rJ   ENCODINGr   NUMBERendswithr   KeyErrorZmax_module_linesr   Z
msgs_storeZget_message_definitionsmsgidnextfiltermapZ_pragma_linenoget)ru   rK   indentsZcheck_equalr   Ztoken_handlersZlast_blank_line_numr   tok_typerB   r   _rT   r!  Zmessage_definitionnamesrA   rA   rE   process_tokens  s   	








zFormatChecker.process_tokensc                 C   s   | j d ur|r|| j kr| jd|d || _ | jj}|r<tdd |d}|dkr*dnd}||kr>| jd	||f|d
 d S d S d S )Nr:   r   c                 S   s   | |kr| | S | S rt   rA   )xyrA   rA   rE   <lambda>C  r^   z2FormatChecker._check_line_ending.<locals>.<lambda>rQ   r>   r   r   r;   r%  )r&  r   r   Zexpected_line_ending_formatr   )ru   Zline_endingr   expectedrA   rA   rE   r)  4  s    

z FormatChecker._check_line_endingc                    s   t ||d }| jjD ]4\}}}|||   fdd| D }|r1 tkr1| |||| q|s? tkr?| |||| qd S )Nr   c                    s   i | ]\}}| kr||qS rA   rA   )r[   kvZ
block_typerA   rE   r   Q  s    z<FormatChecker._process_retained_warnings.<locals>.<dictcomp>)rM   r   r   r   itemsr   _add_continuation_messager   )ru   rK   Zcurrent_posZsingle_line_block_stmtZ
indent_posr   indentationshintsrA   rB  rE   r(  L  s   z(FormatChecker._process_retained_warningsc                    s   fdd}| j jrtjkrd S | j \}}|tjs'|tjr0d|d < |j	t
tfv rH|v rH| j || d S |vrkt t fdd|D sm| || d S d S d S )Nc                    s      | ko  d | kS )Nr+   )rH   )
token_type)next_idxrK   rA   rE   same_token_around_nlX  s   zHFormatChecker._check_continued_indentation.<locals>.same_token_around_nlTr+   c                 3   s     | ]} d t | kV  qdS )r+   N)rd   )r[   r   )length_indentationrA   rE   	<genexpr>v  s
    
z=FormatChecker._check_continued_indentation.<locals>.<genexpr>)r   r   rH   rI   rN   r   rJ   r   r   rs   r   r   r   rd   r  rD  )ru   rK   rH  rI  r   r   rA   )rJ  rH  rK   rE   r-  W  s.   z*FormatChecker._check_continued_indentationc           	   	   C   sL   t |j \}}t|||\}}| jd||||||||fd d S )Nr2   r   )_CONTINUATION_MSG_PARTSrs   ro   r   r   r   rT   )	ru   r   rE  rK   rO   Zreadable_typeZreadable_positionZ	hint_linerj   rA   rA   rE   rD  ~  s   

z'FormatChecker._add_continuation_messager6   c              	   C   s<  |j sdS | jsdS | }|dur|j}nt|jtjr/||jj	v r/|jj
d jd }n|j j}|j}|s>J |||krR| j|dkrR| || dS || jv rYdS z|j}W n tyj   |j}Y nw |sqJ |g }t||d D ]!}d| j|< z|| j|   W qz ty   |d Y qzw dS )z7check the node line number and check it if not yet doneNr   r*   r+   rQ   )Zis_statementrootZpure_pythonZprevious_siblingZ
fromlineno
isinstanceparentr   
TryFinally	finalbodybodytolinenoZ	statementr   r6  _check_multi_statement_lineZblockstart_tolinenoAttributeErrorr   rg   r   rstripr1  )ru   nodeZ	prev_sibl	prev_linerT   rS  linesrA   rA   rE   visit_default  sF   





zFormatChecker.visit_defaultc                 C   s   t |tjrdS t |tjrt |jtjrdS t |jtjr(|jjs(| jj	r(dS t |jtj
r=t|jjdkr=| jjr=dS | jd|d d| j|< dS )z/Check for lines containing multiple statements.Nr*   r6   )rW  r+   )rN  r   WithZ	TryExceptrO  rP  Iforelser   Zsingle_line_if_stmtClassDefrd   rR  Zsingle_line_class_stmtr   r   )ru   rW  rT   rA   rA   rE   rT    s,   z)FormatChecker._check_multi_statement_linec                    s   j jj j  fdd}h d}g }|dD ]'}|d |v r)|| q|r7|| d|}g }|||}|du rB nq|rO|d|| dS dS )zBcheck lines have less than a maximum number of characters
        c                    s   |  dsjd|d n$| d}|stjjv rn| t|d  dvr/jd|t|d |} t| }|red| v re|	d	
d\}}}| d
kreddd |dD v r[d S | dd	d  } t| kr| | s|jd|t| fd |d	 S )Nr>   r/   r   z	
 )r>   r#  r.   )rT   r  r  r*   disabler,   c                 S   s   h | ]}|  qS rA   )r,  )r[   Z_msg_idrA   rA   rE   	<setcomp>  s    z@FormatChecker.check_lines.<locals>.check_line.<locals>.<setcomp>r   #r   r   )r0  r   rV  _EMPTY_LINEr   r   rd   r
   searchgroup	partitionr,  r   rsplit)rT   r   Zstripped_lineZmobjZfront_of_equalr9  Zback_of_equalZignore_long_lineZ	max_charsru   rA   rE   
check_line  s,   



z-FormatChecker.check_lines.<locals>.check_line>              Tr=   rQ   N)r   max_line_lengthZignore_long_lines
splitlinesrg   ri   )ru   rY  r   rh  Zunsplit_endsZunsplitrT   rA   rg  rE   r     s(   



zFormatChecker.check_linesc           
      C   s  | j j}|dkr
d}d}t|}|d| |kr*||d }|d7 }|d| |ksd}|re|d dv re|d |d krQ|d dkrEd}nd	}| jd
||d |S ||d 7 }|dd }|re|d dv s4||ksk|rd}	|d dkrud}	| jd||| t| |	|| fd dS )z.return the indent level of the string
        r   rX   r   Nr*   rQ   rR   )tabspace)rt  rs  r4   r%  spacestabsr1   r   )r   r   rd   r   )
ru   stringr?  r   r\   levelZ	unit_sizeZsupplr   Zi_typerA   rA   rE   r*    s<   
z FormatChecker.check_indent_levelrt   )-rw   rx   ry   r   r   r   r   Z__implements__nameMSGSZmsgsri   _DEFAULT_NO_SPACE_CHECK_CHOICES_NO_SPACE_CHECK_CHOICESr  r   rb  optionsrv   r   r   r   r   r   r   r   r   r  r  r  r  r  r   r   r"  r;  r)  r(  r-  rD  r   rZ  rT  r   r*  rA   rA   rA   rE   r   C  s    



lL	
3d'
)Ar   c                 C   s   |  t|  dS )z.required method to auto register this checker N)Zregister_checkerr   )r   rA   rA   rE   register7  r   r~  c                  C   s   t dD ]} qt|  d S )Nr   )r   r   )valrA   rA   rE   funkier<  s   r  )Dr   r   sysrI   	functoolsr   Zastroidr   Zpylint.interfacesr   r   r   Zpylint.checkersr   Zpylint.checkers.utilsr   Zpylint.utilsr	   r
   r   r   r  version_inforg   r  r  r   rY   	frozensetr   rN   rJ   r  r   r  r   r   r  r   rb  r|  r{  ZNODErz  rF   rG   rM   rP   rW   rZ   ro   rp   r   r   r   r   r   r   r   rL  rf   r   r   r   r   r   r~  r  rA   rA   rA   rE   <module>   s   $	



T


% /     y