# -*- coding: utf-8 -*- """ Imports and provides the 'correct' version of readline for the platform. Readline is used throughout IPython as:: import IPython.utils.rlineimpl as readline In addition to normal readline stuff, this module provides have_readline boolean and _outputfile variable used in IPython.utils. """ import os import re import sys import time import warnings from subprocess import Popen, PIPE 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: dynload_idx = None else: sys.path.pop(dynload_idx) try: from readline import * import readline as _rl have_readline = True except ImportError: try: from pyreadline import * import pyreadline as _rl have_readline = True except ImportError: have_readline = False if sys.platform == 'darwin': # dirty trick, part II: if dynload_idx is not None: # 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 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) if (sys.platform == 'win32' or sys.platform == 'cli') and have_readline: try: _outputfile=_rl.GetOutputFile() except AttributeError: warnings.warn("Failed GetOutputFile") have_readline = False # Test to see if libedit is being used instead of GNU readline. # Thanks to Boyd Waters for the original patch. uses_libedit = False if have_readline: # Official Python docs state that 'libedit' is in the docstring for libedit readline: uses_libedit = _rl.__doc__ and 'libedit' in _rl.__doc__ # 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. 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) # 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: try: _rl.clear_history except AttributeError: def clear_history(): pass _rl.clear_history = clear_history