Emacs 26, Mojave, elpy, readline
I first started having problems with macOS readline
and macports Python a year or two
ago. Initially, it was bugs in resetting the tty to a sane configuration when a Python
REPL exited. That seems to have been solved, but I'm now encountering readline
problems with Python 3.7, GNU Emacs 26.1, and elpy
. These notes describe what seems
to be a solution, at least for the time being.
I typically install Python versions like this via macports:
sudo port install python37 sudo port install py37-pip sudo port install py37-virtualenv sudo port install py37-virtualenvwrapper
Subsequently, I'll use the Python through virtual environments, such as:
mkvirtualenv -p python3.7 py37
With Python versions 3.5 or earlier, it is necessary to use gnureadline
to work around
problems in the macports readline
which uses libedit
. This can be done by
installing py-gnureadline
with macports and configuring it as the readline
via
$PYTHONSTARTUP
. Both the REPL and elpy
work fine with this configuration.
With Python 3.6+, gnureadline
works properly with the REPL, but elpy
has problems
with it, preventing inferior Python processes from working properly with Emacs.
Workaround
This is how I resolved the elpy
problem.
At this point in the process, there is a ~/.virtualenvs/py37/lib/python3.7/readline.so
,
which is a symbolic link to
/opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload/readline.cpython-37m-darwin.so
.
This is the libedit
readline
.
Use easy_install
to (not pip
)
install gnureadline
.
sudo easy_install gnureadline
This installs gnureadline
in
~/.virtualenvs/py37/lib/python3.7/gnureadline-6.3.8-py3.7-macosx-10.12-x86_64.egg
.
Once installed, gnureadline
is functional, at least in $PYTHONSTARTUP
and in ordinary
python code. elpy
also works when editing python code. However, elpy
fails when
sending code to a python process. One can test this by first starting an Emacs via
Emacs -Q
and then running the command M-x run-python
. When I did this, I received
warnings like the following:
Warning (python): Your ‘python-shell-interpreter’ doesn’t seem to support readline, yet ‘python-shell-completion-native-enable’ was t and "python" is not part of the ‘python-shell-completion-native-disabled-interpreters’ list. Native completions have been disabled locally.
The failure, I think, is due to path precedence problems in sys.path
which cause the
libedit
readline
to be used instead of gnureadline
. In any event, I found a
workaround.
The final setp in the workaround is taken from
here,
which renames the libedit
readline
so that it can't be found.
cd /opt/local/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/lib-dynload
sudo mv readline.cpython-37m-darwin.so mv readline.cpython-37m-darwin.so.bak
The solution leads me to believe that, somewhere in elpy
, is code that loads
gnureadline
if it cant find readline
.
Regardless, with the rename, python inferior processes work correctly. And, fortunately, my
$PYTHONSTARTUP
continues to work properly as well.