This page collects information for creating a usable Python programming environment in Emacs.
There are a number of Python modes for Emacs. The major ones right now are python.el which comes with Emacs 24.2 and up and python-mode.el which used to be included in Python (up to 2.6.8). The older python.el from Emacs 24.1 and before has a number of fans as well.
Beyond the basic Python modes described above, there are a number of modes that support Python programming.
Emacs’ 24.2+ python.el contains the following guide on how to set it up to use IPython 0.11:
(setq python-shell-interpreter "ipython" python-shell-interpreter-args "" python-shell-prompt-regexp "In \\[[0-9]+\\]: " python-shell-prompt-output-regexp "Out\\[[0-9]+\\]: " python-shell-completion-setup-code "from IPython.core.completerlib import module_completion" python-shell-completion-module-string-code "';'.join(module_completion('''%s'''))\n" python-shell-completion-string-code "';'.join(get_ipython().Completer.all_completions('''%s'''))\n")
For iPython 0.10 everything would be the same except for `python-shell-completion-string-code` and `python-shell-completion-module-string-code`:
(setq python-shell-completion-string-code "';'.join(__IP.complete('''%s'''))\n" python-shell-completion-module-string-code "")
Unfortunately running iPython on Windows needs some more tweaking. The way you must set `python-shell-interpreter` and `python-shell-interpreter-args` is as follows:
(setq python-shell-interpreter "C:\\Python27\\python.exe" python-shell-interpreter-args "-i C:\\Python27\\Scripts\\ipython-script.py")
That will spawn the iPython process correctly (Of course you need to modify the paths according to your system).
(setq py-jython-command "c:/Program Files/IronPython 2.6 for .NET 4.0/ipy.exe")
If you have
‘transient-mark-mode’ on, you can just use
‘comment-dwim’: select a region and hit `M-;’. The DoWhatIMean means that it will comment or uncomment the region as appropriate. If you do not have
‘transient-mark-mode’ on by default, you can hit C-SPC twice to activate it temporarily.
( doesn’t python-mode.el offer `py-comment-region? --CH )
You can also use “rectangles” with comment/uncomment region (among other things that you can do with rectangles). See RectangleCommands or “(emacs) Rectangles” in the Emacs manual.
To browse the new Python documentation using Info, you will need the necessary Info files. These files are not currently available from the official download site since they are generated by a development version of Sphinx, the documentation system used by Python. You can however download a copy of the documentation for
These Info files are different than the ones generated from the old Python documentation (prior to python 2.5) which were not built by Sphinx. One result of these differences is that
C-h S) will not work correctly in
‘python-mode’ since the InfoLook support in “python.el” is based on the old version. To fix this issue, you can add the following code to your .emacs:
(require 'info-look) (info-lookup-add-help :mode 'python-mode :regexp "[[:alnum:]_]+" :doc-spec '(("(python)Index" nil "")))
An alternative method for fixing
‘info-lookup-symbol’ support is provided by the pydoc-info package.
More than one code checking tool can be applied in flymake by using a wrapper script that runs the desired tools and combines their output. It has lots of issues, one being that flymake does not seem to show more than one error message per line of code, meaning that an error or warning which is intentionally left unfixed can mask an error or warning that would get more attention.
Additionally, the scripts that check python code are either rather anemic, and don’t notice too much (pychecker) or are aggressive, and warn about all sorts of things that they should not (pylint). pep8.py tends to be annoyingly aggressive about whitespace.
There are several scripts around to do this, supporting various tools. Each expects to find the code checking tools in your path (pep8.py, pychecker, pylint, pyflakes, etc). Additionally this script attempts to support virtual environments, but this is largely untested.
Please note that pylint now comes with an executable “epylint” that is meant to be the interface to Emacs.
The flymake mode in Emacs 22 does not understand Python, but it can be made to work with pylint. To do this, first you’ll need to create a script somewhere along your PATH called ‘epylint’. That script is here
It might appear that for some combinations of flymake, pylint and epylint the above script might not work properly (it didn’t for me). Debugging showed that the regexp wasn’t matching the output of pylint, ever, so the lines were being printed from pylint verbatim, meaning that flymake was doing a “best effort” match, and everything was coming up as an error, even minor warnings.
Here is an alternative version of the epylint script that works great for me. It doesn’t throw away all the R and C errors, just the most annoying ones. You can easily modify it to include or exclude messages to your preference. I find it easier to have the messages in the script rather than messing about with .pylintrc and the like.
(I’ve also got a version that inserts the overall code quality metric, as determined by pylint, so you can see at a glance how close you are to pylint perfection; holler here if you want to see it).
Once you test that this works on sample Python files, then add the following to your InitFile to enable flymake checking of Python scripts using pylint:
(when (load "flymake" t) (defun flymake-pylint-init () (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) (list "epylint" (list local-file))))
(add-to-list 'flymake-allowed-file-name-masks '("\\.py\\'" flymake-pylint-init)))
Now if you turn on
‘flymake-mode’ inside a Python file, you should see lines with warnings highlighted in blue, and lines with errors highlighted in red. Just hover your mouse over either type of line for a few seconds and you’ll see a tooltip describing the error/warning. Plus, the modeline will show you two numbers, X/Y, where X is the number of errors in your script, and Y is the total number of warnings. – JohnWiegley
You can customise the way flymake highlights your Python by running ‘M-x customize-face’ on ‘flymake-errline’ or ‘flymake-warnline’. For example, you can remove the background highlight and make the face be just a subtle coloured underline.
Found a desciption on how to use this pair at www.plope.com/Members/chrism/flymake-mode I did a copy ‘n paste for simplicity.
(when (load "flymake" t) (defun flymake-pyflakes-init () ; Make sure it's not a remote buffer or flymake would not work (when (not (subsetp (list (current-buffer)) (tramp-list-remote-buffers))) (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) (list "pyflakes" (list local-file))))) (add-to-list 'flymake-allowed-file-name-masks '("\\.py\\'" flymake-pyflakes-init)))
The normal operation of flymake allows the user to see the error message for a particular line by “hovering” the mouse over the line. This is inconvenient for people who try to use the keyboard for all input. FlymakeCursor was designed to address that: it displays the flymake error in the minibuffer region, when the cursor is placed on a line containing a flymake error.
Download the pyflakes tgz file from Pypi. Unpack it, then run the setup:
\Python27\python.exe \temp\\temp\pyflakes-0.5.0\setup.py install
This will install pyflakes.
To run pyflakes from a command prompt, you then need something like this:
\Python27\python.exe \Python27\Scripts\pyflakes myfile.py
To make it simpler, you can create a file called
pyflakes.cmd and put it into c:\python27 . The contents should be:
@echo off goto START ------------------------------------------------------- pyflakes.cmd ------------------------------------------------------- :START SETLOCAL if _%1==_ goto USAGE %~dp0\python.exe %~dp0\Scripts\pyflakes %* goto ALL_DONE :USAGE echo usage: pyflakes ^<file^> [^<optionalargs^>] echo run the pyflakes syntax checker on a python source file. :ALL_DONE ENDLOCAL
Then, modify one line in the elisp snip given above, to be like this:
(when (load "flymake" t) (defun flymake-pyflakes-init () ; Make sure it's not a remote buffer or flymake would not work (when (not (subsetp (list (current-buffer)) (tramp-list-remote-buffers))) (let* ((temp-file (flymake-init-create-temp-buffer-copy 'flymake-create-temp-inplace)) (local-file (file-relative-name temp-file (file-name-directory buffer-file-name)))) (list "c:\\Python27\\pyflakes.cmd" (list local-file))))) (add-to-list 'flymake-allowed-file-name-masks '("\\.py\\'" flymake-pyflakes-init)))
Also see PyIndent
I made the following changes to python-mode.el to make debugging work again with current IPython (0.9.1):
;; pdbtrack constants (defconst py-pdbtrack-stack-entry-regexp "^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_<>]+\\)()"; this is new ; "^> \\([^(]+\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()" ; "^> \\(.*\\)(\\([0-9]+\\))\\([?a-zA-Z0-9_]+\\)()" "Regular expression pdbtrack uses to find a stack trace entry.")
;(defconst py-pdbtrack-input-prompt "\n[(<]*[Pp]db[>)]+ " (defconst py-pdbtrack-input-prompt "\n[(<]*[Ii]?[Pp]db[>)]+ "; this is new "Regular expression pdbtrack uses to recognize a pdb prompt.")
(setq block (ansi-color-filter-apply block)) ; this is new (setq target (py-pdbtrack-get-source-buffer block))
Now when I debug in the IPython console (using %run -d, or %pdb on, etc.) pdbtrack makes sure to show me the current source code and corresponding line. Note that these changes may break debugging in a standard python-shell, I have not tested this.
(defun pytidy-whole-buffer () (interactive) (let ((a (point))) (shell-command-on-region (point-min) (point-max) "<Name_Of_Executable_Script>" t) (goto-char a)))
Note: <Name_Of_Executable_Script> should match the name of the pythonTidy script on your path, make sure you set execute permissions.
bind this to any key you wish, I have:
(define-key python-mode-map (kbd "<f9>") 'pytidy-whole-buffer)
in my python-mode-hook. invoking the command pretty-prints the hole buffer, you can invoke undo if something went wrong, and the cursor stays put.