B
    mJv\K                @   s
  d Z ddlZddlZddlZddlZddlZddlm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 ddlmZ ddlmZ dd	lmZ dd
lmZ ddlmZ G dd dZG dd deZG dd deZG dd deZG dd deZG dd deZeeeeedZe dZ!dZ"dZ#e#e"ffZ$e%dZ&ej'ej(ej)ej*fZ+dZ,ej-Z.de. Z/ej0dkZ1ej0dkZ2ej0d kZ3d!d"hZ4d#d$hZ5e6e7d%d& d'D d(d)d*gZ8d+d,d-d.d/Z9e%d0Z:e%d1Z;d2d3 Z<d4d5 Z=d6d7 Z>d8d9 Z?d:d; Z@d<d= ZAd>ZBd?d@ ZCdpdAdBZDdCdD ZEdEdF ZFdGdH ZGG dIdJ dJejHZIG dKdL dLeIZJG dMdN dNeIZKdOdPdQdRdSdTdUdVdWdXh
ZLdOdYdQdRdSdZdUdVd[d\d]
ZMd^d_d`d^d^d^d^d^dadad]
ZNdbdc ZOG ddde deeIZPG dfdg dgeIZQG dhdi dieIZRdjdk ZSG dldm dmeIZTdndo ZUdS )qzbasic checker for Python code    N)Pattern)checkers)
exceptions)
interfaces)utils)	reporters)get_node_last_lineno)nodesc               @   s0   e Zd ZdZdZdZdZdZdZe	dd Z
dS )NamingStyleNc             C   s2   | j | j| j| j| j| j| j| j| j| jd
| S )N)
moduleconstclassfunctionmethodattrargumentvariableclass_attribute	inlinevar)MOD_NAME_RGXCONST_NAME_RGXCLASS_NAME_RGXDEFAULT_NAME_RGXCLASS_ATTRIBUTE_RGXCOMP_VAR_RGX)cls	name_type r   3lib/python3.7/site-packages/pylint/checkers/base.py	get_regexI   s    zNamingStyle.get_regex)__name__
__module____qualname__r   r   r   r   r   r   classmethodr   r   r   r   r   r
   =   s   r
   c               @   sL   e Zd ZdZedZedZedZedZ	edZ
edZdS )	SnakeCaseStylez(Regex rules for snake_case naming style.z[a-z_][a-z0-9_]+$z([a-z_][a-z0-9_]*)$z(([a-z_][a-z0-9_]*)|(__.*__))$z[a-z_][a-z0-9_]*$z<(([a-z_][a-z0-9_]{2,})|(_[a-z0-9_]*)|(__[a-z][a-z0-9_]+__))$z!(([a-z_][a-z0-9_]{2,}|(__.*__)))$N)r    r!   r"   __doc__recompiler   r   r   r   r   r   r   r   r   r   r$   Y   s   



r$   c               @   sL   e Zd ZdZedZedZedZedZ	edZ
edZdS )	CamelCaseStylez'Regex rules for camelCase naming style.z[a-z_][a-zA-Z0-9]+$z([a-z_][a-zA-Z0-9]*)$z (([a-z_][A-Za-z0-9]*)|(__.*__))$z[a-z_][A-Za-z0-9]*$z3(([a-z_][a-zA-Z0-9]{2,})|(__[a-z][a-zA-Z0-9_]+__))$z!([a-z_][A-Za-z0-9]{2,}|(__.*__))$N)r    r!   r"   r%   r&   r'   r   r   r   r   r   r   r   r   r   r   r(   f   s   




r(   c               @   sL   e Zd ZdZedZedZedZedZ	edZ
edZdS )PascalCaseStylez(Regex rules for PascalCase naming style.z[A-Z_][a-zA-Z0-9]+$z (([A-Z_][A-Za-z0-9]*)|(__.*__))$z0[A-Z_][a-zA-Z0-9]{2,}$|(__[a-z][a-zA-Z0-9_]+__)$z[A-Z_][a-zA-Z0-9]{2,}$N)r    r!   r"   r%   r&   r'   r   r   r   r   r   r   r   r   r   r   r)   q   s   




r)   c               @   sL   e Zd ZdZedZedZedZedZ	edZ
edZdS )UpperCaseStylez(Regex rules for UPPER_CASE naming style.z[A-Z_][A-Z0-9_]+$z(([A-Z_][A-Z0-9_]*)|(__.*__))$z/([A-Z_][A-Z0-9_]{2,})|(__[a-z][a-zA-Z0-9_]+__)$z[A-Z_][A-Z0-9_]{2,}$N)r    r!   r"   r%   r&   r'   r   r   r   r   r   r   r   r   r   r   r*   |   s   




r*   c               @   s   e Zd Zedd ZdS )AnyStylec             C   s
   t dS )Nz.*)r&   r'   )r   r   r   r   r   r      s    zAnyStyle.get_regexN)r    r!   r"   r#   r   r   r   r   r   r+      s   r+   )
snake_caseZ	camelCase
PascalCase
UPPER_CASEanyz^___reversed__)__getitem____len__)iszis notz==z!=inznot inzunittest.casez%s.type)   r5   )r5   r   )r5      z_py_abc.ABCMetazabc.ABCMetaZexemptignorec             C   s   g | ]}d  t|gqS ).)joinBUILTINS).0xr   r   r   
<listcomp>   s    r=   )setdictlistzset()z{}z[]>z>=<z<=)rB   z<=rA   z>=)z==z!=rB   rA   z<=z>=)r!   c             C   s   | }x|r t |jtjs |j}qW |r4t|jts8dS |jj}xP|tjtj	fD ]:}x4|j
D ]*\}}|r||| jkrdS q`|| jkr`dS q`W qTW dS )z Detect that the given node (AssignName) is inside an
    exception handler and redefines an import from the tryexcept body.
    Returns True if the node redefines an import, False otherwise.
    FT)
isinstanceparentastroidExceptHandlerr   Zerror_of_typeImportErrornodes_of_classZ
ImportFromZImportnamesname)nodecurrentZ	try_blockZimport_noderJ   aliasr   r   r   _redefines_import   s    


rN   c             C   s@   | j }x4|dk	r:t|tjtjtjtjtjfr2dS |j }qW dS )z4return True if the node is inside a kind of for loopNTF)rD   rC   rE   ForZListCompZSetCompZDictCompGeneratorExp)rK   rD   r   r   r   in_loop   s    


rQ   c             C   s<   x6| D ].}t |ttfr(t||r4dS q||krdS qW dS )zUreturn true if the object is an element of <nested_list> or of a nested
    list
    TF)rC   r@   tuplein_nested_list)Znested_listobjZelmtr   r   r   rS      s    

rS   c             C   sJ   t jt jf}| j}x2t||r.| t|dg krD|} |j}|dkrP qW |S )z
    Returns the loop node that holds the break node in arguments.

    Args:
        break_node (astroid.Break): the break node of interest.

    Returns:
        astroid.For or astroid.While: the loop node holding the break node.
    orelseN)rE   rO   WhilerD   rC   getattr)Z
break_node
loop_nodesrD   r   r   r   _get_break_loop_node   s    
rY   c                sV   t jt jf}t jt jf}fddj||dD  t fddjt j|dD S )z
    Returns true if a loop may ends up in a break statement.

    Args:
        loop (astroid.For, astroid.While): the loop node inspected.

    Returns:
        bool: True if the loop may ends up in a break statement, False otherwise.
    c                s   g | ]}| kr|qS r   r   )r;   _node)loopr   r   r=     s   z%_loop_exits_early.<locals>.<listcomp>)
