You can click on the Google or Yahoo buttons to sign-in with these identity providers,
or you just type your identity uri and click on the little login button.
[register] [login]
remember me
Forgot your password ?
search
possible views
rset views
CSV export
JSON export
table
XML export
entity views
Cards
CSV export (entities)
file tree view
inlined view
JSON export (entities)
list
one line
owlabox
primary
RDF export
RSS export
text
tree view
XBEL export
XML export (entities)
bookmarks
active projects
all projects
latest blogs
latest releases
Logilab Debian Repository
versions: dev
versions: planned
Pylint User Manual
This document is meant to be the reference user manual for Pylint. This is a
work in progress so some sections or parts may be missing (sometimes marked by a
XXX). If you think it's lacking some important information, please talk about
it on the python-projects mailing list (see the `Mailing lists` section for
more information about the list).
Contents
Introduction
What is pylint?
Installation
Dependencies
Distributions
Source distribution installation
Note for Windows users
Invoking pylint
Pylint output
Source code analysis section
Reports section
Command line options
Daily pylint usage
Bug reports, feedback
Mailing lists
Advanced usage
Base configuration
Environment
Messages control
About analysis
Pylint heuristics
About astng inference
Enhancing Pylint
Writing your own checker
Contribute !
Contribution Instructions
Other information
IDE integration
Some projects using Pylint
Introduction
What is pylint?
Pylint is a tool that checks for errors in python code, tries to enforce a
coding standard and looks for smelling code. This is similar but nevertheless
different from what pychecker provides, especially since pychecker explicitly
does not bother with coding style. The default coding style used by pylint is
close to PEP 008 (aka Guido's style guide). For more information about
code smells, refer to Martin Fowler's refactoring book
One important thing to note is that Pylint isn't smarter than you are: it may
warn you about things that you have conscientiously done. That's for example
because it tries to detect things that may be dangerous in a context, but maybe
not in others, or because it checks for some things that you don't care
about. Generally, you shouldn't expect pylint to be totally quiet about your
code, so don't necessarily be alarmed if it gives you a hell lot of messages for
your proudly(XXX) project ;)
Pylint will display a number of messages as it analyzes the code, as well as
some statistics about the number of warnings and errors found in different
files. The messages are classified under various categories such as errors and
warnings (more below). If you run pylint twice, it will display the statistics
from the previous run together with the ones from the current run, so that you
can see if the code has improved or not.
Last but not least, the code is given an overall mark, based on the number an
severity of the warnings and errors. This has proven to be very motivating for
programmers.
Installation
Dependencies
Pylint requires the latest logilab-astng and logilab-common
packages. It should be compatible with any python version >= 2.5.
Distributions
The source tarball is available at ftp://download.logilab.org/pub/pylint.
You may apt-get a well-tested debian or ubuntu package by adding one of:
deb download.logilab.org/production unstable/
deb download.logilab.org/production sid/
deb download.logilab.org/production squeeze/
deb download.logilab.org/production lenny/
to your /etc/apt/sources.list file. Pylint is also available in the
standard Debian distribution (but add our public debian repository
anyway if you want to get the latest releases and upgrades earlier)
Pylint is also available in Gentoo, Fedora 4, Ubuntu, FreeBSD, Darwin
(and maybe others, if you know about more OSes, please drop us a note!).
Source distribution installation
From the source distribution, extract the tarball, go to the extracted
directory and simply run
python setup.py install
You'll have to install dependencies in a similar way.
Windows users may get valuable information about pylint installation on
this page.
Note for Windows users
On Windows, once you have installed pylint, the command line usage is
pylint.bat [options] module_or_package
But this will only work if pylint.bat is either in the current
directory, or on your system path. (setup.py install install python.bat
to the Scripts subdirectory of your Python installation -- e.g.
C:Python24Scripts.) You can do any of the following to solve this:
change to the appropriate directory before running pylint.bat
add the Scripts directory to your path statement in your autoexec.bat
file (this file is found in the root directory of your boot-drive)
create a 'redirect' batch file in a directory actually on your
systems path
To effect (2), simply append the appropriate directory name to the PATH=
statement in autoexec.bat. Be sure to use the Windows directory
separator of ';' between entries. Then, once you have rebooted (this is
necessary so that the new path statement will take effect when
autoexec.bat is run), you will be able to invoke PyLint with
pylint.bat on the command line.
(3) is the best solution. Once done, you can call pylint at the command
line without the .bat, just as do non-Windows users by typing:
pylint [options] module_or_package
To effect option (3), simply create a plain text file pylint.bat with
the single line:
C:\PythonDirectory\Scripts\pylint.bat
(where PythonDirectory is replaced by the actual Python installation
directory on your system -- e.g. C:Python24Scriptspylint.bat).
Invoking pylint
Pylint is meant to be called from the command line. The usage is
pylint [options] module_or_package
You should give pylint the name of a Python package or module. Pylint
will import this package or module, so you should pay attention to
your PYTHONPATH, since it is a common error to analyze an
installed version of a module instead of the development version.
It is also possible to analyze python files, with a few
restriction. The thing to keep in mind is that pylint will try to
convert the file name to a module name, and only be able to process
the file if it succeeds.
pylint mymodule.py
should always work since the current working
directory is automatically added on top of the python path
pylint directory/mymodule.py
will work if "directory" is a python package (i.e. has an __init__.py
file) or if "directory" is in the python path.
For more details on this see the Frequently Asked Questions.
You can also start a thin gui around pylint (require TkInter) by
typing
pylint-gui
This should open a window where you can enter the name of the package
or module to check, at pylint messages will be displayed in the user
interface.
It is also possible to call Pylint from an other Python program,
thanks to py_run() function in lint module,
assuming Pylint options are stored in pylint_options string, as
from pylint import lint
lint.py_run( pylint_options)
To silently run Pylint on a module_name.py module,
and get its standart output and error:
from pylint import lint
(pylint_stdout, pylint_stderr) = lint.py_run( 'module_name.py', True)
Pylint output
The default format for the output is raw text. But passing pylint the
--output-format=html or -h y or -o html option will produce an HTML document.
There are several sections in pylint's output.
Source code analysis section
For each python module,
pylint will first display a few '*' characters followed by the name
of the module. Then, a number of messages with the following
format:
MESSAGE_TYPE: LINE_NUM:[OBJECT:] MESSAGE
You can get another output format, useful since it's recognized by
most editors or other development tools using the --parseable=y
option.
The message type can be:
[R]efactor for a "good practice" metric violation
[C]onvention for coding standard violation
[W]arning for stylistic problems, or minor programming issues
[E]rror for important programming issues (i.e. most probably bug)
[F]atal for errors which prevented further processing
Sometimes the line of code which caused the error is displayed with
a caret pointing to the error. This may be generalized in future
versions of pylint.
Example (extracted from a run of pylint on itself...):
************* Module pylint.checkers.format
W: 50: Too long line (86/80)
W:108: Operator not followed by a space
print >>sys.stderr, 'Unable to match %r', line
^
W:141: Too long line (81/80)
W: 74:searchall: Unreachable code
W:171:FormatChecker.process_tokens: Redefining built-in (type)
W:150:FormatChecker.process_tokens: Too many local variables (20/15)
W:150:FormatChecker.process_tokens: Too many branches (13/12)
Reports section
Following the analysis message, pylint will display a set of reports,
each one focusing on a particular aspect of the project, such as number
of messages by categories, modules dependencies...
For instance, the metrics report displays summaries gathered from the
current run.
the number of processed modules
for each module, the percentage of errors and warnings
the total number of errors and warnings
percentage of classes, functions and modules with docstrings, and
a comparison from the previous run
percentage of classes, functions and modules with correct name
(according to the coding standard), and a comparison from the
previous run
a list of external dependencies found in the code, and where they appear
Also, a global evaluation for the code is computed, and an
optional witty comment is displayed (if --comment=y was
specified on the command line).
Command line options
First of all, we have two basic (but useful) options.
--version
show program's version number and exit
-h, --help
show help about the command line options
Pylint is architectured around several checkers. By default all
checkers are enabled. You can disable a specific checker or some of its
messages or messages categories by specifying
--disable=<id>. A more general disable can be enabled with
or disable all checkers using
--enable=w<id>. See the list of available features for a
description of provided checkers with their functionalities.
The --disable and --enable options can be used with comma separated lists
mixing checkers, message ids and categories like -d C,W,E0611,design
Each checker has some specific options, which can take either a yes/no
value, an integer, a python regular expression, or a comma separated
list of values (which are generally used to override a regular
expression in special cases). For a full list of options, use --help
Specifying all the options suitable for your setup and coding
standards can be tedious, so it is possible to use a rc file to
specify the default values. Pylint looks for /etc/pylintrc and
~/.pylintrc. The --generate-rcfile option will generate a
commented configuration file according to the current configuration on
standard output and exit. You can put other options before this one to
use them in the configuration, or start with the default values and
hand tune the configuration.
Other useful global options include:
--zope
Initialize Zope products before starting
--ignore=file
Add <file> (may be a directory) to the black
list. It should be a base name, not a path.
You may set this option multiple times.
--statistics=y_or_n
Compute statistics on collected data.
--persistent=y_or_n
Pickle collected data for later comparisons.
--comment=y_or_n
Add a comment according to your evaluation note.
--parseable=y_or_n
Use a parseable output format.
--html=y_or_n
Use HTML as output format instead of text.
--list-msgs
Generate pylint's messages.
--full-documentation
Generate pylint's full documentation, in reST format.
Daily pylint usage
What pylint says is not to be taken as gospel. While getting as
few false positives for errors as possible is a goal for us -- and
python makes it hard enough, it is not the case for warnings.
Quoting Alexandre:
My usage pattern for pylint is to generally run pylint -e quite often to
get stupid errors flagged before launching an application (or before
committing). I generally run pylint with all the bells and whistles
activated some time before a release, when I want to cleanup the code.
And when I do that I simply ignore tons of the false warnings (and I
can do that without being driven mad by this dumb program which is not
smart enough to understand the dynamicity of Python because I only run
it once or twice a week in this mode)
Quoting Marteen Ter Huurne:
In our project we just accepted that we have to make some modifications in our
code to please PyLint:
stick to more naming conventions (unused variables ending in underscores,
mix-in class names ending in "Mixin")
making all abstract methods explicit (rather than just not defining them in
the superclass)
for messages which are useful in general, but not in a specific case: add "#
pylint: disable=X0123" comments
for PyLint bugs: add "#pylint: disable=X0123" comments
for PyLint limitations: add "#pylint: disable=X0123" comments
(for instance Twisted's modules create a lot of definitions dynamically so
PyLint does not know about them)
The effort is worth it, since PyLint helps us a lot in keeping the code clean
and finding errors early. Although most errors found by PyLint would also be
found by the regression tests, by fixing them before committing, we save time.
And our regression tests do not cover all code either, just the most complex
parts.
Bug reports, feedback
You think you have found a bug in Pylint? Well, this may be the case
since Pylint is under development. Please take the time to send a bug
report to python-projects@logilab.org if you've not found it already reported on
the tracker page. This mailing list is also a nice place to
discuss Pylint issues, see below for more information about pylint's related
lists.
You can check for already reported bugs, planned features on pylint's tracker
web page: www.logilab.org/project/name/pylint
Notice that if you don't find something you have expected in pylint's
tracker page, it may be on the tracker page of one of its dependencies, namely
astng and common:
www.logilab.org/project/name/logilab-astng
www.logilab.org/project/name/logilab-common
Mailing lists
Use the python-projects@logilab.org mailing list for anything related
to Pylint. This is in most cases better than sending an email directly
to the author, since others will benefit from the exchange, and you'll
be more likely answered by someone subscribed to the list. This is a
moderated mailing list, so if you're not subscribed email you send will have to
be validated first before actually being sent on the list.
You can subscribe to this mailing list at
lists.logilab.org/mailman/listinfo/python-projects
Archives are available at
lists.logilab.org/pipermail/python-projects/
If you prefer speaking french instead of english, you can use the
generic forum-fr@logilab.org mailing list:
Notice though that this list has a very low traffic since most pylint related
discussions are done on the python-projects mailing list.
Advanced usage
Base configuration
To be written...
Environment
To be written...
Messages control
An example available from the examples directory:
"""pylint option block-disable"""__revision__=NoneclassFoo(object):"""block-disable test"""def__init__(self):passdefmeth1(self,arg):"""this issues a message"""printselfdefmeth2(self,arg):"""and this one not"""# pylint: disable=W0613printself\
+"foo"defmeth3(self):"""test one line disabling"""# no errorprintself.bla# pylint: disable=E1101# errorprintself.blopdefmeth4(self):"""test re-enabling"""# pylint: disable=E1101# no errorprintself.blaprintself.blop# pylint: enable=E1101# errorprintself.blipdefmeth5(self):"""test IF sub-block re-enabling"""# pylint: disable=E1101# no errorprintself.blaifself.blop:# pylint: enable=E1101# errorprintself.blipelse:# no errorprintself.blip# no errorprintself.blipdefmeth6(self):"""test TRY/EXCEPT sub-block re-enabling"""# pylint: disable=E1101# no errorprintself.blatry:pylint:enable=E1101# errorprintself.blipexceptUndefinedName:# pylint: disable=E0602# no errorprintself.blip# no errorprintself.blipdefmeth7(self):"""test one line block opening disabling"""ifself.blop:# pylint: disable=E1101# errorprintself.blipelse:# errorprintself.blip# errorprintself.blipdefmeth8(self):"""test late disabling"""# errorprintself.blip# pylint: disable=E1101# no errorprintself.blaprintself.blop
About analysis
Pylint heuristics
To be written...
About astng inference
To be written...
Enhancing Pylint
Writing your own checker
You can find some simple examples in the examples
directory of the distribution (custom.py and custom_raw.py). I'll try to
quickly explain the essentials here.
First, there are two kinds of checkers :
* raw checkers, which are analysing each module as a raw file stream
* ast checkers, which are working on an ast representation of the module
The ast representation used is an extension of the one provided with the
standard python distribution in the compiler package. The extension
adds additional information and methods on the tree nodes to ease
navigation and code introspection.
An AST checker is a visitor, and should implement
visit_<lowered class name>
leave_<lowered class name>
methods for the nodes it's interested in. To get description of the different
classes used in an ast tree, look at the compiler.ast documentation.
Checkers are ordered by priority. For each module, pylint's engine:
give the module source file as a stream to raw checkers
get an ast representation for the module
make a depth first descent of the tree, calling visit_<> on each AST
checker when entering a node, and living_<> on the back traversal
Notice that the source code is probably the best source of
documentation, it should be clear and well documented. Don't hesitate to
ask for any information on the python-projects mailing list.
Contribute !
All our software is developped using the mercurial version control
system. This is a very cool distributed vcs and its usage is very similar to
other ones such as cvs or subversion (though the distributed feature introduced
some different usage patterns).