From 273c64095a2347c52a41a6fac878aa24d1c14e30 2015-04-09 22:01:17 From: Min RK Date: 2015-04-09 22:01:17 Subject: [PATCH] remove jupyter_console --- diff --git a/IPython/testing/iptest.py b/IPython/testing/iptest.py index b9b4665..eee3a5c 100644 --- a/IPython/testing/iptest.py +++ b/IPython/testing/iptest.py @@ -213,9 +213,8 @@ if sys.platform == 'win32': sec.exclude('plugin.test_exampleip') sec.exclude('plugin.dtexample') -# terminal: -if (not have['pexpect']) or (not have['zmq']): - test_sections['terminal'].exclude('console') +# don't run jupyter_console tests found via shim +test_sections['terminal'].exclude('console') # extensions: sec = test_sections['extensions'] diff --git a/jupyter_console/__init__.py b/jupyter_console/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_console/__init__.py +++ /dev/null diff --git a/jupyter_console/__main__.py b/jupyter_console/__main__.py deleted file mode 100644 index c93a817..0000000 --- a/jupyter_console/__main__.py +++ /dev/null @@ -1,3 +0,0 @@ -if __name__ == '__main__': - from IPython.terminal.console import app - app.launch_new_instance() diff --git a/jupyter_console/app.py b/jupyter_console/app.py deleted file mode 100644 index 9596d4d..0000000 --- a/jupyter_console/app.py +++ /dev/null @@ -1,146 +0,0 @@ -""" 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. -""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import signal - -from IPython.terminal.ipapp import TerminalIPythonApp, frontend_flags as term_flags - -from IPython.utils.traitlets import ( - Dict, Any -) -from IPython.utils.warn import error - -from IPython.consoleapp import ( - IPythonConsoleApp, app_aliases, app_flags, aliases, flags - ) - -from IPython.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) -# 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) -aliases['colors'] = 'InteractiveShell.colors' - -# 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 = [ZMQTerminalInteractiveShell] + IPythonConsoleApp.classes - flags = Dict(flags) - aliases = Dict(aliases) - frontend_aliases = Any(frontend_aliases) - frontend_flags = Any(frontend_flags) - - subcommands = Dict() - - force_interact = True - - def parse_command_line(self, argv=None): - super(ZMQTerminalIPythonApp, self).parse_command_line(argv) - self.build_kernel_argv(self.extra_args) - - def init_shell(self): - IPythonConsoleApp.initialize(self) - # relay sigint to kernel - signal.signal(signal.SIGINT, self.handle_sigint) - self.shell = ZMQTerminalInteractiveShell.instance(parent=self, - display_banner=False, profile_dir=self.profile_dir, - ipython_dir=self.ipython_dir, - manager=self.kernel_manager, - client=self.kernel_client, - ) - - 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: - # 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 - - -launch_new_instance = ZMQTerminalIPythonApp.launch_instance - - -if __name__ == '__main__': - launch_new_instance() - diff --git a/jupyter_console/completer.py b/jupyter_console/completer.py deleted file mode 100644 index f9fef11..0000000 --- a/jupyter_console/completer.py +++ /dev/null @@ -1,81 +0,0 @@ -# -*- coding: utf-8 -*- -"""Adapt readline completer interface to make ZMQ request.""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -try: - from queue import Empty # Py 3 -except ImportError: - from Queue import Empty # Py 2 - -from IPython.config import Configurable -from IPython.core.completer import IPCompleter -from IPython.utils.py3compat import str_to_unicode, unicode_to_str, cast_bytes, cast_unicode -from IPython.utils.traitlets import Float -import IPython.utils.rlineimpl as readline - -class ZMQCompleter(IPCompleter): - """Client-side completion machinery. - - How it works: self.complete will be called multiple times, with - state=0,1,2,... When state=0 it should compute ALL the completion matches, - and then return them for each value of state.""" - - timeout = Float(5.0, config=True, help='timeout before completion abort') - - def __init__(self, shell, client, config=None): - super(ZMQCompleter,self).__init__(config=config) - - self.shell = shell - self.client = client - self.matches = [] - # don't do any splitting client-side, - # rely on the kernel for that - self.splitter.delims = '\r\n' - if self.readline: - self.readline.set_completer_delims('\r\n') - - def complete_request(self, text): - line = str_to_unicode(readline.get_line_buffer()) - byte_cursor_pos = readline.get_endidx() - - # get_endidx is a byte offset - # account for multi-byte characters to get correct cursor_pos - bytes_before_cursor = cast_bytes(line)[:byte_cursor_pos] - cursor_pos = len(cast_unicode(bytes_before_cursor)) - - # send completion request to kernel - # Give the kernel up to 5s to respond - msg_id = self.client.complete( - code=line, - cursor_pos=cursor_pos, - ) - - msg = self.client.shell_channel.get_msg(timeout=self.timeout) - if msg['parent_header']['msg_id'] == msg_id: - content = msg['content'] - cursor_start = content['cursor_start'] - matches = [ line[:cursor_start] + m for m in content['matches'] ] - if content["cursor_end"] < cursor_pos: - extra = line[content["cursor_end"]: cursor_pos] - matches = [m + extra for m in matches] - matches = [ unicode_to_str(m) for m in matches ] - return matches - return [] - - def rlcomplete(self, text, state): - if state == 0: - try: - self.matches = self.complete_request(text) - except Empty: - #print('WARNING: Kernel timeout on tab completion.') - pass - - try: - return self.matches[state] - except IndexError: - return None - - def complete(self, text, line, cursor_pos=None): - return self.rlcomplete(text, 0) diff --git a/jupyter_console/interactiveshell.py b/jupyter_console/interactiveshell.py deleted file mode 100644 index c11484f..0000000 --- a/jupyter_console/interactiveshell.py +++ /dev/null @@ -1,585 +0,0 @@ -# -*- coding: utf-8 -*- -"""terminal client to the IPython kernel""" - -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -from __future__ import print_function - -import base64 -import bdb -import errno -import signal -import os -import sys -import time -import subprocess -from getpass import getpass -from io import BytesIO - -try: - from queue import Empty # Py 3 -except ImportError: - from Queue import Empty # Py 2 - -from zmq import ZMQError - -from IPython.core import page -from IPython.core import release -from IPython.terminal.console.zmqhistory import ZMQHistoryManager -from IPython.utils.warn import warn, error -from IPython.utils import io -from IPython.utils.py3compat import string_types, input -from IPython.utils.traitlets import List, Enum, Any, Instance, Unicode, Float, Bool -from IPython.utils.tempdir import NamedFileInTemporaryDirectory - -from IPython.terminal.interactiveshell import TerminalInteractiveShell -from IPython.terminal.console.completer import ZMQCompleter - -class ZMQTerminalInteractiveShell(TerminalInteractiveShell): - """A subclass of TerminalInteractiveShell that uses the 0MQ kernel""" - _executing = False - _execution_state = Unicode('') - _pending_clearoutput = False - kernel_banner = Unicode('') - kernel_timeout = Float(60, config=True, - help="""Timeout for giving up on a kernel (in seconds). - - On first connect and restart, the console tests whether the - kernel is running and responsive by sending kernel_info_requests. - This sets the timeout in seconds for how long the kernel can take - before being presumed dead. - """ - ) - - image_handler = Enum(('PIL', 'stream', 'tempfile', 'callable'), - config=True, allow_none=True, help= - """ - Handler for image type output. This is useful, for example, - when connecting to the kernel in which pylab inline backend is - activated. There are four handlers defined. 'PIL': Use - Python Imaging Library to popup image; 'stream': Use an - external program to show the image. Image will be fed into - the STDIN of the program. You will need to configure - `stream_image_handler`; 'tempfile': Use an external program to - show the image. Image will be saved in a temporally file and - the program is called with the temporally file. You will need - to configure `tempfile_image_handler`; 'callable': You can set - any Python callable which is called with the image data. You - will need to configure `callable_image_handler`. - """ - ) - - stream_image_handler = List(config=True, help= - """ - Command to invoke an image viewer program when you are using - 'stream' image handler. This option is a list of string where - the first element is the command itself and reminders are the - options for the command. Raw image data is given as STDIN to - the program. - """ - ) - - tempfile_image_handler = List(config=True, help= - """ - Command to invoke an image viewer program when you are using - 'tempfile' image handler. This option is a list of string - where the first element is the command itself and reminders - are the options for the command. You can use {file} and - {format} in the string to represent the location of the - generated image file and image format. - """ - ) - - callable_image_handler = Any(config=True, help= - """ - Callable object called via 'callable' image handler with one - argument, `data`, which is `msg["content"]["data"]` where - `msg` is the message from iopub channel. For exmaple, you can - find base64 encoded PNG data as `data['image/png']`. - """ - ) - - mime_preference = List( - default_value=['image/png', 'image/jpeg', 'image/svg+xml'], - config=True, help= - """ - Preferred object representation MIME type in order. First - matched MIME type will be used. - """ - ) - - manager = Instance('IPython.kernel.KernelManager', allow_none=True) - client = Instance('IPython.kernel.KernelClient', allow_none=True) - def _client_changed(self, name, old, new): - self.session_id = new.session.session - session_id = Unicode() - - def init_completer(self): - """Initialize the completion machinery. - - This creates completion machinery that can be used by client code, - either interactively in-process (typically triggered by the readline - library), programmatically (such as in test suites) or out-of-process - (typically over the network by remote frontends). - """ - from IPython.core.completerlib import (module_completer, - magic_run_completer, cd_completer) - - self.Completer = ZMQCompleter(self, self.client, config=self.config) - - - self.set_hook('complete_command', module_completer, str_key = 'import') - self.set_hook('complete_command', module_completer, str_key = 'from') - self.set_hook('complete_command', magic_run_completer, str_key = '%run') - self.set_hook('complete_command', cd_completer, str_key = '%cd') - - # Only configure readline if we truly are using readline. IPython can - # do tab-completion over the network, in GUIs, etc, where readline - # itself may be absent - if self.has_readline: - self.set_readline_completer() - - def run_cell(self, cell, store_history=True): - """Run a complete IPython cell. - - Parameters - ---------- - cell : str - The code (including IPython code such as %magic functions) to run. - store_history : bool - If True, the raw and translated cell will be stored in IPython's - history. For user code calling back into IPython's machinery, this - should be set to False. - """ - if (not cell) or cell.isspace(): - # pressing enter flushes any pending display - self.handle_iopub() - return - - # flush stale replies, which could have been ignored, due to missed heartbeats - while self.client.shell_channel.msg_ready(): - self.client.shell_channel.get_msg() - # execute takes 'hidden', which is the inverse of store_hist - msg_id = self.client.execute(cell, not store_history) - - # first thing is wait for any side effects (output, stdin, etc.) - self._executing = True - self._execution_state = "busy" - while self._execution_state != 'idle' and self.client.is_alive(): - try: - self.handle_input_request(msg_id, timeout=0.05) - except Empty: - # display intermediate print statements, etc. - self.handle_iopub(msg_id) - except ZMQError as e: - # Carry on if polling was interrupted by a signal - if e.errno != errno.EINTR: - raise - - # after all of that is done, wait for the execute reply - while self.client.is_alive(): - try: - self.handle_execute_reply(msg_id, timeout=0.05) - except Empty: - pass - else: - break - self._executing = False - - #----------------- - # message handlers - #----------------- - - def handle_execute_reply(self, msg_id, timeout=None): - msg = self.client.shell_channel.get_msg(block=False, timeout=timeout) - if msg["parent_header"].get("msg_id", None) == msg_id: - - self.handle_iopub(msg_id) - - content = msg["content"] - status = content['status'] - - if status == 'aborted': - self.write('Aborted\n') - return - elif status == 'ok': - # handle payloads - for item in content["payload"]: - source = item['source'] - if source == 'page': - page.page(item['data']['text/plain']) - elif source == 'set_next_input': - self.set_next_input(item['text']) - elif source == 'ask_exit': - self.ask_exit() - - elif status == 'error': - for frame in content["traceback"]: - print(frame, file=io.stderr) - - self.execution_count = int(content["execution_count"] + 1) - - include_other_output = Bool(False, config=True, - help="""Whether to include output from clients - other than this one sharing the same kernel. - - Outputs are not displayed until enter is pressed. - """ - ) - other_output_prefix = Unicode("[remote] ", config=True, - help="""Prefix to add to outputs coming from clients other than this one. - - Only relevant if include_other_output is True. - """ - ) - - def from_here(self, msg): - """Return whether a message is from this session""" - return msg['parent_header'].get("session", self.session_id) == self.session_id - - def include_output(self, msg): - """Return whether we should include a given output message""" - from_here = self.from_here(msg) - if msg['msg_type'] == 'execute_input': - # only echo inputs not from here - return self.include_other_output and not from_here - - if self.include_other_output: - return True - else: - return from_here - - def handle_iopub(self, msg_id=''): - """Process messages on the IOPub channel - - This method consumes and processes messages on the IOPub channel, - such as stdout, stderr, execute_result and status. - - It only displays output that is caused by this session. - """ - while self.client.iopub_channel.msg_ready(): - sub_msg = self.client.iopub_channel.get_msg() - msg_type = sub_msg['header']['msg_type'] - parent = sub_msg["parent_header"] - - if self.include_output(sub_msg): - if msg_type == 'status': - self._execution_state = sub_msg["content"]["execution_state"] - elif msg_type == 'stream': - if sub_msg["content"]["name"] == "stdout": - if self._pending_clearoutput: - print("\r", file=io.stdout, end="") - self._pending_clearoutput = False - print(sub_msg["content"]["text"], file=io.stdout, end="") - io.stdout.flush() - elif sub_msg["content"]["name"] == "stderr": - if self._pending_clearoutput: - print("\r", file=io.stderr, end="") - self._pending_clearoutput = False - print(sub_msg["content"]["text"], file=io.stderr, end="") - io.stderr.flush() - - elif msg_type == 'execute_result': - if self._pending_clearoutput: - print("\r", file=io.stdout, end="") - self._pending_clearoutput = False - self.execution_count = int(sub_msg["content"]["execution_count"]) - if not self.from_here(sub_msg): - sys.stdout.write(self.other_output_prefix) - format_dict = sub_msg["content"]["data"] - self.handle_rich_data(format_dict) - - # taken from DisplayHook.__call__: - hook = self.displayhook - hook.start_displayhook() - hook.write_output_prompt() - hook.write_format_data(format_dict) - hook.log_output(format_dict) - hook.finish_displayhook() - - elif msg_type == 'display_data': - data = sub_msg["content"]["data"] - handled = self.handle_rich_data(data) - if not handled: - if not self.from_here(sub_msg): - sys.stdout.write(self.other_output_prefix) - # if it was an image, we handled it by now - if 'text/plain' in data: - print(data['text/plain']) - - elif msg_type == 'execute_input': - content = sub_msg['content'] - self.execution_count = content['execution_count'] - if not self.from_here(sub_msg): - sys.stdout.write(self.other_output_prefix) - sys.stdout.write(self.prompt_manager.render('in')) - sys.stdout.write(content['code']) - - elif msg_type == 'clear_output': - if sub_msg["content"]["wait"]: - self._pending_clearoutput = True - else: - print("\r", file=io.stdout, end="") - - _imagemime = { - 'image/png': 'png', - 'image/jpeg': 'jpeg', - 'image/svg+xml': 'svg', - } - - def handle_rich_data(self, data): - for mime in self.mime_preference: - if mime in data and mime in self._imagemime: - self.handle_image(data, mime) - return True - - def handle_image(self, data, mime): - handler = getattr( - self, 'handle_image_{0}'.format(self.image_handler), None) - if handler: - handler(data, mime) - - def handle_image_PIL(self, data, mime): - if mime not in ('image/png', 'image/jpeg'): - return - import PIL.Image - raw = base64.decodestring(data[mime].encode('ascii')) - img = PIL.Image.open(BytesIO(raw)) - img.show() - - def handle_image_stream(self, data, mime): - raw = base64.decodestring(data[mime].encode('ascii')) - imageformat = self._imagemime[mime] - fmt = dict(format=imageformat) - args = [s.format(**fmt) for s in self.stream_image_handler] - with open(os.devnull, 'w') as devnull: - proc = subprocess.Popen( - args, stdin=subprocess.PIPE, - stdout=devnull, stderr=devnull) - proc.communicate(raw) - - def handle_image_tempfile(self, data, mime): - raw = base64.decodestring(data[mime].encode('ascii')) - imageformat = self._imagemime[mime] - filename = 'tmp.{0}'.format(imageformat) - with NamedFileInTemporaryDirectory(filename) as f, \ - open(os.devnull, 'w') as devnull: - f.write(raw) - f.flush() - fmt = dict(file=f.name, format=imageformat) - args = [s.format(**fmt) for s in self.tempfile_image_handler] - subprocess.call(args, stdout=devnull, stderr=devnull) - - def handle_image_callable(self, data, mime): - self.callable_image_handler(data) - - def handle_input_request(self, msg_id, timeout=0.1): - """ Method to capture raw_input - """ - req = self.client.stdin_channel.get_msg(timeout=timeout) - # in case any iopub came while we were waiting: - self.handle_iopub(msg_id) - if msg_id == req["parent_header"].get("msg_id"): - # wrap SIGINT handler - real_handler = signal.getsignal(signal.SIGINT) - def double_int(sig,frame): - # call real handler (forwards sigint to kernel), - # then raise local interrupt, stopping local raw_input - real_handler(sig,frame) - raise KeyboardInterrupt - signal.signal(signal.SIGINT, double_int) - content = req['content'] - read = getpass if content.get('password', False) else input - try: - raw_data = read(content["prompt"]) - except EOFError: - # turn EOFError into EOF character - raw_data = '\x04' - except KeyboardInterrupt: - sys.stdout.write('\n') - return - finally: - # restore SIGINT handler - signal.signal(signal.SIGINT, real_handler) - - # only send stdin reply if there *was not* another request - # or execution finished while we were reading. - if not (self.client.stdin_channel.msg_ready() or self.client.shell_channel.msg_ready()): - self.client.input(raw_data) - - def mainloop(self, display_banner=False): - while True: - try: - self.interact(display_banner=display_banner) - #self.interact_with_readline() - # XXX for testing of a readline-decoupled repl loop, call - # interact_with_readline above - break - except KeyboardInterrupt: - # this should not be necessary, but KeyboardInterrupt - # handling seems rather unpredictable... - self.write("\nKeyboardInterrupt in interact()\n") - - self.client.shutdown() - - def _banner1_default(self): - return "IPython Console {version}\n".format(version=release.version) - - def compute_banner(self): - super(ZMQTerminalInteractiveShell, self).compute_banner() - if self.client and not self.kernel_banner: - msg_id = self.client.kernel_info() - while True: - try: - reply = self.client.get_shell_msg(timeout=1) - except Empty: - break - else: - if reply['parent_header'].get('msg_id') == msg_id: - self.kernel_banner = reply['content'].get('banner', '') - break - self.banner += self.kernel_banner - - def wait_for_kernel(self, timeout=None): - """method to wait for a kernel to be ready""" - tic = time.time() - self.client.hb_channel.unpause() - while True: - msg_id = self.client.kernel_info() - reply = None - while True: - try: - reply = self.client.get_shell_msg(timeout=1) - except Empty: - break - else: - if reply['parent_header'].get('msg_id') == msg_id: - return True - if timeout is not None \ - and (time.time() - tic) > timeout \ - and not self.client.hb_channel.is_beating(): - # heart failed - return False - return True - - def interact(self, display_banner=None): - """Closely emulate the interactive Python console.""" - - # batch run -> do not interact - if self.exit_now: - return - - if display_banner is None: - display_banner = self.display_banner - - if isinstance(display_banner, string_types): - self.show_banner(display_banner) - elif display_banner: - self.show_banner() - - more = False - - # run a non-empty no-op, so that we don't get a prompt until - # we know the kernel is ready. This keeps the connection - # message above the first prompt. - if not self.wait_for_kernel(self.kernel_timeout): - error("Kernel did not respond\n") - return - - if self.has_readline: - self.readline_startup_hook(self.pre_readline) - hlen_b4_cell = self.readline.get_current_history_length() - else: - hlen_b4_cell = 0 - # exit_now is set by a call to %Exit or %Quit, through the - # ask_exit callback. - - while not self.exit_now: - if not self.client.is_alive(): - # kernel died, prompt for action or exit - - action = "restart" if self.manager else "wait for restart" - ans = self.ask_yes_no("kernel died, %s ([y]/n)?" % action, default='y') - if ans: - if self.manager: - self.manager.restart_kernel(True) - self.wait_for_kernel(self.kernel_timeout) - else: - self.exit_now = True - continue - try: - # protect prompt block from KeyboardInterrupt - # when sitting on ctrl-C - self.hooks.pre_prompt_hook() - if more: - try: - prompt = self.prompt_manager.render('in2') - except Exception: - self.showtraceback() - if self.autoindent: - self.rl_do_indent = True - - else: - try: - prompt = self.separate_in + self.prompt_manager.render('in') - except Exception: - self.showtraceback() - - line = self.raw_input(prompt) - if self.exit_now: - # quick exit on sys.std[in|out] close - break - if self.autoindent: - self.rl_do_indent = False - - except KeyboardInterrupt: - #double-guard against keyboardinterrupts during kbdint handling - try: - self.write('\n' + self.get_exception_only()) - source_raw = self.input_splitter.raw_reset() - hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell) - more = False - except KeyboardInterrupt: - pass - except EOFError: - if self.autoindent: - self.rl_do_indent = False - if self.has_readline: - self.readline_startup_hook(None) - self.write('\n') - self.exit() - except bdb.BdbQuit: - warn('The Python debugger has exited with a BdbQuit exception.\n' - 'Because of how pdb handles the stack, it is impossible\n' - 'for IPython to properly format this particular exception.\n' - 'IPython will resume normal operation.') - except: - # exceptions here are VERY RARE, but they can be triggered - # asynchronously by signal handlers, for example. - self.showtraceback() - else: - try: - self.input_splitter.push(line) - more = self.input_splitter.push_accepts_more() - except SyntaxError: - # Run the code directly - run_cell takes care of displaying - # the exception. - more = False - if (self.SyntaxTB.last_syntax_error and - self.autoedit_syntax): - self.edit_syntax_error() - if not more: - source_raw = self.input_splitter.raw_reset() - hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell) - self.run_cell(source_raw) - - - # Turn off the exit flag, so the mainloop can be restarted if desired - self.exit_now = False - - def init_history(self): - """Sets up the command history. """ - self.history_manager = ZMQHistoryManager(client=self.client) - self.configurables.append(self.history_manager) - diff --git a/jupyter_console/tests/__init__.py b/jupyter_console/tests/__init__.py deleted file mode 100644 index e69de29..0000000 --- a/jupyter_console/tests/__init__.py +++ /dev/null diff --git a/jupyter_console/tests/test_console.py b/jupyter_console/tests/test_console.py deleted file mode 100644 index e7bc884..0000000 --- a/jupyter_console/tests/test_console.py +++ /dev/null @@ -1,64 +0,0 @@ -"""Tests for two-process terminal frontend""" - -# Copyright (c) Jupyter Development Team. -# Distributed under the terms of the Modified BSD License. - -import sys - -from nose import SkipTest - -from traitlets.tests.utils import check_help_all_output -from IPython.testing import decorators as dec - -@dec.skip_win32 -def test_console_starts(): - """test that `ipython console` starts a terminal""" - p, pexpect, t = start_console() - p.sendline('5') - idx = p.expect([r'Out\[\d+\]: 5', pexpect.EOF], timeout=t) - idx = p.expect([r'In \[\d+\]', pexpect.EOF], timeout=t) - stop_console(p, pexpect, t) - -def test_help_output(): - """ipython console --help-all works""" - check_help_all_output('jupyter_console') - -def test_display_text(): - "Ensure display protocol plain/text key is supported" - # equivalent of: - # - # x = %lsmagic - # from IPython.display import display; display(x); - p, pexpect, t = start_console() - p.sendline('x = %lsmagic') - idx = p.expect([r'In \[\d+\]', pexpect.EOF], timeout=t) - p.sendline('from IPython.display import display; display(x);') - p.expect([r'Available line magics:', pexpect.EOF], timeout=t) - stop_console(p, pexpect, t) - -def stop_console(p, pexpect, t): - "Stop a running `ipython console` running via pexpect" - # send ctrl-D;ctrl-D to exit - p.sendeof() - p.sendeof() - p.expect([pexpect.EOF, pexpect.TIMEOUT], timeout=t) - if p.isalive(): - p.terminate() - - -def start_console(): - "Start `ipython console` using pexpect" - import pexpect - - args = ['-m', 'IPython', 'console', '--colors=NoColor'] - cmd = sys.executable - - try: - p = pexpect.spawn(cmd, args=args) - except IOError: - raise SkipTest("Couldn't find command %s" % cmd) - - # timeout after one minute - t = 60 - idx = p.expect([r'In \[\d+\]', pexpect.EOF], timeout=t) - return p, pexpect, t diff --git a/jupyter_console/tests/test_image_handler.py b/jupyter_console/tests/test_image_handler.py deleted file mode 100644 index 26c92e5..0000000 --- a/jupyter_console/tests/test_image_handler.py +++ /dev/null @@ -1,94 +0,0 @@ -# Copyright (c) IPython Development Team. -# Distributed under the terms of the Modified BSD License. - -import os -import sys -import unittest -import base64 - -try: - from unittest.mock import patch -except ImportError: - from mock import patch - -from IPython.kernel import KernelClient -from IPython.terminal.console.interactiveshell import ZMQTerminalInteractiveShell -from IPython.utils.tempdir import TemporaryDirectory -from IPython.testing.decorators import skip_without -from IPython.utils.ipstruct import Struct - - -SCRIPT_PATH = os.path.join( - os.path.abspath(os.path.dirname(__file__)), 'writetofile.py') - - -class ZMQTerminalInteractiveShellTestCase(unittest.TestCase): - - def setUp(self): - client = KernelClient() - self.shell = ZMQTerminalInteractiveShell(kernel_client=client) - self.raw = b'dummy data' - self.mime = 'image/png' - self.data = {self.mime: base64.encodestring(self.raw).decode('ascii')} - - def test_no_call_by_default(self): - def raise_if_called(*args, **kwds): - assert False - - shell = self.shell - shell.handle_image_PIL = raise_if_called - shell.handle_image_stream = raise_if_called - shell.handle_image_tempfile = raise_if_called - shell.handle_image_callable = raise_if_called - - shell.handle_image(None, None) # arguments are dummy - - @skip_without('PIL') - def test_handle_image_PIL(self): - import PIL.Image - - open_called_with = [] - show_called_with = [] - - def fake_open(arg): - open_called_with.append(arg) - return Struct(show=lambda: show_called_with.append(None)) - - with patch.object(PIL.Image, 'open', fake_open): - self.shell.handle_image_PIL(self.data, self.mime) - - self.assertEqual(len(open_called_with), 1) - self.assertEqual(len(show_called_with), 1) - self.assertEqual(open_called_with[0].getvalue(), self.raw) - - def check_handler_with_file(self, inpath, handler): - shell = self.shell - configname = '{0}_image_handler'.format(handler) - funcname = 'handle_image_{0}'.format(handler) - - assert hasattr(shell, configname) - assert hasattr(shell, funcname) - - with TemporaryDirectory() as tmpdir: - outpath = os.path.join(tmpdir, 'data') - cmd = [sys.executable, SCRIPT_PATH, inpath, outpath] - setattr(shell, configname, cmd) - getattr(shell, funcname)(self.data, self.mime) - # cmd is called and file is closed. So it's safe to open now. - with open(outpath, 'rb') as file: - transferred = file.read() - - self.assertEqual(transferred, self.raw) - - def test_handle_image_stream(self): - self.check_handler_with_file('-', 'stream') - - def test_handle_image_tempfile(self): - self.check_handler_with_file('{file}', 'tempfile') - - def test_handle_image_callable(self): - called_with = [] - self.shell.callable_image_handler = called_with.append - self.shell.handle_image_callable(self.data, self.mime) - self.assertEqual(len(called_with), 1) - assert called_with[0] is self.data diff --git a/jupyter_console/tests/writetofile.py b/jupyter_console/tests/writetofile.py deleted file mode 100644 index a6f9e28..0000000 --- a/jupyter_console/tests/writetofile.py +++ /dev/null @@ -1,33 +0,0 @@ -#----------------------------------------------------------------------------- -# Copyright (C) 2012 The IPython Development Team -# -# Distributed under the terms of the BSD License. The full license is in -# the file COPYING, distributed as part of this software. -#----------------------------------------------------------------------------- - -""" -Copy data from input file to output file for testing. - -Command line usage: - - python writetofile.py INPUT OUTPUT - -Binary data from INPUT file is copied to OUTPUT file. -If INPUT is '-', stdin is used. - -""" - -if __name__ == '__main__': - import sys - from IPython.utils.py3compat import PY3 - (inpath, outpath) = sys.argv[1:] - - if inpath == '-': - if PY3: - infile = sys.stdin.buffer - else: - infile = sys.stdin - else: - infile = open(inpath, 'rb') - - open(outpath, 'w+b').write(infile.read()) diff --git a/jupyter_console/zmqhistory.py b/jupyter_console/zmqhistory.py deleted file mode 100644 index 9384a39..0000000 --- a/jupyter_console/zmqhistory.py +++ /dev/null @@ -1,95 +0,0 @@ -""" ZMQ Kernel History accessor and manager. """ -#----------------------------------------------------------------------------- -# Copyright (C) 2010-2011 The IPython Development Team. -# -# Distributed under the terms of the BSD License. -# -# The full license is in the file COPYING.txt, distributed with this software. -#----------------------------------------------------------------------------- - -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from IPython.core.history import HistoryAccessorBase -from IPython.utils.traitlets import Dict, List - -try: - from queue import Empty # Py 3 -except ImportError: - from Queue import Empty # Py 2 - -class ZMQHistoryManager(HistoryAccessorBase): - """History accessor and manager for ZMQ-based kernels""" - input_hist_parsed = List([""]) - output_hist = Dict() - dir_hist = List() - output_hist_reprs = Dict() - - def __init__(self, client): - """ - Class to load the command-line history from a ZMQ-based kernel, - and access the history. - - Parameters - ---------- - - client: `IPython.kernel.KernelClient` - The kernel client in order to request the history. - """ - self.client = client - - def _load_history(self, raw=True, output=False, hist_access_type='range', - **kwargs): - """ - Load the history over ZMQ from the kernel. Wraps the history - messaging with loop to wait to get history results. - """ - history = [] - if hasattr(self.client, "history"): - ## In tests, KernelClient may not have a history method - msg_id = self.client.history(raw=raw, output=output, - hist_access_type=hist_access_type, - **kwargs) - while True: - try: - reply = self.client.get_shell_msg(timeout=1) - except Empty: - break - else: - if reply['parent_header'].get('msg_id') == msg_id: - history = reply['content'].get('history', []) - break - return history - - def get_tail(self, n=10, raw=True, output=False, include_latest=False): - return self._load_history(hist_access_type='tail', n=n, raw=raw, - output=output) - - def search(self, pattern="*", raw=True, search_raw=True, - output=False, n=None, unique=False): - return self._load_history(hist_access_type='search', pattern=pattern, - raw=raw, search_raw=search_raw, - output=output, n=n, unique=unique) - - def get_range(self, session, start=1, stop=None, raw=True,output=False): - return self._load_history(hist_access_type='range', raw=raw, - output=output, start=start, stop=stop, - session=session) - - def get_range_by_str(self, rangestr, raw=True, output=False): - return self._load_history(hist_access_type='range', raw=raw, - output=output, rangestr=rangestr) - - def end_session(self): - """ - Nothing to do for ZMQ-based histories. - """ - pass - - def reset(self, new_session=True): - """ - Nothing to do for ZMQ-based histories. - """ - pass -