skip_klassc             3   s   | ]}t | kr|V  qd S )N)rY   )r;   rZ   )inner_loop_nodesr   r   	<genexpr>  s   z$_loop_exits_early.<locals>.<genexpr>)rE   rO   rV   FunctionDefClassDefrH   r/   ZBreak)r[   rX   Zdefinition_nodesr   )r]   r[   r   _loop_exits_early   s    


ra   c             C   s.   | d k	o,| j d k	o,| j tko,|dkp,|tjkS )Nr   )	lastgroupEXEMPT_NAME_CATEGORIESr   INFERENCE_FAILURE)match	node_type
confidencer   r   r   _is_multi_naming_match  s    

rh   zbuiltins.propertyc             C   s>   t h}t }| dk	r6|| j |dd | jD  ||fS )zReturns a tuple of property classes and names.

    Property classes are fully qualified, such as 'abc.abstractproperty' and
    property names are the actual names, such as 'abstract_property'.
    Nc             s   s   | ]}| d dd V  qdS )r8      N)rsplit)r;   Zpropr   r   r   r^   /  s    z"_get_properties.<locals>.<genexpr>)BUILTIN_PROPERTYr>   updateproperty_classes)configrn   property_namesr   r   r   _get_properties$  s    rq   c             C   s   t |\}}|  sdS | jr(| jj}ng }xh|D ]`}t|tjsXt|tjrx|j|krxt	
|}|r| |krdS q2t|tjr2|jdkr2dS q2W dS )a\  Determine the name type whose regex the a function's name should match.

    :param node: A function node.
    :type node: astroid.node_classes.NodeNG
    :param config: Configuration from which to pull additional property classes.
    :type config: :class:`optparse.Values`

    :returns: One of ('function', 'method', 'attr')
    :rtype: str
    r   r   )setterdeleterr   )rq   	is_method
decoratorsr	   rC   rE   Name	Attributeattrnamer   
safe_inferqname)rK   ro   rn   rp   ru   	decoratorinferedr   r   r   _determine_function_name_type4  s"    



r}   c             C   s   t t| dkS )z
    Determine if the given `node` has abstract methods.

    The methods should be made abstract by decorating them
    with `abc` decorators.
    r   )lenr   Zunimplemented_abstract_methods)rK   r   r   r   _has_abstract_methodsZ  s    r   c             C   s|  i }xdD ]}y|| }W n t k
r6   t Y nX i ||< |dkr
y0||d|   }|d | }d| || d< W n  t k
r   d|| d< Y nX y(|d|  d | }d| || d	< W q
 t k
r   d|| d	< Y q
X q
W d
}xtdD ]l}|| }	||d}
|
dk	r"t|
|	}nd\}
}||t|	t|
||| dd|| d	df7 }qW | tj	|ddd dS )zymake a report of

    * percentage of different types documented
    * percentage of different types with a bad name
    )r   r   r   r   r   undocumented_g      Y@z%.2fZpercent_documentedNCbadname_Zpercent_badname)typeZnumberz
old number
differencez%documentedz%badnameN)r   r   0   ri   )ZchildrenZcolsZrheaders)
KeyErrorr   ZEmptyReportErrorgetr   Zdiff_stringstrappendreporter_nodesZTable)ZsectstatsZ	old_statsZ
nice_statsrf   ZtotalZ
documentedZpercentlinesnewoldZdiff_strr   r   r   report_by_type_statsd  sD    


r   c             C   s@   | j r<x4| j jD ](}t|tjrt|jdd| jkrdS qW dS )zreturn True if the object is a method redefined via decorator.

    For example:
        @property
        def x(self): return self._x
        @x.setter
        def x(self, value): self._x = value
    rJ   NTF)ru   r	   rC   rE   rw   rW   exprrJ   )rK   r{   r   r   r   redefined_by_decorator  s    	r   c               @   s   e Zd ZejZdZdS )_BasicCheckerbasicN)r    r!   r"   r   IAstroidChecker__implements__rJ   r   r   r   r   r     s   r   c               @   s  e Zd Zddddddddd	d
difdddddddddddddddifdZeddd Zdd  Zed!d"d#d$ Zed%d&d' Z	ed(d)ddd*d+dd,d- Z
e
Zd.d/ Zd0d1 Zed2d3d4 Zed5d6d7 Zed5d8d9 Zed:d;d<d= Zed:d>d? Zed@dAdB Zed@dCdD ZedEdFdG ZdHdI ZedJdKdL ZedMdNdO ZdPdQ ZdRdS ZdTdU ZdVdW ZdXdY ZdZS )[BasicErrorChecker)z__init__ method is a generatorzinit-is-generatorz^Used when the special class method __init__ is turned into a generator by a yield in its body.)zExplicit return in __init__zreturn-in-initzIUsed when the special class method __init__ has an explicit return value.)z%s already defined line %szfunction-redefinedz3Used when a function / class / method is redefined.)z%r not properly in loopznot-in-loopz=Used when break or continue keywords are used outside a loop.)zReturn outside functionzreturn-outside-functionzEUsed when a "return" statement is found outside a function or method.)zYield outside functionzyield-outside-functionzDUsed when a "yield" statement is found outside a function or method.z%Return with argument inside generatorzreturn-arg-in-generatorzUsed when a "return" statement with an argument is found outside in a generator function or method (e.g. with some "yield" statements).Z
maxversion)r5   r5   )z#Use of the non-existent %s operatorznonexistent-operatorzzUsed when you attempt to use the C-style pre-increment or pre-decrement operator -- and ++, which doesn't exist in Python.)z1Duplicate argument name %s in function definitionzduplicate-argument-namezCDuplicate argument names in function definitions are syntax errors.)z4Abstract class %r with abstract methods instantiatedzabstract-class-instantiatedzeUsed when an abstract class with `abc.ABCMeta` as metaclass has abstract methods and is instantiated.)z-Else clause on loop without a break statementzuseless-else-on-loopzLoops should only have an else clause if they can exit early with a break statement, otherwise the statements under else should be on the same scope as the loop itself.)z.More than one starred expression in assignmentztoo-many-star-expressionszhEmitted when there are more than one starred expressions (`*x`) in an assignment. This is a SyntaxError.)z4Starred assignment target must be in a list or tuplezinvalid-star-assignment-targetzFEmitted when a star expression is used as a starred assignment target.)z4Can use starred expression only in assignment targetzstar-needs-assignment-targetzCEmitted when a star expression is not used in an assignment target.)zName %r is nonlocal and globalznonlocal-and-globalz0Emitted when a name is both nonlocal and global.)z0'continue' not supported inside 'finally' clausezcontinue-in-finallyz]Emitted when the `continue` keyword is found inside a finally clause, which is a SyntaxError.)z&nonlocal name %s found without bindingznonlocal-without-bindingz^Emitted when a nonlocal variable does not have an attached name somewhere in the parent scopesz+Name %r is used prior to global declarationzused-prior-global-declarationzcEmitted when a name is used prior a global declaration, which results in an error since Python 3.6.Z
minversion)r5   r   )ZE0100ZE0101ZE0102ZE0103ZE0104ZE0105ZE0106ZE0107ZE0108ZE0110ZW0120ZE0112ZE0113ZE0114ZE0115ZE0116ZE0117ZE0118zfunction-redefinedc             C   s   |  d| d S )Nr   )_check_redefinition)selfrK   r   r   r   visit_classdef  s    z BasicErrorChecker.visit_classdefc             C   sH   d}x:|  D ].}t|tjr(| |S t|tjr|d7 }qW |dkS )Nr   ri   )ZiteredrC   rE   Tuple_too_many_starred_for_tupleStarred)r   Zassign_tupleZstarred_countelemr   r   r   r     s    
z-BasicErrorChecker._too_many_starred_for_tupleztoo-many-star-expressionszinvalid-star-assignment-targetc             C   sV   |j d }t|j d tjr*| jd|d t|tjs:d S | |rR| jd|d d S )Nr   zinvalid-star-assignment-target)rK   ztoo-many-star-expressions)ZtargetsrC   rE   r   add_messager   r   )r   rK   Zassign_targetr   r   r   visit_assign"  s    

