I found something useful! I found something useful!
Flymake is an on-the-fly syntax checker for Emacs. Essentially every so often it runs your buffer through a language-specific syntax checker and highlights code errors and warnings in a different color. I can hear "real" IDE people laughing at me now, but for better or worse, I will probably use Emacs until I die; not because I like it particularly, but because it's the only thing my fingers know how to use, thus searching for better tools is pointless.
Out of the box, Flymake can't analyze Python code, but it helpfully has a plugin system. It allows you to plug in, for example, pylint or pyflakes or probably any other checker. I use pyflakes regularly. Pyflakes is excellent, it basically just whines when you're using a name that hasn't been defined (an indictment of your lack of testing for that code path) or you've imported a name twice, or you're not using a name that you've imported. Importantly, it walks the Python AST rather than trying to import things (which other checkers seem to tend to try to do), so it's fast and using it has no side effects. I tend to use pyflakes as a before-checkin sanity check to make sure I haven't forgotten to remove an import, so it made sense to try to fit it into my editor.
Here's what I did to get it working. As I said, it's all cargo-culted, consistent with the rest of my Emacs configuration.
The stuff I added to the .emacs file:
(when (load "flymake" t) (defun flymake-pyflakes-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 "pyflakes" (list local-file)))) (add-to-list 'flymake-allowed-file-name-masks '("\\.py\\'" flymake-pyflakes-init))) (add-hook 'find-file-hook 'flymake-find-file-hook)
The first stanza tells flymake to use pyflakes on .py files when in flymake-mode. The second tells emacs to always use flymake as a minor mode when loading buffers so I don't have to type "M-x flymake-mode" to get syntax checking when I load a buffer.
And now! It works. I don't know how it works but it does. The below picture proves it (I import traceback but I don't use it).
And thus verify come the inane checkins for things I'm working on now that read "remove unused import".