rlineimpl.py
112 lines
| 3.8 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 | ||
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
|
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) | ||||
fperez
|
r644 | if sys.platform == 'win32' 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 | ||
if sys.platform == 'darwin' and have_readline: | ||||
MinRK
|
r3906 | # 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: | ||||
MinRK
|
r3937 | 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() | ||||
MinRK
|
r3906 | |||
if p.returncode == 4: | ||||
# EINTR | ||||
time.sleep(dt) | ||||
dt *= 2 | ||||
continue | ||||
MinRK
|
r3937 | elif p is None or p.returncode: | ||
MinRK
|
r3906 | warnings.warn("libedit detection failed: %s"%err) | ||
break | ||||
else: | ||||
Fernando Perez
|
r2556 | break | ||
MinRK
|
r3938 | if p is not None and p.returncode == 0 and re.search(br'/libedit[\.\d+]*\.dylib\s', out): | ||
bgranger
|
r890 | # we are bound to libedit - new in Leopard | ||
_rl.parse_and_bind("bind ^I rl_complete") | ||||
MinRK
|
r3475 | 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) | ||||
bgranger
|
r890 | uses_libedit = True | ||
MinRK
|
r3937 | # cleanup names | ||
del dt,p,out,err | ||||
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 | ||