B
    A!p\E                 @   sV  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d
dddddddgZddd
ddddddddddgZejdk red dddddd d!d"d#d$d%d&d'd(d)d*d+d,d-gZd.d/d0gZd1d2d3gZd4ZeejejejgZ ejejfZ!dZ"d5Z#d6Z$d7Z%d8Z&d9Z'e&e%e'gZ(e&e%gZ)d:d;d<d=d>d?d@dAdBdCdDdEdFej*ifdGdHdIdJdKdLdMdNgifdOdPdQZ+dRdS Z,dTdU Z-dVdW Z.dXdY Z/dZd[ Z0d\d] Z1d^d_ Z2G d`da daZ3dbZ4dcZ5ddZ6deZ7dfZ8dgZ9dhZ:e4die5dje6dke7dle8dmiZ;dnZ<dodp Z=dqdr Z>G dsdt dtZ?G dudv dvZ@G dwdx dxeZAdydz ZBd{d| ZCdS )}zPython 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delinnotraisereturnyield)   r   printz==<>z!=z<>z<=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)zline-too-longz=Used when a line is longer than a given number of characters.)z Too many lines in module (%s/%s)ztoo-many-linesz@Used when a module has too many lines, reducing its readability.)zTrailing whitespaceztrailing-whitespacezHUsed when there is whitespace between the end of a line and the newline.)zFinal newline missingzmissing-final-newlinez7Used when the last line in a file is missing a newline.)zTrailing newlinesztrailing-newlinesz3Used when there are trailing blank lines in a file.)z)Bad indentation. Found %s %s, expected %szbad-indentationzUUsed when an unexpected number of indentation's tabulations or spaces has been found.)zWrong %s indentation%s%s.
%s%szbad-continuationZTODO)z)Found indentation with %ss instead of %sszmixed-indentationz;Used when there are some mixed tabs and spaces in a module.)zUnnecessary semicolonz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 linezmultiple-statementsz<Used when more than on statement are found on the same line.Zscope)z#Unnecessary parens after %r keywordzsuperfluous-parenszLUsed when a single item in parentheses follows an if, for, or other keyword.z%s space %s %s %s
%sz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 CRLFz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'.z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_liner-   r-   5lib/python3.7/site-packages/pylint/checkers/format.py_underline_token   s    r2   c             C   sZ   | |krdS |d | d k r&||  } }| d d |d d krBd S |d d | d d  S )Nr   r   r'   r&   r-   )Ztoken1Ztoken2r-   r-   r1   _column_distance   s    
r3   c             C   sH   |dkr|  |d |kpF|dkoF|  |d |koF| |d tjkS )Nr   r&   r'   )r.   typetokenizeCOMMENT)tokensline_endr.   r-   r-   r1   _last_token_on_line_is   s
    r9   c             C   s<   |  |d tjkp:|  |d tjko:|  |d tjkS )Nr&   r'   )r4   r5   NLr6   )r7   positionr-   r-   r1   _token_followed_by_eol   s    r<   c             C   s*   d}x | D ]}|dkr ||7 }q
P q
W |S )z.Return the indention string of the given line. z 	r-   )lineresultcharr-   r-   r1   _get_indent_string   s    

rA   c             C   s<   d}x2| D ]*}|dkr |d7 }q
|dkr2|t 7 }q
P q
W |S )z?Return the length of the indentation on the given token's line.r   r+   r&   	)_TAB_LENGTH)r>   r?   r@   r-   r-   r1   _get_indent_length  s    