zBasicErrorChecker.visit_assignzstar-needs-assignment-targetc             C   sv   t |jtjrdS tr6t |jtjtjtjtjfr6dS |	 }t |tj
sNdS |j|ksd|j|rr| jd|d dS )z@Check that a Starred expression is used in an assignment target.Nzstar-needs-assignment-target)rK   )rC   rD   rE   CallPY35Listr   SetDictZ	statementAssignvalueZ	parent_ofr   )r   rK   Zstmtr   r   r   visit_starred/  s    zBasicErrorChecker.visit_starredzinit-is-generatorzreturn-in-initzduplicate-argument-nameznonlocal-and-globalc       
      C   s  |  | | | t|s>t|s>| | r6dp8d| |jtj	tj
tjfd}| r|jdkr| r| jd|d qdd |D }td	d
 |D r| jd|d nF| rtsx8|D ]0}t|jtjr|jjd k	r| jd||jd qW tt}td |jj|jjg}x&tj|D ]}||j | q$W xH| D ]<}t |dkrHx&|D ]}	| jd|	j!|	|	jfd q`W qHW d S )Nr   r   )r\   __init__zinit-is-generator)rK   c             S   s   g | ]
}|j qS r   )r   )r;   rr   r   r   r=   [  s    z7BasicErrorChecker.visit_functiondef.<locals>.<listcomp>c             s   s   | ]}t |s|V  qd S )N)r   Zis_none)r;   vr   r   r   r^   ]  s    z6BasicErrorChecker.visit_functiondef.<locals>.<genexpr>zreturn-in-initzreturn-arg-in-generator)rK   lineri   zduplicate-argument-name)r   rK   args)"_check_nonlocal_and_global_check_name_used_prior_globalr   r   Z(is_registered_in_singledispatch_functionr   rt   rH   rE   ZReturnr_   r`   rJ   Zis_generatorr   r/   PY33rC   r   Const
fromlinenocollectionsdefaultdictr@   filterr   Z
kwonlyargs	itertoolschainfrom_iterabler   valuesr~   lineno)
r   rK   Zreturnsr   ZretnodeZarg_clustersZ	argumentsargZargument_duplicatesr   r   r   r   visit_functiondefC  sF    






z#BasicErrorChecker.visit_functiondefc                s    fdd  tjD }|s"d S x^  tjD ]N}|  k	rBq0|j}||}|sXq0|j}|r0||jkr0| jd||fd q0W d S )Nc                s*   i | ]"}|j D ]}|  kr||qqS r   )rI   scope)r;   childrJ   )rK   r   r   
<dictcomp>  s   
zCBasicErrorChecker._check_name_used_prior_global.<locals>.<dictcomp>zused-prior-global-declaration)rK   r   )	rH   rE   Globalrv   r   rJ   r   r   r   )r   rK   Zscope_globals	node_namerJ   Zcorresponding_globalZglobal_linenor   )rK   r   r     s    

z/BasicErrorChecker._check_name_used_prior_globalc                s    fddt jj}t|fdd tjD }|s>dS t|fdd tjD }x$||D ]}| j	d|f d qlW dS )	z.Check that a name is both nonlocal and global.c                s   |    kS )N)r   )rL   )rK   r   r   
same_scope  s    z@BasicErrorChecker._check_nonlocal_and_global.<locals>.same_scopec             3   s   | ]} |r|j V  qd S )N)rI   )r;   r   )r   r   r   r^     s   z?BasicErrorChecker._check_nonlocal_and_global.<locals>.<genexpr>Nc             3   s   | ]} |r|j V  qd S )N)rI   )r;   r   )r   r   r   r^     s   znonlocal-and-global)r   rK   )
r   r   r   r>   rH   rE   ZNonlocalr   intersectionr   )r   rK   Z	from_iterZ	nonlocalsZglobal_varsrJ   r   )rK   r   r   r     s    

z,BasicErrorChecker._check_nonlocal_and_globalzreturn-outside-functionc             C   s"   t | tjs| jd|d d S )Nzreturn-outside-function)rK   )rC   framerE   r_   r   )r   rK   r   r   r   visit_return  s    zBasicErrorChecker.visit_returnzyield-outside-functionc             C   s   |  | d S )N)_check_yield_outside_func)r   rK   r   r   r   visit_yield  s    zBasicErrorChecker.visit_yieldc             C   s   |  | d S )N)r   )r   rK   r   r   r   visit_yieldfrom  s    z!BasicErrorChecker.visit_yieldfromznot-in-loopzcontinue-in-finallyc             C   s   |  |d d S )Ncontinue)_check_in_loop)r   rK   r   r   r   visit_continue  s    z BasicErrorChecker.visit_continuec             C   s   |  |d d S )Nbreak)r   )r   rK   r   r   r   visit_break  s    zBasicErrorChecker.visit_breakzuseless-else-on-loopc             C   s   |  | d S )N)_check_else_on_loop)r   rK   r   r   r   	visit_for  s    zBasicErrorChecker.visit_forc             C   s   |  | d S )N)r   )r   rK   r   r   r   visit_while  s    zBasicErrorChecker.visit_whileznonexistent-operatorc             C   s@   |j dkr<t|jtjr<|jj |j kr<| jd||j d d dS )z9check use of the non-existent ++ and -- operator operatorz+-znonexistent-operator   )rK   r   N)oprC   operandrE   UnaryOpr   )r   rK   r   r   r   visit_unaryop  s    
zBasicErrorChecker.visit_unaryopc             C   sz   |  }xN|jd krP t|tjtjfs>| jd|f|d d S ||jkrT|j  }q
d S t|tjsv| jd|f|d d S )Nznonlocal-without-binding)r   rK   )r   rD   rC   rE   r`   r_   r   locals)r   rK   rJ   Zcurrent_scoper   r   r   _check_nonlocal_without_binding  s    


z1BasicErrorChecker._check_nonlocal_without_bindingznonlocal-without-bindingc             C   s    x|j D ]}| || qW d S )N)rI   r   )r   rK   rJ   r   r   r   visit_nonlocal  s    z BasicErrorChecker.visit_nonlocalzabstract-class-instantiatedc             C   s@   y$x|j  D ]}| || qW W n tjk
r:   dS X dS )zS Check instantiating abstract class with
        abc.ABCMeta as metaclass.
        N)funcinfer!_check_inferred_class_is_abstractrE   InferenceError)r   rK   inferredr   r   r   
visit_call  s
    zBasicErrorChecker.visit_callc             C   s   t |tjsd S t|}||kr&d S t|}|s6d S | }|d kr~x2| D ]&}| dkrP| j	d|j
f|d P qPW d S | tkr| j	d|j
f|d d S )Nzabc.ABCzabstract-class-instantiated)r   rK   )rC   rE   r`   r   Znode_frame_classr   	metaclass	ancestorsrz   r   rJ   ABC_METACLASSES)r   r|   rK   klassZabstract_methodsr   ancestorr   r   r   r     s&    
z3BasicErrorChecker._check_inferred_class_is_abstractc             C   s(   t | tjtjfs$| jd|d d S )Nzyield-outside-function)rK   )rC   r   rE   r_   Lambdar   )r   rK   r   r   r   r   '  s    z+BasicErrorChecker._check_yield_outside_funcc             C   s.   |j r*t|s*| jd||j d jd d dS )z>Check that any loop with an else clause has a break statement.zuseless-else-on-loopr   ri   )rK   r   N)rU   ra   r   r   )r   rK   r   r   r   r   +  s
    z%BasicErrorChecker._check_else_on_loopc             C   s   |j }xr|rxt|tjtjfr,||jkr,dS t|tjtjfr@P t|tjrp||j	krpt|tj
