Hello community, here is the log from the commit of package python3-jupyter_console for openSUSE:Factory checked in at 2016-02-01 19:57:27 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-jupyter_console (Old) and /work/SRC/openSUSE:Factory/.python3-jupyter_console.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python3-jupyter_console" Changes: -------- --- /work/SRC/openSUSE:Factory/python3-jupyter_console/python3-jupyter_console.changes 2015-10-14 16:45:16.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python3-jupyter_console.new/python3-jupyter_console.changes 2016-02-01 19:57:43.000000000 +0100 @@ -1,0 +2,13 @@ +Sat Jan 16 23:47:08 UTC 2016 - a...@gmx.de + +- specfile: + * update copyright year + +- update to version 4.1.0: + * readline/completion fixes + * use is_complete messages to determine if input is complete + (important for non-Python kernels) + * fix: 4.0 was looking for jupyter_console_config in IPython config + directories, not Jupyter + +------------------------------------------------------------------- Old: ---- jupyter_console-4.0.3.tar.gz New: ---- jupyter_console-4.1.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-jupyter_console.spec ++++++ --- /var/tmp/diff_new_pack.SgrqEj/_old 2016-02-01 19:57:44.000000000 +0100 +++ /var/tmp/diff_new_pack.SgrqEj/_new 2016-02-01 19:57:44.000000000 +0100 @@ -1,7 +1,7 @@ # # spec file for package python3-jupyter_console # -# Copyright (c) 2015 SUSE LINUX GmbH, Nuernberg, Germany. +# Copyright (c) 2016 SUSE LINUX GmbH, Nuernberg, Germany. # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -17,7 +17,7 @@ Name: python3-jupyter_console -Version: 4.0.3 +Version: 4.1.0 Release: 0 Summary: Jupyter terminal console License: BSD-3-Clause @@ -50,6 +50,7 @@ %package doc-html Summary: HTML documentation for %{name} +Group: Development/Languages/Python Recommends: %{name} = %{version} %description doc-html @@ -57,6 +58,7 @@ %package doc-pdf Summary: HTML documentation for %{name} +Group: Development/Languages/Python Recommends: %{name} = %{version} %description doc-pdf ++++++ jupyter_console-4.0.3.tar.gz -> jupyter_console-4.1.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_console-4.0.3/PKG-INFO new/jupyter_console-4.1.0/PKG-INFO --- old/jupyter_console-4.0.3/PKG-INFO 2015-10-07 13:37:49.000000000 +0200 +++ new/jupyter_console-4.1.0/PKG-INFO 2016-01-13 13:02:30.000000000 +0100 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: jupyter_console -Version: 4.0.3 +Version: 4.1.0 Summary: Jupyter terminal console Home-page: https://jupyter.org Author: Jupyter Development Team diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_console-4.0.3/README.md new/jupyter_console-4.1.0/README.md --- old/jupyter_console-4.0.3/README.md 2015-07-16 00:56:24.000000000 +0200 +++ new/jupyter_console-4.1.0/README.md 2016-01-13 11:59:23.000000000 +0100 @@ -1,6 +1,8 @@ # Jupyter Console +[![Build Status](https://travis-ci.org/jupyter/jupyter_console.svg?branch=master)](https://travis-ci.org/jupyter/jupyter_console) +[![Documentation Status](http://readthedocs.org/projects/jupyter-console/badge/?version=latest)](http://jupyter-console.readthedocs.org/en/latest/?badge=latest) -A terminal-based console frontend for Jupter kernels. +A terminal-based console frontend for Jupyter kernels. This code is based on the single-process IPython terminal. Install: @@ -15,3 +17,9 @@ jupyter console -h +## Resources +- [Project Jupyter website](https://jupyter.org) +- [Documentation for Jupyter Console](http://jupyter-console.readthedocs.org/en/latest/) [[PDF](https://media.readthedocs.org/pdf/jupyter-console/latest/jupyter-notebook.pdf)] +- [Documentation for Project Jupyter](http://jupyter.readthedocs.org/en/latest/index.html) [[PDF](https://media.readthedocs.org/pdf/jupyter/latest/jupyter.pdf)] +- [Issues](https://github.com/jupyter/jupyter_console/issues) +- [Technical support - Jupyter Google Group](https://groups.google.com/forum/#!forum/jupyter) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_console-4.0.3/docs/changelog.rst new/jupyter_console-4.1.0/docs/changelog.rst --- old/jupyter_console-4.0.3/docs/changelog.rst 2015-10-07 13:07:11.000000000 +0200 +++ new/jupyter_console-4.1.0/docs/changelog.rst 2016-01-13 11:59:25.000000000 +0100 @@ -3,6 +3,17 @@ A summary of changes in Jupyter console releases. +4.1 +--- + +4.1.0 +~~~~~ + +- readline/completion fixes +- use is_complete messages to determine if input is complete (important for non-Python kernels) +- fix: 4.0 was looking for jupyter_console_config in IPython config directories, not Jupyter + + 4.0 --- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_console-4.0.3/jupyter_console/_version.py new/jupyter_console-4.1.0/jupyter_console/_version.py --- old/jupyter_console-4.0.3/jupyter_console/_version.py 2015-10-07 13:35:59.000000000 +0200 +++ new/jupyter_console-4.1.0/jupyter_console/_version.py 2016-01-13 13:01:53.000000000 +0100 @@ -1,2 +1,2 @@ -version_info = (4, 0, 3) +version_info = (4, 1, 0) __version__ = '.'.join(map(str, version_info)) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_console-4.0.3/jupyter_console/app.py new/jupyter_console-4.1.0/jupyter_console/app.py --- old/jupyter_console-4.0.3/jupyter_console/app.py 2015-10-07 13:02:41.000000000 +0200 +++ new/jupyter_console-4.1.0/jupyter_console/app.py 2016-01-13 11:59:23.000000000 +0100 @@ -7,13 +7,13 @@ # Copyright (c) IPython Development Team. # Distributed under the terms of the Modified BSD License. +import logging import signal -from IPython.terminal.ipapp import TerminalIPythonApp, frontend_flags as term_flags - from traitlets import ( Dict, Any ) +from traitlets.config import catch_config_error from IPython.utils.warn import error from jupyter_core.application import JupyterApp, base_aliases, base_flags, NoStart @@ -41,10 +41,6 @@ flags = dict(base_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) @@ -67,7 +63,7 @@ #----------------------------------------------------------------------------- -class ZMQTerminalIPythonApp(TerminalIPythonApp, JupyterApp, JupyterConsoleApp): +class ZMQTerminalIPythonApp(JupyterApp, JupyterConsoleApp): name = "jupyter-console" version = __version__ """Start a terminal frontend to the IPython zmq kernel.""" @@ -88,7 +84,6 @@ """ examples = _examples - _config_file_name_default = JupyterApp._config_file_name_default classes = [ZMQTerminalInteractiveShell] + JupyterConsoleApp.classes flags = Dict(flags) @@ -105,14 +100,11 @@ self.build_kernel_argv(self.extra_args) def init_shell(self): - if self._dispatching: - raise NoStart() JupyterConsoleApp.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, + display_banner=False, manager=self.kernel_manager, client=self.kernel_client, ) @@ -125,12 +117,7 @@ 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 + self.kernel_manager.interrupt_kernel() else: self.shell.write_err('\n') error("Cannot interrupt kernels we didn't start.\n") @@ -138,21 +125,29 @@ # raise the KeyboardInterrupt if we aren't waiting for execution, # so that the interact loop advances, and prompt is redrawn, etc. raise KeyboardInterrupt - - def initialize(self, argv=None): - try: - super(ZMQTerminalIPythonApp, self).initialize(argv) - except NoStart: - pass - def init_code(self): - # no-op in the frontend, code gets run in the backend - pass + @catch_config_error + def initialize(self, argv=None): + """Do actions after construct, but before starting the app.""" + super(ZMQTerminalIPythonApp, self).initialize(argv) + if self._dispatching: + return + # create the shell + self.init_shell() + # and draw the banner + self.init_banner() + + def init_banner(self): + """optionally display the banner""" + self.shell.show_banner() + # Make sure there is a space below the banner. + if self.log_level <= logging.INFO: print() def start(self): # JupyterApp.start dispatches on NoStart - JupyterApp.start(self) super(ZMQTerminalIPythonApp, self).start() + self.log.debug("Starting the jupyter console mainloop...") + self.shell.mainloop() main = launch_new_instance = ZMQTerminalIPythonApp.launch_instance diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_console-4.0.3/jupyter_console/interactiveshell.py new/jupyter_console-4.1.0/jupyter_console/interactiveshell.py --- old/jupyter_console-4.0.3/jupyter_console/interactiveshell.py 2015-08-28 00:12:10.000000000 +0200 +++ new/jupyter_console-4.1.0/jupyter_console/interactiveshell.py 2016-01-13 11:59:23.000000000 +0100 @@ -109,12 +109,32 @@ """ ) + use_kernel_is_complete = Bool(True, config=True, + help="""Whether to use the kernel's is_complete message + handling. If False, then the frontend will use its + own is_complete handler. + """ + ) + kernel_is_complete_timeout = Float(1, config=True, + help="""Timeout (in seconds) for giving up on a kernel's is_complete + response. + + If the kernel does not respond at any point within this time, + the kernel will no longer be asked if code is complete, and the + console will default to the built-in is_complete test. + """ + ) + manager = Instance('jupyter_client.KernelManager', allow_none=True) client = Instance('jupyter_client.KernelClient', allow_none=True) def _client_changed(self, name, old, new): self.session_id = new.session.session session_id = Unicode() + def __init__(self, *args, **kwargs): + super(ZMQTerminalInteractiveShell, self).__init__(*args, **kwargs) + self._source_lines_buffered = [] + def init_completer(self): """Initialize the completion machinery. @@ -220,6 +240,43 @@ self.execution_count = int(content["execution_count"] + 1) + def handle_is_complete_reply(self, msg_id, timeout=None): + """ + Wait for a repsonse from the kernel, and return two values: + more? - (boolean) should the frontend ask for more input + indent - an indent string to prefix the input + Overloaded methods may want to examine the comeplete source. Its is + in the self._source_lines_buffered list. + """ + ## Get the is_complete response: + msg = None + try: + msg = self.client.shell_channel.get_msg(block=True, timeout=timeout) + except Empty: + warn('The kernel did not respond to an is_complete_request. ' + 'Setting `use_kernel_is_complete` to False.') + self.use_kernel_is_complete = False + return False, "" + ## Handle response: + if msg["parent_header"].get("msg_id", None) != msg_id: + warn('The kernel did not respond properly to an is_complete_request: %s.' % str(msg)) + return False, "" + else: + status = msg["content"].get("status", None) + indent = msg["content"].get("indent", "") + ## Return more? and indent string + if status == "complete": + return False, indent + elif status == "incomplete": + return True, indent + elif status == "invalid": + raise SyntaxError() + elif status == "unknown": + return False, indent + else: + warn('The kernel sent an invalid is_complete_reply status: "%s".' % status) + return False, indent + include_other_output = Bool(False, config=True, help="""Whether to include output from clients other than this one sharing the same kernel. @@ -396,6 +453,9 @@ signal.signal(signal.SIGINT, double_int) content = req['content'] read = getpass if content.get('password', False) else input + if self.has_readline: + # Disable tab completion while we prompt for arbitrary input + self.readline.set_completer(None) try: raw_data = read(content["prompt"]) except EOFError: @@ -407,6 +467,9 @@ finally: # restore SIGINT handler signal.signal(signal.SIGINT, real_handler) + # Restore tab completion ready for our next input prompt + if self.has_readline: + self.set_readline_completer() # only send stdin reply if there *was not* another request # or execution finished while we were reading. @@ -476,6 +539,11 @@ return False return True + _next_line_indent = '' + + def _indent_current_str(self): + return self._next_line_indent + def interact(self, display_banner=None): """Closely emulate the interactive Python console.""" @@ -503,6 +571,7 @@ if self.has_readline: self.readline_startup_hook(self.pre_readline) hlen_b4_cell = self.readline.get_current_history_length() + self.refill_readline_hist() else: hlen_b4_cell = 0 # exit_now is set by a call to %Exit or %Quit, through the @@ -534,6 +603,7 @@ self.rl_do_indent = True else: + self._next_line_indent = '' try: prompt = self.separate_in + self.prompt_manager.render('in') except Exception: @@ -550,7 +620,7 @@ #double-guard against keyboardinterrupts during kbdint handling try: self.write('\n' + self.get_exception_only()) - source_raw = self.input_splitter.raw_reset() + source_raw = self.get_source_and_reset() hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell) more = False except KeyboardInterrupt: @@ -573,8 +643,7 @@ self.showtraceback() else: try: - self.input_splitter.push(line) - more = self.input_splitter.push_accepts_more() + more, indent = self.handle_source(line) except SyntaxError: # Run the code directly - run_cell takes care of displaying # the exception. @@ -582,8 +651,10 @@ if (self.SyntaxTB.last_syntax_error and self.autoedit_syntax): self.edit_syntax_error() + if more: + self._next_line_indent = indent if not more: - source_raw = self.input_splitter.raw_reset() + source_raw = self.get_source_and_reset() hlen_b4_cell = self._replace_rlhist_multiline(source_raw, hlen_b4_cell) self.run_cell(source_raw) @@ -596,3 +667,23 @@ self.history_manager = ZMQHistoryManager(client=self.client) self.configurables.append(self.history_manager) + def get_source_and_reset(self): + """ + Get the source code entered so far, and reset source input line(s). + """ + source, self._source_lines_buffered = self._source_lines_buffered, [] + return "\n".join(source) + + def handle_source(self, line): + """ + Save the line with previous source lines, and see if more + input is needed. Returns more? and indent_string. + """ + self._source_lines_buffered.append(line) + ## Ask client if line is complete; get indent for next line: + if self.use_kernel_is_complete: + msg_id = self.client.is_complete("\n".join(self._source_lines_buffered)) + return self.handle_is_complete_reply(msg_id, timeout=self.kernel_is_complete_timeout) + else: + more = (line != "") + return more, "" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_console-4.0.3/jupyter_console/tests/test_image_handler.py new/jupyter_console-4.1.0/jupyter_console/tests/test_image_handler.py --- old/jupyter_console-4.0.3/jupyter_console/tests/test_image_handler.py 2015-07-16 00:56:24.000000000 +0200 +++ new/jupyter_console-4.1.0/jupyter_console/tests/test_image_handler.py 2016-01-13 11:59:23.000000000 +0100 @@ -11,7 +11,7 @@ except ImportError: from mock import patch -from IPython.kernel import KernelClient +from jupyter_client import KernelClient from jupyter_console.interactiveshell import ZMQTerminalInteractiveShell from ipython_genutils.tempdir import TemporaryDirectory from ipython_genutils.testing.decorators import skip_without diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_console-4.0.3/setup.py new/jupyter_console-4.1.0/setup.py --- old/jupyter_console-4.0.3/setup.py 2015-09-01 18:31:57.000000000 +0200 +++ new/jupyter_console-4.1.0/setup.py 2016-01-13 11:59:23.000000000 +0100 @@ -84,6 +84,7 @@ extras_require = setuptools_args['extras_require'] = { 'test:python_version=="2.7"': ['mock'], 'test:sys_platform != "win32"': ['pexpect'], + ':sys_platform == "win32"': ['pyreadline'], }