B
    AWv\z ã               @   sþ  d Z ddlmZ ddlZddlZddlZddlZyddlZW n ek
rT   dZY nX ddl	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 ddlmZ ddlmZ ejZdd„ Zdd„ Zdd„ Zdddddddddddddd gifd!d"d#d$œZ e!d%œd&d'„Z"edk	rdG d(d)„ d)ej#ƒZ$G d*d+„ d+ej%ej&ej'ej(ƒZ)d,d-„ Z*d.d/„ Z+d0d1„ Z,G d2d3„ d3e-ƒZ.d4d5„ Z/ej0d6d7„ ƒZ1G d8d9„ d9ƒZ2d:d;„ Z3d<d=„ Z4e5d>krúe2e	j6d?d… ƒ dS )@a   %prog [options] modules_or_packages

  Check that module(s) satisfy a coding standard (and more !).

    %prog --help

  Display this help message and exit.

    %prog --help-msg <msg-id>[,<msg-id>]

  Display help messages about given message identifiers and exit.
é    )Úprint_functionN)Úversion)Úmodutils)Úcheckers)Ú
interfaces)Ú	reporters)Ú
exceptions)Úutils)Úconfig)Únodesc             C   s2   | j | j| j| j| j| jf}| j| j|| j| j	fS )N)
ÚabspathÚpathÚmoduleÚobjÚlineÚcolumnÚmsg_idZsymbolÚmsgÚ
confidence)ÚmessageÚlocation© r   ú*lib/python3.7/site-packages/pylint/lint.pyÚ_get_new_args\   s    r   c             C   sp   t j t j | ¡¡}t j |¡s,t j |¡}x>t j t j |d¡¡sH|S |}t j |¡}||kr.t  ¡ S q.W d S )Nz__init__.py)	Úosr   ÚrealpathÚ
expanduserÚisdirÚdirnameÚexistsÚjoinÚgetcwd)Úfilepathr   Zold_dirnamer   r   r   Ú_get_python_pathh   s    r#   c             C   sŽ   i }t  ¡ }xt| D ]l}| di ¡}| |¡ xP| ¡ D ]D\}}||krP|||< q6t|tƒrj||  |¡ q6|| | ||< q6W qW ||d< |S )NÚby_msg)ÚcollectionsÚCounterÚpopÚupdateÚitemsÚ
isinstanceÚdict)ÚstatsZmergedr$   ÚstatZmessage_statsÚkeyÚitemr   r   r   Ú_merge_statsv   s    



r0   )z%sÚfatalzoUsed when an error occurred preventing the analysis of a               module (unable to find it for instance).)z%s: %szastroid-errorzšUsed when an unexpected error occurred while building the Astroid  representation. This is usually accompanied by a traceback. Please report such errors !)zerror while code parsing: %szparse-errorzlUsed when an exception occurred while building the Astroid representation which could be handled by astroid.)z0Unable to run raw checkers on built-in module %szraw-checker-failedzRUsed to inform that a built-in module has not been checked using the raw checkers.)z#Unable to consider inline option %rzbad-inline-optionzUUsed when an inline option is either badly formatted or can't be used inside modules.)zLocally disabling %s (%s)zlocally-disabledzEUsed when an inline option disables a message or a messages category.)zIgnoring entire filezfile-ignoredz0Used to inform that the file will not be checked)zSuppressed %s (from line %d)zsuppressed-messagezºA message was triggered on a line, but suppressed explicitly by a disable= comment in the file. This message is not generated for messages that are ignored due to configuration settings.)zUseless suppression of %szuseless-suppressionzbReported when a message is explicitly disabled for a line or a block of code, but never triggered.z+Pragma "%s" is deprecated, use "%s" insteadzdeprecated-pragmaz—Some inline pylint options have been renamed or reworked, only the most recent form should be used. NOTE:skip-all is only available with pylint >= 0.26Z	old_names)ZI0014zdeprecated-disable-all)z%szsyntax-errorz0Used when a syntax error is raised for a module.)zUnrecognized file option %rzunrecognized-inline-optionz2Used when an unknown inline option is encountered.)zBad option value %rzbad-option-valuez:Used when a bad value for an inline option is encountered.)ZF0001ZF0002ZF0010ZI0001ZI0010ZI0011ZI0013ZI0020ZI0021ZI0022ZE0001ZE0011ZE0012)Úreturnc              C   s,   t tddƒ} | rt| dƒƒS tr(t ¡ S dS )zNUse sched_affinity if available for virtualized or containerized environments.Úsched_getaffinityNr   é   )Úgetattrr   ÚlenÚmultiprocessingÚ	cpu_count)r3   r   r   r   Ú
_cpu_countÚ   s    r9   c               @   s   e Zd Zdd„ Zdd„ ZdS )ÚChildLinterc             C   s¼   | j \}}| _d| jd< | j dd ¡| _| j dd ¡| _x~t|jdƒD ]n}y|  |d ¡}| |¡ W qF t	k
r² } z.t
d| tjd t
|tjd | i ¡ W d d }~X Y qFX qFW d S )	Nr4   ÚjobsÚpython3_porting_modeÚpluginsÚSTOPr   z0internal error with sending report for module %s)Úfile)Z_argsÚ_configr'   Ú_python3_porting_modeÚ_pluginsÚiterÚgetÚ_run_linterÚputÚ	ExceptionÚprintÚsysÚstderr)ÚselfÚtasks_queueÚresults_queueÚfile_or_moduleÚresultÚexr   r   r   Úrunè   s    