rp| jd|d |j }qW | jd||d dS )z/check that a node is inside a for or while loopNzcontinue-in-finally)rK   znot-in-loop)rK   r   )rD   rC   rE   rO   rV   rU   r`   r_   Z
TryFinally	finalbodyZContinuer   )r   rK   r   rZ   r   r   r   r   7  s    


z BasicErrorChecker._check_in_loopc             C   s   |j  }||j }||k	r|t||s|t|tjrB|jtkrBdS tj	| ddd}|rf|
|jrfdS | jd|||jfd dS )z:check for redefinition of a function / method / class nameNzdummy-variables-rgx)defaultzfunction-redefined)rK   r   )rD   r   rJ   rE   Zare_exclusiverC   r`   REDEFINABLE_METHODS
lint_utilsZget_global_optionre   r   r   )r   Z	redeftyperK   Zparent_frameZdefined_selfZdummy_variables_rgxr   r   r   r   L  s    


z%BasicErrorChecker._check_redefinitionN)r    r!   r"   msgsr   check_messagesr   r   r   r   r   visit_asyncfunctiondefr   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r     sn   	4
%r   c               @   s  e Zd ZdZejZdZddddddd	d
ddddddddZdde	ffZ
dd Zdd Zeddd Zeddd Zeddd Zd d! Zd"d# Zd$d% Zed&d'd(d)d* Zed+d, Zed-d. Zed/d0d1 Zed2d3d4 ZeZd5d6 Zed7d8d9d: Zed7d;d< Zed7d8d=d> Zed7d?d@ Z edAdBdC Z!dDdE Z"edFdAdGdHdIdJ Z#edKdLdM Z$edNdOdP Z%dQdR Z&dSdT Z'dUdV Z(d`dXdYZ)dZd[ Z*ed\d]d^ Z+d_S )aBasicCheckera*  checks for :
    * doc strings
    * number of arguments, local variables, branches, returns and statements in
    functions, methods
    * required module attributes
    * dangerous default values as arguments
    * redefinition of function / method / class
    * uses of the global statement
    r   )zUnreachable codeunreachablezbUsed when there is some code behind a "return" or "raise" statement, which will never be accessed.)z&Dangerous default value %s as argumentzdangerous-default-valuez_Used when a mutable value as list or dictionary is detected in a default value for an argument.)z!Statement seems to have no effectzpointless-statementzEUsed when a statement doesn't have (or at least seems to) any effect.)zString statement has no effectzpointless-string-statementzUsed when a string is used as a statement (which of course has no effect). This is a particular case of W0104 with its own message so you can easily disable it if you're using those strings as documentation, instead of comments.)z&Expression "%s" is assigned to nothingzexpression-not-assignedzqUsed when an expression that is not a function call is assigned to nothing. Probably something else was intended.)zLambda may not be necessaryzunnecessary-lambdazUsed when the body of a lambda expression is a function call on the same argument list as the lambda itself; such lambda expressions are in all but a few cases replaceable with the function being called in the body of the lambda.)zDuplicate key %r in dictionaryzduplicate-keyzDUsed when a dictionary expression binds the same key multiple times.)zUse of execz	exec-usedz~Used when you use the "exec" statement (function for Python 3), to discourage its usage. That doesn't mean you cannot use it !)zUse of evalz	eval-usedzUsed when you use the "eval" function, to discourage its usage. Consider using `ast.literal_eval` for safely evaluating strings containing Python expressions from untrusted sources. )z3%s statement in finally block may swallow exceptionzlost-exceptionzUsed when a break or a return statement is found inside the finally clause of a try...finally block: the exceptions raised in the try clause will be silently swallowed instead of being re-raised.)z5Assert called on a 2-uple. Did you mean 'assert x,y'?zassert-on-tuplezA call of assert on a tuple will always evaluate to true if the tuple is not empty, and will always evaluate to false if it is.)z?Following "as" with another context manager looks like a tuple.zconfusing-with-statementa2  Emitted when a `with` statement component returns multiple values and uses name binding with `as` only for a part of those values, as in with ctx() as a, b. This can be misleading, since it's not clear if the context manager returns a tuple or if the node without a name binding is another context manager.)z3Using a conditional statement with a constant valuezusing-constant-testzEmitted when a conditional statement (If or ternary if) uses a constant value for its test. This might not be what the user intended to do.)z/The first reversed() argument is not a sequencezbad-reversed-sequencezUsed when the first argument to reversed() builtin isn't a sequence (does not implement __reversed__, nor __getitem__ and __len__)z$format function is not called on strzmisplaced-format-functionzEmitted when format function is not called on str object. e.g doing print("value: {}").format(123) instead of print("value: {}".format(123)). This might not be what the user intended to do.)ZW0101ZW0102ZW0104ZW0105ZW0106ZW0108ZW0109ZW0122ZW0123ZW0150ZW0199ZW0124ZW0125ZE0111ZE0119ZRP0101zStatistics by typec             C   s   t | | d | _d | _d S )N)r   r   r   _tryfinallys)r   linterr   r   r   r     s    zBasicChecker.__init__c             C   s    g | _ | jjddddd| _dS )z2initialize visit variables and statistics
        r   )r   r   r   Zclass_N)r   r   	add_statsr   )r   r   r   r   open  s    zBasicChecker.openzusing-constant-testc             C   s   |  ||j d S )N)_check_using_constant_testtest)r   rK   r   r   r   visit_if  s    zBasicChecker.visit_ifc             C   s   |  ||j d S )N)r   r   )r   rK   r   r   r   visit_ifexp  s    zBasicChecker.visit_ifexpc             C   s&   |j r"x|j D ]}| || qW d S )N)Zifsr   )r   rK   Zif_testr   r   r   visit_comprehension  s    z BasicChecker.visit_comprehensionc          	   C   s   t jt jjt jt jt jt jjt j	t j
