Elpy supports the notion of projects, a related collection of files under a common directory. This common directory is called the project root. A number of Elpy’s commands work on all files inside the project root.
C-c C-f (elpy-find-file)¶
Find a file in the current project. This uses a search-as-you-type interface for all files under the project root.
A prefix argument enables “do what I mean” mode. On an import statement, it will try to open the module imported. Elsewhere in a file, it will look for an associated test or implementation file, and if found, open that. If this fails, either way, it will fall back to the normal find file in project behavior.
If the current file is called
foo.py, then this will search for a
test_foo.pyin the same directory, or in a
testssubdirectory. If the current file is already called
test_foo.py, it will try and find a
This command uses find-file-in-project under the hood, so see there for more options.
C-c C-s (elpy-rgrep-symbol)¶
Search the files in the current project for a string. By default, this uses the symbol at point. With a prefix argument, it will prompt for a regular expression to search.
This is basically a
grep -rthrough the project.
In addition to these two commands,
elpy-check also supports
optionally checking all files in the current project.
Elpy’s idea of the project root and which files belong to a project and which don’t can be influenced as well.
Set the current project root directory. This directory should contain all files related to the current project.
When Elpy searches for files in the current project, it will ignore files in directories listed here.
To find the project root, Elpy can utilize a number of heuristics. With this option, you can configure which are used.
To configure Elpy specifically for a single project, you can use Emacs’ Directory Variables. Elpy provides a simple interface to this.
Set or change the value of a project-wide variable. With a prefix argument, the value for the variable is removed.
This only takes effect in new buffers.
When you type Python code, Elpy will try and figure out possible completions and provide them in a suggestion window. If Elpy doesn’t do so automatically, you can force it to complete right where you are.
Provide completion suggestions for a completion at point.
You can use cursor keys or
M-p to scroll through
RET to use the selected completion, or
to complete the common part.
On any completion option,
<f1> will display a
temporary window with documentation.
C-w will display a
temporary window showing the source code of the completion to get some
Elpy uses Company Mode for the completion interface, so its documentation is a good place for further information.
Emacs can run a Python interpreter in a special buffer, making it much easier to send code snippets over. Elpy provides additional functionality to seamlessly work with interactive Python in a style similar to ESS.
Elpy uses the Python interpreter setup from the Emacs
python package. This
section briefly summarizes some common setups; add the one you need to your
.emacs file. Note that the code below (and Elpy in general) require at least
Use the Python standard interpreter (default):
(setq python-shell-interpreter "python" python-shell-interpreter-args "-i")
Use Jupyter console (recommended for interactive Python):
(setq python-shell-interpreter "jupyter" python-shell-interpreter-args "console --simple-prompt")
(setq python-shell-interpreter "ipython" python-shell-interpreter-args "-i --simple-prompt")
Note that various issues with plotting have been reported when running IPython 5 in Emacs under Windows. We recommend using Jupyter console instead.
If you have an older version of IPython and the above code does not work for you, you may also try:
(setenv "IPY_TEST_SIMPLE_PROMPT" "1") (setq python-shell-interpreter "ipython" python-shell-interpreter-args "-i")
The Shell Buffer¶
C-c C-z (elpy-shell-switch-to-shell)¶
Switch to buffer with a Python interpreter running, starting one if necessary.
By default, Elpy tries to find the root directory of the current project (git, svn or hg repository, python package or projectile project) and starts the python interpreter here. This behaviour can be suppressed with the option
By default, python buffers are all attached to a same python shell (that lies in the *Python* buffer), meaning that all buffers and code fragments will be send to this shell. elpy-shell-toggle-dedicated-shell attaches a dedicated python shell (not shared with the other python buffers) to the current python buffer. To make this the default behavior (like the deprecated option elpy-dedicated-shells did), use the following snippet:
(add-hook 'elpy-mode-hook (lambda () (elpy-shell-toggle-dedicated-shell 1)))
Attach the current python buffer to a specific python shell (whose name is asked with completion). You can use this function to have one python shell per project, with:
(add-hook 'elpy-mode-hook (lambda () (elpy-shell-set-local-shell elpy-project-root)))
C-c C-k (elpy-shell-kill)¶
Kill the associated python shell.
C-c C-K (elpy-shell-kill-all)¶
Kill all active python shells.
Use these commands, either interactively or from your
.emacs, to set the interactive interpreter to either ipython or cpython. As ipython requires some more setup work in older Emacsen, these will take care of the right setup for you.
Evaluating code fragments¶
Elpy provides commands to send the current Python statement (
f), class definition (
c), top-level statement
s), group of Python statements (
g), cell (
r), or buffer (
b) to the Python shell for evaluation. These
commands are bound to prefix
C-c C-y, followed by the single character
indicating what to send; e.g.,
C-c C-y e sends the Python statement at
Each of the commands to send code fragments to the shell has four variants, one
for each combination of: whether or not the point should move after sending
(“step”), and whether or not the Python shell should be focused after sending
(“go”). Step is activated by
C-, go by
S-. For example:
C-c C-y e (elpy-shell-send-statement)¶
Send the current statement to the Python shell and keep point position. Here statement refers to the Python statement the point is on, including potentially nested statements and, if point is on an if/elif/else clause, the entire if statement (with all its elif/else clauses).
C-c C-y C-e (elpy-shell-send-statement-and-step)¶
Send the current statement to the Python shell and move point to first subsequent statement.
Also bound to
C-c C-y E (elpy-shell-send-statement-and-go)¶
Send the current statement to the Python shell, keeping point position, and switch focus to the Python shell buffer.
C-c C-y C-S-E (elpy-shell-send-statement-and-step-and-go)¶
Send the current statement to the Python shell, move point to first subsequent statement, and switch focus to the Python shell buffer.
Elpy provides support for sending multiple statements to the shell.
C-c C-y G (elpy-shell-send-group-and-step)¶
Send the current or next group of top-level statements to the Python shell and step. A sequence of top-level statements is a group if they are not separated by empty lines. Empty lines within each top-level statement are ignored.
If the point is within a statement, send the group around this statement. Otherwise, go to the top-level statement below point and send the group around this statement.
C-c C-y W (elpy-shell-send-codecell-and-step)¶
Send the current code cell to the Python shell and step. A code cell is a piece of code surrounded by special separator lines; see below. For example, you can insert two lines starting with
##to quickly send the code in-between.
Regular expression for matching a line indicating the beginning of a code cell. By default,
##.*is treated as a beginning of a code cell, as are the code cell beginnings in Python files exported from IPython or Jupyter notebooks (e.g.,
Regular expression for matching a line indicating the boundary of a cell (beginning or ending). By default,
##.*is treated as a cell boundary, as are the boundaries in Python files exported from IPython or Jupyter notebooks (e.g.,
# In:, or
elpy-shell-codecell-beginning-regexpmust also match the cell boundaries defined here.
The functions for sending the entire buffer have special support for avoiding accidental code execution, e.g.:
C-c C-y r (elpy-shell-send-region-or-buffer)¶
Send the the active region (if any) or the entire buffer (otherwise) to the Python shell and keep point position.
When sending the whole buffer, this command will also escape any uses of the
if __name__ == '__main__'idiom, to prevent accidental execution of a script. If you want this to be evaluated, pass a prefix argument with
Also bound to
The list of remaining commands to send code fragments is:
C-c C-y s (elpy-shell-send-top-statement)¶
C-c C-y S (elpy-shell-send-top-statement-and-go)¶
C-c C-y f (elpy-shell-send-defun)¶
C-c C-y F (elpy-shell-send-defun-and-go)¶
C-c C-y c (elpy-shell-send-defclass)¶
C-c C-y C (elpy-shell-send-defclass-and-go)¶
C-c C-y g (elpy-shell-send-group)¶
C-c C-y G (elpy-shell-send-group-and-go)¶
C-c C-y w (elpy-shell-send-codecell)¶
C-c C-y W (elpy-shell-send-codecell-and-go)¶
C-c C-y R (elpy-shell-send-region-or-buffer-and-go)¶
C-c C-y b (elpy-shell-send-buffer)¶
C-c C-y B (elpy-shell-send-buffer-and-go)¶
C-c C-y C-s (elpy-shell-send-top-statement-and-step)¶
C-c C-y C-S-S (elpy-shell-send-top-statement-and-step-and-go)¶
C-c C-y C-f (elpy-shell-send-defun-and-step)¶
C-c C-y C-S-F (elpy-shell-send-defun-and-step-and-go)¶
C-c C-y C-c (elpy-shell-send-defclass-and-step)¶
C-c C-y C-S-C (elpy-shell-send-defclass-and-step-and-go)¶
C-c C-y C-S-G (elpy-shell-send-group-and-step-and-go)¶
C-c C-y C-W (elpy-shell-send-codecell-and-step-and-go)¶
C-c C-y C-r (elpy-shell-send-region-or-buffer-and-step)¶
C-c C-y C-S-R (elpy-shell-send-region-or-buffer-and-step-and-go)¶
C-c C-y C-b (elpy-shell-send-buffer-and-step)¶
C-c C-y C-S-B (elpy-shell-send-buffer-and-step-and-go)¶
When package eval-sexp-fu is loaded and
active, the statements sent to the shell are briefly flashed after running an
evaluation command, thereby providing visual feedback.
Whenever a code fragment is sent to the Python shell, Elpy prints it in the Python shell buffer (i.e., it looks as if it was actually typed into the shell). This behavior can be turned on and off via the custom variable elpy-shell-echo-input and further customized via
elpy-shell-echo-input-cont-prompt(whether to show continuation prompts for multi-line inputs) and
elpy-shell-echo-input-lines-tail(how much to cut when input is long).
Elpy shows the output produced by a code fragment sent to the shell in the echo area when the shell buffer is currently invisible. This behavior can be controlled via elpy-shell-echo-output (never, always, or only when shell invisible). Output echoing is particularly useful if the custom variable
elpy-shell-display-buffer-after-sendis set to
nil(the default value). Then, no window is needed to display the shell (thereby saving screen real estate), but the outputs can still be seen in the echo area.
When a multiple statements are sent to the shell simultaneously (e.g., via
elpy-shell-send-group-and-step), Elpy by default captures the value of the last Python statement (if is an expression) and shows it in the shell buffer. This variable can be used to turn off this behavior (then shell won’t show any output, except for single-line statements).
Whether to display the Python shell after sending something to it (default
Whenever you save a file, Elpy will run a syntax check and highlight possible errors or warnings inline.
C-c C-n (elpy-flymake-next-error)¶
C-c C-p (elpy-flymake-previous-error)¶
You can navigate between any error messages with these keys. The current error will be shown in the minibuffer.
Elpy uses the built-in Flymake library to find syntax errors on the fly, so see there for more configuration options.
C-c C-v (elpy-check)¶
Alternatively, you can run a syntax check on the current file where the output is displayed in a new buffer, giving you an overview and allowing you to jump to the errors from there.
With a prefix argument, this will run the syntax check on all files in the current project.
To change which command is used for syntax checks, you can customize this option. By default, Elpy uses the
flake8program, which you have to install separately. The
elpy-configcommand will prompt you to do this if Elpy can’t find the program.
It is possible to create a single virtual env for the sole purpose of installing
flake8in there, and then simply link the command script to a directory inside your
PATH, meaning you do not need to install the program in every virtual env separately.
Elpy provides a single interface to documentation.
C-c C-d (elpy-doc)¶
When point is on a symbol, Elpy will try and find the documentation for that object, and display that. If it can’t find the documentation for whatever reason, it will try and look up the symbol at point in pydoc. If it’s not there, either, it will prompt the user for a string to look up in pydoc.
With a prefix argument, Elpy will skip all the guessing and just prompt the user for a string to look up in pydoc.
If the autodoc module is enabled (not the case by default) the documentation is automatically updated with the symbol at point or the currently selected company candidate.
The idle delay in seconds until documentation is updated automatically.
Testing is an important part of programming. Elpy provides a central interface to testing, which allows for a good workflow for tests.
Elpy’s test interface is built around Emacs’ compilation framework. Elpy will run test commands as a compilation job, with all the advantages this brings.
C-c C-t (elpy-test)¶
Start a test run. This uses the currently configured test runner to discover and run tests. If point is inside a test case, the test runner will run exactly that test case. Otherwise, or if a prefix argument is given, it will run all tests.
This changes the current test runner. Elpy supports the standard unittest discovery runner, the Django discovery runner, nose and py.test. You can also write your own, as described in Writing Test Runners.
Note on Django runners: Elpy tries to find manage.py within your project structure. If it’s unable to find it, it falls back to django-admin.py. You must set the environment variable
This enables a good workflow. You write a test and use
to watch it fail. You then go to your implementation file, for example
C-u C-c C-f, and make the test pass. You can use a key
recompile (I use
<f5> for this) to just re-run
that one test. Once that passes, you can use
C-c C-t again to
run all tests to make sure they all pass as well. Repeat.
For an even more automated way, you can use tdd.el, which will run your last compile command whenever you save a file.
Elpy supports various forms of refactoring Python code.
C-c C-e (elpy-multiedit-python-symbol-at-point)¶
Edit all occurrences of the symbol at point at once. This will highlight all such occurrences, and editing one of them will edit all. This is an easy way to rename identifiers.
If the backend does not support finding occurrences (currently only Jedi does), or if a prefix argument is given, this will edit syntactic occurrences instead of semantic ones. This can match more occurrences than it should, so be careful. You can narrow the current buffer to the current function using
C-x n dto restrict where this matches.
Finally, if there is a region active, Elpy will edit all occurrences of the text in the region.
C-c C-r f (elpy-format-code)¶
Format code using the available formatter.
Elpy has basic Django support such as parsing either manage.py or django-admin.py (If it does not find manage.py it falls back to django-admin.py) for command completion assistance. Can also start runserver automatically and you can give an ip address and port.
C-c C-x c (elpy-django-command)¶
Choose what command you’d like to run via django-admin.py or manage.py.
C-c C-x r (elpy-django-runserver)¶
Start the development server command, runserver. Default arguments are 127.0.0.1 for ip address and 8000 for port. These can be changed via
Elpy allows one to profile asynchronously python scripts using cProfile.
Send the current buffer or region to the profiler and display the result with
elpy-profile-visualizer. The default visualizer is snakeviz, a browser-based graphical profile viewer that can be installed with pip install snakeviz. If the profiling fails, the python error output is displayed.