rD   c       
      C   s   | sdS dd | D } t |}d}dd | D }t|dkr~|d d }t|| }||kr`dnd	}t|||dkrvd
ndf }||df |  dg|d d d  }x|D ]\}}	|	||< qW d||fS )zCReturn a line with |s for each of the positions in the given lists.)r=   r=   c             S   s   g | ]}t |qS r-   )rD   ).0indentr-   r-   r1   
<listcomp>  s    z)_get_indent_hint_line.<locals>.<listcomp>r=   c             S   s   g | ]}|d fqS )|r-   )rE   posr-   r-   r1   rG     s    r&   r   addremovesr,   r+   r)   )rD   lenabs_CONTINUATION_HINT_MESSAGEappendsortjoin)
Zbar_positionsZbad_positiondelta_messageZmarkersZexpected_positionZdelta	directionr>   r;   Zmarkerr-   r-   r1   _get_indent_hint_line  s(    rU   c               @   s   e Zd ZdZdd ZdS )_ContinuedIndent)valid_outdent_stringsvalid_continuation_stringscontext_typer.   r;   c             C   s"   || _ || _|| _|| _|| _d S )N)rW   rX   rY   r;   r.   )selfrY   r.   r;   rW   rX   r-   r-   r1   __init__5  s
    z_ContinuedIndent.__init__N)__name__
__module____qualname__	__slots__r[   r-   r-   r-   r1   rV   ,  s   rV   z
dict-valuehangingzhanging-block	continuedzcontinued-blocksingleZmulti)r`   z in dict value)r`   r=   )r`   z before block)ra   r=   )ra   z before blockz (%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 )Nr-   )rE   ar-   r-   r1   
<dictcomp>`  s    z!_Indentations.<locals>.<dictcomp>r-   )argsr-   r-   r1   _Indentations^  s    rf   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)rb   Z	with_bodyr-   r-   r1   _BeforeBlockIndentationsc  s    
ri   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 )N)_tokens)rZ   r7   r-   r-   r1   r[   s  s    zTokenWrapper.__init__c             C   s   | j | d S )Nr&   )rk   )rZ   idxr-   r-   r1   r.   v  s    zTokenWrapper.tokenc             C   s   | j | d S )Nr   )rk   )rZ   rl   r-   r-   r1   r4   y  s    zTokenWrapper.typec             C   s   | j | d d S )Nr'   r   )rk   )rZ   rl   r-   r-   r1   
start_line|  s    zTokenWrapper.start_linec             C   s   | j | d d S )Nr'   r&   )rk   )rZ   rl   r-   r-   r1   	start_col  s    zTokenWrapper.start_colc             C   s   | j | d S )Nr(   )rk   )rZ   rl   r-   r-   r1   r>     s    zTokenWrapper.linec             C   s   t | |S )zPGet the string of TABs and Spaces used for indentation of the line of this token)rA   r>   )rZ   rl   r-   r-   r1   line_indent  s    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+   )ro   rn   rM   )rZ   rl   ro   r-   r-   r1   token_indent  s    
zTokenWrapper.token_indentN)r\   r]   r^   __doc__r[   r.   r4   rm   rn   r>   ro   rp   r-   r-   r-   r1   rj   p  s   rj   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_configrj   rk   )rZ   r7   configr-   r-   r1   r[     s    zContinuedLineState.__init__c             C   s
   t | jS )N)boolrt   )rZ   r-   r-   r1   has_content  s    zContinuedLineState.has_contentc             C   s   | j jddS )Nz\trB   )rw   indent_stringreplace)rZ   r-   r-   r1   _block_indent_string  s    z'ContinuedLineState._block_indent_stringc             C   s   | j d | jj S )Nr   )r}   rw   indent_after_paren)rZ   r-   r-   r1   _continuation_string  s    z'ContinuedLineState._continuation_stringc             C   s   | j jS )N)rw   r~   )rZ   r-   r-   r1   _continuation_size  s    z%ContinuedLineState._continuation_sizec             C   sF   | j dkrdS |}| j|tkr*|d7 }| j|tk| _|| _ dS )z7Record the first non-junk token at the start of a line.r)   Nr&   )rs   rk   r.   _ASYNC_TOKEN_CONTINUATION_BLOCK_OPENERSru   )rZ   rI   Zcheck_token_positionr-   r-   r1   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)rs   ru   )rZ   r-   r-   r1   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   rv   rt   )rZ   r-   r-   r1   next_logical_line  s    z$ContinuedLineState.next_logical_linec             C   s   | j |||f d S )N)rv   rP   )rZ   Ztoken_positionstatevalid_indentationsr-   r-   r1   add_block_warning  s    z$ContinuedLineState.add_block_warningc             C   s\   d}| j |dkr(| jd jdkr(d}| j| }| j |tkrJ|j}n|j}|| fS )z>Returns the valid offsets for the token at the given position.r)   )r$   r   :)rk   r.   rt   _CLOSING_BRACKETSrW   rX   copy)rZ   rl   Z	stack_toprF   r   r-   r-   r1   get_valid_indentations  s    
z)ContinuedLineState.get_valid_indentationsc          
   C   s   | j |}| jrP| j| jkrPtt||t|| j |t|| j || jd  S |dkr| 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   )rk   ro   ru   r   r}   rV   HANGING_BLOCKrf   ri   rt   rW   rX   r   listkeysHANGING_DICT_VALUEHANGING)rZ   bracketr;   indentationZparen_alignZ
next_alignZnext_align_keysr-   r-   r1   _hanging_indent_after_bracket  s0    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&   )rk   ro   rp   ru   r}   rV   CONTINUED_BLOCKrf   ri   r   	CONTINUED)rZ   r   r;   r   rp   Znext_token_indentr-   r-   r1   _continuation_inside_bracket  s$    z/ContinuedLineState._continuation_inside_bracketc             C   s   | j   d S )N)rt   pop)rZ   r-   r-   r1   	pop_token,  s    zContinuedLineState.pop_tokenc             C   s:   t | j|r"| j| || n| 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)r<   rk   rt   rP   r   r   )rZ   r.   r;   r-   r-   r1   
push_token/  s    zContinuedLineState.push_tokenN)r\   r]   r^   rq   r[   propertyrz   r}   r   r   r   r   r   r   r   r   r   r   r   r-   r-   r-   r1   rr     s   	3rr   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,d,d-d.gd/d0ff	Zdgd2d3Zd4d5 Zd6d7 Zd8d9 Zd:d; Zd<d= Zd>d? Zd@dA ZdBdC ZdDdE ZdFdG ZdHdI ZdJdK ZdLdM ZdNdO Z dPdQ Z!dRdS Z"dTdU Z#dVdW Z$dXdY Z%dZd[ Z&d\d] Z'e(d^d_d` Z)dadb Z*dcdd Z+dedf Z,d1S )hFormatCheckerz]checks for :
    * unauthorized constructions
    * strict indentation
    * line length
    formatzmax-line-lengthd   intz<int>z.Maximum number of characters on a single line.)defaultr4   metavarhelpzignore-long-linesZregexpz<regexp>z^\s*(# )?<?https?://\S+>?$z>Regexp for a line that is allowed to be longer than the limit.)r4   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   r4   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-formatZchoicez<empty or LF or CRLF>r=   LFCRLFzIExpected format of line ending, e.g. empty (any line ending), LF or CRLF.)r4   r   r   r   r   Nc             C   s$   t | | d | _d | _d g| _d S )N)r   r[   _lines_visited_lines_bracket_stack)rZ   linterr-   r-   r1   r[     s    zFormatChecker.__init__c             C   s   | j   | j  d S )N)r   r   _current_liner   )rZ   r-   r-   r1   
_pop_token  s    
zFormatChecker._pop_tokenc             C   s   | j | | j|| d S )N)r   rP   r   r   )rZ   r.   rl   r-   r-   r1   _push_token  s    zFormatChecker._push_tokenc             C   sf   t ||dr | jd||d ||}||}||tkrV|dd | j|< | || dS )z8a new line has been encountered, process it if necessary;zunnecessary-semicolon)r>   r*   r   N)	r9   add_messagerm   r>   r4   _JUNK_TOKENSsplitr   check_lines)rZ   r7   r8   Z
line_startline_numr>   r-   r-   r1   new_line  s    

