IDE Features

Projects

Elpy supports the notion ofprojects, a related collection of filesunder a common directory. This common directory is called theproject root. A number of Elpy’s commands work on all filesinside the project root.

C-c C-f (elpy-find-file)

Find a file in the current project. This uses a search-as-you-typeinterface for all files under the project root.

A prefix argument enables “do what I mean” mode. On an importstatement, it will try to open the module imported. Elsewhere in afile, it will look for an associated test or implementation file,and if found, open that. If this fails, either way, it will fallback to the normal find file in project behavior.

If the current file is calledfoo.py, then this will search foratest_foo.py in the same directory, or in atest ortests subdirectory. If the current file is already calledtest_foo.py, it will try and find afoo.py nearby.

This command usesprojectile orfind-file-in-project under the hood, so youneed one of them to be installed.

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 willprompt for a regular expression to search.

This is basically agrep-r through the project.

In addition to these two commands,elpy-check also supportsoptionally checking all files in the current project.

Elpy’s idea of the project root and which files belong to a projectand which don’t can be influenced as well.

M-x elpy-set-project-root

Set the current project root directory. This directory shouldcontain all files related to the current project.

elpy-project-ignored-directories (Customize Option)

When Elpy searches for files in the current project, it will ignorefiles in directories listed here.

elpy-project-root-finder-functions (Customize Option)

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 useEmacs’Directory Variables. Elpy provides a simple interface tothis.

M-x elpy-set-project-variable

Set or change the value of a project-wide variable. With a prefixargument, the value for the variable is removed.

This only takes effect in new buffers.

Completion

When you type Python code, Elpy will try and figure out possiblecompletions and provide them in a suggestion window. If Elpy doesn’tdo so automatically, you can force it to complete right where you are.

M-TAB (elpy-company-backend)

Provide completion suggestions for a completion at point.

You can use cursor keys orM-n andM-p to scroll throughthe options,RET to use the selected completion, orTABto complete the common part.

On any completion option,C-d or<f1> will display atemporary window with documentation.C-w will display atemporary window showing the source code of the completion to get somecontext.

Elpy usesCompany Mode for the completion interface, so itsdocumentation is a good place for further information.

elpy-get-info-from-shell (Customize Option)

Ift, use the shell to gather docstrings and completions. Normally elpyprovides completion and documentation using static code analysis (fromjedi). With this option, elpy will add the completion candidatesand the docstrings from the associated python shell; This activatesfallback completion candidates for cases when the static code analysisfails.

Navigation

Elpy supports advanced navigation features.

M-. (elpy-goto-definition)

Go to the location where the identifier at point is defined. Thisis not always easy to make out, so the result can be wrong. Also,the backends can not always identify what kind of symbol is atpoint. Especially after a few indirections, they have basically nohope of guessing right, so they don’t.

C-x 4 M-. (elpy-goto-definition-other-window)

Same aselpy-go-to-definition (with the same caveats) but goes tothe definition of the symbol at point in other window, if defined.

M-* (pop-tag-mark)

Go back to the last place whereM-. was used, effectivelyturningM-. andM-* into a forward and backwardmotion for definition lookups.

C-c C-o (elpy-occur-definitions)

Search the buffer for a list of definitions of classes and functions.

M-x elpy-goto-assignment

Go to the location where the identifier at point is assigned.It is not bound by default, so you will have to bind it manually.You can also use it as a replacement toelpy-goto-definition (seeJumping to assignment).

If you use an Emacs version superior to 25, Elpy will define thenecessary backends for thexref package.

M-. (xref-find-definitions)

Find the definition of the identifier at point.

C-x 4 . (xref-find-definition-other-window)

LikeM-. but switch to the other window.

C-x 5 . (xref-find-definition-other-frame)

LikeM-. but switch to the other frame.

M-, (xref-pop-marker-stack)

Go back to the last place whereM-. was used, effectivelyturningM-. andM-, into a forward and backwardmotion for definition lookups.

M-? (xref-find-references)

Find references for an identifier of the current buffer.

C-M-. (xref-find-apropos)

Find all meaningful symbols that match a given pattern.

Interactive Python

Emacs can run a Python interpreter in a special buffer, making it much easier tosend code snippets over. Elpy provides additional functionality to seamlesslywork with interactive Python in a style similar toESS.

Interpreter Setup

Elpy uses the Python interpreter setup from the Emacspython package. Thissection 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 leastEmacs 24.4.

Use the Python standard interpreter (default):

(setqpython-shell-interpreter"python"python-shell-interpreter-args"-i")

Use Jupyter console (recommended for interactive Python):

