rlineimpl.py
124 lines
| 4.5 KiB
| text/x-python
|
PythonLexer
vivainio
|
r503 | # -*- coding: utf-8 -*- | ||
fperez
|
r644 | """ Imports and provides the 'correct' version of readline for the platform. | ||
vivainio
|
r503 | |||
Brian Granger
|
r2498 | Readline is used throughout IPython as:: | ||
import IPython.utils.rlineimpl as readline | ||||
vivainio
|
r503 | |||
fperez
|
r644 | In addition to normal readline stuff, this module provides have_readline | ||
Brian Granger
|
r2498 | boolean and _outputfile variable used in IPython.utils. | ||
Fernando Perez
|
r1853 | """ | ||
vivainio
|
r503 | |||
MinRK
|
r3937 | import os | ||
MinRK
|
r3906 | import re | ||
vivainio
|
r503 | import sys | ||
MinRK
|
r3906 | import time | ||
MinRK
|
r3475 | import warnings | ||
vivainio
|
r503 | |||
MinRK
|
r3906 | from subprocess import Popen, PIPE | ||
MinRK
|
r5206 | if sys.platform == 'darwin': | ||
# dirty trick, to skip the system readline, because pip-installed readline | ||||
# will never be found on OSX, since lib-dynload always comes ahead of site-packages | ||||
from distutils import sysconfig | ||||
lib_dynload = sysconfig.get_config_var('DESTSHARED') | ||||
del sysconfig | ||||
try: | ||||
dynload_idx = sys.path.index(lib_dynload) | ||||
except ValueError: | ||||
MinRK
|
r5209 | dynload_idx = None | ||
MinRK
|
r5206 | else: | ||
sys.path.pop(dynload_idx) | ||||
fperez
|
r644 | try: | ||
from readline import * | ||||
import readline as _rl | ||||
have_readline = True | ||||
except ImportError: | ||||
vivainio
|
r671 | try: | ||
from pyreadline import * | ||||
import pyreadline as _rl | ||||
have_readline = True | ||||
MinRK
|
r3538 | except ImportError: | ||
vivainio
|
r671 | have_readline = False | ||
vivainio
|
r503 | |||
MinRK
|
r5206 | if sys.platform == 'darwin': | ||
# dirty trick, part II: | ||||
MinRK
|
r5209 | if dynload_idx is not None: | ||
MinRK
|
r5206 | # restore path | ||
sys.path.insert(dynload_idx, lib_dynload) | ||||
if not have_readline: | ||||
# *only* have system readline, try import again | ||||
try: | ||||
from readline import * | ||||
import readline as _rl | ||||
have_readline = True | ||||
except ImportError: | ||||
have_readline = False | ||||
else: | ||||
# if we want to warn about EPD / Fink having bad readline | ||||
# we would do it here | ||||
pass | ||||
# cleanup dirty trick vars | ||||
del dynload_idx, lib_dynload | ||||
MinRK
|
r3538 | if have_readline and hasattr(_rl, 'rlmain'): | ||
# patch add_history to allow for strings in pyreadline <= 1.5: | ||||
# fix copied from pyreadline 1.6 | ||||
import pyreadline | ||||
if pyreadline.release.version <= '1.5': | ||||
def add_history(line): | ||||
"""add a line to the history buffer.""" | ||||
from pyreadline import lineobj | ||||
if not isinstance(line, lineobj.TextLine): | ||||
line = lineobj.TextLine(line) | ||||
return _rl.add_history(line) | ||||
Pawel Jasinski
|
r8573 | if (sys.platform == 'win32' or sys.platform == 'cli') and have_readline: | ||
vivainio
|
r503 | try: | ||
fperez
|
r644 | _outputfile=_rl.GetOutputFile() | ||
vivainio
|
r671 | except AttributeError: | ||
MinRK
|
r3938 | warnings.warn("Failed GetOutputFile") | ||
fperez
|
r644 | have_readline = False | ||
bgranger
|
r884 | |||
# Test to see if libedit is being used instead of GNU readline. | ||||
MinRK
|
r3906 | # Thanks to Boyd Waters for the original patch. | ||
bgranger
|
r884 | uses_libedit = False | ||
MinRK
|
r5209 | |||
MinRK
|
r5206 | if have_readline: | ||
# Official Python docs state that 'libedit' is in the docstring for libedit readline: | ||||
Christian Boos
|
r5234 | uses_libedit = _rl.__doc__ and 'libedit' in _rl.__doc__ | ||
MinRK
|
r5206 | # Note that many non-System Pythons also do not use proper readline, | ||
# but do not report libedit at all, nor are they linked dynamically against libedit. | ||||
# known culprits of this include: EPD, Fink | ||||
# There is not much we can do to detect this, until we find a specific failure | ||||
# case, rather than relying on the readline module to self-identify as broken. | ||||
MinRK
|
r5209 | |||
MinRK
|
r5206 | if uses_libedit and sys.platform == 'darwin': | ||
_rl.parse_and_bind("bind ^I rl_complete") | ||||
warnings.warn('\n'.join(['', "*"*78, | ||||
"libedit detected - readline will not be well behaved, including but not limited to:", | ||||
" * crashes on tab completion", | ||||
" * incorrect history navigation", | ||||
" * corrupting long-lines", | ||||
" * failure to wrap or indent lines properly", | ||||
"It is highly recommended that you install readline, which is easy_installable:", | ||||
" easy_install readline", | ||||
"Note that `pip install readline` generally DOES NOT WORK, because", | ||||
"it installs to site-packages, which come *after* lib-dynload in sys.path,", | ||||
"where readline is located. It must be `easy_install readline`, or to a custom", | ||||
"location on your PYTHONPATH (even --user comes after lib-dyload).", | ||||
"*"*78]), | ||||
RuntimeWarning) | ||||
bgranger
|
r884 | |||
fperez
|
r644 | # the clear_history() function was only introduced in Python 2.4 and is | ||
# actually optional in the readline API, so we must explicitly check for its | ||||
# existence. Some known platforms actually don't have it. This thread: | ||||
# http://mail.python.org/pipermail/python-dev/2003-August/037845.html | ||||
# has the original discussion. | ||||
if have_readline: | ||||
vivainio
|
r503 | try: | ||
vivainio
|
r671 | _rl.clear_history | ||
fperez
|
r644 | except AttributeError: | ||
def clear_history(): pass | ||||
Fernando Perez
|
r1853 | _rl.clear_history = clear_history | ||