How I work on Python 2 and Python 3 with the Python Language Server (in GNU Emacs)
Python is one of the programming languages that I usually edit in
GNU Emacs. These days, that means using the Language Server
protocol through lsp-mode and the pyls
Python
language server.
Back when I first set this up and wrote early notes on using
LSP-based editing of Python, I had not solved
the problem of wanting to edit both Python 3 and Python 2 based
code in my GNU Emacs sessions.
If you want to do this, it turns out to be important to run either
the Python 2 pyls
or the Python 3 pyls
, depending on whether
the file you're editing is written in Python 2 or Python 3. This
creates several problems that I had to solve, and eventually did
with brute force (if I used Python virtual environments, it probably
would be easier).
First, it's obviously necessary to install both versions at once.
I install pyls into $HOME/.local/
by using pip's '--user' switch,
so I created a .local/bin/py2-pyls subdirectory and manually moved
the Python 2 version of pyls from .local/bin into it. This requires
me to always update the Python 2 version of pyls before the Python
3 version, which is a bit annoying, but that's life in a world of
both versions.
To pick the right version of pyls
to run, I use a cover script; the
cover script uses various heuristic checks to try to figure out if it's
being run in a directory with Python 2 or Python 3 code (it doesn't work
for the case of mixed code and I'm not sure that would work in general
anyway). I don't have $HOME/.local/bin on my $PATH and GNU Emacs will
conveniently just try to run 'pyls
' to start the Python LSP server, so
I put the cover script in my $HOME/bin.
The most important checks the cover script uses are to look for
which version of Python seems to be being run by '#!' lines in
any *.py files in the current directory, and whether there
are any obvious 'print
' statements (which indicate Python 2).
If you're going to do this, note that some Python programs are
installed with their '#!' line being '#!/usr/bin/env python3'
or the like, instead of directly running the Python interpreter.
I missed this in the first version of the cover script because
all of our Python scripts directly use '#!/usr/bin/python3'.
(Also, the default Python version for my cover script is Python 3, because Python 3 is what I'm writing all my new Python code in.)
All of this is basically a hack but it works pretty well for me, especially in combination with how I'm dealing with my Python indentation problem. The result is a pretty seamless LSP-based Python editing experience in GNU Emacs where everything basically works. I'm not sure I'm sold on the whole LSP-based experience for editing Python, but that's not the fault of my hacks.
|
|