(setqpython-shell-interpreter"jupyter"python-shell-interpreter-args"console --simple-prompt"python-shell-prompt-detect-failure-warningnil)(add-to-list'python-shell-completion-native-disabled-interpreters"jupyter")

Use IPython:

(setqpython-shell-interpreter"ipython"python-shell-interpreter-args"-i --simple-prompt")

Note that various issues with plotting have been reported when running IPython 5in Emacs under Windows. We recommend using Jupyter console instead.

If you have an older version of IPython and the above code does not work foryou, you may also try:

(setenv"IPY_TEST_SIMPLE_PROMPT""1")(setqpython-shell-interpreter"ipython"python-shell-interpreter-args"-i")

As anIPython user, you might be interested in theEmacs IPythonNotebook or anElpy layer forSpacemacs, too.

Note for MacOS users:In some configurations, display artifacts (lines of^G s) canappear in the shell. This can be fixed by prepending-cexec('__import__(\\'readline\\')') topython-shell-interpeter-args (e.g.(setqpython-shell-interpreter-args"-cexec('__import__(\\'readline\\')')-i") for python)

The Shell Buffer

C-c C-z (elpy-shell-switch-to-shell)

Switch to buffer with a Python interpreter running, starting one ifnecessary.

By default, Elpy tries to find the root directory of the current project(git, svn or hg repository, python package or projectile project) andstarts the python interpreter here. This behaviour can be suppressedwith the optionelpy-shell-starting-directory.

elpy-shell-starting-directory (Customize Option)

Govern the directory in which Python shells will be started.Can be'project-root (default) to use the current project root,'current-directory to use the buffer current directory, or astring indicating a specific path.

M-x elpy-shell-toggle-dedicated-shell

By default, python buffers are all attached to a same python shell(that lies in the*Python* buffer), meaning that all buffers andcode fragments will be sent 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 optionelpy-dedicated-shells did), use the following snippet:

