# -*- 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 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 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' 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 sys.platform == 'darwin' and have_readline: # Previously this used commands.getstatusoutput, which uses os.popen. # Switching to subprocess.Popen, and exponential falloff for EINTR # seems to make this better behaved in environments such as PyQt and gdb dt = 1e-3 while dt < 1: try: p = Popen(['otool', '-L', _rl.__file__], stdout=PIPE, stderr=PIPE) except OSError: try: # otool not available (no XCode), use lsof instead. # This *could* have a false positive # if another package that uses libedit explicitly # has been imported prior to this test. p = Popen(['lsof', '-p', str(os.getpid())], stdout=PIPE, stderr=PIPE) except OSError: # This is highly unlikely, but let's be sure # we don't crash IPython just because we can't find lsof p = out = err = None warnings.warn("libedit detection failed") break out,err = p.communicate() if p.returncode == 4: # EINTR time.sleep(dt) dt *= 2 continue elif p is None or p.returncode: warnings.warn("libedit detection failed: %s"%err) break else: break if p is not None and p.returncode == 0 and re.search(br'/libedit[\.\d+]*\.dylib\s', out): # we are bound to libedit - new in Leopard _rl.parse_and_bind("bind ^I rl_complete") warnings.warn("Leopard libedit detected - readline will not be well behaved " "including some crashes on tab completion, and incorrect history navigation. " "It is highly recommended that you install readline, " "which is easy_installable with: 'easy_install readline'", RuntimeWarning) uses_libedit = True # cleanup names del dt,p,out,err # 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