t jf	}t jt jt jf}t jt jt jt jt jt jf}d }t|t jf| | }t||st|}|st||r| jd|d d S )Nzusing-constant-test)rK   )rE   ModuleZscoped_nodesrP   r   r_   r`   bases	GeneratorZUnboundMethodBoundMethodr   r   r   rw   r   ZBinOpZBoolOpr   Z	SubscriptrC   r   r   ry   r   )r   rK   r   Zconst_nodesZstructsZexcept_nodesr   emitr   r   r   r     s,    	

z'BasicChecker._check_using_constant_testc             C   s   | j d  d7  < dS )z<check module name, docstring and required arguments
        r   ri   N)r   )r   _r   r   r   visit_module  s    zBasicChecker.visit_modulec             C   s   | j d  d7  < dS )zWcheck module name, docstring and redefinition
        increment branch counter
        r   ri   N)r   )r   rK   r   r   r   r   $  s    zBasicChecker.visit_classdefzpointless-statementzpointless-string-statementzexpression-not-assignedc             C   s
  |j }t|tjrt|j tr| }t|tjtjtjfrt|tjrT|j	dkrTn2|
 }|dk	r| |krt|tjtjfrdS | jd|d dS t|tjtjtjtjfst|jtjr|jj|gkrdS t|tjr| jd|| d n| jd|d dS )z3check for various kind of statements without effectr   Nzpointless-string-statement)rK   zexpression-not-assigned)rK   r   zpointless-statement)r   rC   rE   r   r   r   r`   r   r_   rJ   Zprevious_siblingr   Z	AnnAssignr   ZYieldZAwaitEllipsisr   rD   Z	TryExceptbodyr/   rH   	as_string)r   rK   r   r   Zsiblingr   r   r   
visit_expr*  s,    	zBasicChecker.visit_exprc             c   sJ   xD|D ]<}t |tjr<t |jtjrB|jj| jjkrB|V  q|V  qW d S )N)rC   rE   r   r   rv   rJ   r   vararg)rK   	call_argsr   r   r   r   _filter_varargZ  s    
zBasicChecker._filter_varargc             C   s>   | sdS x0| D ](}t |jtjr2|jj|kr6dS qdS qW dS )NTF)rC   r   rE   rv   rJ   )r   Zvariadic_namer   r   r   r   _has_variadic_argumenth  s    
z#BasicChecker._has_variadic_argumentzunnecessary-lambdac             C   s"  |j jrdS |j}t|tjs"dS t|jjtjrHt|jjjtjrHdS t	|j j }t	| 
||j }|j jr| |j|j jrdS n|js|jrdS |j jr| |j|j jrdS n
|jrdS t|t|krdS x6t||D ](\}}t|tjsdS |j|jkrdS qW | jd|j|d dS )z6check whether or not the lambda is suspicious
        Nzunnecessary-lambda)r   rK   )r   defaultsr   rC   rE   r   r   rw   r   r@   r  Zkwargr  kwargskeywordsr  Zstarargsr~   ziprv   rJ   r   r   )r   rK   callZordinary_argsZnew_call_argsr   Z
passed_argr   r   r   visit_lambdat  s8    zBasicChecker.visit_lambdazdangerous-default-valuec             C   s,   | j | rdpd  d7  < | | dS )zdcheck function name, docstring, arguments, redefinition,
        variable names, max locals
        r   r   ri   N)r   rt   _check_dangerous_default)r   rK   r   r   r   r     s    zBasicChecker.visit_functiondefc          	   C   s   dd }x|j jD ]}yt| }W n tjk
r>   wY nX t|tjr| t	kr||krnt	|  }ntt|tjs||r||r|
 }qt|tjrd|j| f }qd| | f }nd| t	|  f }| jd||fd qW d S )Nc             S   s   t | tjtjtjfS )N)rC   rE   r   r   r   )nr   r   r   <lambda>  s    z7BasicChecker._check_dangerous_default.<locals>.<lambda>z	%s() (%s)z%s (%s)zdangerous-default-value)rK   r   )r   r  nextr   rE   r   rC   Instancerz   DEFAULT_ARGUMENT_SYMBOLSZpytyper   rJ   r   r   )r   rK   Zis_iterabler   r   msgr   r   r   r    s(    
z%BasicChecker._check_dangerous_defaultr   zlost-exceptionc             C   s    |  | | |dtjf dS )z1 - check is the node has a right sibling (if so, that's some
        unreachable code)
        2 - check is the node is inside the finally clause of a try...finally
        block
        returnN)_check_unreachable_check_not_in_finallyrE   r_   )r   rK   r   r   r   r     s    
zBasicChecker.visit_returnc             C   s   |  | dS )z\check is the node has a right sibling (if so, that's some unreachable
        code)
        N)r  )r   rK   r   r   r   r     s    zBasicChecker.visit_continuec             C   s$   |  | | |dtjtjf dS )z1 - check is the node has a right sibling (if so, that's some
        unreachable code)
        2 - check is the node is inside the finally clause of a try...finally
        block
        r   N)r  r  rE   rO   rV   )r   rK   r   r   r   r     s    
zBasicChecker.visit_breakc             C   s   |  | dS )z\check if the node has a right sibling (if so, that's some unreachable
        code)
        N)r  )r   rK   r   r   r   visit_raise  s    zBasicChecker.visit_raisez	exec-usedc             C   s   | j d|d dS )z'just print a warning on exec statementsz	exec-used)rK   N)r   )r   rK   r   r   r   
visit_exec  s    zBasicChecker.visit_execc             C   s   t |jtjsd S |jjdkr"d S t|jj}|tjkr>d S |s|jj}t |tj	sZd S t |jtj
r|jjdkr| jd|d d S )Nformatprintzmisplaced-format-function)rK   )rC   r   rE   rw   rx   r   ry   r   Uninferabler   rv   rJ   r   )r   Z	call_noder   Z	call_exprr   r   r    _check_misplaced_format_function  s    
z-BasicChecker._check_misplaced_format_functionz	eval-usedzbad-reversed-sequencezmisplaced-format-functionc             C   s~   |  | t|jtjrz|jj}|| ksz|| ksz|dkrP| jd|d n*|dkrd| 	| n|dkrz| jd|d dS )zovisit a Call node -> check if this is not a blacklisted builtin
        call and check for * or ** use
        execz	exec-used)rK   reversedevalz	eval-usedN)
r  rC   r   rE   rv   rJ   r   rootr   _check_reversed)r   rK   rJ   r   r   r   r     s    
zBasicChecker.visit_callzassert-on-tuplec             C   s:   |j dkr6t|jtjr6t|jjdkr6| jd|d dS )z0check the use of an assert statement on a tuple.Nr   zassert-on-tuple)rK   )ZfailrC   r   rE   r   r~   eltsr   )r   rK   r   r   r   visit_assert+  s    
zBasicChecker.visit_assertzduplicate-keyc             C   sR   t  }xF|jD ]<\}}t|tjr|j}||kr@| jd||d || qW dS )z!check duplicate key in dictionaryzduplicate-key)rK   r   N)r>   itemsrC   rE   r   r   r   add)r   rK   keyskr   keyr   r   r   
visit_dict5  s    zBasicChecker.visit_dictc             C   s   | j | dS )zupdate try...finally flagN)r   r   )r   rK   r   r   r   visit_tryfinally@  s    zBasicChecker.visit_tryfinallyc             C   s   | j   dS )zupdate try...finally flagN)r   pop)r   rK   r   r   r   leave_tryfinallyD  s    zBasicChecker.leave_tryfinallyc             C   s"   |  }|dk	r| jd|d dS )zcheck unreachable codeNr   )rK   )Znext_siblingr   )r   rK   Zunreach_stmtr   r   r   r  H  s    zBasicChecker._check_unreachabler   c             C   s^   | j s
dS |j}|}xD|rXt||sXt|drL||jkrL| jd||d dS |}|j}qW dS )zcheck that a node is not inside a finally clause of a
        try...finally statement.
        If we found before a try...finally bloc a parent which its type is
        in breaker_classes, we skip the whole check.Nr   zlost-exception)rK   r   )r   rD   rC   hasattrr   r   )r   rK   r   Zbreaker_classesZ_parentrZ   r   r   r   r  N  s    z"BasicChecker._check_not_in_finallyc          
   C   s  yt t j|dd}W n t jk
