Helpful Emacs python-mode-hooks, especially for type hinting

Type hinting Python with Emacs is easy

There are six GNU Emacs packages (all available on MELPA) that serve as my foundation for speedily writing type hinted Python as described in PEP 484:

  • flycheck: Syntax checking, specifically for mypy (you can use a checker other than mypy if you don’t need type hinting)
  • anaconda-mode: “Code navigation, documentation lookup and completion for Python.”
  • pyimport: “Manage Python imports from Emacs”
  • importmagic: “resolves unimported Python symbols”
  • pyimpsort: “Sort python imports”
  • blacken: An Emacs package for Python’s “zero configuration” linter, black

So, how do they all tie together? A section of my .emacs.d/ looks something like this:

(global-flycheck-mode)
(add-hook 'python-mode-hook                                                   (lambda ()
(anaconda-mode)
(anaconda-eldoc-mode)
(importmagic-mode) (local-set-key (kbd "C-x C-d") 'anaconda-mode-show-doc) (local-set-key (kbd "C-x C-w") 'anaconda-mode-find-definitions) (add-hook 'before-save-hook 'pyimport-remove-unused) (add-hook 'before-save-hook 'importmagic-fix-imports) (add-hook 'before-save-hook 'pyimpsort-buffer) (add-hook 'before-save-hook 'blacken-buffer) (set (make-local-variable 'compile-command) (concat "python3 " (buffer-name)))))

I’ll explain what is going on in more detail below.

Syntax checking

If you have…

  • flycheck installed and enabled through MELPA
  • mypy installed through pip
  • (global-flycheck-mode) or perhaps something more conservative
  • Enabled mypy in flycheck-mode via C-u C-c ! x

…you will get syntax checking for type hinted Python in your Emacs buffers. Once again, you can use a different checker other than mypy if you are not interested in type hinting.

Keystrokes

I try to use the same keystrokes across all Emacs modes with intelligent defaults; sometimes different language modes override the defaults.

In python-mode, after declaring (anaconda-mode), I want the following keystrokes set:

  • C-x C-d usually defaults to devdocs-search but is overridden in python-mode to anaconda-mode-show-doc
  • C-x C-w usually defaults to dumb-jump-go but is overridden in python-mode to anaconda-mode-find-definitions
  • C-x c stays as compile, but the compile-command now runs the current buffer in python3

Note that if you’re using a virtual environment for Python in a project, you’ll need to setup Anaconda with pythonic-activate.

before-save-hook

There are four save hooks that let me breeze through writing lots of Python code very quickly by cleaning up my considerable mess upon every save. The mess that I create usually involves imports and inconsistent formatting.

  • pyimport-remove-unused removes any unused imports in the saved file
  • importmagic-fix-imports finds imports that I forgot to write
  • pyimpsort-buffer sorts the imports appropriately
  • blacken-buffer lints the code so that it is consistent

The above problems can now be caught or fixed before a formal linting process even begins.

Using all of the above, I’ve found that writing plenty of type hinted Python code in Emacs quickly is very pleasing. I hope that you will encounter the same.

My .emacs.d/ may be of further help and can be viewed here: https://github.com/enzuru/.emacs.d