zFormatChecker.new_linec             C   s"   t  | _d|jkr| jd d S )NZprint_functionr   )set_keywords_with_parensZfuture_importsrJ   )rZ   moduler-   r-   r1   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 }xft|t|d D ]N}|| }|d tjkrdS |d dkr|d7 }qx|d d	krx|d8 }|rqx||d  d d
ks||d  d tjtjtj	fkrt||d krdS |dkr6|st| j
d||d n>|dkrR| j
d||d n"|| jkrt|st| j
d||d dS |dkrx|d dkrdS |d dkrd}qx|d dkrdS |d dkrxdS qxW 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   zsuperfluous-parens)r>   re   )r   r   r   )andorTr   )_inside_bracketsr   strrangerM   r5   r:   NEWLINE	ENDMARKERr6   r   r   )	rZ   r7   startZfound_and_orZdepthZkeyword_tokenr   ir.   r-   r-   r1   _check_keyword_parentheses  sX    
 

z(FormatChecker._check_keyword_parenthesesc             C   s   |  || d | || d dkr<||d  d dkr<d S |dkr||d  d tjkrpt||d  d r||d  d tkr| ||ttf n| ||ttf d S )Nr&   r    r   r   )	r   r5   NAMEkeyword	iskeywordr   _check_space	_MUST_NOT_IGNORE)rZ   r7   r   r-   r-   r1   _opening_bracket(  s    $zFormatChecker._opening_bracketc             C   s   |  dr|   |   ||d  d dkrB|| d dkrBd S t}|| d tkrz||d  d dkrzt| jjkrzt}| |||tf d S )Nr   r&   r#   r   )	r   r   r   r   _TRAILING_COMMArx   no_space_checkr   r   )rZ   r7   r   Zpolicy_beforer-   r-   r1   _closing_bracket7  s    
$$zFormatChecker._closing_bracketc             C   s   |  dsdS d}x||d dd D ]}|d dkr:dS |d dkrJdS |d d	kr`|d7 }q&|d d
krv|d8 }q&|d dkr|sdS q&|d dkrq&q&|d tjtjtjfkr&dS q&W dS )z,Extended check of PEP-484 type hint presencer   Fr   r&   Nr)   r   Tr#   r    r   ).z...)r   r5   r   STRINGr:   )rZ   r7   r   Zbracket_levelr.   r-   r-   r1   _has_valid_type_annotationE  s(    


z(FormatChecker._has_valid_type_annotationc             C   s^   |  ||r | ||ttf n:| ds4| drH| ||ttf n| ||ttf dS )z*Check the spacing of a single equals sign.r   lambdaN)r   r   _MUSTr   r   )rZ   r7   r   r-   r-   r1   _check_equals_spacing_  s
    z#FormatChecker._check_equals_spacingc             C   s   |  d| d S )Nr   )r   )rZ   r7   r   r-   r-   r1   _open_lambdah  s    zFormatChecker._open_lambdac             C   sr   |  drd S |  dr.t| jjkr.ttf}nttf}| ||| |  drX|   n|  drn| 	d| d S )Nr    r!   r   r   )
r   _DICT_SEPARATORrx   r   r   r   r   r   r   r   )rZ   r7   r   policyr-   r-   r1   _handle_colonk  s    




zFormatChecker._handle_colonc             C   sP   ||d  d t kr(| ||ttf n| ||ttf | drL|   d S )Nr&   r   )r   r   r   r   r   r   r   )rZ   r7   r   r-   r-   r1   _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   )rZ   r7   r   r-   r-   r1   _check_surrounded_by_space  s    z(FormatChecker._check_surrounded_by_spacec          
      sn  dd } fdd}ddg}|| }||d  |f|||d  fg}xnt t||D ]\\}	\}
}||	 d tksT|
tkrzqTt| }|d krqT|
tkr|dkp|
tko|dk||	< qTW g }t|s|d |d kr||d df n.x,t||d	D ]\}}
}|s||
|f qW xV|D ]N\}
}||}||
\}} j	d
|d d ||||t
|f|d d d qW d S )Nc             S   s   | t krdS dS )N)zExactly oneZrequired)ZNoZallowed)r   )r   r-   r-   r1   _policy_string  s    z2FormatChecker._check_space.<locals>._policy_stringc                sR   | d dkrdS | d dkr dS | d dkr0dS | d dkr@dS   d	rNd
S dS )Nr&   r   Zcommar   z()[]{}r   )r   r   z<=z>=z!=z==Z
comparisonr   zkeyword argument assignmentZ
assignment)r   )r.   )rZ   r-   r1   _name_construct  s    
z3FormatChecker._check_space.<locals>._name_constructTr&   r   Zaround)ZbeforeZafterzbad-whitespacer'   )r>   re   
col_offset)	enumeratezip_EOLr   r3   r   r   anyrP   r   r2   )rZ   r7   r   Zpoliciesr   r   Z
good_spacer.   ZpairsZ	other_idxr   Z
token_pairZdistancewarningsokr;   Z	constructcountr   r-   )rZ   r1   r     s6     
zFormatChecker._check_spacec             C   s   | j d |kS )Nr)   )r   )rZ   leftr-   r-   r1   r     s    zFormatChecker._inside_bracketsc          	   C   s|   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 }x&|D ]\}}x|D ]}|||< qdW qVW |S )N=r   r   r   )_KEYWORD_TOKENSr   _OPENING_BRACKETSr   r   r   r   _SPACED_OPERATORSr   r   r   r   )rZ   rawdispatchr7   handlerr.   r-   r-   r1   _prepare_token_dispatcher  s    



z'FormatChecker._prepare_token_dispatcherc          	   C   s  dg| _ dg}d}d}i | _i | _|  }d| _d}t|| j| _xt|D ]\}\}}	}
}}|
d |kr|
d }|t	j
kr| t||d |d  n| t||d | |t	jkrd}| t|| | j  | |	| n|t	j
kr"d}| |	|d d | ||d d  n|t	jkrHd}t|dkr|d= nv|t	jkr|dsd|}| t||d  | j  n:|t	jt	jfkr| j| |rd}| ||d | |t	jkr|	dr| jd	|d
 y||	 }W n tk
r   Y qNX ||| qNW |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r|dkr| jd|d
 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)   z
lzlowercase-l-suffix)r>   ztoo-many-lines)re   r>   ztrailing-newlines)*r   r   r   r   _last_line_endingrr   rx   r   r   r5   INDENTr   rj   r   _process_retained_warningsr   _check_line_endingcheck_indent_levelrP   DEDENTrM   r:   strip_check_continued_indentationr   r6   ENCODINGr   NUMBERendswithr   KeyErrorZmax_module_linesr   Z
msgs_storeZget_message_definitionsZmsgidnextfiltermapZ_pragma_linenoget)rZ   r7   indentsZcheck_equalr   Ztoken_handlersZlast_blank_line_numrl   tok_typer.   r   _r>   r   Zmessage_definitionnamesr-   r-   r1   process_tokens  sv    	 




zFormatChecker.process_tokensc             C   sx   | j d k	r&|r&|| j kr&| jd|d || _ | jj}|rttdd |d}|dkrTdnd}||krt| jd	||f|d
 d S )Nzmixed-line-endings)r>   c             S   s   | |kr| | S | S )Nr-   )xyr-   r-   r1   <lambda>C  s    z2FormatChecker._check_line_ending.<locals>.<lambda>r=   r*   r   r   zunexpected-line-ending-format)re   r>   )r   r   rx   Zexpected_line_ending_formatr   )rZ   Zline_endingr   expectedr-   r-   r1   r   4  s    
z FormatChecker._check_line_endingc                s   t ||d }xt| jjD ]h\}}}|||   fdd| D }|rd tkrd| |||| q|s tkr| |||| qW d S )Nr   c                s   i | ]\}}| kr||qS r-   r-   )rE   kv)
block_typer-   r1   rd   Q  s    z<FormatChecker._process_retained_warnings.<locals>.<dictcomp>)r9   r   rv   rp   itemsrh   _add_continuation_messagerg   )rZ   r7   Zcurrent_posZsingle_line_block_stmtZ
indent_posr   indentationsZhintsr-   )r	  r1   r   L  s    z(FormatChecker._process_retained_warningsc                s   fdd}| j jr&tjkr*d S | j \}}|tjsN|tjr`d|d < |j	t
tfkr|kr| j || nB|krt t fdd|D s| || d S )Nc                s      | ko  d | kS )Nr'   )r4   )
token_type)next_idxr7   r-   r1   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)rM   )rE   r   )length_indentationr-   r1   	<genexpr>w  s   z=FormatChecker._check_continued_indentation.<locals>.<genexpr>)r   rz   r4   r5   r:   r   r6   r   rp   rY   r   r   r   rM   r   r  )rZ   r7   r  r  r   r   r-   )r  r  r7   r1   r   W  s"    