r0   Y nX |tjkr@dS |dkrt|jd tjryt	|jd j
 }W n tjk
r   dS X t|dddkrt |r| jd|d dS t|tjtjfrdS t|tjrZ|jjdkrt |jr| jd|d dS td	d
 |j D rZy|jt  W n$ tk
rT   | jd|d Y nX dS t|drxhtD ]B}x:|D ]0}y|| W n tjk
r   P Y nX qvW P qlW | jd|d n| jd|d dS )z5 check that the argument to `reversed` is a sequence r   )ZpositionNrJ   iterzbad-reversed-sequence)rK   r?   c             s   s"   | ]}|j d kot|V  qdS )r?   N)rJ   r   is_builtin_object)r;   r   r   r   r   r^     s   z/BasicChecker._check_reversed.<locals>.<genexpr>rW   )r   ry   Zget_argument_from_callZNoSuchArgumentErrorrE   r  rC   r   r   r  r   r   r   rW   r.  r   r   r   r  Z_proxiedrJ   r/   r   r   REVERSED_PROTOCOL_METHODr   r,  REVERSED_METHODSZNotFoundError)r   rK   r   r   methodsmethr   r   r   r   `  sT    



zBasicChecker._check_reversedzconfusing-with-statementc             C   s   t s4g }|j}t|tjr&||j ||j n|j}|rxjt||dd  D ]T\}}t|d tjrR|d d krRt|d tj	sRt s|j
|jj
krR| jd|d qRW d S )Nri   r   zconfusing-with-statement)rK   )PY3KrD   rC   rE   ZWithextendr#  r	  
AssignNamer   r   r   )r   rK   ZpairsZparent_nodeZ	prev_pairZpairr   r   r   
visit_with  s    zBasicChecker.visit_withN)r   ),r    r!   r"   r%   r   r   r   rJ   r   r   Zreportsr   r   r   r   r   r   r   r   r   r   r  staticmethodr  r  r  r   r   r  r   r   r   r  r  r  r   r"  r(  r)  r+  r  r  r   r6  r   r   r   r   r   f  sf   			$/4&

;r   r   r   r   r   r   r   r   r   r   r   ZconstantZ	attributezclass attributezinline iteration)
r   r   r   r   r   r   r   r   r   r   r,   r.   r-   r/   c           
   C   s   g } xt tD ]t}t| }t| }|dd}| d|f |dtt dd|f df | d|f d d	d
d||f df qW t	| S )Nr   -z%s-naming-styleZchoicez<style>z'Naming style matching correct %s names.)r   r   choicesmetavarhelpz%s-rgxregexpz<regexp>zHRegular expression matching correct %s names. Overrides %s-naming-style.)r   r   r:  r;  )
sortedKNOWN_NAME_TYPESHUMAN_READABLE_TYPESDEFAULT_NAMING_STYLESreplacer   r@   NAMING_STYLESr%  rR   )Zname_optionsr   Zhuman_readable_nameZdefault_styler   r   r   _create_naming_options  s*    
rC  c            
   @   sF  e Zd Zdddd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dddd
ffe  ZdddhiZdd Zd d! Zd"d# Z	e
d$d%d&d' Zd(d) Ze
d$d%d*d+d, Ze
d$d%d*d-d. ZeZe
d$d%d/d0 Ze
d$d%d*d1d2 Zd3d4 Zd5d6 Zd7d8 Zejfd9d:Zd;d< Zed=d> Zd?S )@NameChecker)zBlack listed name "%s"zblacklisted-namezDUsed when the name is listed in the black list (unauthorized names).)z"%s name "%s" doesn't conform to %szinvalid-nameziUsed when the name doesn't conform to naming rules associated to its type (constant, variable, class...).)z*Name %s will become a keyword in Python %szassign-to-new-keywordzaUsed when assignment will become invalid in future Python release due to introducing new keyword.)ZC0102ZC0103ZW0111z
good-names)ijr&  exZRunr   Zcsvz<names>zJGood variable names which should always be accepted, separated by a comma.)r   r   r:  r;  z	bad-names)ZfooZbarZbazZtotoZtutuZtatazHBad variable names which should always be refused, separated by a comma.z
name-groupr   z<name1:name2>zrColon-delimited sets of names that determine each other's naming style when the name regexes allow several styles.zinclude-naming-hintFZynz<y_or_n>z?Include a hint for the correct naming format with invalid-name.zproperty-classes)zabc.abstractpropertyz<decorator names>zList of decorators that produce properties, such as abc.abstractproperty. Add to this list to register other decorators that produce valid properties. These decorators are taken in consideration only for invalid-name.)r5      asyncawaitc             C   s.   t | | i | _i | _i | _i | _i | _d S )N)r   r   Z_name_category_name_group
_bad_names_name_regexps_name_hints)r   r   r   r   r   r   T  s    zNameChecker.__init__c             C   st   | j jddddddddddd
| _x4| jjD ](}x"|dD ]}d|f | j|< q<W q,W |  \}}|| _|| _	d S )Nr   )
Zbadname_moduleZbadname_classZbadname_functionZbadname_methodZbadname_attrZbadname_constZbadname_variableZbadname_inlinevarZbadname_argumentZbadname_class_attribute:zgroup_%s)
r   r   r   ro   
name_groupsplitrK  _create_naming_rulesrM  rN  )r   groupr   regexpshintsr   r   r   r   \  s"    
zNameChecker.openc             C   s   i }i }xt D ]x}d|f }t| j|}t| |||< d|f }t| j|d }|d k	rb|||< |d k	rzd|j ||< qd| ||< qW ||fS )Nz%s_naming_stylez%s_rgxz
%r patternz%s naming style)r>  rW   ro   rB  r   pattern)r   rT  rU  r   Znaming_style_option_nameZnaming_style_nameZcustom_regex_setting_nameZcustom_regexr   r   r   rR  q  s    


z NameChecker._create_naming_ruleszblacklisted-namezinvalid-namec             C   s$   |  d|jdd | i | _d S )Nr   r8   rj   )_check_namerJ   rQ  rL  )r   rK   r   r   r   r     s    zNameChecker.visit_modulec       	      C   s   x| j  D ]}t|dk rqtt}tj}x0| D ]$}|t| | t	t||}q8W t|| dkrt
|| dd d}tj|dd   }n|| d }x|D ]}| j|  qW qW d S )Nr   ri   c             S   s   t dd | D S )Nc             s   s   | ]}|d  j V  qdS )r   N)r   )r;   Zwarningr   r   r   r^     s    z=NameChecker.leave_module.<locals>.<lambda>.<locals>.<genexpr>)min)rS  r   r   r   r    s    z*NameChecker.leave_module.<locals>.<lambda>)r'  r   )rL  r   r~   r   r   r@   sysmaxsizer   rX  r=  r   r   _raise_name_warning)	r   rK   Z
all_groupsgroupsZmin_warningsrS  Zby_linewarningsr   r   r   r   leave_module  s     

zNameChecker.leave_modulezassign-to-new-keywordc             C   sZ   |  |j| | d|j| x6|j D ](\}}t||s*| d||d  q*W d S )Nr   r   r   )&_check_assign_to_new_keyword_violationrJ   rW  Zinstance_attrsr#  r/   Zinstance_attr_ancestors)r   rK   r   Zanodesr   r   r   r     s
    zNameChecker.visit_classdefc             C   s   |  |j| tj}| rPt|j |jr4d S t	|j rJtj