zChildLinter.runc             C   s†   t ƒ }| ¡  | jr | | j¡ | | j¡ | ¡  | t 	¡ ¡ | j
rP| ¡  | |¡ dd„ |jjD ƒ}||jj|j||j|jfS )Nc             S   s   g | ]}t |ƒ‘qS r   )r   )Ú.0Úmr   r   r   ú
<listcomp>  s    z+ChildLinter._run_linter.<locals>.<listcomp>)ÚPyLinterÚload_default_pluginsrB   Úload_plugin_modulesZload_configuration_from_configr@   Úload_plugin_configurationÚset_reporterr   ZCollectingReporterrA   r<   ÚcheckÚreporterÚmessagesÚ
file_stateÚ	base_nameÚcurrent_namer,   Ú
msg_status)rK   rN   ÚlinterÚmsgsr   r   r   rE   þ   s"    
zChildLinter._run_linterN)Ú__name__Ú
__module__Ú__qualname__rQ   rE   r   r   r   r   r:   ç   s   r:   c                   sL  e Zd ZdZejfZdZdZdZ	e
Zedd„ ƒZdZdJ‡ fd	d
„	Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ Zdd„ ZdKd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+d,„ Z d-d.„ Z!edLd0d1„ƒZ"d2d3„ Z#d4d5„ Z$d6d7„ Z%d8d9„ Z&d:d;„ Z'd<d=„ Z(dMd>d?„Z)d@dA„ Z*dBdC„ Z+dDdE„ Z,dFdG„ Z-dHdI„ Z.‡  Z/S )NrU   a  lint Python modules using external checkers.

    This is the main checker controlling the other ones and the reports
    generation. It is itself both a raw checker and an astroid checker in order
    to:
    * handle message activation / deactivation at the module level
    * handle some basic but necessary stats'data (number of classes, methods...)

    IDE plugin developers: you may have to call
    `astroid.builder.MANAGER.astroid_cache.clear()` across runs if you want
    to ensure the latest code version is actually checked.
    Úmasterr   c               C   sh  dddddddœfdd	d
ddddœfdddddddœfdddddddœfdddddddd œfd!d"ddd#dd$d œfd%dd&ddd'd(d)œfd*dddd+dd,d œfd-d.d/d0d1d2„ t jD ƒd3d4d5 d6d7„ t jD ƒ¡f d8œfd9dd:d;d3d<d=œfd>dd:d?d3d@d=œfdAddBddCdDœfdEdFdGdHddIdJœfdKddLd"ddMdNœfdOdFdPdQdRdSœfdTddUg dVdSœfdWddLddXdSœfdYdZd[d\œffS )]NÚignoreZcsvz<file>[,<file>...]Ú
black_list)ZCVSzPAdd files or directories to the blacklist. They should be base names, not paths.)ÚtypeÚmetavarÚdestÚdefaultÚhelpzignore-patternsZ
regexp_csvz<pattern>[,<pattern>...]Úblack_list_rer   zwAdd files or directories matching the regex patterns to the blacklist. The regex matches against base names, not paths.Ú
persistentTZynz<y_or_n>r4   z,Pickle collected data for later comparisons.)rl   ri   rj   Úlevelrm   zload-pluginsz	<modules>zuList of plugins (as comma separated values of python modules names) to load, usually to register additional checkers.)ri   rj   rl   rp   rm   zoutput-formatÚtextÚstringz<format>ÚfÚReportsz´Set the output format. Available formats are text, parseable, colorized, json and msvs (visual studio). You can also give a reporter class, e.g. mypackage.mymodule.MyReporterClass.)rl   ri   rj   ÚshortÚgrouprm   ÚreportsFÚrz<Tells whether to display a full report or only the messages.Ú
evaluationz<python_expression>zN10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)a6  Python expression which should return a note less than 10 (10 is the highest note). You have access to the variables errors warning, statement which respectively contain the number of errors / warnings messages and the total number of statements analyzed. This is used by the global evaluation report (RP0004).)ri   rj   rv   rp   rl   rm   ÚscoreÚszActivate the evaluation score.r   Zmultiple_choicez<levels>Ú c             S   s   g | ]
}|j ‘qS r   )Úname)rR   Úcr   r   r   rT   ª  s    z)PyLinter.make_options.<locals>.<listcomp>zMessages controlz`Only show warnings with the listed confidence levels. Leave empty to show all. Valid levels: %s.z, c             s   s   | ]}|j V  qd S )N)r}   )rR   r~   r   r   r   ú	<genexpr>®  s    z(PyLinter.make_options.<locals>.<genexpr>)ri   rj   rl   Úchoicesrv   rm   Úenablez	<msg ids>Úea/  Enable the message, report, category or checker with the given id(s). You can either give multiple identifier separated by comma (,) or put this option multiple time (only on the command line, not in the configuration file where it should appear only once). See also the "--disable" option for examples.)ri   rj   ru   rv   rm   ÚdisableÚdac  Disable the message, report, category or checker with the given id(s). You can either give multiple identifiers separated by comma (,) or put this option multiple times (only on the command line, not in the configuration file where it should appear only once). You can also use "--disable=all" to disable everything first and then reenable specific checks. For example, if you want to run only the similarities checker, you can use "--disable=all --enable=similarities". If you want to run only the classes checker, but have no Warning level messages displayed, use "--disable=all --enable=classes --disable=W".zmsg-templatez
<template>zŒTemplate used to display messages. This is a python new-style format string used to format the message information. See doc for all details.)ri   rj   rv   rm   r;   Úintz<n-processes>ÚjzsUse multiple processes to speed up Pylint. Specifying 0 will auto-detect the number of processors available to use.)ri   rj   ru   rl   rm   zunsafe-load-any-extensionz<yn>zAllow loading of arbitrary C extensions. Extensions are imported into the active Python interpreter and may run arbitrary code.)ri   rj   rl   Úhiderm   zlimit-inference-resultsz<number-of-results>éd   z¯Control the amount of potential inferred values when inferring a single object. This can help the performance when dealing with large functions or complex, nested conditions. )ri   rj   rl   rm   zextension-pkg-whitelistz<pkg[,pkg]>z®A comma-separated list of package or module names from where C extensions may be loaded. Extensions are loading into the active Python interpreter and may run arbitrary code.zsuggestion-modezŠWhen enabled, pylint would attempt to guess common misconfiguration and emit user-friendly hints instead of false-positive error messages.z	exit-zeroÚ
store_truez…Always return a 0 (non-error) status code, even if lint errors are found. This is primarily useful in continuous integration scripts.)Úactionrm   )r   ÚCONFIDENCE_LEVELSr    r   r   r   r   Úmake_options>  sÖ    
	zPyLinter.make_options))zMessages controlz%Options controlling analysis messages)rt   z2Options related to output formatting and reportingr   Nc                s8  t  ¡ | _d | _d | _i | _t t¡| _	i | _
d| _t  ¡ | _d | _d | _d | _|| _|t ¡  | _|tj | _| j| jdœ| _| j| jdœ| _dtttjf }t j | ¡ t j | ¡ t t| ƒjt!||pÎt"j#d t$j% | ¡ ddt&fdd	t'fd
dt(ff| _)|  *| ¡ t+ƒ | _,d| _-d| _.|  /¡  |r4|  0|¡ d S )NF)r   rƒ   )zdisable-msgz
enable-msgz%%prog %s
astroid %s
Python %s)Zusager   Zconfig_fileZRP0001zMessages by categoryZRP0002z% errors / warnings by moduleZRP0003ZMessages)1r	   ZMessagesStoreÚ
msgs_storer[   Ú_reporter_nameÚ
_reportersr%   ÚdefaultdictÚlistÚ	_checkersÚ_pragma_linenoÚ_ignore_fileÚ	FileStater]   r_   Úcurrent_filer,   Ú_external_optsrU   rŒ   ÚoptionsÚoption_groupsr   rƒ   Ú_options_methodsÚ_bw_options_methodsr   Úastroid_versionrI   ÚMessagesHandlerMixInÚ__init__ÚReportsHandlerMixInÚsuperÚ__doc__r
   ZPYLINTRCr   ÚBaseTokenCheckerÚreport_total_messages_statsÚreport_messages_by_module_statsÚreport_messages_statsrw   Úregister_checkerÚsetÚ_dynamic_pluginsrA   Ú_error_modeZload_provider_defaultsrY   )rK   r˜   r[   r™   ÚpylintrcZfull_version)Ú	__class__r   r   rž   6  sL    




zPyLinter.__init__c             C   s&   t  | ¡ t | ¡ | js"|  ¡  d S )N)r   Z
initializer   r[   Ú_load_reporter)rK   r   r   r   rV   l  s    

zPyLinter.load_default_pluginsc             C   s>   x8|D ]0}|| j krq| j  |¡ t |¡}| | ¡ qW dS )z`take a list of module names which are pylint plugins and load
        and register them
        N)r¨   Úaddr   Úload_module_from_nameÚregister)rK   ÚmodnamesÚmodnamer   r   r   r   rW   t  s    


