##// END OF EJS Templates
use a bytes regex to check for libedit...
MinRK -
Show More
@@ -1,112 +1,112
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """ Imports and provides the 'correct' version of readline for the platform.
2 """ Imports and provides the 'correct' version of readline for the platform.
3
3
4 Readline is used throughout IPython as::
4 Readline is used throughout IPython as::
5
5
6 import IPython.utils.rlineimpl as readline
6 import IPython.utils.rlineimpl as readline
7
7
8 In addition to normal readline stuff, this module provides have_readline
8 In addition to normal readline stuff, this module provides have_readline
9 boolean and _outputfile variable used in IPython.utils.
9 boolean and _outputfile variable used in IPython.utils.
10 """
10 """
11
11
12 import os
12 import os
13 import re
13 import re
14 import sys
14 import sys
15 import time
15 import time
16 import warnings
16 import warnings
17
17
18 from subprocess import Popen, PIPE
18 from subprocess import Popen, PIPE
19
19
20 try:
20 try:
21 from readline import *
21 from readline import *
22 import readline as _rl
22 import readline as _rl
23 have_readline = True
23 have_readline = True
24 except ImportError:
24 except ImportError:
25 try:
25 try:
26 from pyreadline import *
26 from pyreadline import *
27 import pyreadline as _rl
27 import pyreadline as _rl
28 have_readline = True
28 have_readline = True
29 except ImportError:
29 except ImportError:
30 have_readline = False
30 have_readline = False
31
31
32 if have_readline and hasattr(_rl, 'rlmain'):
32 if have_readline and hasattr(_rl, 'rlmain'):
33 # patch add_history to allow for strings in pyreadline <= 1.5:
33 # patch add_history to allow for strings in pyreadline <= 1.5:
34 # fix copied from pyreadline 1.6
34 # fix copied from pyreadline 1.6
35 import pyreadline
35 import pyreadline
36 if pyreadline.release.version <= '1.5':
36 if pyreadline.release.version <= '1.5':
37 def add_history(line):
37 def add_history(line):
38 """add a line to the history buffer."""
38 """add a line to the history buffer."""
39 from pyreadline import lineobj
39 from pyreadline import lineobj
40 if not isinstance(line, lineobj.TextLine):
40 if not isinstance(line, lineobj.TextLine):
41 line = lineobj.TextLine(line)
41 line = lineobj.TextLine(line)
42 return _rl.add_history(line)
42 return _rl.add_history(line)
43
43
44 if sys.platform == 'win32' and have_readline:
44 if sys.platform == 'win32' and have_readline:
45 try:
45 try:
46 _outputfile=_rl.GetOutputFile()
46 _outputfile=_rl.GetOutputFile()
47 except AttributeError:
47 except AttributeError:
48 print "Failed GetOutputFile"
48 warnings.warn("Failed GetOutputFile")
49 have_readline = False
49 have_readline = False
50
50
51 # Test to see if libedit is being used instead of GNU readline.
51 # Test to see if libedit is being used instead of GNU readline.
52 # Thanks to Boyd Waters for the original patch.
52 # Thanks to Boyd Waters for the original patch.
53 uses_libedit = False
53 uses_libedit = False
54 if sys.platform == 'darwin' and have_readline:
54 if sys.platform == 'darwin' and have_readline:
55 # Previously this used commands.getstatusoutput, which uses os.popen.
55 # Previously this used commands.getstatusoutput, which uses os.popen.
56 # Switching to subprocess.Popen, and exponential falloff for EINTR
56 # Switching to subprocess.Popen, and exponential falloff for EINTR
57 # seems to make this better behaved in environments such as PyQt and gdb
57 # seems to make this better behaved in environments such as PyQt and gdb
58 dt = 1e-3
58 dt = 1e-3
59 while dt < 1:
59 while dt < 1:
60 try:
60 try:
61 p = Popen(['otool', '-L', _rl.__file__], stdout=PIPE, stderr=PIPE)
61 p = Popen(['otool', '-L', _rl.__file__], stdout=PIPE, stderr=PIPE)
62 except OSError:
62 except OSError:
63 try:
63 try:
64 # otool not available (no XCode), use lsof instead.
64 # otool not available (no XCode), use lsof instead.
65 # This *could* have a false positive
65 # This *could* have a false positive
66 # if another package that uses libedit explicitly
66 # if another package that uses libedit explicitly
67 # has been imported prior to this test.
67 # has been imported prior to this test.
68 p = Popen(['lsof', '-p', str(os.getpid())], stdout=PIPE, stderr=PIPE)
68 p = Popen(['lsof', '-p', str(os.getpid())], stdout=PIPE, stderr=PIPE)
69 except OSError:
69 except OSError:
70 # This is highly unlikely, but let's be sure
70 # This is highly unlikely, but let's be sure
71 # we don't crash IPython just because we can't find lsof
71 # we don't crash IPython just because we can't find lsof
72 p = out = err = None
72 p = out = err = None
73 warnings.warn("libedit detection failed")
73 warnings.warn("libedit detection failed")
74 break
74 break
75
75
76 out,err = p.communicate()
76 out,err = p.communicate()
77
77
78 if p.returncode == 4:
78 if p.returncode == 4:
79 # EINTR
79 # EINTR
80 time.sleep(dt)
80 time.sleep(dt)
81 dt *= 2
81 dt *= 2
82 continue
82 continue
83 elif p is None or p.returncode:
83 elif p is None or p.returncode:
84 warnings.warn("libedit detection failed: %s"%err)
84 warnings.warn("libedit detection failed: %s"%err)
85 break
85 break
86 else:
86 else:
87 break
87 break
88
88
89 if p is not None and p.returncode == 0 and re.search(r'/libedit[\.\d+]*\.dylib\s', out):
89 if p is not None and p.returncode == 0 and re.search(br'/libedit[\.\d+]*\.dylib\s', out):
90 # we are bound to libedit - new in Leopard
90 # we are bound to libedit - new in Leopard
91 _rl.parse_and_bind("bind ^I rl_complete")
91 _rl.parse_and_bind("bind ^I rl_complete")
92 warnings.warn("Leopard libedit detected - readline will not be well behaved "
92 warnings.warn("Leopard libedit detected - readline will not be well behaved "
93 "including some crashes on tab completion, and incorrect history navigation. "
93 "including some crashes on tab completion, and incorrect history navigation. "
94 "It is highly recommended that you install readline, "
94 "It is highly recommended that you install readline, "
95 "which is easy_installable with: 'easy_install readline'",
95 "which is easy_installable with: 'easy_install readline'",
96 RuntimeWarning)
96 RuntimeWarning)
97 uses_libedit = True
97 uses_libedit = True
98 # cleanup names
98 # cleanup names
99 del dt,p,out,err
99 del dt,p,out,err
100
100
101 # the clear_history() function was only introduced in Python 2.4 and is
101 # the clear_history() function was only introduced in Python 2.4 and is
102 # actually optional in the readline API, so we must explicitly check for its
102 # actually optional in the readline API, so we must explicitly check for its
103 # existence. Some known platforms actually don't have it. This thread:
103 # existence. Some known platforms actually don't have it. This thread:
104 # http://mail.python.org/pipermail/python-dev/2003-August/037845.html
104 # http://mail.python.org/pipermail/python-dev/2003-August/037845.html
105 # has the original discussion.
105 # has the original discussion.
106
106
107 if have_readline:
107 if have_readline:
108 try:
108 try:
109 _rl.clear_history
109 _rl.clear_history
110 except AttributeError:
110 except AttributeError:
111 def clear_history(): pass
111 def clear_history(): pass
112 _rl.clear_history = clear_history
112 _rl.clear_history = clear_history
General Comments 0
You need to be logged in to leave comments. Login now