Hello community, here is the log from the commit of package python3-jupyter_client for openSUSE:Factory checked in at 2015-10-19 22:50:08 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python3-jupyter_client (Old) and /work/SRC/openSUSE:Factory/.python3-jupyter_client.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Package is "python3-jupyter_client" Changes: -------- --- /work/SRC/openSUSE:Factory/python3-jupyter_client/python3-jupyter_client.changes 2015-10-08 08:24:13.000000000 +0200 +++ /work/SRC/openSUSE:Factory/.python3-jupyter_client.new/python3-jupyter_client.changes 2015-10-20 00:04:09.000000000 +0200 @@ -1,0 +2,10 @@ +Sat Oct 10 16:22:42 UTC 2015 - arun@gmx.de + +- update to version 4.1.1: + * Setuptools fixes for jupyter kernelspec + * jupyter kernelspec list includes paths + * add :meth:`KernelManager.blocking_client` + * provisional implementation of comm_info requests from upcoming 5.1 + release of the protocol + +------------------------------------------------------------------- Old: ---- jupyter_client-4.0.0.tar.gz New: ---- jupyter_client-4.1.1.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python3-jupyter_client.spec ++++++ --- /var/tmp/diff_new_pack.Ik1Vq4/_old 2015-10-20 00:04:10.000000000 +0200 +++ /var/tmp/diff_new_pack.Ik1Vq4/_new 2015-10-20 00:04:10.000000000 +0200 @@ -17,7 +17,7 @@ Name: python3-jupyter_client -Version: 4.0.0 +Version: 4.1.1 Release: 0 Summary: Jupyter protocol implementation and client libraries License: BSD-3-Clause @@ -53,6 +53,7 @@ %package doc-html Summary: HTML documentation for %{name} +Group: Development/Languages/Python Recommends: %{name} = %{version} %description doc-html @@ -60,6 +61,7 @@ %package doc-pdf Summary: HTML documentation for %{name} +Group: Development/Languages/Python Recommends: %{name} = %{version} %description doc-pdf ++++++ jupyter_client-4.0.0.tar.gz -> jupyter_client-4.1.1.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/MANIFEST.in new/jupyter_client-4.1.1/MANIFEST.in --- old/jupyter_client-4.0.0/MANIFEST.in 2015-04-09 09:15:10.000000000 +0200 +++ new/jupyter_client-4.1.1/MANIFEST.in 1970-01-01 01:00:00.000000000 +0100 @@ -1,22 +0,0 @@ -include COPYING.md -include CONTRIBUTING.md -include README.md - -# Documentation -graft docs -exclude docs/\#* - -# Examples -graft examples - -# docs subdirs we want to skip -prune docs/build -prune docs/gh-pages -prune docs/dist - -# Patterns to exclude from any directory -global-exclude *~ -global-exclude *.pyc -global-exclude *.pyo -global-exclude .git -global-exclude .ipynb_checkpoints diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/PKG-INFO new/jupyter_client-4.1.1/PKG-INFO --- old/jupyter_client-4.0.0/PKG-INFO 2015-07-12 20:44:34.000000000 +0200 +++ new/jupyter_client-4.1.1/PKG-INFO 2015-10-08 13:41:25.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: jupyter_client -Version: 4.0.0 +Version: 4.1.1 Summary: Jupyter protocol implementation and client libraries Home-page: http://jupyter.org Author: Jupyter Development Team diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/docs/api/client.rst new/jupyter_client-4.1.1/docs/api/client.rst --- old/jupyter_client-4.0.0/docs/api/client.rst 2015-05-29 02:03:06.000000000 +0200 +++ new/jupyter_client-4.1.1/docs/api/client.rst 2015-09-03 11:35:14.000000000 +0200 @@ -18,6 +18,8 @@ .. automethod:: history + .. automethod:: comm_info + .. automethod:: is_complete .. automethod:: input diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/docs/api/index.rst new/jupyter_client-4.1.1/docs/api/index.rst --- old/jupyter_client-4.0.0/docs/api/index.rst 2015-05-29 02:03:06.000000000 +0200 +++ new/jupyter_client-4.1.1/docs/api/index.rst 2015-09-23 10:59:33.000000000 +0200 @@ -5,6 +5,7 @@ .. toctree:: :maxdepth: 2 + :caption: Jupyter API kernelspec manager diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/docs/api/manager.rst new/jupyter_client-4.1.1/docs/api/manager.rst --- old/jupyter_client-4.0.0/docs/api/manager.rst 2015-05-29 02:03:06.000000000 +0200 +++ new/jupyter_client-4.1.1/docs/api/manager.rst 2015-10-08 10:43:27.000000000 +0200 @@ -26,6 +26,8 @@ For the client API, see :mod:`jupyter_client.client`. + .. automethod:: blocking_client + .. automethod:: shutdown_kernel .. automethod:: restart_kernel @@ -48,3 +50,9 @@ .. automethod:: remove_kernel .. automethod:: shutdown_all + +Utility functions +----------------- + +.. autofunction:: run_kernel + diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/docs/changelog.rst new/jupyter_client-4.1.1/docs/changelog.rst --- old/jupyter_client-4.0.0/docs/changelog.rst 1970-01-01 01:00:00.000000000 +0100 +++ new/jupyter_client-4.1.1/docs/changelog.rst 2015-10-08 11:14:48.000000000 +0200 @@ -0,0 +1,25 @@ +.. _changelog: + +========================= +Changes in Jupyter Client +========================= + +4.1 +=== + +4.1.0 +----- + +`4.1.0 on GitHub https://github.com/jupyter/jupyter_client/milestones/4.1`__ + +Highlights: + +- Setuptools fixes for ``jupyter kernelspec`` +- ``jupyter kernelspec list`` includes paths +- add :meth:`KernelManager.blocking_client` +- provisional implementation of ``comm_info`` requests from upcoming 5.1 release of the protocol + +4.0 +=== + +The first release of Jupyter Client as its own package. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/docs/conf.py new/jupyter_client-4.1.1/docs/conf.py --- old/jupyter_client-4.0.0/docs/conf.py 2015-05-27 04:19:02.000000000 +0200 +++ new/jupyter_client-4.1.1/docs/conf.py 2015-10-08 10:43:27.000000000 +0200 @@ -59,10 +59,16 @@ # |version| and |release|, also used in various other places throughout the # built documents. # +version_ns = {} +here = os.path.dirname(__file__) +version_py = os.path.join(here, os.pardir, 'jupyter_client', '_version.py') +with open(version_py) as f: + exec(compile(f.read(), version_py, 'exec'), version_ns) + # The short X.Y version. -version = '4.0' +version = '%i.%i' % version_ns['version_info'][:2] # The full version, including alpha/beta/rc tags. -release = '4.0' +release = version_ns['__version__'] # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. @@ -142,7 +148,7 @@ # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +#html_static_path = ['_static'] # Add any extra paths that contain custom files (such as robots.txt or # .htaccess) here, relative to this directory. These files are copied diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/docs/index.rst new/jupyter_client-4.1.1/docs/index.rst --- old/jupyter_client-4.0.0/docs/index.rst 2015-05-27 04:19:02.000000000 +0200 +++ new/jupyter_client-4.1.1/docs/index.rst 2015-10-08 10:43:27.000000000 +0200 @@ -1,19 +1,42 @@ -jupyter_client |version| +Jupyter Client |version| ======================== This package provides the Python API for starting, managing and communicating with Jupyter kernels. -Contents: +.. important:: + This document contains the authoritative description of the + Jupyter messaging protocol. All developers are strongly encouraged to + keep it updated as the implementation evolves, so that we have a single + common reference for all protocol details. + .. toctree:: :maxdepth: 2 + :caption: User Documentation messaging + +.. toctree:: + :maxdepth: 2 + :caption: Developer documentation + kernels wrapperkernels + +.. toctree:: + :maxdepth: 2 + :caption: API + api/index +.. toctree:: + :maxdepth: 2 + :caption: Changes + + changelog + + Indices and tables ================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/docs/kernels.rst new/jupyter_client-4.1.1/docs/kernels.rst --- old/jupyter_client-4.0.0/docs/kernels.rst 2015-05-27 04:19:02.000000000 +0200 +++ new/jupyter_client-4.1.1/docs/kernels.rst 2015-09-12 17:22:09.000000000 +0200 @@ -1,3 +1,5 @@ +.. _kernels: + ========================== Making kernels for Jupyter ========================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/docs/messaging.rst new/jupyter_client-4.1.1/docs/messaging.rst --- old/jupyter_client-4.0.0/docs/messaging.rst 2015-06-29 21:54:05.000000000 +0200 +++ new/jupyter_client-4.1.1/docs/messaging.rst 2015-10-08 10:43:27.000000000 +0200 @@ -9,10 +9,9 @@ The ZeroMQ_ library provides the low-level transport layer over which these messages are sent. -.. Note:: - - This document should be considered the authoritative description of the - IPython messaging protocol, and all developers are strongly encouraged to +.. important:: + This document contains the authoritative description of the + IPython messaging protocol. All developers are strongly encouraged to keep it updated as the implementation evolves, so that we have a single common reference for all protocol details. @@ -24,8 +23,9 @@ that use it. The current version of the specification is 5.0. -'New in' and 'Changed in' messages in this document refer to versions of the -message spec, not versions of :mod:`jupyter_client`. +.. note:: + *New in* and *Changed in* messages in this document refer to versions of the + **Jupyter message specification**, not versions of :mod:`jupyter_client`. Introduction ============ @@ -41,13 +41,13 @@ A single kernel can be simultaneously connected to one or more frontends. The kernel has four sockets that serve the following functions: -1. Shell: this single ROUTER socket allows multiple incoming connections from +1. **Shell**: this single ROUTER socket allows multiple incoming connections from frontends, and this is the socket where requests for code execution, object information, prompts, etc. are made to the kernel by any frontend. The communication on this socket is a sequence of request/reply actions from each frontend and the kernel. -2. IOPub: this socket is the 'broadcast channel' where the kernel publishes all +2. **IOPub**: this socket is the 'broadcast channel' where the kernel publishes all side effects (stdout, stderr, etc.) as well as the requests coming from any client over the shell socket and its own requests on the stdin socket. There are a number of actions in Python which generate side effects: :func:`print` @@ -58,7 +58,7 @@ about communications taking place with one client over the shell channel to be made available to all clients in a uniform manner. -3. stdin: this ROUTER socket is connected to all frontends, and it allows +3. **stdin**: this ROUTER socket is connected to all frontends, and it allows the kernel to request input from the active frontend when :func:`raw_input` is called. The frontend that executed the code has a DEALER socket that acts as a 'virtual keyboard' for the kernel while this communication is happening (illustrated in the @@ -72,7 +72,7 @@ which ones are from other clients, so they can display each type appropriately. -4. Control: This channel is identical to Shell, but operates on a separate socket, +4. **Control**: This channel is identical to Shell, but operates on a separate socket, to allow important messages to avoid queueing behind execution requests (e.g. shutdown or abort). The actual format of the messages allowed on each of these channels is @@ -107,6 +107,8 @@ 'msg_id' : uuid, 'username' : str, 'session' : uuid, + # ISO 8601 timestamp for when the message is created + 'date': str, # All recognized message type strings are listed below. 'msg_type' : str, # the message protocol version @@ -116,10 +118,10 @@ # In a chain of messages, the header from the parent is copied so that # clients can track where messages come from. 'parent_header' : dict, - + # Any metadata associated with the message. 'metadata' : dict, - + # The actual content of the message must be a dict, whose structure # depends on the message type. 'content' : dict, @@ -127,7 +129,14 @@ .. versionchanged:: 5.0 - ``version`` key added to the header. + ``version`` key added to the header. + +.. versionchanged:: 5.1 + + ``date`` in the header was accidentally omitted from the spec prior to 5.1, + but it has always been in the canonical implementation, + so implementers are strongly encouraged to include it. + It will be mandatory in 5.1. .. _wire_protocol: @@ -199,7 +208,7 @@ # once: digester = HMAC(key, digestmod=hashlib.sha256) - + # for each message d = digester.copy() for serialized_dict in (header, parent, metadata, content): @@ -345,7 +354,7 @@ Execution results ~~~~~~~~~~~~~~~~~ - + Message type: ``execute_reply``:: content = { @@ -366,7 +375,7 @@ # payloads are considered deprecated. # The only requirement of each payload dict is that it have a 'source' key, # which is a string classifying the payload (e.g. 'page'). - + 'payload' : list(dict), # Results for the user_expressions. @@ -398,12 +407,12 @@ When status is 'abort', there are for now no additional data fields. This happens when the kernel was interrupted by a signal. -Payloads -******** +Payloads (DEPRECATED) +~~~~~~~~~~~~~~~~~~~~~ .. admonition:: Execution payloads - Payloads are considered deprecated, though their replacement is not yet implemented. + Payloads are considered **deprecated**, though their replacement is not yet implemented. Payloads are a way to trigger frontend actions from the kernel. Current payloads: @@ -481,7 +490,7 @@ # The code context in which introspection is requested # this may be up to an entire multiline cell. 'code' : str, - + # The cursor position within 'code' (in unicode characters) where inspection is requested 'cursor_pos' : int, @@ -510,10 +519,10 @@ content = { # 'ok' if the request succeeded or 'error', with error information as in all other replies. 'status' : 'ok', - + # found should be true if an object was found, false otherwise 'found' : bool, - + # data can be empty if nothing is found 'data' : dict, 'metadata' : dict, @@ -539,7 +548,7 @@ # this may be up to an entire multiline cell, such as # 'foo = a.isal' 'code' : str, - + # The cursor position within 'code' (in unicode characters) where completion is requested 'cursor_pos' : int, } @@ -556,15 +565,15 @@ # The list of all matches to the completion request, such as # ['a.isalnum', 'a.isalpha'] for the above example. 'matches' : list, - + # The range of text that should be replaced by the above matches when a completion is accepted. # typically cursor_end is the same as cursor_pos in the request. 'cursor_start' : int, 'cursor_end' : int, - + # Information that frontend plugins might use for extra display information about completions. 'metadata' : dict, - + # status should be 'ok' unless an exception was raised during the request, # in which case it should be 'error', along with the usual error message content # in other messages. @@ -588,7 +597,7 @@ Message type: ``history_request``:: content = { - + # If True, also return output history in the resulting dict. 'output' : bool, @@ -597,7 +606,7 @@ # So far, this can be 'range', 'tail' or 'search'. 'hist_access_type' : str, - + # If hist_access_type is 'range', get a range of input cells. session can # be a positive session number, or a negative number to count back from # the current session. @@ -605,10 +614,10 @@ # start and stop are line numbers within that session. 'start' : int, 'stop' : int, - + # If hist_access_type is 'tail' or 'search', get the last n cells. 'n' : int, - + # If hist_access_type is 'search', get cells matching the specified glob # pattern (with * and ? as wildcards). 'pattern' : str, @@ -616,7 +625,7 @@ # If hist_access_type is 'search' and unique is true, do not # include duplicated history. Default is false. 'unique' : bool, - + } .. versionadded:: 4.0 @@ -670,7 +679,7 @@ content = { # One of 'complete', 'incomplete', 'invalid', 'unknown' 'status' : str, - + # If status is 'incomplete', indent should contain the characters to use # to indent the next line. This is only a hint: frontends may ignore it # and use their own autoindentation rules. For other statuses, this @@ -700,6 +709,37 @@ 'hb_port' : int, # The port the heartbeat socket is listening on. } +.. _msging_comm_info: + +Comm info +--------- + +When a client needs the currently open comms in the kernel, it can issue a +request for the currently open comms. When the optional ``target_name`` is +specified, the reply only contains the currently open comms for the target. + +Message type: ``comm_info_request``:: + + content = { + # Optional, the target name + 'target_name': str, + } + +Message type: ``comm_info_reply``:: + + content = { + # A dictionary of the comms, indexed by uuids. + 'comms': { + comm_id: { + 'target_name': str, + }, + }, + } + +.. versionadded:: 5.1 + + ``comm_info`` is a proposed addition for msgspec v5.1. + .. _msging_kernel_info: Kernel info @@ -740,12 +780,12 @@ # Name of the programming language in which kernel is implemented. # Kernel included in IPython returns 'python'. 'name': str, - + # Language version number. # It is Python version number (e.g., '2.7.3') for the kernel # included in IPython. 'version': 'X.Y.Z', - + # mimetype for script files in this language 'mimetype': str, @@ -783,7 +823,7 @@ .. versionchanged:: 5.0 Versions changed from lists of integers to strings. - + .. versionchanged:: 5.0 ``ipython_version`` is removed. @@ -841,7 +881,7 @@ When the clients detect a dead kernel thanks to inactivity on the heartbeat socket, they simply send a forceful process termination signal, since a dead process is unlikely to respond in any useful way to messages. - + Messages on the PUB/SUB socket ============================== @@ -854,14 +894,14 @@ content = { # The name of the stream is one of 'stdout', 'stderr' 'name' : str, - + # The text is an arbitrary string to be written to that stream 'text' : str, } .. versionchanged:: 5.0 - 'data' key renamed to 'text' for conistency with the notebook format. + 'data' key renamed to 'text' for consistency with the notebook format. Display Data ------------ @@ -1051,7 +1091,7 @@ Extra status messages are added between the notebook webserver and websocket clients that are not sent by the kernel. These are: - + - restarting (kernel has died, but will be automatically restarted) - dead (kernel has died, restarting has failed) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/docs/wrapperkernels.rst new/jupyter_client-4.1.1/docs/wrapperkernels.rst --- old/jupyter_client-4.0.0/docs/wrapperkernels.rst 2015-05-27 04:19:02.000000000 +0200 +++ new/jupyter_client-4.1.1/docs/wrapperkernels.rst 2015-09-12 17:22:09.000000000 +0200 @@ -68,6 +68,8 @@ from ipyernel.kernelapp import IPKernelApp IPKernelApp.launch_instance(kernel_class=MyKernel) +Now create a `JSON kernel spec file http://jupyter-client.readthedocs.org/en/latest/kernels.html#kernel-specs`_ and install it using ``jupyter kernelspec install ``. Place your kernel module anywhere Python can import it (try current directory for testing). Finally, you can run your kernel using ``jupyter console --kernel <mykernelname>``. Note that ``<mykernelname>`` in the below example is ``echo``. + Example ------- @@ -116,7 +118,7 @@ .. class:: MyKernel - .. method:: do_complete(code, cusor_pos) + .. method:: do_complete(code, cursor_pos) Code completion @@ -127,7 +129,7 @@ :ref:`msging_completion` messages - .. method:: do_inspect(code, cusor_pos, detail_level=0) + .. method:: do_inspect(code, cursor_pos, detail_level=0) Object introspection diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client/_version.py new/jupyter_client-4.1.1/jupyter_client/_version.py --- old/jupyter_client-4.0.0/jupyter_client/_version.py 2015-07-12 20:42:25.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client/_version.py 2015-10-08 13:40:39.000000000 +0200 @@ -1,4 +1,4 @@ -version_info = (4, 0, 0) +version_info = (4, 1, 1) __version__ = '.'.join(map(str, version_info)) protocol_version_info = (5, 0) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client/adapter.py new/jupyter_client-4.1.1/jupyter_client/adapter.py --- old/jupyter_client-4.0.0/jupyter_client/adapter.py 2015-05-21 22:24:13.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client/adapter.py 2015-10-08 13:40:15.000000000 +0200 @@ -6,6 +6,8 @@ import re import json +from datetime import datetime + from jupyter_client import protocol_version_info @@ -382,6 +384,8 @@ A Jupyter message appropriate in the new version. """ header = msg['header'] + if 'date' not in header: + header['date'] = datetime.now().isoformat() if 'version' in header: from_version = int(header['version'].split('.')[0]) else: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client/client.py new/jupyter_client-4.1.1/jupyter_client/client.py --- old/jupyter_client-4.0.0/jupyter_client/client.py 2015-07-02 19:45:41.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client/client.py 2015-09-16 17:15:03.000000000 +0200 @@ -60,10 +60,10 @@ hb_channel_class = Type(HBChannelABC) # Protected traits - _shell_channel = Any - _iopub_channel = Any - _stdin_channel = Any - _hb_channel = Any + _shell_channel = Any() + _iopub_channel = Any() + _stdin_channel = Any() + _hb_channel = Any() # flag for whether execute requests should be allowed to call raw_input: allow_stdin = True @@ -345,6 +345,16 @@ self.shell_channel.send(msg) return msg['header']['msg_id'] + def comm_info(self, target_name=None): + """Request comm info.""" + if target_name is None: + content = {} + else: + content = dict(target_name=target_name) + msg = self.session.msg('comm_info_request', content) + self.shell_channel.send(msg) + return msg['header']['msg_id'] + def _handle_kernel_info_reply(self, msg): """handle kernel info reply diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client/connect.py new/jupyter_client-4.1.1/jupyter_client/connect.py --- old/jupyter_client-4.0.0/jupyter_client/connect.py 2015-06-14 00:03:36.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client/connect.py 2015-09-12 17:22:09.000000000 +0200 @@ -26,7 +26,7 @@ from ipython_genutils.py3compat import (str_to_bytes, bytes_to_str, cast_bytes_py2, string_types) from traitlets import ( - Bool, Integer, Unicode, CaselessStrEnum, Instance, + Bool, Integer, Unicode, CaselessStrEnum, Instance, Type, ) from jupyter_core.paths import jupyter_data_dir, jupyter_runtime_dir @@ -334,6 +334,16 @@ key=self.session.key, ) + # factory for blocking clients + blocking_class = Type(klass=object, default_value='jupyter_client.BlockingKernelClient') + def blocking_client(self): + """Make a blocking client connected to my kernel""" + info = self.get_connection_info() + info['parent'] = self + bc = self.blocking_class(**info) + bc.session.key = self.session.key + return bc + def cleanup_connection_file(self): """Cleanup connection file *if we wrote it* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client/consoleapp.py new/jupyter_client-4.1.1/jupyter_client/consoleapp.py --- old/jupyter_client-4.0.0/jupyter_client/consoleapp.py 2015-05-08 23:45:15.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client/consoleapp.py 2015-09-12 22:25:09.000000000 +0200 @@ -21,6 +21,8 @@ Dict, List, Unicode, CUnicode, CBool, Any ) +from jupyter_core.application import base_flags, base_aliases + from .blocking import BlockingKernelClient from . import KernelManager, tunnel_to_kernel, find_connection_file, connect from .kernelspec import NoSuchKernel @@ -35,7 +37,7 @@ #----------------------------------------------------------------------------- flags = {} - +flags.update(base_flags) # the flags that are specific to the frontend # these must be scrubbed before being passed to the kernel, # or it will raise an error on unrecognized flags @@ -55,6 +57,7 @@ flags.update(app_flags) aliases = {} +aliases.update(base_aliases) # also scrub aliases from the frontend app_aliases = dict( @@ -105,7 +108,7 @@ kernel_manager_class = KernelManager kernel_client_class = BlockingKernelClient - kernel_argv = List(Unicode) + kernel_argv = List(Unicode()) # connection info: @@ -319,6 +322,8 @@ Classes which mix this class in should call: JupyterConsoleApp.initialize(self,argv) """ + if self._dispatching: + return self.init_connection_file() self.init_ssh() self.init_kernel_manager() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client/kernelspecapp.py new/jupyter_client-4.1.1/jupyter_client/kernelspecapp.py --- old/jupyter_client-4.0.0/jupyter_client/kernelspecapp.py 2015-07-12 20:42:11.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client/kernelspecapp.py 2015-10-08 11:14:48.000000000 +0200 @@ -34,15 +34,30 @@ return KernelSpecManager(parent=self, data_dir=self.data_dir) def start(self): - specs = self.kernel_spec_manager.find_kernel_specs() + paths = self.kernel_spec_manager.find_kernel_specs() specs = {kname: { - "resources_dir": specs[kname], + "resources_dir": paths[kname], "spec": self.kernel_spec_manager.get_kernel_spec(kname).to_dict() - } for kname in specs} + } for kname in paths} if not self.json_output: + if not specs: + print("No kernels available") + return + # pad to width of longest kernel name + name_len = len(sorted(paths, key=lambda name: len(name))[-1]) + + def path_key(item): + """sort key function for Jupyter path priority""" + path = item[1] + for idx, prefix in enumerate(self.jupyter_path): + if path.startswith(prefix): + return (idx, path) + # not in jupyter path, artificially added to the front + return (-1, path) + print("Available kernels:") - for kernelname, spec in sorted(specs.items()): - print(" %s" % kernelname) + for kernelname, path in sorted(paths.items(), key=path_key): + print(" %s %s" % (kernelname.ljust(name_len), path)) else: print(json.dumps({ 'kernelspecs': specs @@ -52,7 +67,17 @@ class InstallKernelSpec(JupyterApp): version = __version__ - description = """Install a kernel specification directory.""" + description = """Install a kernel specification directory. + + Given a SOURCE DIRECTORY containing a kernel spec, + jupyter will copy that directory into one of the Jupyter kernel directories. + The default is to install kernelspecs for all users. + `--user` can be specified to install a kernel only for the current user. + """ + examples = """ + jupyter kernelspec install /path/to/my_kernel --user + """ + usage = "jupyter kernelspec install SOURCE_DIR [--options]" kernel_spec_manager = Instance(KernelSpecManager) def _kernel_spec_manager_default(self): @@ -114,10 +139,12 @@ ) except OSError as e: if e.errno == errno.EACCES: - print("Permission denied") + print(e, file=sys.stderr) + if not self.user: + print("Perhaps you want to install with `sudo` or `--user`?", file=sys.stderr) self.exit(1) elif e.errno == errno.EEXIST: - print("A kernel spec is already present at %s" % e.filename) + print("A kernel spec is already present at %s" % e.filename, file=sys.stderr) self.exit(1) raise @@ -150,6 +177,11 @@ try: kernelspec.install(self.kernel_spec_manager, user=self.user) except OSError as e: + if e.errno == errno.EACCES: + print(e, file=sys.stderr) + if not self.user: + print("Perhaps you want to install with `sudo` or `--user`?", file=sys.stderr) + self.exit(1) self.exit(e) class KernelSpecApp(Application): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client/launcher.py new/jupyter_client-4.1.1/jupyter_client/launcher.py --- old/jupyter_client-4.0.0/jupyter_client/launcher.py 2015-04-09 08:12:17.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client/launcher.py 2015-09-17 13:35:34.000000000 +0200 @@ -114,6 +114,10 @@ if independent: kwargs['preexec_fn'] = lambda: os.setsid() else: + # Create a new process group. This makes it easier to + # interrupt the kernel, because we want to interrupt the + # children of the kernel process also. + kwargs['preexec_fn'] = lambda: os.setpgrp() env['JPY_PARENT_PID'] = str(os.getpid()) proc = Popen(cmd, **kwargs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client/manager.py new/jupyter_client-4.1.1/jupyter_client/manager.py --- old/jupyter_client-4.0.0/jupyter_client/manager.py 2015-06-18 05:32:27.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client/manager.py 2015-09-17 13:35:34.000000000 +0200 @@ -64,22 +64,25 @@ def _kernel_spec_manager_default(self): return kernelspec.KernelSpecManager(data_dir=self.data_dir) - kernel_name = Unicode(kernelspec.NATIVE_KERNEL_NAME) - - kernel_spec = Instance(kernelspec.KernelSpec) + def _kernel_spec_manager_changed(self): + self._kernel_spec = None - def _kernel_spec_default(self): - return self.kernel_spec_manager.get_kernel_spec(self.kernel_name) + kernel_name = Unicode(kernelspec.NATIVE_KERNEL_NAME) def _kernel_name_changed(self, name, old, new): + self._kernel_spec = None if new == 'python': self.kernel_name = kernelspec.NATIVE_KERNEL_NAME - # This triggered another run of this function, so we can exit now - return - self.kernel_spec = self.kernel_spec_manager.get_kernel_spec(new) - self.ipykernel = new in {'python', 'python2', 'python3'} - kernel_cmd = List(Unicode, config=True, + _kernel_spec = None + + @property + def kernel_spec(self): + if self._kernel_spec is None: + self._kernel_spec = self.kernel_spec_manager.get_kernel_spec(self.kernel_name) + return self._kernel_spec + + kernel_cmd = List(Unicode(), config=True, help="""DEPRECATED: Use kernel_name instead. The Popen Command to launch the kernel. @@ -96,9 +99,10 @@ def _kernel_cmd_changed(self, name, old, new): warnings.warn("Setting kernel_cmd is deprecated, use kernel_spec to " "start different kernels.") - self.ipykernel = False - ipykernel = Bool(True) + @property + def ipykernel(self): + return self.kernel_name in {'python', 'python2', 'python3'} # Protected traits _launch_args = Any() @@ -235,6 +239,7 @@ env.update(self.kernel_spec.env or {}) # launch the kernel subprocess + self.log.debug("Starting kernel: %s", kernel_cmd) self.kernel = self._launch_kernel(kernel_cmd, env=env, **kw) self.start_restarter() @@ -380,17 +385,26 @@ from .win_interrupt import send_interrupt send_interrupt(self.kernel.win32_interrupt_event) else: - self.kernel.send_signal(signal.SIGINT) + self.signal_kernel(signal.SIGINT) else: raise RuntimeError("Cannot interrupt kernel. No kernel is running!") def signal_kernel(self, signum): - """Sends a signal to the kernel. + """Sends a signal to the process group of the kernel (this + usually includes the kernel and any subprocesses spawned by + the kernel). Note that since only SIGTERM is supported on Windows, this function is only useful on Unix systems. """ if self.has_kernel: + if hasattr(os, "getpgid") and hasattr(os, "killpg"): + try: + pgid = os.getpgid(self.kernel.pid) + os.killpg(pgid, signum) + return + except OSError: + pass self.kernel.send_signal(signum) else: raise RuntimeError("Cannot signal kernel. No kernel is running!") diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client/session.py new/jupyter_client-4.1.1/jupyter_client/session.py --- old/jupyter_client-4.0.0/jupyter_client/session.py 2015-04-09 08:47:29.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client/session.py 2015-09-03 11:35:14.000000000 +0200 @@ -864,6 +864,8 @@ # force copy to workaround pyzmq #646 buffers = [memoryview(b.bytes) for b in msg_list[5:]] message['buffers'] = buffers + if self.debug: + pprint.pprint(message) # adapt to the current version return adapt(message) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client.egg-info/PKG-INFO new/jupyter_client-4.1.1/jupyter_client.egg-info/PKG-INFO --- old/jupyter_client-4.0.0/jupyter_client.egg-info/PKG-INFO 2015-07-12 20:44:34.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client.egg-info/PKG-INFO 1970-01-01 01:00:00.000000000 +0100 @@ -1,21 +0,0 @@ -Metadata-Version: 1.1 -Name: jupyter-client -Version: 4.0.0 -Summary: Jupyter protocol implementation and client libraries -Home-page: http://jupyter.org -Author: Jupyter Development Team -Author-email: jupyter@googlegroups.com -License: BSD -Description: UNKNOWN -Keywords: Interactive,Interpreter,Shell,Web -Platform: Linux -Platform: Mac OS X -Platform: Windows -Classifier: Intended Audience :: Developers -Classifier: Intended Audience :: System Administrators -Classifier: Intended Audience :: Science/Research -Classifier: License :: OSI Approved :: BSD License -Classifier: Programming Language :: Python -Classifier: Programming Language :: Python :: 2.7 -Classifier: Programming Language :: Python :: 3 -Classifier: Programming Language :: Python :: 3.3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client.egg-info/SOURCES.txt new/jupyter_client-4.1.1/jupyter_client.egg-info/SOURCES.txt --- old/jupyter_client-4.0.0/jupyter_client.egg-info/SOURCES.txt 2015-07-12 20:44:34.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client.egg-info/SOURCES.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,64 +0,0 @@ -CONTRIBUTING.md -COPYING.md -MANIFEST.in -README.md -setup.cfg -setup.py -docs/Makefile -docs/conf.py -docs/index.rst -docs/kernels.rst -docs/make.bat -docs/messaging.rst -docs/requirements.txt -docs/wrapperkernels.rst -docs/api/client.rst -docs/api/index.rst -docs/api/kernelspec.rst -docs/api/manager.rst -docs/figs/frontend-kernel.png -docs/figs/frontend-kernel.svg -jupyter_client/__init__.py -jupyter_client/_version.py -jupyter_client/adapter.py -jupyter_client/channels.py -jupyter_client/channelsabc.py -jupyter_client/client.py -jupyter_client/clientabc.py -jupyter_client/connect.py -jupyter_client/consoleapp.py -jupyter_client/jsonutil.py -jupyter_client/kernelspec.py -jupyter_client/kernelspecapp.py -jupyter_client/launcher.py -jupyter_client/localinterfaces.py -jupyter_client/manager.py -jupyter_client/managerabc.py -jupyter_client/multikernelmanager.py -jupyter_client/restarter.py -jupyter_client/session.py -jupyter_client/threaded.py -jupyter_client/win_interrupt.py -jupyter_client.egg-info/PKG-INFO -jupyter_client.egg-info/SOURCES.txt -jupyter_client.egg-info/dependency_links.txt -jupyter_client.egg-info/pbr.json -jupyter_client.egg-info/requires.txt -jupyter_client.egg-info/top_level.txt -jupyter_client/blocking/__init__.py -jupyter_client/blocking/channels.py -jupyter_client/blocking/client.py -jupyter_client/ioloop/__init__.py -jupyter_client/ioloop/manager.py -jupyter_client/ioloop/restarter.py -jupyter_client/tests/__init__.py -jupyter_client/tests/test_adapter.py -jupyter_client/tests/test_connect.py -jupyter_client/tests/test_jsonutil.py -jupyter_client/tests/test_kernelmanager.py -jupyter_client/tests/test_kernelspec.py -jupyter_client/tests/test_localinterfaces.py -jupyter_client/tests/test_multikernelmanager.py -jupyter_client/tests/test_public_api.py -jupyter_client/tests/test_session.py -scripts/jupyter-kernelspec \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client.egg-info/dependency_links.txt new/jupyter_client-4.1.1/jupyter_client.egg-info/dependency_links.txt --- old/jupyter_client-4.0.0/jupyter_client.egg-info/dependency_links.txt 2015-07-12 20:44:34.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client.egg-info/dependency_links.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ - diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client.egg-info/pbr.json new/jupyter_client-4.1.1/jupyter_client.egg-info/pbr.json --- old/jupyter_client-4.0.0/jupyter_client.egg-info/pbr.json 2015-07-12 20:44:34.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client.egg-info/pbr.json 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -{"git_version": "846c387", "is_release": true} \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client.egg-info/requires.txt new/jupyter_client-4.1.1/jupyter_client.egg-info/requires.txt --- old/jupyter_client-4.0.0/jupyter_client.egg-info/requires.txt 2015-07-12 20:44:34.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client.egg-info/requires.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1,6 +0,0 @@ -traitlets -jupyter_core -pyzmq>=13 - -[test] -ipykernel diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/jupyter_client.egg-info/top_level.txt new/jupyter_client-4.1.1/jupyter_client.egg-info/top_level.txt --- old/jupyter_client-4.0.0/jupyter_client.egg-info/top_level.txt 2015-07-12 20:44:34.000000000 +0200 +++ new/jupyter_client-4.1.1/jupyter_client.egg-info/top_level.txt 1970-01-01 01:00:00.000000000 +0100 @@ -1 +0,0 @@ -jupyter_client diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/setup.cfg new/jupyter_client-4.1.1/setup.cfg --- old/jupyter_client-4.0.0/setup.cfg 2015-07-12 20:44:34.000000000 +0200 +++ new/jupyter_client-4.1.1/setup.cfg 2015-04-09 09:03:44.000000000 +0200 @@ -1,8 +1,2 @@ [bdist_wheel] -universal = 1 - -[egg_info] -tag_date = 0 -tag_build = -tag_svn_revision = 0 - +universal=1 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/jupyter_client-4.0.0/setup.py new/jupyter_client-4.1.1/setup.py --- old/jupyter_client-4.0.0/setup.py 2015-05-08 23:45:15.000000000 +0200 +++ new/jupyter_client-4.1.1/setup.py 2015-10-08 11:14:48.000000000 +0200 @@ -86,6 +86,12 @@ if 'setuptools' in sys.modules: setup_args.update(setuptools_args) + setup_args['entry_points'] = { + 'console_scripts': [ + 'jupyter-kernelspec = jupyter_client.kernelspecapp:KernelSpecApp.launch_instance', + ] + } + setup_args.pop('scripts', None) if __name__ == '__main__': setup(**setup_args)