zPyLinter.load_plugin_modulesc             C   s2   x,| j D ]"}t |¡}t|dƒr| | ¡ qW dS )zàCall the configuration hook for plugins

        This walks through the list of plugins, grabs the "load_configuration"
        hook, if exposed, and calls it to allow plugins to configure specific
        settings.
        Úload_configurationN)r¨   r   r®   Úhasattrr²   )rK   r±   r   r   r   r   rX     s    

z"PyLinter.load_plugin_configurationc          	   C   sh   | j  ¡ }|| jkr(|  | j| ƒ ¡ n<y|  ¡ }W n" ttfk
rV   t |¡‚Y nX |  |ƒ ¡ d S )N)	rŽ   Úlowerr   rY   Ú_load_reporter_classÚImportErrorÚAttributeErrorr   ZInvalidReporterError)rK   r}   Úreporter_classr   r   r   r¬   ‹  s    

zPyLinter._load_reporterc             C   s2   | j }t t |¡¡}| d¡d }t||ƒ}|S )NÚ.éÿÿÿÿ)rŽ   r   r®   Zget_module_partÚsplitr5   )rK   Zqnamer   Ú
class_namer¸   r   r   r   rµ   —  s
    
zPyLinter._load_reporter_classc             C   s   || _ | |_dS )z5set the reporter used to display messages and reportsN)r[   ra   )rK   r[   r   r   r   rY   ž  s    zPyLinter.set_reporterc          
   C   s
  || j ks|| jkr¦|rÂy| j | }W n< tk
rb   | j| }t d|| d¡d f t¡ Y nX t |¡}t	|t
tfƒr˜x"|D ]}||dd q‚W n||ƒ dS n|dkrÂ|| _| jrÂ|  ¡  ytj | ||||¡ W n* tjk
r   td| tjd	 Y nX dS )
z[overridden from config.OptionsProviderMixin to handle some
        special options
        z"%s is deprecated, replace it by %sú-r   T)Zignore_unknownNzoutput-formatz(option %s can't be read from config file)r?   )rš   r›   ÚKeyErrorÚwarningsÚwarnr»   ÚDeprecationWarningr	   Z
_check_csvr*   r‘   ÚtuplerŽ   r   r¬   r   r¢   Ú
set_optionr
   ZUnsupportedActionrH   rI   rJ   )rK   ÚoptnameÚvaluerŠ   ÚoptdictÚmethZ_idr   r   r   rÃ   £  s0    


zPyLinter.set_optionc             C   s   || j |j< d S )N)r   r}   )rK   r¸   r   r   r   Úregister_reporterÅ  s    zPyLinter.register_reporterc             C   sJ   t | jdd„ d}y| | | ¡¡ W n tk
r:   Y nX | | ¡ |S )Nc             S   s   t | ddƒS )Nr}   r|   )r5   )Úxr   r   r   Ú<lambda>É  s    z'PyLinter.report_order.<locals>.<lambda>)r.   )ÚsortedÚ_reportsr'   ÚindexÚ
ValueErrorÚappend)rK   rw   r   r   r   Úreport_orderÈ  s    
zPyLinter.report_orderc             C   sŽ   |j dkstdƒ‚| j|j  |¡ x$|jD ]\}}}|  ||||¡ q,W |  |¡ t|dƒrj| j	 
|¡ | ¡  t|ddƒsŠ|  |j¡ dS )zoregister a new checker

        checker is an object implementing IRawChecker or / and IAstroidChecker
        r   zchecker priority can't be >= 0rb   ZenabledTN)ÚpriorityÚAssertionErrorr’   r}   rÏ   rw   Zregister_reportZregister_options_providerr³   r   Zregister_messages_from_checkerZload_defaultsr5   rƒ   )rK   ÚcheckerZr_idZr_titleZr_cbr   r   r   r¦   Ö  s    