z*FormatChecker._check_continued_indentationc       	   	   C   sL   t |j \}}t|||\}}| jd||||||||fd d S )Nzbad-continuation)r>   re   )_CONTINUATION_MSG_PARTSrY   rU   rp   r   rm   r>   )	rZ   r   r  r7   r;   Zreadable_typeZreadable_positionZ	hint_linerS   r-   r-   r1   r  ~  s    z'FormatChecker._add_continuation_messagezmultiple-statementsc          	   C   sH  |j s
dS | jsdS | }|dk	r0|j}n:t|jtjr^||jj	kr^|jj
d jd }n|j j}|j}|s|t|||kr| j|dkr| || dS || jkrdS y
|j}W n tk
r   |j}Y nX |st|g }xZt||d D ]H}d| j|< y|| j|   W q tk
r>   |d Y qX qW dS )z7check the node line number and check it if not yet doneNr   r&   r'   r=   )Zis_statementrootZpure_pythonZprevious_siblingZ
fromlineno
isinstanceparentr   
TryFinallyZ	finalbodybodytolinenoZ	statementAssertionErrorr   r   _check_multi_statement_lineZblockstart_tolinenoAttributeErrorr   rP   r   rstripr   )rZ   nodeZ	prev_siblZ	prev_liner>   r  linesr-   r-   r1   visit_default  s<    



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rP|jjsP| jj	rPdS t |jtj
rzt|jjdkrz| jjrzdS | jd|d d| j|< dS )z/Check for lines containing multiple statements.Nr&   zmultiple-statements)r  r'   )r  r   ZWithZ	TryExceptr  r  ZIfZorelserx   Zsingle_line_if_stmtZClassDefrM   r  Zsingle_line_class_stmtr   r   )rZ   r  r>   r-   r-   r1   r    s    z)FormatChecker._check_multi_statement_linec          
      s   j jj j  fdd}ddddddddd	d
