##// END OF EJS Templates
fix oinspect module
fix oinspect module

File last commit:

r22913:da5a98f8
r22961:64f6d323
Show More
interactiveshell.py
501 lines | 18.4 KiB | text/x-python | PythonLexer
Matthias Bussonnier
Remove readline mention, fit IPython typo.
r22557 """IPython terminal interface using prompt_toolkit"""
Min RK
undeprecate terminal.interactiveshell...
r22549 from __future__ import print_function
Thomas Kluyver
Move most readline code from InteractiveShell to terminal subclass...
r21846
Min RK
undeprecate terminal.interactiveshell...
r22549 import os
import sys
Min RK
fix some deprecations...
r22742 import warnings
Pierre Gerold
Replace all import of IPython.utils.warn module
r22092 from warnings import warn
Brian Granger
Complete reorganization of InteractiveShell....
r2761
Min RK
undeprecate terminal.interactiveshell...
r22549 from IPython.core.interactiveshell import InteractiveShell, InteractiveShellABC
Min RK
fix some deprecations...
r22742 from IPython.utils import io
memeplex
Allow to pass a pygments class to highlighting_style....
r22766 from IPython.utils.py3compat import PY3, cast_unicode_py2, input, string_types
Min RK
undeprecate terminal.interactiveshell...
r22549 from IPython.utils.terminal import toggle_set_term_title, set_term_title
from IPython.utils.process import abbrev_cwd
memeplex
Allow to pass a pygments class to highlighting_style....
r22766 from traitlets import Bool, Unicode, Dict, Integer, observe, Instance, Type, default, Enum, Union
Min RK
undeprecate terminal.interactiveshell...
r22549
Thomas Kluyver
Pull shortcut definitions out to a separate module
r22642 from prompt_toolkit.enums import DEFAULT_BUFFER, EditingMode
from prompt_toolkit.filters import (HasFocus, Condition, IsDone)
Min RK
undeprecate terminal.interactiveshell...
r22549 from prompt_toolkit.history import InMemoryHistory
Jacob Niehus
Add true_color option for prompt_toolkit
r22682 from prompt_toolkit.shortcuts import create_prompt_application, create_eventloop, create_prompt_layout, create_output
Min RK
undeprecate terminal.interactiveshell...
r22549 from prompt_toolkit.interface import CommandLineInterface
from prompt_toolkit.key_binding.manager import KeyBindingManager
from prompt_toolkit.layout.processors import ConditionalProcessor, HighlightMatchingBracketProcessor
from prompt_toolkit.styles import PygmentsStyle, DynamicStyle
from pygments.styles import get_style_by_name, get_all_styles
memeplex
Allow to pass a pygments class to highlighting_style....
r22766 from pygments.style import Style
Min RK
undeprecate terminal.interactiveshell...
r22549 from pygments.token import Token
from .debugger import TerminalPdb, Pdb
from .magics import TerminalMagics
Thomas Kluyver
Let IPython.lib.guisupport detect terminal-integrated event loops...
r22913 from .pt_inputhooks import get_inputhook_name_and_func
Min RK
undeprecate terminal.interactiveshell...
r22549 from .prompts import Prompts, ClassicPrompts, RichPromptDisplayHook
from .ptutils import IPythonPTCompleter, IPythonPTLexer
Thomas Kluyver
Pull shortcut definitions out to a separate module
r22642 from .shortcuts import register_ipython_shortcuts
Min RK
undeprecate terminal.interactiveshell...
r22549
Matthias Bussonnier
Fix interact() and mainloop() for backward compat.
r22562 DISPLAY_BANNER_DEPRECATED = object()
Min RK
undeprecate terminal.interactiveshell...
r22549
Matthias Bussonnier
Restore the ability to use %colors to switch terminal theme....
r22578 from pygments.style import Style
class _NoStyle(Style): pass
_style_overrides_light_bg = {
Token.Prompt: '#0000ff',
Token.PromptNum: '#0000ee bold',
Token.OutPrompt: '#cc0000',
Token.OutPromptNum: '#bb0000 bold',
}
_style_overrides_linux = {
Token.Prompt: '#00cc00',
Token.PromptNum: '#00bb00 bold',
Token.OutPrompt: '#cc0000',
Token.OutPromptNum: '#bb0000 bold',
}
Min RK
undeprecate terminal.interactiveshell...
r22549 def get_default_editor():
try:
ed = os.environ['EDITOR']
if not PY3:
ed = ed.decode()
return ed
except KeyError:
pass
except UnicodeError:
warn("$EDITOR environment variable is not pure ASCII. Using platform "
"default editor.")
if os.name == 'posix':
return 'vi' # the only one guaranteed to be there!
else:
return 'notepad' # same in Windows!
Min RK
safer check for isatty...
r22758 # conservatively check for tty
# overridden streams can result in things like:
# - sys.stdin = None
# - no isatty method
for _name in ('stdin', 'stdout', 'stderr'):
_stream = getattr(sys, _name)
if not _stream or not hasattr(_stream, 'isatty') or not _stream.isatty():
_is_tty = False
break
Min RK
undeprecate terminal.interactiveshell...
r22549 else:
Min RK
safer check for isatty...
r22758 _is_tty = True
Min RK
undeprecate terminal.interactiveshell...
r22549
_use_simple_prompt = ('IPY_TEST_SIMPLE_PROMPT' in os.environ) or (not _is_tty)
class TerminalInteractiveShell(InteractiveShell):
space_for_menu = Integer(6, help='Number of line at the bottom of the screen '
'to reserve for the completion menu'
).tag(config=True)
def _space_for_menu_changed(self, old, new):
self._update_layout()
pt_cli = None
debugger_history = None
Thomas Kluyver
Fix switching prompts in doctest mode
r22606 _pt_app = None
Min RK
undeprecate terminal.interactiveshell...
r22549
simple_prompt = Bool(_use_simple_prompt,
help="""Use `raw_input` for the REPL, without completion, multiline input, and prompt colors.
Useful when controlling IPython as a subprocess, and piping STDIN/OUT/ERR. Known usage are:
IPython own testing machinery, and emacs inferior-shell integration through elpy.
This mode default to `True` if the `IPY_TEST_SIMPLE_PROMPT`
environment variable is set, or the current terminal is not a tty.
"""
).tag(config=True)
@property
def debugger_cls(self):
return Pdb if self.simple_prompt else TerminalPdb
confirm_exit = Bool(True,
help="""
Set to confirm when you try to exit IPython with an EOF (Control-D
in Unix, Control-Z/Enter in Windows). By typing 'exit' or 'quit',
you can force a direct exit without any confirmation.""",
).tag(config=True)
editing_mode = Unicode('emacs',
help="Shortcut style to use at the prompt. 'vi' or 'emacs'.",
).tag(config=True)
mouse_support = Bool(False,
help="Enable mouse support in the prompt"
).tag(config=True)
memeplex
Allow to pass a pygments class to highlighting_style....
r22766 highlighting_style = Union([Unicode('legacy'), Type(klass=Style)],
help="""The name or class of a Pygments style to use for syntax
highlighting: \n %s""" % ', '.join(get_all_styles())
Min RK
undeprecate terminal.interactiveshell...
r22549 ).tag(config=True)
Jamshed Vesuna
Only track unique history of commands
r22859
Min RK
undeprecate terminal.interactiveshell...
r22549 @observe('highlighting_style')
Matthias Bussonnier
Restore the ability to use %colors to switch terminal theme....
r22578 @observe('colors')
Min RK
undeprecate terminal.interactiveshell...
r22549 def _highlighting_style_changed(self, change):
Matthias Bussonnier
Restore the ability to use %colors to switch terminal theme....
r22578 self.refresh_style()
def refresh_style(self):
memeplex
Allow to pass a pygments class to highlighting_style....
r22766 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
Min RK
undeprecate terminal.interactiveshell...
r22549
Matthias Bussonnier
Restore the ability to use %colors to switch terminal theme....
r22578
Min RK
undeprecate terminal.interactiveshell...
r22549 highlighting_style_overrides = Dict(
help="Override highlighting format for specific tokens"
).tag(config=True)
Jacob Niehus
Add true_color option for prompt_toolkit
r22682 true_color = Bool(False,
help=("Use 24bit colors instead of 256 colors in prompt highlighting. "
"If your terminal supports true color, the following command "
"should print 'TRUECOLOR' in orange: "
"printf \"\\x1b[38;2;255;100;0mTRUECOLOR\\x1b[0m\\n\"")
).tag(config=True)
Min RK
undeprecate terminal.interactiveshell...
r22549 editor = Unicode(get_default_editor(),
help="Set the editor used by IPython (default to $EDITOR/vi/notepad)."
).tag(config=True)
prompts_class = Type(Prompts, help='Class used to generate Prompt token for prompt_toolkit').tag(config=True)
prompts = Instance(Prompts)
@default('prompts')
def _prompts_default(self):
return self.prompts_class(self)
@observe('prompts')
def _(self, change):
self._update_layout()
@default('displayhook_class')
def _displayhook_class_default(self):
return RichPromptDisplayHook
term_title = Bool(True,
help="Automatically set the terminal title"
).tag(config=True)
Jamshed Vesuna
Only track unique history of commands
r22859 display_completions = Enum(('column', 'multicolumn','readlinelike'),
michaelpacer
Fixed formatting at end of lines
r22726 help= ( "Options for displaying tab completions, 'column', 'multicolumn', and "
"'readlinelike'. These options are for `prompt_toolkit`, see "
"`prompt_toolkit` documentation for more information."
michaelpacer
added help line tointeractiveshell.py
r22720 ),
default_value='multicolumn').tag(config=True)
Matthias Bussonnier
Extend the completion layout to use a third readlinelike option....
r22554
Min RK
undeprecate terminal.interactiveshell...
r22549 highlight_matching_brackets = Bool(True,
help="Highlight matching brackets .",
).tag(config=True)
@observe('term_title')
def init_term_title(self, change=None):
# Enable or disable the terminal title.
if self.term_title:
toggle_set_term_title(True)
set_term_title('IPython: ' + abbrev_cwd())
else:
toggle_set_term_title(False)
def init_display_formatter(self):
super(TerminalInteractiveShell, self).init_display_formatter()
# terminal only supports plain text
self.display_formatter.active_types = ['text/plain']
def init_prompt_toolkit_cli(self):
if self.simple_prompt:
# Fall back to plain non-interactive output for tests.
# This is very limited, and only accepts a single line.
def prompt():
return cast_unicode_py2(input('In [%d]: ' % self.execution_count))
self.prompt_for_code = prompt
return
Thomas Kluyver
Pull shortcut definitions out to a separate module
r22642 # Set up keyboard shortcuts
Min RK
undeprecate terminal.interactiveshell...
r22549 kbmanager = KeyBindingManager.for_prompt()
Thomas Kluyver
Pull shortcut definitions out to a separate module
r22642 register_ipython_shortcuts(kbmanager.registry, self)
Min RK
undeprecate terminal.interactiveshell...
r22549
# Pre-populate history from IPython's history database
history = InMemoryHistory()
last_cell = u""
for __, ___, cell in self.history_manager.get_tail(self.history_load_length,
include_latest=True):
# Ignore blank lines and consecutive duplicates
cell = cell.rstrip()
if cell and (cell != last_cell):
history.append(cell)
Jamshed Vesuna
Only track unique history of commands
r22859 last_cell = cell
Min RK
undeprecate terminal.interactiveshell...
r22549
memeplex
Allow to pass a pygments class to highlighting_style....
r22766 self._style = self._make_style_from_name_or_cls(self.highlighting_style)
Min RK
undeprecate terminal.interactiveshell...
r22549 style = DynamicStyle(lambda: self._style)
editing_mode = getattr(EditingMode, self.editing_mode.upper())
Thomas Kluyver
Fix switching prompts in doctest mode
r22606 self._pt_app = create_prompt_application(
Min RK
undeprecate terminal.interactiveshell...
r22549 editing_mode=editing_mode,
key_bindings_registry=kbmanager.registry,
history=history,
Min RK
Make IPythonPTCompleter(shell) backward-compatible...
r22768 completer=IPythonPTCompleter(shell=self),
Min RK
undeprecate terminal.interactiveshell...
r22549 enable_history_search=True,
style=style,
mouse_support=self.mouse_support,
**self._layout_options()
)
self._eventloop = create_eventloop(self.inputhook)
Jacob Niehus
Add true_color option for prompt_toolkit
r22682 self.pt_cli = CommandLineInterface(
self._pt_app, eventloop=self._eventloop,
output=create_output(true_color=self.true_color))
Min RK
undeprecate terminal.interactiveshell...
r22549
memeplex
Allow to pass a pygments class to highlighting_style....
r22766 def _make_style_from_name_or_cls(self, name_or_cls):
Min RK
undeprecate terminal.interactiveshell...
r22549 """
Small wrapper that make an IPython compatible style from a style name
Jamshed Vesuna
Only track unique history of commands
r22859 We need that to add style for prompt ... etc.
Min RK
undeprecate terminal.interactiveshell...
r22549 """
Matthias Bussonnier
Make everyone happy with a neutral colortheme by default.
r22609 style_overrides = {}
memeplex
Allow to pass a pygments class to highlighting_style....
r22766 if name_or_cls == 'legacy':
Matthias Bussonnier
Restore the ability to use %colors to switch terminal theme....
r22578 legacy = self.colors.lower()
if legacy == 'linux':
style_cls = get_style_by_name('monokai')
style_overrides = _style_overrides_linux
elif legacy == 'lightbg':
style_overrides = _style_overrides_light_bg
Matthias Bussonnier
Make everyone happy with a neutral colortheme by default.
r22609 style_cls = get_style_by_name('pastie')
elif legacy == 'neutral':
Matthias Bussonnier
Restore the ability to use %colors to switch terminal theme....
r22578 # The default theme needs to be visible on both a dark background
# and a light background, because we can't tell what the terminal
# looks like. These tweaks to the default theme help with that.
Matthias Bussonnier
Make everyone happy with a neutral colortheme by default.
r22609 style_cls = get_style_by_name('default')
Matthias Bussonnier
Restore the ability to use %colors to switch terminal theme....
r22578 style_overrides.update({
Token.Number: '#007700',
Token.Operator: 'noinherit',
Token.String: '#BB6622',
Token.Name.Function: '#2080D0',
Token.Name.Class: 'bold #2080D0',
Token.Name.Namespace: 'bold #2080D0',
Matthias Bussonnier
Make everyone happy with a neutral colortheme by default.
r22609 Token.Prompt: '#009900',
Token.PromptNum: '#00ff00 bold',
Token.OutPrompt: '#990000',
Token.OutPromptNum: '#ff0000 bold',
Matthias Bussonnier
Restore the ability to use %colors to switch terminal theme....
r22578 })
elif legacy =='nocolor':
style_cls=_NoStyle
style_overrides = {}
else :
raise ValueError('Got unknown colors: ', legacy)
else :
memeplex
Allow to pass a pygments class to highlighting_style....
r22766 if isinstance(name_or_cls, string_types):
style_cls = get_style_by_name(name_or_cls)
else:
style_cls = name_or_cls
Matthias Bussonnier
Restore the ability to use %colors to switch terminal theme....
r22578 style_overrides = {
Token.Prompt: '#009900',
Token.PromptNum: '#00ff00 bold',
Token.OutPrompt: '#990000',
Token.OutPromptNum: '#ff0000 bold',
}
Min RK
undeprecate terminal.interactiveshell...
r22549 style_overrides.update(self.highlighting_style_overrides)
style = PygmentsStyle.from_defaults(pygments_style_cls=style_cls,
style_dict=style_overrides)
return style
def _layout_options(self):
"""
Return the current layout option for the current Terminal InteractiveShell
"""
return {
'lexer':IPythonPTLexer(),
'reserve_space_for_menu':self.space_for_menu,
'get_prompt_tokens':self.prompts.in_prompt_tokens,
'get_continuation_tokens':self.prompts.continuation_prompt_tokens,
'multiline':True,
Matthias Bussonnier
Extend the completion layout to use a third readlinelike option....
r22554 'display_completions_in_columns': (self.display_completions == 'multicolumn'),
Min RK
undeprecate terminal.interactiveshell...
r22549
# Highlight matching brackets, but only when this setting is
# enabled, and only when the DEFAULT_BUFFER has the focus.
'extra_input_processors': [ConditionalProcessor(
processor=HighlightMatchingBracketProcessor(chars='[](){}'),
filter=HasFocus(DEFAULT_BUFFER) & ~IsDone() &
Condition(lambda cli: self.highlight_matching_brackets))],
}
def _update_layout(self):
"""
Ask for a re computation of the application layout, if for example ,
some configuration options have changed.
"""
Thomas Kluyver
Fix switching prompts in doctest mode
r22606 if self._pt_app:
self._pt_app.layout = create_prompt_layout(**self._layout_options())
Min RK
undeprecate terminal.interactiveshell...
r22549
def prompt_for_code(self):
document = self.pt_cli.run(
pre_run=self.pre_prompt, reset_current_buffer=True)
return document.text
Thomas Kluyver
Be more lenient when bytes are sent to stdout/stderr on Py2+Windows...
r22701 def enable_win_unicode_console(self):
Thomas Kluyver
Don't require win_unicode_console on Python 3.6...
r22867 if sys.version_info >= (3, 6):
# Since PEP 528, Python uses the unicode APIs for the Windows
# console by default, so WUC shouldn't be needed.
return
Thomas Kluyver
Be more lenient when bytes are sent to stdout/stderr on Py2+Windows...
r22701 import win_unicode_console
if PY3:
win_unicode_console.enable()
else:
# https://github.com/ipython/ipython/issues/9768
from win_unicode_console.streams import (TextStreamWrapper,
stdout_text_transcoded, stderr_text_transcoded)
class LenientStrStreamWrapper(TextStreamWrapper):
def write(self, s):
if isinstance(s, bytes):
s = s.decode(self.encoding, 'replace')
self.base.write(s)
stdout_text_str = LenientStrStreamWrapper(stdout_text_transcoded)
stderr_text_str = LenientStrStreamWrapper(stderr_text_transcoded)
win_unicode_console.enable(stdout=stdout_text_str,
stderr=stderr_text_str)
Min RK
undeprecate terminal.interactiveshell...
r22549 def init_io(self):
if sys.platform not in {'win32', 'cli'}:
return
Thomas Kluyver
Be more lenient when bytes are sent to stdout/stderr on Py2+Windows...
r22701 self.enable_win_unicode_console()
Min RK
undeprecate terminal.interactiveshell...
r22549
Thomas Kluyver
Be more lenient when bytes are sent to stdout/stderr on Py2+Windows...
r22701 import colorama
Min RK
undeprecate terminal.interactiveshell...
r22549 colorama.init()
# For some reason we make these wrappers around stdout/stderr.
# For now, we need to reset them so all output gets coloured.
# https://github.com/ipython/ipython/issues/8669
Min RK
fix some deprecations...
r22742 # io.std* are deprecated, but don't show our own deprecation warnings
# during initialization of the deprecated API.
with warnings.catch_warnings():
warnings.simplefilter('ignore', DeprecationWarning)
io.stdout = io.IOStream(sys.stdout)
io.stderr = io.IOStream(sys.stderr)
Min RK
undeprecate terminal.interactiveshell...
r22549
def init_magics(self):
super(TerminalInteractiveShell, self).init_magics()
self.register_magics(TerminalMagics)
def init_alias(self):
# The parent class defines aliases that can be safely used with any
# frontend.
super(TerminalInteractiveShell, self).init_alias()
# Now define aliases that only make sense on the terminal, because they
# need direct access to the console in a way that we can't emulate in
# GUI or web frontend
if os.name == 'posix':
for cmd in ['clear', 'more', 'less', 'man']:
self.alias_manager.soft_define_alias(cmd, cmd)
Fernando Perez
Fix paste/cpaste bug and refactor/cleanup that code a lot....
r5435
Matthias Bussonnier
Improve deprecation warning....
r22442
Thomas Kluyver
Remove the readline shell machinery...
r22436 def __init__(self, *args, **kwargs):
Min RK
undeprecate terminal.interactiveshell...
r22549 super(TerminalInteractiveShell, self).__init__(*args, **kwargs)
self.init_prompt_toolkit_cli()
self.init_term_title()
self.keep_running = True
self.debugger_history = InMemoryHistory()
def ask_exit(self):
self.keep_running = False
rl_next_input = None
def pre_prompt(self):
if self.rl_next_input:
self.pt_cli.application.buffer.text = cast_unicode_py2(self.rl_next_input)
self.rl_next_input = None
Matthias Bussonnier
Fix interact() and mainloop() for backward compat.
r22562 def interact(self, display_banner=DISPLAY_BANNER_DEPRECATED):
if display_banner is not DISPLAY_BANNER_DEPRECATED:
warn('interact `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
Min RK
Allow starting TerminalInteractiveShell more than once...
r22764 self.keep_running = True
Min RK
undeprecate terminal.interactiveshell...
r22549 while self.keep_running:
print(self.separate_in, end='')
try:
code = self.prompt_for_code()
except EOFError:
if (not self.confirm_exit) \
or self.ask_yes_no('Do you really want to exit ([y]/n)?','y','n'):
self.ask_exit()
else:
if code:
self.run_cell(code, store_history=True)
Matthias Bussonnier
Fix interact() and mainloop() for backward compat.
r22562 def mainloop(self, display_banner=DISPLAY_BANNER_DEPRECATED):
Min RK
undeprecate terminal.interactiveshell...
r22549 # An extra layer of protection in case someone mashing Ctrl-C breaks
# out of our internal code.
Matthias Bussonnier
Fix interact() and mainloop() for backward compat.
r22562 if display_banner is not DISPLAY_BANNER_DEPRECATED:
warn('mainloop `display_banner` argument is deprecated since IPython 5.0. Call `show_banner()` if needed.', DeprecationWarning, stacklevel=2)
Min RK
undeprecate terminal.interactiveshell...
r22549 while True:
try:
self.interact()
break
except KeyboardInterrupt:
print("\nKeyboardInterrupt escaped interact()\n")
_inputhook = None
def inputhook(self, context):
if self._inputhook is not None:
self._inputhook(context)
Thomas Kluyver
Let IPython.lib.guisupport detect terminal-integrated event loops...
r22913 active_eventloop = None
Min RK
undeprecate terminal.interactiveshell...
r22549 def enable_gui(self, gui=None):
if gui:
Thomas Kluyver
Let IPython.lib.guisupport detect terminal-integrated event loops...
r22913 self.active_eventloop, self._inputhook =\
get_inputhook_name_and_func(gui)
Min RK
undeprecate terminal.interactiveshell...
r22549 else:
Thomas Kluyver
Let IPython.lib.guisupport detect terminal-integrated event loops...
r22913 self.active_eventloop = self._inputhook = None
Min RK
undeprecate terminal.interactiveshell...
r22549
# Run !system commands directly, not through pipes, so terminal programs
# work correctly.
system = InteractiveShell.system_raw
def auto_rewrite_input(self, cmd):
"""Overridden from the parent class to use fancy rewriting prompt"""
if not self.show_rewritten_input:
return
tokens = self.prompts.rewrite_prompt_tokens()
if self.pt_cli:
self.pt_cli.print_tokens(tokens)
print(cmd)
else:
prompt = ''.join(s for t, s in tokens)
print(prompt, cmd, sep='')
_prompts_before = None
def switch_doctest_mode(self, mode):
"""Switch prompts to classic for %doctest_mode"""
if mode:
self._prompts_before = self.prompts
self.prompts = ClassicPrompts(self)
elif self._prompts_before:
self.prompts = self._prompts_before
self._prompts_before = None
Thomas Kluyver
Fix switching prompts in doctest mode
r22606 self._update_layout()
Min RK
undeprecate terminal.interactiveshell...
r22549
InteractiveShellABC.register(TerminalInteractiveShell)
if __name__ == '__main__':
TerminalInteractiveShell.instance().interact()