zPyLinter.register_checkerc             C   sX   xR| j j ¡ D ]B\}}|dkr8x0|D ]}|  |¡ q$W qx|D ]}|  |¡ q>W qW d S )N)ÚEÚF)r   Z_msgs_by_categoryr)   r   rƒ   )rK   ZmsgcatZmsgidsÚmsgidr   r   r   Údisable_noerror_messagesé  s    

z!PyLinter.disable_noerror_messagesc             C   s6   x0| j  ¡ D ]"}x|D ]\}}}|  |¡ qW qW dS )zdisable all reportersN)rÌ   ÚvaluesZdisable_report)rK   r   Z	report_idÚ_r   r   r   Údisable_reportersó  s    zPyLinter.disable_reportersc             C   s®   d| _ |  ¡  |  d¡ | jr||  d¡ x&|  d¡D ]}| d¡r4|  |¡ q4W | j}| dd¡r†| 	dd¡}|  
d|¡ n
|  d¡ |  dd	¡ |  d
d	¡ |  dd	¡ dS )z9error mode: enable only errors; no reports, no persistentTZmiscellaneousÚallÚpython3rÔ   zMESSAGES CONTROLrƒ   rw   Fro   rz   N)r©   r×   rƒ   rA   Ú_checker_messagesÚ
startswithr   Úcfgfile_parserÚ
has_optionrD   Úglobal_set_optionrÃ   )rK   r   Úconfig_parserrÅ   r   r   r   Ú
error_modeù  s     



zPyLinter.error_modec             C   s‚   |   d¡ |  d¡ | jrNx2|  d¡D ]$}| d¡r@|  |¡ q&|   |¡ q&W | j}| dd¡rx| dd¡}|  d|¡ d| _	dS )z8Disable all other checkers and enable Python 3 warnings.rÛ   rÜ   rÔ   zMESSAGES CONTROLrƒ   TN)
rƒ   r   r©   rÝ   rÞ   rß   rà   rD   rá   rA   )rK   r   râ   rÅ   r   r   r   r<     s    


zPyLinter.python3_porting_modec             C   s   ddh}x|D ]\}}}}}|t jkr,qtj |¡}|dkrBq| d¡}| ¡ dksd| ¡ dkr | ¡ dkr„| jd|d d	d
 | jd|d d d| _dS y| 	dd¡\}	}
W n. t
k
râ   | jd| ¡ |d d wY nX |	 ¡ }	|	| jks|	| jkry| j|	 }W n@ tk
rR   | j|	 }| jd|d |	|	 dd¡fd
 Y nX xÂt |
¡D ]ž}|	|kr||d | j|< yR|	|fdkr¼| jd|d dd
 | jd|d d d| _dS ||d|d ƒ W n, tjk
rú   | jd||d d Y nX q`W q| jd|	|d d qW dS )z`process tokens from the current module to search for module/block
        level options
        rƒ   r   Nr4   zdisable-allz	skip-filezdeprecated-pragmar   )zdisable-allz	skip-file)r   Úargszfile-ignored)r   Tú=zbad-inline-option)rä   r   z-msgr|   )rƒ   rÛ   )zdisable=allz	skip-filer   zbad-option-valuezunrecognized-inline-option)ÚtokenizeÚCOMMENTr	   Z
OPTION_RGXÚsearchrv   ÚstripÚadd_messager”   r»   rÎ   rš   r›   r¾   ÚreplaceÚ_splitstripr“   r   ZUnknownMessageError)rK   ÚtokensZcontrol_pragmasÚtok_typeZcontentÚstartrÙ   ÚmatchZfirst_groupZoptrÅ   rÇ   rÖ   r   r   r   Úprocess_tokens$  sd    



"zPyLinter.process_tokensc                s   ˆ g‡ fdd„ˆ j  ¡ D ƒ S )z'return all available checkers as a listc                s"   g | ]}|D ]}|ˆ k	r|‘qqS r   r   )rR   r’   r~   )rK   r   r   rT   k  s   z)PyLinter.get_checkers.<locals>.<listcomp>)r’   rØ   )rK   r   )rK   r   Úget_checkersh  s    
zPyLinter.get_checkersc             C   s   |   ¡ }tdd„ |D ƒƒS )z7Get all the checker names that this linter knows about.c             S   s   h | ]}|j d kr|j ’qS )rf   )r}   )rR   rZ   r   r   r   ú	<setcomp>u  s    z-PyLinter.get_checker_names.<locals>.<setcomp>)rò   rË   )rK   Zcurrent_checkersr   r   r   Úget_checker_namesq  s    zPyLinter.get_checker_namesc                s‚   ˆ j jsˆ  ¡  ˆ g}xRˆ  ¡ dd… D ]>}‡ fdd„|jD ƒ}|s\t‡ fdd„|jD ƒƒr(| |¡ q(W t|t 	d¡dd	}|S )
z9return checkers needed for activated messages and reportsr4   Nc                s   h | ]}ˆ   |¡r|’qS r   )Zis_message_enabled)rR   r   )rK   r   r   ró     s    z,PyLinter.prepare_checkers.<locals>.<setcomp>c             3   s   | ]}ˆ   |d  ¡V  qdS )r   N)Zreport_is_enabled)rR   rx   )rK   r   r   r   €  s    z,PyLinter.prepare_checkers.<locals>.<genexpr>rÑ   T)r.   Úreverse)
r
   rw   rÚ   rò   rb   ÚanyrÏ   rË   ÚoperatorÚ