ntj}| t|| jd|j|| |jj}|d k	r| || d S )N)ro   )r_  rJ   r   HIGHrt   r   Zoverrides_a_methodrD   r   has_known_bases	INFERENCErd   rW  r}   ro   r   _recursive_check_names)r   rK   rg   r   r   r   r   r     s    zNameChecker.visit_functiondefc             C   s"   x|j D ]}| d|| qW d S )Nr   )rI   rW  )r   rK   rJ   r   r   r   visit_global  s    zNameChecker.visit_globalc             C   s,  |  |j| | }| }t|tjr<| d|j| nt|tjrt|tj	rt
|stt|jtjr| d|j| qt|s| d|j| nt|tjr| d|j| nnt|tjr|j|kr|j| krt|s| d|j| n0t|tjr(t||js(| d|j| dS )z!check module level assigned namesr   r   r   r   r   N)r_  rJ   r   assign_typerC   rE   ZComprehensionrW  r   r   rQ   r   ry   r   r`   rN   rF   r_   Zargnamesr@   Zlocal_attr_ancestors)r   rK   r   re  r   r   r   visit_assignname  s(    zNameChecker.visit_assignnamec             C   s>   x8|D ]0}t |tjr(| d|j| q| |j| qW dS )z.check names in a possibly recursive list <arg>r   N)rC   rE   r5  rW  rJ   rc  r!  )r   r   rK   r   r   r   r   rc    s    
z"NameChecker._recursive_check_namesc             C   s   | j ||S )N)rK  r   )r   rf   r   r   r   _find_name_group  s    zNameChecker._find_name_groupc             C   sh   t | }| j| }| jjr.|d| j| j 7 }| ||f}| jd|||d | jd|   d7  < d S )Nz (%r pattern)zinvalid-name)rK   r   rg   r   ri   )	r?  rN  ro   Zinclude_naming_hintrM  rV  
capitalizer   r   )r   rK   rf   rJ   rg   Z
type_labelZhintr   r   r   r   r[    s    
zNameChecker._raise_name_warningc                s    fdd}t |r,t |\}}|r,dS || jjkr<dS || jjkrr| jd    d7  < | jd||d dS | j  }|	|}	t
|	 |r|  }
| j|
i }||	jg }|| ||f |	dkr||s| | || dS )z(check for a name using the type's regexpc                s&    dkr"t | }t|tjr"dS dS )Nr   TF)r   ry   rC   rE   r`   )rK   r   )rf   r   r    _should_exempt_from_invalid_name  s
    
zANameChecker._check_name.<locals>._should_exempt_from_invalid_nameNr   ri   zblacklisted-name)rK   r   )r   Zis_inside_exceptZclobber_in_exceptro   Z
good_namesZ	bad_namesr   r   rM  re   rh   rg  rL  
setdefaultrb   r   r[  )r   rf   rJ   rK   rg   ri  Z
clobberingr   r<  re   rP  Zbad_name_groupr]  r   )rf   r   rW    s(    



zNameChecker._check_namec             C   s2   |  || j}|d k	r.| jd|||ftjd d S )Nzassign-to-new-keyword)rK   r   rg   )_name_became_keyword_in_versionKEYWORD_ONSETr   r   r`  )r   rJ   rK   Zkeyword_first_versionr   r   r   r_    s    
z2NameChecker._check_assign_to_new_keyword_violationc             C   s<   x6|  D ]*\}}| |kr
tj|k r
dtt|S q
W d S )Nr8   )r#  rY  version_infor9   mapr   )rJ   Zrulesversionr  r   r   r   rk  &  s    z+NameChecker._name_became_keyword_in_versionN)r    r!   r"   r   rC  optionsrl  r   r   rR  r   r   r   r^  r   r   r   rd  rf  rc  rg  r[  r   r`  rW  r_  r7  rk  r   r   r   r   rD    s\   	

 rD  c               @   s   e Zd ZdddZdeddddfd	d
ddddffZdd Zedddd Z	edddd Z
edd Zedddd ZeZdejfddZdS )DocStringChecker)zMissing %s docstringzmissing-docstringzUsed when a module, function, class or method has no docstring.Some special methods like __init__ doesn't necessary require a docstring.)zEmpty %s docstringzempty-docstringz^Used when a module, function, class or method has an empty docstring (it would be too easy ;).)ZC0111ZC0112zno-docstring-rgxr<  z<regexp>zcRegular expression which should only match function or class names that do not require a docstring.)r   r   r:  r;  zdocstring-min-lengthrj   intz<int>z[Minimum line length for functions/classes that require docstrings, shorter ones are exempt.c             C   s   | j jddddd| _d S )Nr   )Zundocumented_moduleZundocumented_functionZundocumented_methodZundocumented_class)r   r   r   )r   r   r   r   r   X  s
    zDocStringChecker.openzmissing-docstringzempty-docstringc             C   s   |  d| d S )Nr   )_check_docstring)r   rK   r   r   r   r   `  s    zDocStringChecker.visit_modulec             C   s$   | j j|jd kr | d| d S )Nr   )ro   no_docstring_rgxre   rJ   rs  )r   rK   r   r   r   r   d  s    zDocStringChecker.visit_classdefc             C   s8   ddh}x*| j jD ]}t|tjr|j|krdS qW dS )Nrr   rs   TF)ru   r	   rC   rE   rw   rx   )rK   rI   r{   r   r   r   _is_setter_or_deleteri  s
    z&DocStringChecker._is_setter_or_deleterc             C   s   | j j|jd kr| r dnd}|jr8| |r8d S t|j	 t
jrd}t|j	 rdtjntj}x8|j	  D ]&}|j|krzt||j t
jrzd}P qzW | j||| |d n$t|j	 t
jr| || nd S d S )Nr   r   FT)report_missingrg   )ro   rt  re   rJ   rt   ru   ru  rC   rD   r   rE   r`   r   ra  r   rb  rd   r   r_   rs  r   )r   rK   ZftypeZ
overriddenrg   r   r   r   r   r   q  s$    z"DocStringChecker.visit_functiondefTc       	      C   s<  |j }|dkr|sdS t||j }|dkr6|s6dS | jj}|dkrZ|dkrZ||k rZdS | jd|   d7  < |jrt|jd tj	rt|jd j
tjrt|jd j
j}t|tjrt|jtjrtr|jjdkrdS |jjdkrdS | jd	||f|d
 n4| s8| jd|   d7  < | jd||f|d
 dS )z(check the node has a non empty docstringNr   rj   r   ri   r   r   )r   Zunicodebyteszmissing-docstring)rK   r   rg   zempty-docstring)docr   r   ro   Zdocstring_min_lengthr   r   rC   rE   ZExprr   r   r   ry   r   r   Zboundr  r3  rJ   r   strip)	r   rf   rK   rv  rg   Z	docstringr   Z	max_linesr   r   r   r   rs    s6    

z!DocStringChecker._check_docstringN)r    r!   r"   r   NO_REQUIRED_DOC_RGXrp  r   r   r   r   r   r7  ru  r   r   r   r`  rs  r   r   r   r   rq  .  s&   rq  c               @   s*   e Zd ZdZddiZeddd ZdS )PassCheckerz/check if the pass statement is really necessaryZW0107)zUnnecessary pass statementzunnecessary-passz@Used when a "pass" statement that can be avoided is encountered.zunnecessary-passc             C   sF   t |j|dks4t|jtjtjfrB|jjd k	rB| jd|d d S )Nri   zunnecessary-pass)rK   )	r~   rD   Zchild_sequencerC   rE   r`   r_   rx  r   )r   rK   r   r   r   
visit_pass  s    zPassChecker.visit_passN)r    r!   r"   r%   r   r   r   r|  r   r   r   r   r{    s   r{  c             C   s"   t | tjo t| jdko | j S )zSIs this a call with exactly 1 argument,
    where that argument is positional?
    ri   )rC   rE   r   r~   r   r  )r
  r   r   r   _is_one_arg_pos_call  s    r}  c               @   s   e Zd ZdZdddddddgifd	d