(add-hook'elpy-mode-hook(lambda()(elpy-shell-toggle-dedicated-shell1)))
M-x elpy-shell-set-local-shell

Attach the current python buffer to a specific python shell (whose name isasked 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.

Evaluating code fragments

Elpy provides commands to send the current Python statement (e), functiondefinition (f), class definition (c), top-level statement(s), group of Python statements (g), cell (w), region(r), or buffer (b) to the Python shell for evaluation. Thesecommands are bound to prefixC-c C-y, followed by the single characterindicating what to send; e.g.,C-c C-y e sends the Python statement atpoint.

Each of the commands to send code fragments to the shell has four variants, onefor 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 byC-, go byS-. For example:

C-c C-y e (elpy-shell-send-statement)

Send the current statement to the Python shell and keep point position. Herestatement refers to the Python statement the point is on, includingpotentially nested statements. If point is on an if/elif/else clause send theentire if statement (with all its elif/else clauses). If point is on adecorated function, send the decorator as well.

C-c C-y C-e (elpy-shell-send-statement-and-step)

Send the current statement to the Python shell and move point to firstsubsequent statement.

Also bound toC-RET.

C-c C-y E (elpy-shell-send-statement-and-go)

Send the current statement to the Python shell, keeping point position, andswitch 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 firstsubsequent statement, and switch focus to the Python shell buffer.

Elpy provides support for sending multiple statements to the shell.

C-c C-y O (elpy-shell-send-group-and-step)

Send the current or next group of top-level statements to the Python shelland step. A sequence of top-level statements is a group if they are notseparated by empty lines. Empty lines within each top-level statement areignored.

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 grouparound 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 apiece of code surrounded by special separator lines; see below. For example,you can insert two lines starting with## to quickly send the codein-between.

elpy-shell-codecell-beginning-regexp (Customize Option)

Regular expression for matching a line indicating the beginning of a codecell. By default,##.* is treated as a beginning of a code cell, as arethe code cell beginnings in Python files exported from IPython or Jupyternotebooks (e.g.,#<codecell> or#In[1]:).

elpy-shell-cell-boundary-regexp (Customize Option)

Regular expression for matching a line indicating the boundary of a cell(beginning or ending). By default,##.* is treated as a cell boundary, asare the boundaries in Python files exported from IPython or Jupyter notebooks(e.g.,#<markdowncell>,#In[1]:, or#Out[1]:).

Note thatelpy-shell-codecell-beginning-regexp must also match thecell boundaries defined here.

The functions for sending the entire buffer have special support for avoidingaccidental 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 thePython shell and keep point position.

When sending the whole buffer, this command will also escape any uses of theif__name__=='__main__' idiom, to prevent accidental execution of ascript. If you want this to be evaluated, pass a prefix argument withC-u.

Also bound toC-c C-c.

elpy-shell-add-to-shell-history (Customize Option)

Ift, Elpy will make the code sent available in the shellhistory. This allows one to usecomint-previous-input (C-up)in the python shell to get back the pieces of code sent by Elpy.

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 o (elpy-shell-send-group)
C-c C-y O (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-O (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)

Shell feedback

When packageeval-sexp-fu is loaded andeval-sexp-fu-flash-mode isactive, the statements sent to the shell are briefly flashed after running anevaluation command, thereby providing visual feedback.

elpy-shell-echo-input (Customize Option)

Whenever a code fragment is sent to the Python shell, Elpy prints it in thePython shell buffer (i.e., it looks as if it was actually typed into theshell). This behavior can be turned on and off via the custom variableelpy-shell-echo-input and further customized viaelpy-shell-echo-input-cont-prompt (whether to show continuation promptsfor multi-line inputs) andelpy-shell-echo-input-lines-head /elpy-shell-echo-input-lines-tail (how much to cut when input is long).

elpy-shell-echo-output (Customize Option)

Elpy shows the output produced by a code fragment sent to the shell in theecho area when the shell buffer is currently invisible. This behavior can becontrolled viaelpy-shell-echo-output (never, always, or only when shellinvisible). Output echoing is particularly useful if the custom variableelpy-shell-display-buffer-after-send is set tonil (the defaultvalue). Then, no window is needed to display the shell (thereby saving screenreal estate), but the outputs can still be seen in the echo area.

elpy-shell-display-buffer-after-send (Customize Option)

Whether to display the Python shell after sending something to it (defaultnil).

Syntax Checking

Whenever you save a file, Elpy will run a syntax check and highlightpossible 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. Thecurrent error will be shown in the minibuffer.

Elpy uses the built-inFlymake library to find syntax errors on thefly, so see there for more configuration options.

C-c C-v (elpy-check)

Alternatively, you can run a syntax check on the current file wherethe output is displayed in a new buffer, giving you an overview andallowing you to jump to the errors from there.

With a prefix argument, this will run the syntax check on all filesin the current project.

python-check-command (Customize Option)

To change which command is used for syntax checks, you cancustomize this option. By default, Elpy uses theflake8program, which you have to install separately. Theelpy-config command will prompt you to do this if Elpycan’t find the program.

It is possible to create a single virtual env for the sole purposeof installingflake8 in there, and then simply link the commandscript to a directory inside yourPATH, meaning you donot need to install the program in every virtual env separately.

Documentation

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 documentationfor that object, and display that. If it can’t find thedocumentation for whatever reason, it will try and look up thesymbol at point in pydoc. If it’s not there, either, it will promptthe user for a string to look up in pydoc.

With a prefix argument, Elpy will skip all the guessing and justprompt the user for a string to look up in pydoc.

If theautodoc module is enabled (not by default) thedocumentation is automatically updated with the symbol at point or thecurrently selected company candidate.

elpy-autodoc-delay (Customize Option)

The idle delay in seconds until documentation is updated automatically.

Snippets

Elpy usesyasnippet to provide code templates that helps writing common pieces of code faster.You can access a template by typing a “template key” and hittingTAB to expand it.You may then be asked to fill some fields in the template, just hitTAB when you are done to proceed to the next field.

The sequel presents a list of templates provided by Elpy.

Special methods

Elpy provides a large range of templates for special class methods (__init__,__call__,__add__, …).To call them, simply type_ followed by the method name (for example_init) and hitTAB.

Other useful snippets

  • enc: Encoding statement
  • env: Hashbang statement
  • from: Import statement
  • pdb: Snippet to run pdb at the current script position
  • super: Super statement to call parent methods
  • def: Function definition
  • class: Class definition
  • defs: Class method definition

Folding

Elpy offers code folding by enhancing the builtin folding minor modeHideshow.

When opening a python buffer, Elpy will indicate foldable things with an arrow in the left fringe.Clicking on an arrow will fold the corresponding code blocks.Folded code blocks can be unfolded by clicking on the button at the end of the line.

If you don’t want to use your mouse, you can achieve the same thing with the function

C-c @ C-c (elpy-folding-toggle-at-point)

Toggle folding for the thing at point, it can be a docstring, a comment or a code block.

The display of arrows in the fringe can be disable with the option

elpy-folding-fringe-indicators (Customize Option)

If elpy should display folding fringe indicators or not.

Elpy also provides some other useful features:

C-c @ C-b (elpy-folding-toggle-docstrings)

Toggle folding of all python docstrings.

C-c @ C-m (elpy-folding-toggle-comments)

Toggle folding of all comments.

C-c @ C-f (elpy-folding-hide-leafs)

Hide all code leafs, i.e. code blocks that do not contains any other blocks.

The classical keybindings for hideshow are also available, e.g.:

C-c @ C-a (hs-show-all)

Unfold everything.

(seeHideshow documentation for more information)

Debugging

Elpy provides an interface topdb, the builtin Python debugger.Note that this interface is only available for Emacs 25 and above.

C-c C-u d (elpy-pdb-debug-buffer)

Run pdb on the current buffer. If no breakpoints has been set usingelpy-pdb-toggle-breakpoint-at-point, the debugger willpause at the beginning of the buffer. Else, the debugger will pauseat the first breakpoint. Once pdb is started, thepdb commandscan be used to step through and look into the code evaluation.

With a prefix argumentC-u, ignore the breakpoints andalways pause at the beginning of the buffer.

C-c C-u b (elpy-pdb-toggle-breakpoint-at-point)

Add (or remove) a breakpoint on the current line. Elpy adds a redcircle to the fringe to indicate the presence of a breakpoint. Youcan then useelpy-pdb-debug-buffer to start pdb andpause at each of the breakpoints.

With a prefix argumentC-u, remove all the breakpoints.

C-c C-u p (elpy-pdb-break-at-point)

Run pdb on the current buffer and pause at the cursor position.

C-c C-u e (elpy-pdb-debug-last-exception)

Run post-mortem pdb on the last exception.

Testing

Testing is an important part of programming. Elpy provides a centralinterface 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 theadvantages this brings.

C-c C-t (elpy-test)

Start a test run. This uses the currently configured test runner todiscover and run tests. If point is inside a test case, the testrunner will run exactly that test case. Otherwise, or if a prefixargument is given, it will run all tests.

M-x elpy-set-test-runner

This changes the current test runner. Elpy supports the standardunittest discovery runner, the Django discovery runner, nose,green, py.test and Twisted trial. You can also write your own, asdescribed inWriting Test Runners.

Note on Django runners: Elpy tries to findmanage.py within your projectstructure. If it’s unable to find it, it falls back todjango-admin.py.You must set the environment variableDJANGO_SETTINGS_MODULE accordingly.

This enables a good workflow. You write a test and useC-c C-tto watch it fail. You then go to your implementation file, for exampleusingC-u C-c C-f, and make the test pass. You can use a keybound torecompile (I use<f5> for this) to just re-runthat one test. Once that passes, you can useC-c C-t again torun all tests to make sure they all pass as well. Repeat.

For an even more automated way, you can usetdd.el, which will runyour last compile command whenever you save a file.

Refactoring

C-c C-e (elpy-multiedit-python-symbol-at-point)

Edit all occurrences of the symbol at point at once. This willhighlight all such occurrences, and editing one of them will editall. This is an easy way to rename identifiers.

If the backend does not support finding occurrences (currently onlyJedi does), or if a prefix argument is given, this will editsyntactic occurrences instead of semantic ones. This can match moreoccurrences than it should, so be careful. You can narrow thecurrent buffer to the current function usingC-x n d torestrict where this matches.

Finally, if there is a region active, Elpy will edit alloccurrences of the text in the region.

C-c C-r f (elpy-format-code)

Format code using the available formatter.

If a region is selected, only that region is formatted.Otherwise current buffer is formatted.

elpy-formatter (Customize Option)

Allows the selection of one’s preferred formatter. Available options are:yapf ,autopep8 andblack.

yapf andautopep8 can be configured with style files placed inthe project root directory (determined byelpy-project-root).black can be configured in thepyproject.toml file of your project.

Jedi refactoring

The following commands take advantage of Jedi refactoring possibilities.They all present a diff of the modifications before applying them,this allows to check the ongoing modifications and cancel some of them if needed.
C-c C-r r (elpy-refactor-rename)

Rename all occurences of the symbol at point (variable, function, class, …).If needed, rename occurences in other files as well.

C-c C-r v (elpy-refactor-extract-variable)

Move the selection to a new variable.

C-c C-r f (elpy-refactor-extract-function)

Move the selection to a new function.

C-c C-r i (elpy-refactor-inline)

Inline the variable at point.i.e. replace it with its defining expression.

Profiling

Elpy allows one to profile python scripts asynchronously usingcProfile.

M-x elpy-profile-buffer-or-region

Send the current buffer or region to the profiler and display the result withelpy-profile-visualizer.The default visualizer issnakeviz, a browser-based graphical profile viewer that can be installed withpip install snakeviz.RunSnakeRun (Python-2 only GTK GUI) andpyprof2calltree (uses QCacheGrind or KCacheGrind for display) are supported alternatives and can be similarly installed with pip.

Django

Elpy has basic Django support such as parsing eithermanage.py ordjango-admin.py (If itdoes not findmanage.py it falls back todjango-admin.py) for command completion assistance.Can also startrunserver 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 viadjango-admin.py ormanage.py.Please note that for compatibility reasons, theshell command will usepython (instead of ipython by default).

C-c C-x r (elpy-django-runserver)

Start the development server command,runserver. Default arguments are127.0.0.1 forip address and8000 for port. These can be changed viaelpy-django-server-ipaddr andelpy-django-server-port.