attrgetter)rK   ZneededcheckersrÓ   r\   r   )rK   r   Úprepare_checkersx  s    zPyLinter.prepare_checkersFc             C   s   |rdS |  d¡S )a  Returns whether or not a module should be checked.

        This implementation returns True for all python source file, indicating
        that all files should be linted.

        Subclasses may override this method to indicate that modules satisfying
        certain conditions should not be linted.

        :param str modname: The name of the module to be checked.
        :param str path: The full path to the source code of the module.
        :param bool is_argument: Whetter the file is an argument to pylint or not.
                                 Files which respect this property are always
                                 checked, since the user requested it explicitly.
        :returns: True if the module should be checked.
        :rtype: bool
        Tz.py)Úendswith)r±   r   Úis_argumentr   r   r   Úshould_analyze_file‰  s    zPyLinter.should_analyze_filec             C   s`   x$| j jD ]}| ¡ s
d| j|j< q
W t|ttfƒs:|f}| jj	dkrR|  
|¡ n
|  |¡ dS )zWmain checking entry: check a list of files or modules from their
        name.
        Fr4   N)r   r\   Zmay_be_emittedZ_msgs_staterÖ   r*   r‘   rÂ   r
   r;   Ú	_do_checkÚ_parallel_check)rK   Úfiles_or_modulesr   r   r   r   rZ   ¡  s    zPyLinter.checkc             C   sŒ   t  ¡ }dh}| dd„ | jD ƒ¡ xN| j ¡ D ]@}x:| ¡ D ].\}}}| d¡rTq>||kr>t 	||¡||< q>W q0W | j
|d< | j|d< |S )Nz	long-helpc             s   s   | ]\}}|V  qd S )Nr   )rR   Zopt_namerÙ   r   r   r   r   ¶  s    z,PyLinter._get_jobs_config.<locals>.<genexpr>Z
deprecatedr<   r=   )r%   ÚOrderedDictr(   r—   Z_all_optionsrØ   Zoptions_and_valuesrD   r	   Z_format_option_valuerA   r¨   )rK   Úchild_configZfilter_optionsZopt_providersrÄ   rÆ   Úvalr   r   r   Ú_get_jobs_config³  s    


zPyLinter._get_jobs_configc             c   sž  |   ¡ }g }t ¡ }| ¡ }| ¡ }g }xH|  |¡D ]:}|d |d |d   }	}
}| j|	|
|dr4| |¡ q4W x@tt| j	j
t|ƒƒƒD ]&}t|||fd}| ¡  | |¡ qŠW x |D ]}|d }| |g¡ qºW d}xf|D ]^}y| ¡ }W nF tk
r6 } z&tdtjd t|tjd d	}P W d d }~X Y nX |V  qàW x t| j	j
ƒD ]}| d
¡ qPW x|D ]}| ¡  qjW |rštdtjd t d¡ d S )Nr}   r   Úisarg)rû   )rä   Fz8internal error while receiving results from child linter)r?   Tr>   z$Error occurred, stopping the linter.é    )r  r7   ZManagerZQueueÚexpand_filesrü   rÏ   ÚrangeÚminr
   r;   r6   r:   rï   rF   rD   rG   rH   rI   rJ   r    Úexit)rK   rÿ   r  ÚchildrenZmanagerrL   rM   Zexpanded_filesÚdescrr±   r"   Úis_argrÙ   Zchild_linterZfiles_or_moduler   ZfailedrO   rP   Zchildr   r   r   Ú_parallel_taskÂ  sH    




zPyLinter._parallel_taskc             C   sº   |   ¡  g }d }xr|  |¡D ]d}|s&q|\}| j_}}}}x,|D ]$}	tj|	Ž }	|  |¡ | j |	¡ q@W | 	|¡ |  j
|O  _
qW t|ƒ| _|| _x |  ¡ D ]}
|
| k	rž| j|
_qžW d S )N)Úopenr  r]   r^   r	   ZMessageÚset_current_moduler[   Zhandle_messagerÏ   r`   r0   r,   r_   rò   )rK   rÿ   Z	all_statsr   rO   rÙ   r\   r,   r`   r   rÓ   r   r   r   rþ   õ  s$    




zPyLinter._parallel_checkc                sR  t  ˆ ¡}ˆ  ¡ }‡ fdd„|D ƒ}dd„ |D ƒ}x,|D ]$}| ¡  t |tj¡r8| |¡ q8W xÄˆ  |¡D ]¶}|d |d |d   }}	}
ˆ j	||	|
dsžqlˆ  
||	¡ ˆ  |	|¡}|d krÀqlt  |d ¡ˆ _d	ˆ _|jˆ _ˆ  ||||¡ ˆ j ˆ j¡}x$|D ]\}}}ˆ  ||d |¡ qW qlW |jˆ jd
< xt|ƒD ]}| ¡  q<W d S )Nc                s&   g | ]}t  |t j¡r|ˆ k	r|‘qS r   )r   Ú
implementsÚITokenChecker)rR   r~   )rK   r   r   rT     s   z&PyLinter._do_check.<locals>.<listcomp>c             S   s   g | ]}t  |t j¡r|‘qS r   )r   r  ZIRawChecker)rR   r~   r   r   r   rT     s    r}   r   r  )rû   ÚbasenameFÚ	statement)r	   ZPyLintASTWalkerrù   r  r   r  ZIAstroidCheckerZadd_checkerr  rü   r  Úget_astr•   r]   r”   r?   r–   Úcheck_astroid_moduleZ"iter_spurious_suppression_messagesr   rê   Znbstatementsr,   ÚreversedÚclose)rK   rÿ   Úwalkerr’   ÚtokencheckersÚrawcheckersrÓ   r  r±   r"   r  Úast_nodeZspurious_messagesrÖ   r   rä   r   )rK   r   rý     s8    


zPyLinter._do_checkc             C   s~   t  || jj| jj¡\}}x^|D ]V}|d  }}|d }|  |¡ |dkrht|d ƒ t 	¡ tj
 d¡}| j||d q W |S )zHget modules and errors from a list of modules and handle errors
        Úmodr.   r1   rP   r|   )rä   )r	   Zexpand_modulesr
   rh   rn   r  Ústrrë   r   r!   Úseprê   )rK   ÚmodulesrO   ÚerrorsÚerrorr   r±   r.   r   r   r   r  ?  s    

zPyLinter.expand_filesc             C   sx   |s|dkrdS | j  ||¡ || _|p*|| _i | jd |< d| jd | d< x$tj ¡ D ]}d| jd | |< qZW dS )zYset the name of the currently analyzed module and
        init statistics for it
        NÚ	by_moduler   r  )r[   Zon_set_current_moduler_   r–   r,   r	   Ú	MSG_TYPESrØ   )rK   r±   r"   Úmsg_catr   r   r   r  N  s    
zPyLinter.set_current_modulec          
   C   sÎ   yt j||ddS  tjk
rT } z$| jdt|jddƒt|jƒd W dd}~X Y nv tjk
r„ } z| jd|d	 W dd}~X Y nF t	k
rÈ } z(ddl
}| ¡  | jd
|j|fd	 W dd}~X Y nX dS )z/return an ast(roid) representation for a moduleT)Úsourcezsyntax-errorÚlinenor   )r   rä   Nzparse-error)rä   zastroid-error)ÚMANAGERZast_from_fileÚastroidZAstroidSyntaxErrorrê   r5   r!  r  ZAstroidBuildingExceptionrG   Ú	tracebackÚ	print_excr«   )rK   r"   r±   rP   r)  r   r   r   r  \  s    ,zPyLinter.get_astc          
   C   sÎ   yt  |¡}W nD tjk
rR } z$| jd|jd d |jd d dS d}~X Y nX |jsl| jd|jd nT|  |¡ | j	r€dS | j
 | j|¡ x|D ]}| |¡ q–W x|D ]}| |¡ q®W | |¡ d	S )
z/Check a module from its astroid representation.zsyntax-errorr4   r   )r   rä   Nzraw-checker-failed)rä   FT)r	   Ztokenize_moduleræ   Ú
TokenErrorrê   rä   Zpure_pythonr}   rñ   r”   r]   Zcollect_block_linesr   Zprocess_moduleÚwalk)rK   r  r  r  r  rí   rP   rÓ   r   r   r   r  m  s"     



zPyLinter.check_astroid_modulec             C   sR   i i dœ| _ | jjt_| jjt_tj | jj	¡ xt
j ¡ D ]}d| j |< q<W dS )zinitialize counters)r"  r$   r   N)r,   r
   Zunsafe_load_any_extensionr'  Zalways_load_extensionsZlimit_inference_resultsZmax_inferable_valuesZextension_package_whitelistr(   Zextension_pkg_whitelistr	   r#  rØ   )rK   r$  r   r   r   r  ‹  s    

zPyLinter.openc             C   s¦   | j  t ¡ ¡ | jjdk	r’t | jj¡}| j  | j	|¡ | jj
rR|  | j	|¡}nt ¡ }| jj
rn| j  |¡ |  ¡  | jjr¢t | j	| jj¡ n| j  | j	i ¡ dS )z…close the whole package /module, it's time to make reports !

        if persistent run, pickle results for later comparison
        N)r[   Zdisplay_messagesÚreport_nodesZSectionr]   r^   r
   Úload_resultsZon_closer,   rw   Zmake_reportsÚdisplay_reportsÚ_report_evaluationro   Zsave_results)rK   Úprevious_statsÚsectr   r   r   Úgenerate_reports”  s    zPyLinter.generate_reportsc          
   C   sÀ   t  | jj¡}| jd dkr dS | j j}yt|i | jƒ}W n* tk
rd } zd| }W dd}~X Y n:X || jd< d| }| d¡}|dk	rž|d||| f 7 }| j j	r¼t
 |¡}| j |¡ dS )z!make the global evaluation reportr  r   Nz&An exception occurred while rating: %sZglobal_notez#Your code has been rated at %.2f/10z (previous run: %.2f/10, %+.2f))r
   r.  r]   r^   r,   ry   ÚevalrG   rD   rz   r-  ZEvaluationSectionr[   r/  )rK   r1  ry   ZnoterP   r   Zpnoter2  r   r   r   r0  ¯  s     


zPyLinter._report_evaluation)r   Nr   N)NN)F)N)0rc   rd   re   r¡   r   r  Z__implements__r}   rÑ   rp   ÚMSGSrb   ÚstaticmethodrŒ   r™   rž   rV   rW   rX   r¬   rµ   rY   rÃ   rÈ   rÐ   r¦   r×   rÚ   rã   r<   rñ   rò   rô   rù   rü   rZ   r  r  rþ   rý   r  r  r  r  r  r3  r0  Ú__classcell__r   r   )r«   r   rU   $  sT    u6
"
D	3/
	rU   c             C   s8   ddddg}|t  ||d¡7 }|  tj|ddd¡ d	S )
z#make total errors / warnings reportri   ZnumberZpreviousÚ
difference)Ú
conventionÚrefactorÚwarningr!  é   r4   )r
  ÚcolsÚrheadersN)r   Ztable_lines_from_statsrÏ   r-  ÚTable)r2  r,   r1  Úlinesr   r   r   r£   Ì  s    r£   c             C   sr   |d st  ¡ ‚tdd„ |d  ¡ D ƒƒ}| ¡  d}x |D ]\}}||t|ƒf7 }q<W |  tj|ddd¡ dS )	zmake messages type reportr$   c             S   s"   g | ]\}}|  d ¡s||f‘qS )ÚI)rÞ   )rR   r   rÅ   r   r   r   rT   Ü  s   z)report_messages_stats.<locals>.<listcomp>)z
message idZoccurrencesé   r4   )r
  r=  r>  N)	r   ÚEmptyReportErrorrË   r)   rõ   r  rÏ   r-  r?  )r2  r,   rÙ   Zin_orderr@  rÅ   r   r   r   r   r¥   Õ  s    r¥   c             C   st  t |d ƒdkrt ¡ ‚t t¡}xddD ]\}|| }xN|d  ¡ D ]>}|d | | }|dkrdd}nt|d ƒ| }||| |< qBW q(W g }	x8| ¡ D ],\}}
|	 	|
d |
d |
d |
d	 |f¡ q–W |	 
¡  |	 ¡  d
dddd	g}x^|	D ]V}tdd„ |dd… D ƒƒrqê| 	|d ¡ x$|dd… D ]}| 	d| ¡ q(W qêW t |ƒdkrZt ¡ ‚|  	tj|ddd¡ dS )z(make errors / warnings by modules reportr"  r4   )r1   r!  r;  r:  r9  r   rˆ   r!  r;  r:  r9  r   c             s   s   | ]}|d kV  qdS )r   Nr   )rR   Úentryr   r   r   r     s    z2report_messages_by_module_stats.<locals>.<genexpr>Nrº   z%.2fé   )r
  r=  r>  )r6   r   rC  r%   r   r+   ÚkeysÚfloatr)   rÏ   Úsortrõ   rÛ   r-  r?  )r2  r,   rÙ   Zby_modZm_typeZtotalr   Z	mod_totalZpercentZsorted_resultZmod_infor@  r   r  r   r   r   r¤   è  s>    


r¤   c               @   s   e Zd ZdZdS )ÚArgumentPreprocessingErrorz8Raised if an error occurs during argument preprocessing.N)rc   rd   re   r¡   r   r   r   r   rI    s   rI  c       	      C   s$  d}x|t | ƒk r| | }| d¡ry|dd…  dd¡\}}W n& tk
rl   |dd… d }}Y nX y|| \}}W n tk
rš   |d7 }Y nxX | |= |rè|dkrè|t | ƒksÈ| |  d¡rØd| }t|ƒ‚| | }| |= n |s|dk	rd	| }t|ƒ‚|||ƒ q|d7 }qW dS )
z¶look for some options (keys of <search_for>) which have to be processed
    before others

    values of <search_for> are callback functions to call when the option is
    found
    r   z--rB  Nrå   r4   r½   zOption %s expects a valuez!Option %s doesn't expects a value)r6   rÞ   r»   rÎ   r¾   rI  )	rä   Z
search_forÚiÚargÚoptionr  ÚcbZtakeargr   r   r   r   Úpreprocess_options  s0    rN  c          
   c   st   t tjƒ}g }x*| D ]"}t|ƒ}||kr,qq| |¡ qW |dg tj tjdd…< z
dV  W d|tjdd…< X dS )aB  Prepare sys.path for running the linter checks.

    Within this context, each of the given arguments is importable.
    Paths are added to sys.path in corresponding order to the arguments.
    We avoid adding duplicate directories to sys.path.
    `sys.path` is reset to its original value upon exiting this context.
    r¹   N)r‘   rI   r   r#   rÏ   )rä   ZorigZchangesrK  r   r   r   r   Úfix_import_path;  s    	


rO  c               @   sz   e Zd ZdZeZdZd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d„ Zdd„ ZdS )ÚRunzEhelper class to use as main for pylint :

    run(*sys.argv[1:])
    ))ÚCommandszROptions which are actually commands. Options in this group are mutually exclusive.NTc       	      C   s¦  d | _ g | _d | _y.t|tdf| jdf| jdf| jdfdœƒ W n: tk
rz } zt	|t
jd t
 d¡ W d d }~X Y nX | jdddd	„ d
dddœfdddd	„ d
ddddœfddd
d| jdddœfddd| jddddœfddd| jddddœfddtdddd œfd!dd| jddd"dœfd#d| jdd$d%œfd&d| jdd'dd(œfd)d| jd*d+d,œfd-d| jd.d/œfd0d| jd1d2d,œff| j| j d3 | _}| ¡  | | j¡ |jd4tjdd5 |jd6d7dd5 |jd8d9dd5 | d:¡ | d;¡ |j | jd< |j!}| "d=d¡rtdt# $| %d=d¡¡ƒ | "d=d>¡rFt# &| %d=d>¡¡}| |¡ | '¡  |r^| (|¡ y| )|¡}W n8 t*k
r¤ } z|j+d?kr’d|_+‚ W d d }~X Y nX |sÂt	| ,¡ ƒ t
 d¡ |jj-d@k rðt	dA|jj- t
jd t
 d¡ |jj-dks|jj-d@krJt.d kr2t	dBt
jd | /dCd¡ n|jj-d@krJt0ƒ |j_-| 1¡  t2|ƒ | 3|¡ | 4¡  W d Q R X |r¢|jj5r”t
 d@¡ nt
 | jj6¡ d S )DNTF)z	init-hookÚrcfilezload-pluginsÚverbose)r?   r  rR  Úcallbackc              W   s   dS )Nr4   r   )rä   r   r   r   rÊ   {  s    zRun.__init__.<locals>.<lambda>rr   z<file>zSpecify a configuration file.)rŠ   rT  ri   rj   rm   z	init-hookc              W   s   dS )Nr4   r   )rä   r   r   r   rÊ   …  s    z<code>r4   zRPython code to execute, usually for sys.path manipulation such as pygtk.require().)rŠ   rT  ri   rj   rp   rm   zhelp-msgz<msg-id>rQ  zqDisplay a help message for the given message id and exit. The value may be a comma separated list of message ids.)rŠ   ri   rj   rT  rv   rm   z	list-msgszGenerate pylint's messages.)rŠ   rj   rT  rv   rp   rm   zlist-groupszList pylint's message groups.zlist-conf-levelsz$Generate pylint's confidence levels.)rŠ   rT  rv   rp   rm   zfull-documentationz%Generate pylint's full documentation.zgenerate-rcfilez¢Generate a sample configuration file according to the current configuration. You can put other options before this one to get them in the generated configuration.)rŠ   rT  rv   rm   zgenerate-manzGenerate pylint's man page.)rŠ   rT  rv   rm   r‡   zerrors-onlyrÔ   z–In error mode, checkers without error messages are disabled and for others, only the ERROR messages are displayed, and no reports are done by default.)rŠ   rT  ru   rm   Zpy3kz{In Python 3 porting mode, all checkers will be disabled and only messages emitted by the porting checker will be displayed.)rŠ   rT  rm   rS  ÚvzBIn verbose mode, extra non-checker-related info will be displayed.)r™   rª   zEnvironment variables)rp   ZOutputa5  Using the default text output, the message format is :                          
                                                                                
        MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE                                
                                                                                
There are 5 kind of message types :                                             
    * (C) convention, for programming standard violation                        
    * (R) refactor, for bad code smell                                          
    * (W) warning, for python specific problems                                 
    * (E) error, for probable bugs in the code                                  
    * (F) fatal, if an error occurred which prevented pylint from doing further
processing.
zOutput status codea[  Pylint should leave with following status code:                                 
    * 0 if everything went fine                                                 
    * 1 if a fatal message was issued                                           
    * 2 if an error message was issued                                          
    * 4 if a warning message was issued                                         
    * 8 if a refactor message was issued                                        
    * 16 if a convention message was issued                                     
    * 32 on usage error                                                         
                                                                                
status 1 to 16 will be bit-ORed so you can know which different categories has
been issued by analysing pylint output status code
rA  zc-extension-no-member)rS  ZMASTERzload-pluginsrB  r   z5Jobs number (%d) should be greater than or equal to 0z>Multiprocessing library is missing, fallback to single processr;   )7Ú_rcfilerB   rS  rN  Úcb_init_hookÚcb_set_rcfileÚcb_add_pluginsÚcb_verbose_moderI  rH   rI   rJ   r	  ÚLinterClassÚcb_help_messageÚcb_list_messagesÚcb_list_groupsÚcb_list_confidence_levelsÚcb_full_documentationÚcb_generate_configÚcb_generate_manpageÚcb_error_modeÚcb_python3_porting_moder™   ra   rV   rW   Zadd_help_sectionr
   ZENV_HELPrƒ   r   Zread_config_filerß   rà   r	   Z_unquoterD   rì   Zload_config_filerY   Zload_command_line_configurationÚ
SystemExitÚcoderm   r;   r7   rÃ   r9   rX   rO  rZ   r3  Z	exit_zeror`   )	rK   rä   r[   Zdo_exitrP   ra   râ   r=   Úexcr   r   r   rž   b  s   













zRun.__init__c             C   s
   || _ dS )z>callback for option preprocessing (i.e. before option parsing)N)rV  )rK   r}   rÅ   r   r   r   rX  d  s    zRun.cb_set_rcfilec             C   s   | j  t |¡¡ dS )z>callback for option preprocessing (i.e. before option parsing)N)rB   Úextendr	   rì   )rK   r}   rÅ   r   r   r   rY  h  s    zRun.cb_add_pluginsc             O   s   | j  ¡  dS )zäerror mode:
        * disable all but error messages
        * disable the 'miscellaneous' checker which can be safely deactivated in
          debug
        * disable reports
        * do not save execution information
        N)ra   rã   )rK   rä   Úkwargsr   r   r   rc  l  s    zRun.cb_error_modec             O   s   | j jdd t d¡ dS )z0optik callback for sample config file generation)ZCOMMANDS)Zskipsectionsr   N)ra   Zgenerate_configrI   r	  )rK   rä   ri  r   r   r   ra  v  s    zRun.cb_generate_configc             O   s&   ddl m} | j |¡ t d¡ dS )z0optik callback for sample config file generationr   )Ú__pkginfo__N)Úpylintrj  ra   Zgenerate_manpagerI   r	  )rK   rä   ri  rj  r   r   r   rb  {  s    zRun.cb_generate_manpagec             C   s"   | j j t |¡¡ t d¡ dS )z@optik callback for printing some help about a particular messager   N)ra   r   Zhelp_messager	   rì   rI   r	  )rK   rL  rÄ   rÅ   Úparserr   r   r   r\  ‚  s    zRun.cb_help_messagec             C   s   | j  ¡  t d¡ dS )z.optik callback for printing full documentationr   N)ra   Zprint_full_documentationrI   r	  )rK   rL  rÄ   rÅ   rl  r   r   r   r`  ‡  s    
zRun.cb_full_documentationc             C   s   | j j ¡  t d¡ dS )z.optik callback for printing available messagesr   N)ra   r   Zlist_messagesrI   r	  )rK   rL  rÄ   rÅ   rl  r   r   r   r]  Œ  s    zRun.cb_list_messagesc             O   s*   x| j  ¡ D ]}t|ƒ qW t d¡ dS )z›List all the check groups that pylint knows about

        These should be useful to know what check groups someone can disable
        or enable.
        r   N)ra   rô   rH   rI   r	  )rK   rä   ri  rZ   r   r   r   r^  ‘  s    zRun.cb_list_groupsc             O   s   | j  ¡  dS )z*Activate only the python3 porting checker.N)ra   r<   )rK   rä   ri  r   r   r   rd  ›  s    zRun.cb_python3_porting_modec             O   s
   d| _ d S )NT)rS  )rK   rä   ri  r   r   r   rZ  Ÿ  s    zRun.cb_verbose_mode)NT)rc   rd   re   r¡   rU   r[  r™   rž   rX  rY  rc  ra  rb  r\  r`  r]  r^  rd  rZ  r   r   r   r   rP  S  s"   
  

rP  c             C   s*   xt jD ]}td| ƒ qW t d¡ d S )Nz	%-18s: %sr   )r   r‹   rH   rI   r	  )rL  rÄ   rÅ   rl  rp   r   r   r   r_  £  s    r_  c             C   s   t |ƒ dS )z0exec arbitrary code to set sys.path for instanceN)Úexec)rÄ   rÅ   r   r   r   rW  ©  s    rW  Ú__main__r4   )7r¡   Z
__future__r   r%   Ú
contextlibr÷   r   r7   r¶   rI   ræ   r¿   r(  Zastroid.__pkginfo__r   rœ   r   rk  r   r   r   r   r	   r
   Zpylint.__pkginfo__Zpylint.reporters.ureportsr   r-  r'  r   r#   r0   r5  r…   r9   ZProcessr:   ZOptionsManagerMixInr   rŸ   r¢   rU   r£   r¥   r¤   rG   rI  rN  ÚcontextmanagerrO  rP  r_  rW  rc   Úargvr   r   r   r   Ú<module><   sŽ   


=
       +	,#  R
