EmacsWiki: Python Programming In Emacs (original) (raw)
This page collects information for creating a usable Python programming environment in Emacs.
Quick start
The quickest way to start is just to open a Python file in Emacs – ‘python-mode’
has a nice feature-set as is – see below for details.
Beyond that, as people ask for recommendations fairly often, the following is a reasonable approach:
- If you already use one of the StarterKits like Spacemacs or Doom Emacs, then use its Python configuration.
- If you want to set up a relatively complete environment quickly, and have someone else choose individual packages and handle combining them, then use one of the IDE packages listed below. Elpy appears to be the most popular Python-specific IDE package, while the LanguageServerProtocol supports many languages and has become very popular since c. 2019.
- If you want complete control then select the packages you want from the Support Features section.
Python mode
The built-in ‘python-mode’
supports, from its help, “Syntax highlighting, Indentation, Movement, Shell interaction, Shell completion, Shell virtualenv support, Shell package support, Shell syntax highlighting, Pdb tracking, Symbol completion, Skeletons, FFAP, Code Check, ElDoc, Imenu.
Some history: the built-in ‘python-mode’
comes from the 'gallina' python.el, which comes with Emacs 24.2 and up; this is different from the modes from 'loveshack' python.el , which was the built-in mode up to Emacs 24.1, and python-mode.el, listed below under IDE packages.
IDE packages
These provide powerful and relatively complete environments by combining and customizing other packages, both Emacs Lisp and Python, and resolving conflicts between them.
Spacemacs
- Python layer for Spacemacs. Builds on anaconda-mode and several other packages.
Doom Emacs
- Python module for Doom Emacs.
Language Server Protocol
The main LanguageServerProtocol clients support Python programming with various LSP servers.
LSP clients
LSP servers
General-purpose servers
- Pyright by Microsoft, lsp-mode configuration here. See here for a gist of a full-featured Python config using lsp-mode,
‘lsp-ui’
,‘lsp-pyright’
,‘pyvenv’
,‘treemacs’
and‘dap-mode’
. - basedpyright, a fork of Pyright with various type checking improvements, features from Pylance, and more. Microsoft’s creation of Pylance as a proprietary product had led to community concerns; basedpyright provides a freer and more community-focused alternative.
- Python LSP Server, aka “pylsp”, forked from Palantir’s unmaintained pyls, open-source, extensible via a plug-in mechanism, lsp-mode configuration here
- jedi language server, lsp-mode configuration here
Focused servers
Elpy
python-mode.el
- python-mode.el. Replaces the
‘python-mode’
in python.el.
Anaconda mode
Support Features
Various features that can be added to or improved in Emacs. Note that the IDE packages listed above provide many of these using packages referred to below.
Virtual environments
There is some built-in support for virtual environments in python.el, but these packages provide more features.
- pyvenv - used in elpy, written by the same author. auto-virtualenv provides automatic activation.
- pyenv-mode - uses pyenv, including automatic activation via Projectile.
- virtualenvwrapper. auto-virtualenvwrapper provides automatic activation.
- conda.el - for working with conda environments, including automatic activation.
- pipenv.el - A Pipenv porcelain inside Emacs, including automatic activation through Projectile.
- npy.el - for a nicer integration of Pipenv virtualenvs and inferior python processes.
Indentation
The defaults should see you compliant with PEP8 but see IndentingPython for detail.
Comment/Uncomment Region
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.
python-mode.el also provides `py-comment-region and commands to comment/uncomment all known forms, def, block, clause etc.
Completion
Note that some IDE packages provide completion, e.g. Elpy provides completion using either jedi or rope as a backend to CompanyMode, and anaconda-mode provides completion via CompanyMode or AutoComplete.
You can also configure completion by using either jedi or rope as a backend to either CompanyMode or AutoComplete.
For jedi:
- company-jedi provides a backend for CompanyMode.
- Jedi.el provides a backend for AutoComplete.
For rope:
- Ropemacs can be used as a backend for both CompanyMode and AutoComplete.
Code navigation
The built-in ‘python-mode’
includes support for ImenuMode code navigation. By default it uses a tree-like index, presenting top-level definitions that can be drilled into. To use a flat menu instead, you can use this:
(add-hook 'python-mode-hook (lambda () (setq-local imenu-create-index-function #'python-imenu-create-flat-index)))
LspMode’s ‘lsp-ui-imode’
shows a persistent graphical navigation tree in a side window.
The tools built on jedi support using it to find definitions. jedi-direx provides a tree-style source code viewer for Python buffers.
Helm provides an interface for navigating buffers via ‘helm-semantic-or-imenu’
and ‘helm-imenu-in-all-buffers’
.
helm-cscope provides a Helm interface to xcscope. pycscope supports generating the required cscope index of Python source trees.
Debugging
gud
The native ‘python-mode’
supports pdb tracking via the GrandUnifiedDebugger: when you execute a block of code that contains some call to Python’s pdb (or ipdb) it will prompt the block of code and will follow the execution of pdb, marking the current line with an arrow.
To debug a script run the Emacs command “M-x pdb” and invoke Python’s pdb as “python -m pdb foo.py”
realgud
realgud provides support for pdb, ipdb and trepanning debuggers. Its features not in the gud include single-keystroke debugger commands inside the source code.
dap-mode
dap-mode supports debugging using implementations of the Debug Adapter Protocol, and will be configured automatically by LspMode when available. See the main docs and configuration guide; note especially the instruction to install the Python package debugpy.
Lint, style and syntax checkers
Both Flycheck and FlyMake can be used to wrap checkers such as pep8, pyflakes (flake8 includes both), pylint, pychecker and ruff. Both support multiple checkers per buffer.
Flycheck
Flycheck comes with built-in Python support for flake8, pylint, ruff, Pyright, mypy and the Python compiler. Checkers are also available for Cython and Pyre.
Flycheck can display information from LanguageServerProtocol servers with LspMode, which supports it, and Eglot, via the flycheck-eglot package.
Flymake
FlyMake uses pyflakes by default and can be configured to use flake8, pylint, or ruff (via flymake-ruff).
Flymake can display information from LanguageServerProtocol servers with LspMode, which supports it, and Eglot. When Eglot is enabled, Flymake automatically uses it as a backend.
Reformatting and PEP8 conformance
black
black formats Python code to an almost-fixed style, hence “the uncompromising Python code formatter”.
Both python-black and Elpy support applying black to the current buffer.
ruff
ruff is “an extremely fast Python linter and code formatter, written in Rust.”
ruff-format supports formatting using ruff.
yapf
Yapf attempts to format Python code to the best formatting that conforms to a style guide, even if the original code didn’t violate the style guide. The style guide can be customized; predefined ones include pep8 and google.
Both py-yapf and Elpy support applying yapf to the current buffer.
autopep8
autopep8 formats Python code to conform to the PEP 8 style guide using the pep8 tool.
Both py-autopep8 and Elpy support applying autopep8 to the current buffer.
Tidying imports
Elpy supports using importmagic.
importmagic.el automatically insert missing imports using importmagic.
Refactoring
Ropemacs is a library using Pymacs to talk with the Rope refactoring library.
pylsp-rope is a plugin to extend the refactoring capabilities of Python LSP Server (pylsp) using the Rope refactoring library.
emacs-traad also supports refactoring using Rope.
Jedi.el also has some refactoring support.
Code generation helpers
python-mode skeletons
The built-in python-mode comes with several skeletons and key bindings for functions to insert them (`python-skeleton-’). They can be inserted automatically if you have ‘abbrev-mode’
activated and ‘python-skeleton-autoinsert’
set to ‘t’
.
yasnippet
Yasnippet comes with a broad set of templates for Python.
sphinx-doc
sphinx-doc supports inserting and updating docstring skeletons as used by Sphinx.
python-docstring
python-docstring is a minor mode for intelligently reformatting (refilling) and highlighting Python docstrings. It understands both epytext and Sphinx formats (even intermingled!), so it knows how to reflow them correctly. It will also highlight markup in your docstrings, including epytext and reStructuredText.
org-recipes
org-recipes A code snippet manager with Org and Helm. It is not specific to python and does not expand snippets like yasnippet does, but has the added benefit of combining text with org-mode source blocks that can then be inserted in a buffer via Helm.
Running tests
The pytest Python package subsumes several other test packages, as it supports tests written with pytest, nose, unittest and doctest style test suites, including Django and trial.
python-pytest supports running pytest with an interface based on transient.
pytest also supports running pytest.
Elpy supports the standard unittest discovery runner, the Django discovery runner, nose and pytest
Reporting test coverage
cov shows code coverage data for your code in the left fringe, and supports coverage.py’s coverage.json output.
Profiling
Viewing the results from the Python profilers:
- py-prof provides an interactive table for viewing cProfile output in Emacs
- The Python pstats module provides an interactive tool when a script from a regular shell in Emacs; it can also be used in a Python shell running in Emacs.
Interactive environments - Shells, REPLs and notebooks
The Python shell
You can open an interactive Python shell with ‘run-python’
(“C-c C-p”), and send code for execution by the shell process using the ‘python-shell-send-*’
functions.
The support includes completion, syntax highlighting, virtualenvs, enabling a package (so relative imports work), and remote execution (for files opened with TrampMode). Completion is provided through ‘completion-at-point’
.
Troubleshooting readline issues
readline has historically been used in Python to provide enhanced line-editing and interactive command-line features for REPLs, but with variable support across operating systems, causing many issues.
Don't try to fix non-existent problems!! The issues below may already be dealt with by packages you are using. For example
- Python 3.13 introduced a new interactive interpreter that reimplements some readline functionality in Python
- IPython since version 5.0 uses prompt_toolkit for tab completion
You may see messages like “Your ‘python-shell-interpreter’
doesn’t seem to support readline”
- On Windows, GNU readline support has not been included in CPython historically. To work around this install the Python package
‘pyreadline3’
. The earlier‘pyreadline’
package is no longer supported. - On macOS, GNU readline support has not been included in CPython historically (a similar BSD-licensed package is used instead). To work around this, install the Python package
‘gnureadline’
.
For further recent discussion see
- main page for the `gnureadline' Python package
- Python interpreter doesn't seem to support readline error in Emacs on MacOS - from 2024, includes links to earlier discussions.
Using IPython as the Python shell
In Emacs’s native python-mode, use:
(setq python-shell-interpreter "ipython" python-shell-interpreter-args "-i --simple-prompt --InteractiveShell.display_page=True")
This should work with any recent IPython, including on Windows, and works around an issue when IPython complains about incomplete shell when calling help (e.g. for help(func)).
--simple-prompt
is needed since IPython 5.--InteractiveShell.display_page=True
ensures that anything passed to the pager will be displayed as regular output instead
To get help/pydoc to work fully, run the following, e.g. create an IPython profile then put the code into nopager10.py in ~/.ipython/profile_default/startup/
import pydoc import sys pydoc.help = pydoc.Helper(output = sys.stdout)
ipython-send-shell provides replacements for the built-in ‘python-send-*’
commands that support IPython magic commands.
Emacs IPython Notebook (EIN)
Emacs IPython Notebook (EIN) provides an IPython Notebook client and integrated REPL (like SLIME) in Emacs. It is available on MELPA as ‘ein’. This replaces tkf's EIN, which it was forked from to keep up with IPython/Jupyter development.
ob-python
ob-python provides Org-Babel support for evaluating Python source code. Python source code blocks in Org Mode can be used to define functions, filter and analyze data, create graphics and figures, and produce reproducible research papers using a style similar to literate programming. It is included in the ‘org-plus-contrib’ package from the Org Mode ELPA or MELPA.
ob-ipython
ob-ipython provides Org-Babel support for evaluating Python source code using an IPython kernel. It provides similar features to ob-python (and tries to be more robust) as well as IPython-specific features like magics.
emacs-jupyter
emacs-jupyter provides REPL and Org-Babel support for evaluating Python source code using a Jupyter kernel. It also includes an API for implementing Jupyter kernel frontends in just a few cl-defmethod definitions.
LaTeX or MarkDown
emacs-ipython, an Emacs extension that allows execution of python code inside a LaTeX or MarkDown buffer and display its results, text or graphic in the section below. The extension uses Pymacs to connect to an ipython kernel to execute code.
Live coding
live-py-mode is a Python minor mode supporting live coding, inspired by Bret Victor’s "Inventing on Principle" .
Cell-based operation in Python buffers
These packages support navigating and executing code based on MATLAB-like cells in regular Python buffers.
python-x extends python-mode with features inspired by EmacsSpeaksStatistics and targeted to interactive code evaluation with an inferior Python process.
Viewing generated documentation
This refers to documentation generated by pydoc and similar tools.
Emacs’ native python-mode supports ElDoc via ‘python-eldoc-at-point’
. This returns documentation for object at point by using the inferior python subprocess to inspect its documentation.
pydoc supports generating and viewing pydoc documentation either in an Emacs help buffer, with enhancements like linking to code and coloring for readability, or in a web browser.
helm-pydoc provides a helm interface to pydoc.
Elpy supports viewing documentation from jedi/rope, falling back to pydoc.
Viewing the official Python documentation
This refers to the documentation at https://www.python.org/doc/, including the Python language reference, documentation for the Python standard library, the Python tutorial, etc.
Using Info
You will first need to install an Info file for the Python documentation. As of Python 3.8.0, these can be downloaded pre-built from https://docs.python.org/3/archives/ and https://www.python.org/ftp/python/doc, and installed per Installing Texinfo documentation.
pydoc-info configures Info to use the Python docs, and provides customized support for Python. The version at Lisp:pydoc-info.el has a tiny update to use the official python.info files mentioned above.
For more basic configuration, so that ‘info-lookup-symbol’
searches the Python docs, customize Info as below.
(require 'info-look)
(info-lookup-add-help :mode 'python-mode :regexp "[[:alnum:]_]+" :doc-spec '(("(python)Index" nil "")))
Using a web browser
Pylookup mode allows searching the Python documentation from Emacs and viewing results in a web browser, either on- or off-line.
IronPython
- Install python-mode
(setq py-jython-command "c:/Program Files/IronPython 2.6 for .NET 4.0/ipy.exe")
- Open a .py file. C-c C-t will toggle “jython”, C-c ! will start a shell
Cython
See CythonMode
Editing pip requirements files
pip-requirements is a major mode for editing pip requirements files, with support for syntax highlighting, togglable comments and auto-completion of package names from PyPI.
Troubleshooting
Unicode encoding in python-shell on Mac OS X
(This problem does not occur when using Python 3, macOS 10.15, and Emacs 27.1 from https://emacsformacosx.com. It also should not appear in AquamacsEmacs.).
When using Emacs 24.1 on Mac OS X compiled via homebrew, the python-shell always used US-ASCII as encoding. To fix it I used:
(setenv "LC_CTYPE" "UTF-8") (setenv "LC_ALL" "en_US.UTF-8") (setenv "LANG" "en_US.UTF-8")
To determine your encoding in the python-shell use:
import sys 'US-ASCII'
Not having the right encoding set leads to errors in ipython:
ERROR - failed to write data to stream: <_io.TextIOWrapper name='' mode='w' encoding='US-ASCII'>
Too many __init__.py buffers
In large Python projects, you may end up having lots of buffers similarly named init.py. PACK/init.py contains the code for a Python package PACK. It is handy to name the buffers differently, here “PACK.py”, as if there was a real file of this name. To do this:
(defun my-create-file-buffer (args) "Advice for `create-file-buffer' to use better names than "init.py". When the filename is /path/to/package/init.py, I want "package.py" as the buffer name. This advice is intended to be used like this: (advice-add 'create-file-buffer :filter-args #'my-create-file-buffer)" (let* ((filename (nth 0 args)) (lastname (file-name-nondirectory filename))) (if (string-equal lastname "init.py")
(list (concat (file-name-nondirectory (directory-file-name (file-name-directory filename))) ".py"))
args)))
(advice-add 'create-file-buffer :filter-args #'my-create-file-buffer)
How to improve this page
Round out support features in line with https://lists.gnu.org/archive/html/emacs-devel/2015-10/msg00669.html
Add sections on: semantic editing (a la paredit),
Extend sections on: refactoring, code navigation.
Add a feature comparison table for packages?
Categories: CategoryProgramming, ProgrammingModes