Highlight Python syntax, style and unit test errors in Emacs
Emacs Lisp Python
Pull request Compare This branch is 21 commits behind akaihola:master.
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.


flymake-python: highlight Python syntax, style and unit test errors in Emacs

This project includes tools for enabling Emacs to run external Python lint and unit testing tools in the background while editing and highlighting the results in the source code.


The following external tools are supported:

  • pep8.py
  • PyChecker
  • PyLint
  • PyFlakes
  • nose

Python virtual environments are supported, but this is largely untested.


a script which runs external tools according to user's configuration and parses the output for flymake.el. The script is based on code copied from the Emacs Wiki on 2010-02-25. The original author is unknown.

a modified version of Pavel Kabyakov's flymake.el 0.3 which adds support for

  • the 'info' message type in addition to 'error' and 'warning'
  • passing the reason for running to external tools
.emacs customization:
in addition, a snippet of Emacs Lisp is needed in your ~/.emacs file



Install or make sure you have installed:

Files to install

Make sure that pep8, pylint and pychecker are in your $PATH.

Choose a directory for pyflymake.py (e.g. ~/.emacs.d/) and copy it there. Make sure the script is set as executable.

Copy the provided version of flymake.el in a directory which is in the Emacs load-path. If another version of flymake is installed, make sure this directory precedes it. Example: copy to ~/.emacs.d/flymake.el and add this to your ~/.emacs file:

(add-to-list 'load-path "~/.emacs.d")

Emacs configuration

Add to your ~/.emacs file (customize paths if necessary):

(add-to-list 'load-path "~/.emacs.d") ;; check path

(when (load "flymake" t)
  (defun flymake-pylint-init ()
    (let* ((temp-file (flymake-init-create-temp-buffer-copy
           (local-file (file-relative-name
                        (file-name-directory buffer-file-name))))
      (list "~/.emacs.d/pyflymake.py" (list local-file))))
      ;;     check path

  (add-to-list 'flymake-allowed-file-name-masks
               '("\\.py\\'" flymake-pylint-init)))

If you'd like flymake to be activated automatically, add the following to ~/.emacs as well:

(add-hook 'find-file-hook 'flymake-find-file-hook)


By default, pyflymake.py only runs PyLint, Pep8 and PyFlakes. PyChecker and unit test runners can be enabled in the configuration.

To find the configuration, pyflymake.py looks for .pyflymakerc in the same directory as the file being checked. If it isn't found, parent directories are checked up until the root directory. If no configuration file is found, the default configuration is used.

The .pyflymakerc configuration file is imported by pyflymake.py as a Python module. The TRIGGER_TYPE global variable is set and contains a string indicating the reason why flymake is running the checks.

List of configuration options

VIRTUALENV (default: None)
the Python virtual environment to use when running check tools
the unit test runner command or None if no unit tests should be run
TEST_RUNNER_FLAGS (default: [])
the list of command line arguments for the unit test runner
TEST_RUNNER_OUTPUT (default: 'stderr')
the device on which messages are output by the test runner
ENV (default: {})
additional environment variables when running check tools
PYLINT (default: True)
enable PyLint
PYCHECKER (default: False)
enable PyChecker
PEP8 (default: True)
enable Pep8
PYFLAKES (default: True)
enable PyFlakes
IGNORE_CODES (default: ())
error codes to ignore (in addition to sane defaults)
USE_SANE_DEFAULTS (default: True)

ignore the following error codes in PyLint:

  • C0103 Naming convention
  • C0111 Missing Docstring
  • E1002 Use super on old-style class
  • W0232 No __init__
  • R0904 Too many public methods
  • R0903 Too few public methods
  • R0201 Method could be a function

Enabling a unit test runner

In the root of a source tree in which you want pyflymake to run tests, create the file .pyflymakerc with the following content:

# to run external tools in a virtualenv:
VIRTUALENV = '/home/me/.virtualenvs/thevirtualenv'

# to run unit tests with nose:

# to enable additional checks:

You can use different test runners, too, provided that their output is similar to nose_machineout's. For example, Django's test runner could be used if django-nose is installed:

TEST_RUNNER_COMMAND = '/home/me/project/manage.py'

Trigger type specific configuration

You can specify custom configurations depending on why the checks are being run. Different triggers for flymake.el to run the checks are:

  • open: flymake.el was activated for the buffer
  • edit: the buffer was edited more than .5 seconds ago
  • save: the buffer was saved
  • force: M-x flymake-start-syntax-check was executed manually

Here's an example configuration:

# run unit tests only when checks are forced or buffer saved
if TRIGGER_TYPE in ('save', 'force'):
    TEST_RUNNER_COMMAND = 'nosetests'

# run unit tests only up to the first failure when buffer is saved
if TRIGGER_TYPE == 'save':

# run PyLint on open, save and forced-checks

# don't ignore any messages when a check was forced
if TRIGGER_TYPE == 'force':