h
}g }xZ|dD ]L}|d |krd|| qH|r|| d|}g }|||}|dkrHP qHW |r|d|| dS )zBcheck lines have less than a maximum number of characters
        c                s   |  dsjd|d nH| d}|s6tjjkr6n(| t|d  dkr^jd|t|d |} t| }|rd| kr|	d	
d\}}}| d
krddd |dD krd S | dd	d  } t| kr | sjd|t| fd |d	 S )Nr*   zmissing-final-newline)r>   z	
 )r*   z
ztrailing-whitespace)r>   r   r   r&   disablezline-too-longc             S   s   h | ]}|  qS r-   )r   )rE   Z_msg_idr-   r-   r1   	<setcomp>  s   z@FormatChecker.check_lines.<locals>.check_line.<locals>.<setcomp>r   #r   )r>   re   )r   r   r  _EMPTY_LINErx   r   rM   r
   searchgroup	partitionr   r   rsplit)r>   r   Zstripped_lineZmobjZfront_of_equalr   Zback_of_equal)ignore_long_line	max_charsrZ   r-   r1   
check_line  s(    


z-FormatChecker.check_lines.<locals>.check_line   u    u    Tr)   r=   N)rx   Zmax_line_lengthZignore_long_lines
splitlinesrP   rR   )rZ   r  r   r*  Zunsplit_endsZunsplitr>   r-   )r(  r)  rZ   r1   r     s6    



