Make IPython 5 work
This commit is contained in:
parent
134f72db17
commit
46c9e5c679
2 changed files with 85 additions and 31 deletions
|
@ -2556,7 +2556,7 @@ class Interface:
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def create_ipython_window():
|
def create_ipython_window():
|
||||||
try:
|
try:
|
||||||
from ipython_view import IPythonView
|
from gajim.ipython_view import IPythonView
|
||||||
except ImportError:
|
except ImportError:
|
||||||
print('ipython_view not found')
|
print('ipython_view not found')
|
||||||
return
|
return
|
||||||
|
|
|
@ -59,6 +59,24 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
IPython = None
|
IPython = None
|
||||||
|
|
||||||
|
HAS_IPYTHON5 = True
|
||||||
|
try:
|
||||||
|
from pygments.token import Token
|
||||||
|
from IPython.core.displayhook import DisplayHook
|
||||||
|
from IPython.core.display_trap import DisplayTrap
|
||||||
|
|
||||||
|
class MyPromptDisplayHook(DisplayHook):
|
||||||
|
def __init__(self, shell, view):
|
||||||
|
DisplayHook.__init__(self, shell=shell)
|
||||||
|
self.view = view
|
||||||
|
|
||||||
|
def write_output_prompt(self):
|
||||||
|
tokens = self.shell.prompts.out_prompt_tokens()
|
||||||
|
self.view.write('\n')
|
||||||
|
self.view.write(tokens)
|
||||||
|
except Exception:
|
||||||
|
HAS_IPYTHON5 = False
|
||||||
|
|
||||||
class IterableIPShell:
|
class IterableIPShell:
|
||||||
"""
|
"""
|
||||||
Create an IPython instance. Does not start a blocking event loop,
|
Create an IPython instance. Does not start a blocking event loop,
|
||||||
|
@ -114,7 +132,11 @@ class IterableIPShell:
|
||||||
os.environ['TERM'] = 'dumb'
|
os.environ['TERM'] = 'dumb'
|
||||||
excepthook = sys.excepthook
|
excepthook = sys.excepthook
|
||||||
|
|
||||||
from IPython.config.loader import Config
|
if IPython.version_info[0] >= 5:
|
||||||
|
from traitlets.config.loader import Config
|
||||||
|
else:
|
||||||
|
from IPython.config.loader import Config
|
||||||
|
|
||||||
cfg = Config()
|
cfg = Config()
|
||||||
cfg.InteractiveShell.colors = "Linux"
|
cfg.InteractiveShell.colors = "Linux"
|
||||||
|
|
||||||
|
@ -125,7 +147,7 @@ class IterableIPShell:
|
||||||
|
|
||||||
# InteractiveShell inherits from SingletonConfigurable so use instance()
|
# InteractiveShell inherits from SingletonConfigurable so use instance()
|
||||||
if IPython.version_info[0] >= 1:
|
if IPython.version_info[0] >= 1:
|
||||||
self.IP = IPython.terminal.embed.InteractiveShellEmbed.instance(config=cfg, user_ns=user_ns)
|
self.IP = IPython.terminal.embed.InteractiveShellEmbed.instance(config=cfg, user_ns=user_ns, user_module=user_global_ns)
|
||||||
else:
|
else:
|
||||||
self.IP = IPython.frontend.terminal.embed.InteractiveShellEmbed.instance(config=cfg, user_ns=user_ns)
|
self.IP = IPython.frontend.terminal.embed.InteractiveShellEmbed.instance(config=cfg, user_ns=user_ns)
|
||||||
|
|
||||||
|
@ -144,7 +166,7 @@ class IterableIPShell:
|
||||||
self.complete_sep = re.compile('[\s\{\}\[\]\(\)]')
|
self.complete_sep = re.compile('[\s\{\}\[\]\(\)]')
|
||||||
self.updateNamespace({'exit':lambda:None})
|
self.updateNamespace({'exit':lambda:None})
|
||||||
self.updateNamespace({'quit':lambda:None})
|
self.updateNamespace({'quit':lambda:None})
|
||||||
self.IP.readline_startup_hook(self.IP.pre_readline)
|
#self.IP.readline_startup_hook(self.IP.pre_readline)
|
||||||
# Workaround for updating namespace with sys.modules
|
# Workaround for updating namespace with sys.modules
|
||||||
#
|
#
|
||||||
self.__update_namespace()
|
self.__update_namespace()
|
||||||
|
@ -206,6 +228,7 @@ class IterableIPShell:
|
||||||
|
|
||||||
sys.stdout = orig_stdout
|
sys.stdout = orig_stdout
|
||||||
sys.stdin = orig_stdin
|
sys.stdin = orig_stdin
|
||||||
|
|
||||||
def generatePrompt(self, is_continuation):
|
def generatePrompt(self, is_continuation):
|
||||||
'''
|
'''
|
||||||
Generate prompt depending on is_continuation value
|
Generate prompt depending on is_continuation value
|
||||||
|
@ -217,17 +240,24 @@ class IterableIPShell:
|
||||||
@rtype: string
|
@rtype: string
|
||||||
|
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Backwards compatibility with ipyton-0.11
|
# Backwards compatibility with ipyton-0.11
|
||||||
#
|
#
|
||||||
ver = IPython.__version__
|
ver = IPython.__version__
|
||||||
if '0.11' in ver:
|
if '0.11' in ver:
|
||||||
prompt = self.IP.hooks.generate_prompt(is_continuation)
|
prompt = self.IP.hooks.generate_prompt(is_continuation)
|
||||||
else:
|
else:
|
||||||
if is_continuation:
|
# Prompt for IPython >=5.0:
|
||||||
prompt = self.IP.prompt_manager.render('in2')
|
if hasattr(self.IP, 'prompts'):
|
||||||
else:
|
if is_continuation:
|
||||||
prompt = self.IP.prompt_manager.render('in')
|
prompt = self.IP.prompts.continuation_prompt_tokens(self.IP.prompts)
|
||||||
|
else:
|
||||||
|
prompt = self.IP.prompts.in_prompt_tokens(self.IP.prompts)
|
||||||
|
# Prompt for IPython < 5.0
|
||||||
|
elif hasattr(self.IP, 'prompt_manager'):
|
||||||
|
if is_continuation:
|
||||||
|
prompt = self.IP.prompt_manager.render('in2')
|
||||||
|
else:
|
||||||
|
prompt = self.IP.prompt_manager.render('in')
|
||||||
|
|
||||||
return prompt
|
return prompt
|
||||||
|
|
||||||
|
@ -319,27 +349,6 @@ class IterableIPShell:
|
||||||
return completed, possibilities[1]
|
return completed, possibilities[1]
|
||||||
|
|
||||||
|
|
||||||
def shell(self, cmd,verbose=0,debug=0,header=''):
|
|
||||||
"""
|
|
||||||
Replacement method to allow shell commands without them blocking
|
|
||||||
|
|
||||||
@param cmd: Shell command to execute.
|
|
||||||
@type cmd: string
|
|
||||||
@param verbose: Verbosity
|
|
||||||
@type verbose: integer
|
|
||||||
@param debug: Debug level
|
|
||||||
@type debug: integer
|
|
||||||
@param header: Header to be printed before output
|
|
||||||
@type header: string
|
|
||||||
"""
|
|
||||||
if verbose or debug: print(header+cmd)
|
|
||||||
# flush stdout so we don't mangle python's buffering
|
|
||||||
if not debug:
|
|
||||||
input_, output = os.popen4(cmd)
|
|
||||||
print(output.read())
|
|
||||||
output.close()
|
|
||||||
input_.close()
|
|
||||||
|
|
||||||
class ConsoleView(Gtk.TextView):
|
class ConsoleView(Gtk.TextView):
|
||||||
"""
|
"""
|
||||||
Specialized text view for console-like workflow
|
Specialized text view for console-like workflow
|
||||||
|
@ -384,13 +393,47 @@ class ConsoleView(Gtk.TextView):
|
||||||
self.text_buffer.create_tag('0')
|
self.text_buffer.create_tag('0')
|
||||||
self.text_buffer.create_tag('notouch', editable=False)
|
self.text_buffer.create_tag('notouch', editable=False)
|
||||||
self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
|
self.color_pat = re.compile('\x01?\x1b\[(.*?)m\x02?')
|
||||||
|
if HAS_IPYTHON5:
|
||||||
|
self.style_dict = {
|
||||||
|
Token.Prompt: '0;32',
|
||||||
|
Token.PromptNum: '1;32',
|
||||||
|
Token.OutPrompt: '0;31',
|
||||||
|
Token.OutPromptNum: '1;31',
|
||||||
|
}
|
||||||
self.line_start = \
|
self.line_start = \
|
||||||
self.text_buffer.create_mark('line_start',
|
self.text_buffer.create_mark('line_start',
|
||||||
self.text_buffer.get_end_iter(), True)
|
self.text_buffer.get_end_iter(), True)
|
||||||
self.connect('key-press-event', self.onKeyPress)
|
self.connect('key-press-event', self.onKeyPress)
|
||||||
|
|
||||||
def write(self, text, editable=False):
|
def write(self, text, editable=False):
|
||||||
GLib.idle_add(self._write, text, editable)
|
if type(text) == str:
|
||||||
|
GLib.idle_add(self._write, text, editable)
|
||||||
|
elif IPython.version_info[0] >= 5:
|
||||||
|
GLib.idle_add(self._write5, text, editable)
|
||||||
|
|
||||||
|
def _write5(self, text, editable=False):
|
||||||
|
"""
|
||||||
|
Write given text to buffer
|
||||||
|
|
||||||
|
@param text: Text to append.
|
||||||
|
@type text: list of (token: string)
|
||||||
|
@param editable: If true, added text is editable.
|
||||||
|
@type editable: boolean
|
||||||
|
"""
|
||||||
|
start_mark = self.text_buffer.create_mark(None,
|
||||||
|
self.text_buffer.get_end_iter(),
|
||||||
|
True)
|
||||||
|
|
||||||
|
for token, segment in text:
|
||||||
|
tag = self.style_dict[token]
|
||||||
|
self.text_buffer.insert_with_tags_by_name(self.text_buffer.get_end_iter(),
|
||||||
|
segment, tag)
|
||||||
|
if not editable:
|
||||||
|
self.text_buffer.apply_tag_by_name('notouch',
|
||||||
|
self.text_buffer.get_iter_at_mark(start_mark),
|
||||||
|
self.text_buffer.get_end_iter())
|
||||||
|
self.text_buffer.delete_mark(start_mark)
|
||||||
|
self.scroll_mark_onscreen(self.mark)
|
||||||
|
|
||||||
def _write(self, text, editable=False):
|
def _write(self, text, editable=False):
|
||||||
"""
|
"""
|
||||||
|
@ -401,6 +444,9 @@ class ConsoleView(Gtk.TextView):
|
||||||
@param editable: If true, added text is editable.
|
@param editable: If true, added text is editable.
|
||||||
@type editable: boolean
|
@type editable: boolean
|
||||||
"""
|
"""
|
||||||
|
if type(text) == list and IPython.version_info[0] >= 5:
|
||||||
|
self._write5(text, editable)
|
||||||
|
return
|
||||||
segments = self.color_pat.split(text)
|
segments = self.color_pat.split(text)
|
||||||
segment = segments.pop(0)
|
segment = segments.pop(0)
|
||||||
start_mark = self.text_buffer.create_mark(None,
|
start_mark = self.text_buffer.create_mark(None,
|
||||||
|
@ -555,6 +601,10 @@ class IPythonView(ConsoleView, IterableIPShell):
|
||||||
self.cout = StringIO()
|
self.cout = StringIO()
|
||||||
IterableIPShell.__init__(self, cout=self.cout, cerr=self.cout,
|
IterableIPShell.__init__(self, cout=self.cout, cerr=self.cout,
|
||||||
input_func=self.raw_input)
|
input_func=self.raw_input)
|
||||||
|
if HAS_IPYTHON5:
|
||||||
|
displayhook = MyPromptDisplayHook(shell=self.IP, view=self)
|
||||||
|
self.IP.displayhook = displayhook
|
||||||
|
self.IP.display_trap = DisplayTrap(hook=displayhook)
|
||||||
# self.connect('key_press_event', self.keyPress)
|
# self.connect('key_press_event', self.keyPress)
|
||||||
self.interrupt = False
|
self.interrupt = False
|
||||||
self.execute()
|
self.execute()
|
||||||
|
@ -562,6 +612,10 @@ class IPythonView(ConsoleView, IterableIPShell):
|
||||||
self.cout.truncate(0)
|
self.cout.truncate(0)
|
||||||
self.showPrompt(self.prompt)
|
self.showPrompt(self.prompt)
|
||||||
|
|
||||||
|
def prompt_for_code(self):
|
||||||
|
# IPython 5.0 calls prompt_for_code instead of raw_input
|
||||||
|
return self.raw_input(self)
|
||||||
|
|
||||||
def raw_input(self, prompt=''):
|
def raw_input(self, prompt=''):
|
||||||
"""
|
"""
|
||||||
Custom raw_input() replacement. Get's current line from console buffer
|
Custom raw_input() replacement. Get's current line from console buffer
|
||||||
|
|
Loading…
Add table
Reference in a new issue