/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

  1. """ A minimal application using the ZMQ-based terminal IPython frontend.
  2. This is not a complete console app, as subprocess will not be able to receive
  3. input, there is no real readline support, among other limitations.
  4. Authors:
  5. * Min RK
  6. * Paul Ivanov
  7. """
  8. #-----------------------------------------------------------------------------
  9. # Imports
  10. #-----------------------------------------------------------------------------
  11. import signal
  12. import sys
  13. import time
  14. from IPython.frontend.terminal.ipapp import TerminalIPythonApp, frontend_flags as term_flags
  15. from IPython.utils.traitlets import (
  16. Dict, List, Unicode, Int, CaselessStrEnum, CBool, Any
  17. )
  18. from IPython.utils.warn import warn,error
  19. from IPython.zmq.ipkernel import IPKernelApp
  20. from IPython.zmq.session import Session, default_secure
  21. from IPython.zmq.zmqshell import ZMQInteractiveShell
  22. from IPython.frontend.consoleapp import (
  23. IPythonConsoleApp, app_aliases, app_flags, aliases, app_aliases, flags
  24. )
  25. from IPython.frontend.terminal.console.interactiveshell import ZMQTerminalInteractiveShell
  26. #-----------------------------------------------------------------------------
  27. # Globals
  28. #-----------------------------------------------------------------------------
  29. _examples = """
  30. ipython console # start the ZMQ-based console
  31. ipython console --existing # connect to an existing ipython session
  32. """
  33. #-----------------------------------------------------------------------------
  34. # Flags and Aliases
  35. #-----------------------------------------------------------------------------
  36. # copy flags from mixin:
  37. flags = dict(flags)
  38. # start with mixin frontend flags:
  39. frontend_flags = dict(app_flags)
  40. # add TerminalIPApp flags:
  41. frontend_flags.update(term_flags)
  42. # pylab is not frontend-specific in two-process IPython
  43. frontend_flags.pop('pylab')
  44. # disable quick startup, as it won't propagate to the kernel anyway
  45. frontend_flags.pop('quick')
  46. # update full dict with frontend flags:
  47. flags.update(frontend_flags)
  48. # copy flags from mixin
  49. aliases = dict(aliases)
  50. # start with mixin frontend flags
  51. frontend_aliases = dict(app_aliases)
  52. # load updated frontend flags into full dict
  53. aliases.update(frontend_aliases)
  54. # get flags&aliases into sets, and remove a couple that
  55. # shouldn't be scrubbed from backend flags:
  56. frontend_aliases = set(frontend_aliases.keys())
  57. frontend_flags = set(frontend_flags.keys())
  58. #-----------------------------------------------------------------------------
  59. # Classes
  60. #-----------------------------------------------------------------------------
  61. class ZMQTerminalIPythonApp(TerminalIPythonApp, IPythonConsoleApp):
  62. name = "ipython-console"
  63. """Start a terminal frontend to the IPython zmq kernel."""
  64. description = """
  65. The IPython terminal-based Console.
  66. This launches a Console application inside a terminal.
  67. The Console supports various extra features beyond the traditional
  68. single-process Terminal IPython shell, such as connecting to an
  69. existing ipython session, via:
  70. ipython console --existing
  71. where the previous session could have been created by another ipython
  72. console, an ipython qtconsole, or by opening an ipython notebook.
  73. """
  74. examples = _examples
  75. classes = List([IPKernelApp, ZMQTerminalInteractiveShell, Session])
  76. flags = Dict(flags)
  77. aliases = Dict(aliases)
  78. frontend_aliases = Any(frontend_aliases)
  79. frontend_flags = Any(frontend_flags)
  80. subcommands = Dict()
  81. def parse_command_line(self, argv=None):
  82. super(ZMQTerminalIPythonApp, self).parse_command_line(argv)
  83. self.build_kernel_argv(argv)
  84. def init_shell(self):
  85. IPythonConsoleApp.initialize(self)
  86. # relay sigint to kernel
  87. signal.signal(signal.SIGINT, self.handle_sigint)
  88. self.shell = ZMQTerminalInteractiveShell.instance(config=self.config,
  89. display_banner=False, profile_dir=self.profile_dir,
  90. ipython_dir=self.ipython_dir, kernel_manager=self.kernel_manager)
  91. def init_gui_pylab(self):
  92. # no-op, because we don't want to import matplotlib in the frontend.
  93. pass
  94. def handle_sigint(self, *args):
  95. if self.shell._executing:
  96. if self.kernel_manager.has_kernel:
  97. # interrupt already gets passed to subprocess by signal handler.
  98. # Only if we prevent that should we need to explicitly call
  99. # interrupt_kernel, until which time, this would result in a
  100. # double-interrupt:
  101. # self.kernel_manager.interrupt_kernel()
  102. pass
  103. else:
  104. self.shell.write_err('\n')
  105. error("Cannot interrupt kernels we didn't start.\n")
  106. else:
  107. # raise the KeyboardInterrupt if we aren't waiting for execution,
  108. # so that the interact loop advances, and prompt is redrawn, etc.
  109. raise KeyboardInterrupt
  110. def init_code(self):
  111. # no-op in the frontend, code gets run in the backend
  112. pass
  113. def launch_new_instance():
  114. """Create and run a full blown IPython instance"""
  115. app = ZMQTerminalIPythonApp.instance()
  116. app.initialize()
  117. app.start()
  118. if __name__ == '__main__':
  119. launch_new_instance()