ddZd$ddZdd Zdd Zdd Zdd Z	e
dddddddd Zdd  Zd!d" Zd#S )%ComparisonCheckera  Checks for comparisons

    - singleton comparison: 'expr == True', 'expr == False' and 'expr == None'
    - yoda condition: 'const "comp" right' where comp can be '==', '!=', '<',
      '<=', '>' or '>=', and right can be a variable, an attribute, a method or
      a function
    )zComparison to %s should be %szsingleton-comparisonzQUsed when an expression is compared to singleton values like True, False or None.)zComparison should be %szmisplaced-comparison-constantzUsed when the constant is placed on the left side of a comparison. It is usually clearer in intent to place it in the right hand side of the comparison.z5Using type() instead of isinstance() for a typecheck.zunidiomatic-typecheckzThe idiomatic way to perform an explicit typecheck in Python is to use isinstance(x, Y) rather than type(x) == Y, type(x) is Y. Though there are unusual situations where these give different results.Z	old_names)ZW0154zunidiomatic-typecheck)zComparison to literalzliteral-comparisonzUsed when comparing an object to a literal, which is usually what you do not want to do, since you can compare to a different literal than what was expected altogether.)zRedundant comparison - %szcomparison-with-itselfz/Used when something is compared against itself.)z;Comparing against a callable, did you omit the parenthesis?zcomparison-with-callablezThis message is emitted when pylint detects that a comparison with a callable was made, which might suggest that some parenthesis were omitted, resulting in potential unwanted behaviour.)ZC0121ZC0122ZC0123ZR0123ZR0124ZW0143Fc             C   s   |j dkr.|sd}nd}| jd|d|fd nZ|j dkr\|sBd}nd}| jd|d|fd n,|j d kr|spd	}nd
}| jd|d |fd d S )NTzjust 'expr'zjust 'not expr'zsingleton-comparison)rK   r   Fz
'not expr'z'expr'z'expr is None'z'expr is not None')r   r   )r   Z	singletonZ	root_nodenegative_check
suggestionr   r   r   _check_singleton_comparison  s$    


z-ComparisonChecker._check_singleton_comparisonc             C   sv   t jt jt jt jf}t||}d}t|t jr\t|jtsD|jdkrHdS t|jt	t
ttf}|sd|rr| jd|d dS )zMCheck if we compare to a literal, which is usually what we do not want to do.FNzliteral-comparison)rK   )rE   r   r   r   r   rC   r   r   boolrw  r   rr  floatr   )r   literalrK   r	   Zis_other_literalZis_constr   r   r   _check_literal_comparison&  s    
z+ComparisonChecker._check_literal_comparisonc             C   sF   t |tjrd S t||}d| ||jf }| jd||fd d S )Nz%s %s %rzmisplaced-comparison-constant)rK   r   )rC   rE   r   REVERSED_COMPSr   r   r   r   )r   rK   leftrightoperatorr  r   r   r   _check_misplaced_constant4  s
    z+ComparisonChecker._check_misplaced_constantc             C   s   |j }|jd d }|jd d }t|tjrHt|tjrH|j}|j}n$t|tjrlt|tjrl|j}|j}||krd|||f }| jd||fd dS )zCheck if identifier is compared against itself.
        :param node: Compare node
        :type node: astroid.node_classes.Compare
        :Example:
        val = 786
        if val == val:  # [comparison-with-itself]
            pass
        r   ri   z%s %s %szcomparison-with-itself)rK   r   N)	r  opsrC   rE   r   r   rv   rJ   r   )r   rK   left_operandright_operandr  r  r   r   r   _check_logical_tautology;  s    	

z*ComparisonChecker._check_logical_tautologyc                sl   |j d d }|tkrd S tjtjf |j|j d d  }}t fdd||fD dkrh| jd|d d S )Nr   ri   c             3   s"   | ]}t t| rd V  qdS )ri   N)rC   r   ry   )r;   r   )bare_callablesr   r   r^   a  s   z?ComparisonChecker._check_callable_comparison.<locals>.<genexpr>zcomparison-with-callable)rK   )r  COMPARISON_OPERATORSrE   r_   r   r  sumr   )r   rK   r  r  r  r   )r  r   _check_callable_comparisonV  s    
z,ComparisonChecker._check_callable_comparisonzsingleton-comparisonzmisplaced-comparison-constantzliteral-comparisonzcomparison-with-itselfzcomparison-with-callablec             C   s   |  | | | | | t|jdkr0d S |j}|jd \}}|tkrht|tj	rh| 
|||| |dkrt|tj	r| || nt|tj	r| || |dkrt|tj	r| j||dd |dkr| || d S )Nri   r   z==z!=T)r  )r3   zis not)r  r  _check_unidiomatic_typecheckr~   r  r  r  rC   rE   r   r  r  r  )r   rK   r  r  r  r   r   r   visit_comparei  s&    	


zComparisonChecker.visit_comparec             C   s8   |j d \}}|tkr4|j}t|r4| |||| d S )Nr   )r  TYPECHECK_COMPARISON_OPERATORSr  r}  _check_type_x_is_y)r   rK   r  r  r  r   r   r   r    s
    z.ComparisonChecker._check_unidiomatic_typecheckc             C   s   t |j}t|tjr$| tks(dS |dkrzt|rzt |j}t|tjrz| tkrzt |j	d }t|t
szdS | jd|d dS )z(Check for expressions like type(x) == Y.N)r3   zis notr   zunidiomatic-typecheck)rK   )r   ry   r   rC   rE   r`   rz   
TYPE_QNAMEr}  r   LITERAL_NODE_TYPESr   )r   rK   r  r  r  Z	left_funcZ
right_funcZ	right_argr   r   r   r    s    
z$ComparisonChecker._check_type_x_is_yN)F)r    r!   r"   r%   r   r  r  r  r  r  r   r   r  r  r  r   r   r   r   r~    s0   

r~  c             C   sX   |  t|  |  t|  |  t|  |  t|  |  t|  |  t|  dS )z-required method to auto register this checkerN)Zregister_checkerr   r   rD  rq  r{  r~  )r   r   r   r   register  s    r  )N)Vr%   builtinsr   r   rY  r&   typingr   rE   Zastroid.basesZastroid.scoped_nodesZpylintr   r   r   Zpylint.checkersr   r   Zpylint.checkers.utilsr   Zpylint.reporters.ureportsr	   r   Zpylint.utilsr   r
   r$   r(   r)   r*   r+   rB  r'   rz  r/  ZSEQUENCE_PROTOCOL_METHODSr0  	frozensetr  r   r   r   r   r  ZUNITTEST_CASEr    r:   r  rm  r   r3  r   r   rc   r?   r	  r  r  r  r   rN   rQ   rS   rY   ra   rh   rl   rq   r}   r   r   r   ZBaseCheckerr   r   r   r>  r?  r@  rC  rD  rq  r{  r}  r~  r  r   r   r   r   <module>&   s   




	
&
-   @    W"  -  Q