zFormatChecker.check_linesc       
      C   s   | j j}|dkrd}d}t|}x(|d| |krH||d }|d7 }q"W d}xf|r|d dkr|d |d kr|d dkrd}nd	}| jd
||d |S ||d 7 }|dd }qPW ||ks|rd}	|d dkrd}	| jd||| t| |	|| fd dS )z.return the indent level of the string
        z\trB   r   Nr&   r=   z 	)tabspace)r3  r2  zmixed-indentation)re   r>   ZspacesZtabszbad-indentation)r>   re   )rx   r{   rM   r   )
rZ   stringr  r   rF   levelZ	unit_sizeZsupplre   Zi_typer-   r-   r1   r     s6    z FormatChecker.check_indent_level)N)-r\   r]   r^   rq   r   r   r   Z__implements__nameMSGSZmsgsrR   _DEFAULT_NO_SPACE_CHECK_CHOICES_NO_SPACE_CHECK_CHOICESr   r   r#  Zoptionsr[   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r   r   r   r  r   r  r  r   r   r-   r-   r-   r1   r   C  s   
 
L	
3d'*Ar   c             C   s   |  t|  dS )z.required method to auto register this checker N)Zregister_checkerr   )r   r-   r-   r1   register7  s    r:  c              C   s   xt dD ]} q
W t|  d S )Nr   )r   r   )valr-   r-   r1   funkier<  s    r<  )Drq   r   sysr5   	functoolsr   Zastroidr   Zpylint.interfacesr   r   r   Zpylint.checkersr   Zpylint.checkers.utilsr   Zpylint.utilsr	   r
   r   r   r   version_inforP   r   r   r   rC   	frozensetr   r:   r6   r   r   r   r   r   r   r   r#  r9  r8  ZNODEr7  r2   r3   r9   r<   rA   rD   rU   rV   r   r   r   r   r   rg   rh   r  rO   rf   ri   rj   rr   r   r:  r<  r-   r-   r-   r1   <module>,   s   








% /     y