/IPython/frontend/terminal/console/app.py
https://github.com/yarikoptic/ipython01x · Python · 156 lines · 82 code · 28 blank · 46 comment · 5 complexity · 52dce86c0df77038d4dd54527b62c33a MD5 · raw file
- """ A minimal application using the ZMQ-based terminal IPython frontend.
- This is not a complete console app, as subprocess will not be able to receive
- input, there is no real readline support, among other limitations.
- Authors:
- * Min RK
- * Paul Ivanov
- """
- #-----------------------------------------------------------------------------
- # Imports
- #-----------------------------------------------------------------------------
- import signal
- import sys
- import time
- from IPython.frontend.terminal.ipapp import TerminalIPythonApp, frontend_flags as term_flags
- from IPython.utils.traitlets import (
- Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any
- )
- from IPython.utils.warn import warn,error
- from IPython.zmq.ipkernel import IPKernelApp
- from IPython.zmq.session import Session, default_secure
- from IPython.zmq.zmqshell import ZMQInteractiveShell
- from IPython.frontend.consoleapp import (
- IPythonConsoleApp, app_aliases, app_flags, aliases, app_aliases, flags
- )
- from IPython.frontend.terminal.console.interactiveshell import ZMQTerminalInteractiveShell
- #-----------------------------------------------------------------------------
- # Globals
- #-----------------------------------------------------------------------------
- _examples = """
- ipython console # start the ZMQ-based console
- ipython console --existing # connect to an existing ipython session
- """
- #-----------------------------------------------------------------------------
- # Flags and Aliases
- #-----------------------------------------------------------------------------
- # copy flags from mixin:
- flags = dict(flags)
- # start with mixin frontend flags:
- frontend_flags = dict(app_flags)
- # add TerminalIPApp flags:
- frontend_flags.update(term_flags)
- # pylab is not frontend-specific in two-process IPython
- frontend_flags.pop('pylab')
- # disable quick startup, as it won't propagate to the kernel anyway
- frontend_flags.pop('quick')
- # update full dict with frontend flags:
- flags.update(frontend_flags)
- # copy flags from mixin
- aliases = dict(aliases)
- # start with mixin frontend flags
- frontend_aliases = dict(app_aliases)
- # load updated frontend flags into full dict
- aliases.update(frontend_aliases)
- # get flags&aliases into sets, and remove a couple that
- # shouldn't be scrubbed from backend flags:
- frontend_aliases = set(frontend_aliases.keys())
- frontend_flags = set(frontend_flags.keys())
- #-----------------------------------------------------------------------------
- # Classes
- #-----------------------------------------------------------------------------
- class ZMQTerminalIPythonApp(TerminalIPythonApp, IPythonConsoleApp):
- name = "ipython-console"
- """Start a terminal frontend to the IPython zmq kernel."""
- description = """
- The IPython terminal-based Console.
- This launches a Console application inside a terminal.
- The Console supports various extra features beyond the traditional
- single-process Terminal IPython shell, such as connecting to an
- existing ipython session, via:
- ipython console --existing
- where the previous session could have been created by another ipython
- console, an ipython qtconsole, or by opening an ipython notebook.
- """
- examples = _examples
- classes = List([IPKernelApp, ZMQTerminalInteractiveShell, Session])
- flags = Dict(flags)
- aliases = Dict(aliases)
- frontend_aliases = Any(frontend_aliases)
- frontend_flags = Any(frontend_flags)
-
- subcommands = Dict()
- def parse_command_line(self, argv=None):
- super(ZMQTerminalIPythonApp, self).parse_command_line(argv)
- self.build_kernel_argv(argv)
- def init_shell(self):
- IPythonConsoleApp.initialize(self)
- # relay sigint to kernel
- signal.signal(signal.SIGINT, self.handle_sigint)
- self.shell = ZMQTerminalInteractiveShell.instance(config=self.config,
- display_banner=False, profile_dir=self.profile_dir,
- ipython_dir=self.ipython_dir, kernel_manager=self.kernel_manager)
- def init_gui_pylab(self):
- # no-op, because we don't want to import matplotlib in the frontend.
- pass
- def handle_sigint(self, *args):
- if self.shell._executing:
- if self.kernel_manager.has_kernel:
- # interrupt already gets passed to subprocess by signal handler.
- # Only if we prevent that should we need to explicitly call
- # interrupt_kernel, until which time, this would result in a
- # double-interrupt:
- # self.kernel_manager.interrupt_kernel()
- pass
- else:
- self.shell.write_err('\n')
- error("Cannot interrupt kernels we didn't start.\n")
- else:
- # raise the KeyboardInterrupt if we aren't waiting for execution,
- # so that the interact loop advances, and prompt is redrawn, etc.
- raise KeyboardInterrupt
-
- def init_code(self):
- # no-op in the frontend, code gets run in the backend
- pass
- def launch_new_instance():
- """Create and run a full blown IPython instance"""
- app = ZMQTerminalIPythonApp.instance()
- app.initialize()
- app.start()
- if __name__ == '__main__':
- launch_new_instance()