Hello community,
here is the log from the commit of package python-jupyter_client for
openSUSE:Factory checked in at 2017-10-03 23:16:27
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-jupyter_client (Old)
and /work/SRC/openSUSE:Factory/.python-jupyter_client.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-jupyter_client"
Tue Oct 3 23:16:27 2017 rev:5 rq:527405 version:5.1.0
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-jupyter_client/python-jupyter_client-doc.changes
2017-05-17 17:11:48.076507687 +0200
+++
/work/SRC/openSUSE:Factory/.python-jupyter_client.new/python-jupyter_client-doc.changes
2017-10-03 23:16:29.277149119 +0200
@@ -1,0 +2,13 @@
+Tue Sep 19 19:45:32 UTC 2017 - [email protected]
+
+- Update to version 5.1
+ * Define Jupyter protocol version 5.2,
+ resolving ambiguity of ``cursor_pos`` field in the presence
+ of unicode surrogate pairs.
+ * Add :meth:`Session.clone` for making a copy of a Session object
+ without sharing the digest history.
+ Reusing a single Session object to connect multiple sockets
+ to the same IOPub peer can cause digest collisions.
+ * Avoid global references preventing garbage collection of background
threads.
+
+-------------------------------------------------------------------
python-jupyter_client.changes: same change
Old:
----
jupyter_client-5.0.1.tar.gz
New:
----
jupyter_client-5.1.0.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-jupyter_client-doc.spec ++++++
--- /var/tmp/diff_new_pack.pbq1lj/_old 2017-10-03 23:16:30.384993206 +0200
+++ /var/tmp/diff_new_pack.pbq1lj/_new 2017-10-03 23:16:30.388992644 +0200
@@ -25,7 +25,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-jupyter_client-doc
-Version: 5.0.1
+Version: 5.1.0
Release: 0
Summary: Documentation for python-jupyter_client
License: BSD-3-Clause
++++++ python-jupyter_client.spec ++++++
--- /var/tmp/diff_new_pack.pbq1lj/_old 2017-10-03 23:16:30.444984763 +0200
+++ /var/tmp/diff_new_pack.pbq1lj/_new 2017-10-03 23:16:30.448984201 +0200
@@ -18,7 +18,7 @@
%{?!python_module:%define python_module() python-%{**} python3-%{**}}
Name: python-jupyter_client
-Version: 5.0.1
+Version: 5.1.0
Release: 0
Summary: Jupyter protocol implementation and client libraries
License: BSD-3-Clause
@@ -29,11 +29,7 @@
BuildRequires: python-rpm-macros
BuildRequires: %{python_module devel}
BuildRequires: %{python_module setuptools}
-BuildRequires: %{python_module python-dateutil}
-BuildRequires: %{python_module jupyter_core}
-BuildRequires: %{python_module pyzmq >= 13}
-BuildRequires: %{python_module traitlets}
-Requires: python-python-dateutil
+Requires: python-python-dateutil >= 2.1
Requires: python-jupyter_core
Requires: python-pyzmq >= 13
Requires: python-traitlets
@@ -61,7 +57,7 @@
%files %{python_files}
%defattr(-,root,root,-)
%doc CONTRIBUTING.md COPYING.md README.md
-%python3_only %{_bindir}/jupyter-kernelspec
+# %%python3_only %%{_bindir}/jupyter-kernelspec
%{python_sitelib}/*
%changelog
++++++ jupyter_client-5.0.1.tar.gz -> jupyter_client-5.1.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/MANIFEST.in
new/jupyter_client-5.1.0/MANIFEST.in
--- old/jupyter_client-5.0.1/MANIFEST.in 1970-01-01 01:00:00.000000000
+0100
+++ new/jupyter_client-5.1.0/MANIFEST.in 2017-01-06 14:35:54.000000000
+0100
@@ -0,0 +1,22 @@
+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-5.0.1/PKG-INFO
new/jupyter_client-5.1.0/PKG-INFO
--- old/jupyter_client-5.0.1/PKG-INFO 2017-04-04 14:09:57.000000000 +0200
+++ new/jupyter_client-5.1.0/PKG-INFO 2017-06-22 14:13:50.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 1.1
Name: jupyter_client
-Version: 5.0.1
+Version: 5.1.0
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-5.0.1/docs/changelog.rst
new/jupyter_client-5.1.0/docs/changelog.rst
--- old/jupyter_client-5.0.1/docs/changelog.rst 2017-04-04 09:48:29.000000000
+0200
+++ new/jupyter_client-5.1.0/docs/changelog.rst 2017-06-22 13:46:04.000000000
+0200
@@ -4,6 +4,26 @@
Changes in Jupyter Client
=========================
+5.1
+===
+
+`5.1 on GitHub <https://github.com/jupyter/jupyter_client/milestones/5.1>`__
+
+- Define Jupyter protocol version 5.2,
+ resolving ambiguity of ``cursor_pos`` field in the presence
+ of unicode surrogate pairs.
+
+ .. seealso::
+
+ :ref:`cursor_pos_unicode_note`
+
+- Add :meth:`Session.clone` for making a copy of a Session object
+ without sharing the digest history.
+ Reusing a single Session object to connect multiple sockets
+ to the same IOPub peer can cause digest collisions.
+- Avoid global references preventing garbage collection of background threads.
+
+
5.0
===
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/docs/environment.yml
new/jupyter_client-5.1.0/docs/environment.yml
--- old/jupyter_client-5.0.1/docs/environment.yml 2017-04-04
09:48:29.000000000 +0200
+++ new/jupyter_client-5.1.0/docs/environment.yml 2017-04-06
09:55:35.000000000 +0200
@@ -8,4 +8,3 @@
- jupyter_core
- sphinx>=1.3.6
- sphinx_rtd_theme
-- ipykernel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/docs/messaging.rst
new/jupyter_client-5.1.0/docs/messaging.rst
--- old/jupyter_client-5.0.1/docs/messaging.rst 2017-04-04 09:48:29.000000000
+0200
+++ new/jupyter_client-5.1.0/docs/messaging.rst 2017-06-22 09:57:44.000000000
+0200
@@ -21,7 +21,7 @@
The Jupyter message specification is versioned independently of the packages
that use it.
-The current version of the specification is 5.1.
+The current version of the specification is 5.2.
.. note::
*New in* and *Changed in* messages in this document refer to versions of the
@@ -547,6 +547,14 @@
``name`` key replaced with ``code`` and ``cursor_pos``,
moving the lexing responsibility to the kernel.
+.. versionchanged:: 5.2
+
+ Due to a widespread bug in many frontends, ``cursor_pos``
+ in versions prior to 5.2 is ambiguous in the presence of "astral-plane"
characters.
+ In 5.2, cursor_pos **must be** the actual encoding-independent offset in
unicode codepoints.
+ See :ref:`cursor_pos_unicode_note` for more.
+
+
The reply is a mime-bundle, like a `display_data`_ message,
which should be a formatted representation of information about the context.
In the notebook, this is used to show tooltips over function calls, etc.
@@ -595,6 +603,13 @@
``line``, ``block``, and ``text`` keys are removed in favor of a single
``code`` for context.
Lexing is up to the kernel.
+.. versionchanged:: 5.2
+
+ Due to a widespread bug in many frontends, ``cursor_pos``
+ in versions prior to 5.2 is ambiguous in the presence of "astral-plane"
characters.
+ In 5.2, cursor_pos **must be** the actual encoding-independent offset in
unicode codepoints.
+ See :ref:`cursor_pos_unicode_note` for more.
+
Message type: ``complete_reply``::
@@ -1370,12 +1385,48 @@
just like an execute request.
-To Do
+Notes
=====
-Missing things include:
+.. _cursor_pos_unicode_note:
+
+``cursor_pos`` and unicode offsets
+----------------------------------
+
+Many frontends, especially those implemented in javascript,
+reported cursor_pos as the interpreter's string index,
+which is not the same as the unicode character offset if the interpreter uses
UTF-16 (e.g. javascript or Python 2 on macOS),
+which stores "astral-plane" characters such as ``𝐚 (U+1D41A)`` as surrogate
pairs,
+taking up two indices instead of one, causing a unicode offset
+drift of one per astral-plane character.
+Not all frontends have this behavior, however,
+and after JSON serialization information about which encoding was used
+when calculating the offset is lost,
+so assuming ``cursor_pos`` is calculated in UTF-16 could result in a similarly
incorrect offset
+for frontends that did the right thing.
+
+For this reason, in protocol versions prior to 5.2, ``cursor_pos``
+is officially ambiguous in the presence of astral plane unicode characters.
+Frontends claiming to implement protocol 5.2 **MUST** identify cursor_pos as
the encoding-independent unicode character offset.
+Kernels may choose to expect the UTF-16 offset from requests implementing
protocol 5.1 and earlier, in order to behave correctly with the most popular
frontends.
+But they should know that doing so *introduces* the inverse bug for the
frontends that do not have this bug.
+
+Known affected frontends (as of 2017-06):
+
+- Jupyter Notebook < 5.1
+- JupyterLab < 0.24
+- nteract
+- CoCalc
+- Jupyter Console and QtConsole with Python 2 on macOS and Windows
+
+Known *not* affected frontends:
+
+- QtConsole, Jupyter Console with Python 3 or Python 2 on Linux
+
+.. see-also::
+
+ `Discussion on GitHub
<https://github.com/jupyter/jupyter_client/issues/259>`_
-* Important: finish thinking through the payload concept and API.
.. _ZeroMQ: http://zeromq.org
.. _nteract: https://nteract.io
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/jupyter_client/_version.py
new/jupyter_client-5.1.0/jupyter_client/_version.py
--- old/jupyter_client-5.0.1/jupyter_client/_version.py 2017-04-04
09:48:52.000000000 +0200
+++ new/jupyter_client-5.1.0/jupyter_client/_version.py 2017-06-22
14:08:34.000000000 +0200
@@ -1,5 +1,5 @@
-version_info = (5, 0, 1)
+version_info = (5, 1, 0)
__version__ = '.'.join(map(str, version_info))
-protocol_version_info = (5, 1)
+protocol_version_info = (5, 2)
protocol_version = "%i.%i" % protocol_version_info
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/blocking/client.py
new/jupyter_client-5.1.0/jupyter_client/blocking/client.py
--- old/jupyter_client-5.0.1/jupyter_client/blocking/client.py 2017-02-20
16:32:46.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/blocking/client.py 2017-06-22
14:08:22.000000000 +0200
@@ -46,6 +46,11 @@
return self._recv_reply(msg_id, timeout=timeout)
+ if not meth.__doc__:
+ # python -OO removes docstrings,
+ # so don't bother building the wrapped docstring
+ return wrapped
+
basedoc, _ = meth.__doc__.split('Returns\n', 1)
parts = [basedoc.strip()]
if 'Parameters' not in basedoc:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/jupyter_client/channels.py
new/jupyter_client-5.1.0/jupyter_client/channels.py
--- old/jupyter_client-5.0.1/jupyter_client/channels.py 2017-01-06
14:35:54.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/channels.py 2017-06-22
09:57:44.000000000 +0200
@@ -70,7 +70,6 @@
raise InvalidPortNumber(message)
address = "tcp://%s:%i" % address
self.address = address
- atexit.register(self._notice_exit)
# running is False until `.start()` is called
self._running = False
@@ -78,8 +77,10 @@
self._pause = False
self.poller = zmq.Poller()
- def _notice_exit(self):
- self._exiting = True
+ @staticmethod
+ @atexit.register
+ def _notice_exit():
+ HBChannel._exiting = True
def _create_socket(self):
if self.socket is not None:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/jupyter_client/connect.py
new/jupyter_client-5.1.0/jupyter_client/connect.py
--- old/jupyter_client-5.0.1/jupyter_client/connect.py 2017-02-20
16:32:46.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/connect.py 2017-05-23
18:21:26.000000000 +0200
@@ -207,6 +207,7 @@
for p in path:
matches.extend(glob.glob(os.path.join(p, pat)))
+ matches = [ os.path.abspath(m) for m in matches ]
if not matches:
raise IOError("Could not find %r in %r" % (filename, path))
elif len(matches) == 1:
@@ -371,8 +372,9 @@
control_port=self.control_port,
)
if session:
- # add session
- info['session'] = self.session
+ # add *clone* of my session,
+ # so that state such as digest_history is not shared.
+ info['session'] = self.session.clone()
else:
# add session info
info.update(dict(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/jupyter_client/consoleapp.py
new/jupyter_client-5.1.0/jupyter_client/consoleapp.py
--- old/jupyter_client-5.0.1/jupyter_client/consoleapp.py 2017-02-20
16:32:46.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/consoleapp.py 2017-05-23
18:21:26.000000000 +0200
@@ -161,7 +161,7 @@
"""
if self.existing:
try:
- cf = find_connection_file(self.existing, [self.runtime_dir])
+ cf = find_connection_file(self.existing, ['.',
self.runtime_dir])
except Exception:
self.log.critical("Could not find existing kernel connection
file %s", self.existing)
self.exit(1)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/jupyter_client/manager.py
new/jupyter_client-5.1.0/jupyter_client/manager.py
--- old/jupyter_client-5.0.1/jupyter_client/manager.py 2017-02-20
16:32:46.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/manager.py 2017-04-28
15:54:56.000000000 +0200
@@ -295,7 +295,7 @@
self._close_control_socket()
def shutdown_kernel(self, now=False, restart=False):
- """Attempts to the stop the kernel process cleanly.
+ """Attempts to stop the kernel process cleanly.
This attempts to shutdown the kernels cleanly by:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/jupyter_client/session.py
new/jupyter_client-5.1.0/jupyter_client/session.py
--- old/jupyter_client-5.0.1/jupyter_client/session.py 2017-02-20
16:32:46.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/session.py 2017-06-22
10:22:33.000000000 +0200
@@ -488,6 +488,24 @@
if not self.key:
get_logger().warning("Message signing is disabled. This is
insecure and not recommended!")
+ def clone(self):
+ """Create a copy of this Session
+
+ Useful when connecting multiple times to a given kernel.
+ This prevents a shared digest_history warning about duplicate digests
+ due to multiple connections to IOPub in the same process.
+
+ .. versionadded:: 5.1
+ """
+ # make a copy
+ new_session = type(self)()
+ for name in self.traits():
+ setattr(new_session, name, getattr(self, name))
+ # fork digest_history
+ new_session.digest_history = set()
+ new_session.digest_history.update(self.digest_history)
+ return new_session
+
@property
def msg_id(self):
"""always return new uuid"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/tests/test_adapter.py
new/jupyter_client-5.1.0/jupyter_client/tests/test_adapter.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/test_adapter.py
2017-01-06 14:35:54.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/test_adapter.py
2017-05-18 19:29:10.000000000 +0200
@@ -6,7 +6,6 @@
import copy
import json
from unittest import TestCase
-import nose.tools as nt
from jupyter_client.adapter import adapt, V4toV5, V5toV4, code_to_line
from jupyter_client.session import Session
@@ -18,12 +17,12 @@
msg['header'].pop('version')
original = copy.deepcopy(msg)
adapted = adapt(original)
- nt.assert_equal(adapted['header']['version'], V4toV5.version)
+ assert adapted['header']['version'] == V4toV5.version
def test_code_to_line_no_code():
line, pos = code_to_line("", 0)
- nt.assert_equal(line, "")
- nt.assert_equal(pos, 0)
+ assert line == ""
+ assert pos == 0
class AdapterTest(TestCase):
@@ -263,7 +262,7 @@
msg = self.msg(v5_type, {'key' : 'value'})
v5, v4 = self.adapt(msg)
self.assertEqual(v4['header']['msg_type'], v4_type)
- nt.assert_not_in('version', v4['header'])
+ assert 'version' not in v4['header']
self.assertEqual(v4['content'], v5['content'])
def test_execute_request(self):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/tests/test_client.py
new/jupyter_client-5.1.0/jupyter_client/tests/test_client.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/test_client.py
2017-02-10 14:29:06.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/test_client.py
2017-05-18 19:29:10.000000000 +0200
@@ -8,12 +8,12 @@
pjoin = os.path.join
from unittest import TestCase
-from nose import SkipTest
-
from jupyter_client.kernelspec import KernelSpecManager, NoSuchKernel,
NATIVE_KERNEL_NAME
from ..manager import start_new_kernel
from .utils import test_env
+import pytest
+
from ipython_genutils.py3compat import string_types
from IPython.utils.capture import capture_output
@@ -27,7 +27,7 @@
try:
KernelSpecManager().get_kernel_spec(NATIVE_KERNEL_NAME)
except NoSuchKernel:
- raise SkipTest()
+ pytest.skip()
self.km, self.kc = start_new_kernel(kernel_name=NATIVE_KERNEL_NAME)
self.addCleanup(self.kc.stop_channels)
self.addCleanup(self.km.shutdown_kernel)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/tests/test_connect.py
new/jupyter_client-5.1.0/jupyter_client/tests/test_connect.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/test_connect.py
2017-01-06 14:35:54.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/test_connect.py
2017-05-23 18:21:26.000000000 +0200
@@ -6,10 +6,9 @@
import json
import os
-import nose.tools as nt
-
from traitlets.config import Config
from jupyter_core.application import JupyterApp
+from jupyter_core.paths import jupyter_runtime_dir
from ipython_genutils.tempdir import TemporaryDirectory,
TemporaryWorkingDirectory
from ipython_genutils.py3compat import str_to_bytes
from jupyter_client import connect, KernelClient
@@ -36,11 +35,11 @@
with TemporaryDirectory() as d:
cf = os.path.join(d, 'kernel.json')
connect.write_connection_file(cf, **sample_info)
- nt.assert_true(os.path.exists(cf))
+ assert os.path.exists(cf)
with open(cf, 'r') as f:
info = json.load(f)
info['key'] = str_to_bytes(info['key'])
- nt.assert_equal(info, sample_info)
+ assert info == sample_info
def test_load_connection_file_session():
@@ -56,8 +55,8 @@
app.connection_file = cf
app.load_connection_file()
- nt.assert_equal(session.key, sample_info['key'])
- nt.assert_equal(session.signature_scheme, sample_info['signature_scheme'])
+ assert session.key == sample_info['key']
+ assert session.signature_scheme == sample_info['signature_scheme']
def test_load_connection_file_session_with_kn():
@@ -73,8 +72,8 @@
app.connection_file = cf
app.load_connection_file()
- nt.assert_equal(session.key, sample_info_kn['key'])
- nt.assert_equal(session.signature_scheme,
sample_info_kn['signature_scheme'])
+ assert session.key == sample_info_kn['key']
+ assert session.signature_scheme == sample_info_kn['signature_scheme']
def test_app_load_connection_file():
@@ -89,7 +88,7 @@
if attr in ('key', 'signature_scheme'):
continue
value = getattr(app, attr)
- nt.assert_equal(value, expected, "app.%s = %s != %s" % (attr, value,
expected))
+ assert value == expected, "app.%s = %s != %s" % (attr, value, expected)
def test_load_connection_info():
@@ -112,11 +111,9 @@
def test_find_connection_file():
- cfg = Config()
with TemporaryDirectory() as d:
- cfg.ProfileDir.location = d
cf = 'kernel.json'
- app = DummyConsoleApp(config=cfg, connection_file=cf)
+ app = DummyConsoleApp(runtime_dir=d, connection_file=cf)
app.initialize()
security_dir = app.runtime_dir
@@ -131,7 +128,47 @@
'*ernel*',
'k*',
):
- nt.assert_equal(connect.find_connection_file(query,
path=security_dir), profile_cf)
+ assert connect.find_connection_file(query, path=security_dir) ==
profile_cf
+
- JupyterApp._instance = None
+def test_find_connection_file_local():
+ with TemporaryWorkingDirectory() as d:
+ cf = 'test.json'
+ abs_cf = os.path.abspath(cf)
+ with open(cf, 'w') as f:
+ f.write('{}')
+
+ for query in (
+ 'test.json',
+ 'test',
+ abs_cf,
+ os.path.join('.', 'test.json'),
+ ):
+ assert connect.find_connection_file(query, path=['.',
jupyter_runtime_dir()]) == abs_cf
+
+
+def test_find_connection_file_relative():
+ with TemporaryWorkingDirectory() as d:
+ cf = 'test.json'
+ os.mkdir('subdir')
+ cf = os.path.join('subdir', 'test.json')
+ abs_cf = os.path.abspath(cf)
+ with open(cf, 'w') as f:
+ f.write('{}')
+
+ for query in (
+ os.path.join('.', 'subdir', 'test.json'),
+ os.path.join('subdir', 'test.json'),
+ abs_cf,
+ ):
+ assert connect.find_connection_file(query, path=['.',
jupyter_runtime_dir()]) == abs_cf
+
+
+def test_find_connection_file_abspath():
+ with TemporaryDirectory() as d:
+ cf = 'absolute.json'
+ abs_cf = os.path.abspath(cf)
+ with open(cf, 'w') as f:
+ f.write('{}')
+ assert connect.find_connection_file(abs_cf,
path=jupyter_runtime_dir()) == abs_cf
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/tests/test_jsonutil.py
new/jupyter_client-5.1.0/jupyter_client/tests/test_jsonutil.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/test_jsonutil.py
2017-02-10 14:29:06.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/test_jsonutil.py
2017-05-18 19:29:10.000000000 +0200
@@ -14,8 +14,6 @@
# py2
import mock
-import nose.tools as nt
-
from dateutil.tz import tzlocal, tzoffset
from jupyter_client import jsonutil
from jupyter_client.session import utcnow
@@ -33,29 +31,29 @@
extracted = jsonutil.extract_dates(timestamps)
ref = extracted[0]
for dt in extracted:
- nt.assert_true(isinstance(dt, datetime.datetime))
- nt.assert_not_equal(dt.tzinfo, None)
+ assert isinstance(dt, datetime.datetime)
+ assert dt.tzinfo != None
- nt.assert_equal(extracted[0].tzinfo.utcoffset(ref),
tzlocal().utcoffset(ref))
- nt.assert_equal(extracted[1].tzinfo.utcoffset(ref), timedelta(0))
- nt.assert_equal(extracted[2].tzinfo.utcoffset(ref), timedelta(hours=-8))
- nt.assert_equal(extracted[3].tzinfo.utcoffset(ref), timedelta(hours=8))
- nt.assert_equal(extracted[4].tzinfo.utcoffset(ref), timedelta(hours=-8))
- nt.assert_equal(extracted[5].tzinfo.utcoffset(ref), timedelta(hours=8))
+ assert extracted[0].tzinfo.utcoffset(ref) == tzlocal().utcoffset(ref)
+ assert extracted[1].tzinfo.utcoffset(ref) == timedelta(0)
+ assert extracted[2].tzinfo.utcoffset(ref) == timedelta(hours=-8)
+ assert extracted[3].tzinfo.utcoffset(ref) == timedelta(hours=8)
+ assert extracted[4].tzinfo.utcoffset(ref) == timedelta(hours=-8)
+ assert extracted[5].tzinfo.utcoffset(ref) == timedelta(hours=8)
def test_parse_ms_precision():
base = '2013-07-03T16:34:52'
digits = '1234567890'
parsed = jsonutil.parse_date(base)
- nt.assert_is_instance(parsed, datetime.datetime)
+ assert isinstance(parsed, datetime.datetime)
for i in range(len(digits)):
ts = base + '.' + digits[:i]
parsed = jsonutil.parse_date(ts)
if i >= 1 and i <= 6:
- nt.assert_is_instance(parsed, datetime.datetime)
+ assert isinstance(parsed, datetime.datetime)
else:
- nt.assert_is_instance(parsed, str)
+ assert isinstance(parsed, str)
@@ -66,10 +64,10 @@
data = dict(naive=naive, utc=utcnow(), withtz=naive.replace(tzinfo=other))
with mock.patch.object(jsonutil, 'tzlocal', lambda : local):
jsondata = json.dumps(data, default=jsonutil.date_default)
- nt.assert_in("Z", jsondata)
- nt.assert_equal(jsondata.count("Z"), 1)
+ assert "Z" in jsondata
+ assert jsondata.count("Z") == 1
extracted = jsonutil.extract_dates(json.loads(jsondata))
for dt in extracted.values():
- nt.assert_is_instance(dt, datetime.datetime)
- nt.assert_not_equal(dt.tzinfo, None)
+ assert isinstance(dt, datetime.datetime)
+ assert dt.tzinfo != None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/tests/test_kernelmanager.py
new/jupyter_client-5.1.0/jupyter_client/tests/test_kernelmanager.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/test_kernelmanager.py
2017-01-06 14:35:54.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/test_kernelmanager.py
2017-05-18 19:29:10.000000000 +0200
@@ -13,13 +13,11 @@
import time
from unittest import TestCase
-from ipython_genutils.testing import decorators as dec
-
from traitlets.config.loader import Config
from jupyter_core import paths
from jupyter_client import KernelManager
from ..manager import start_new_kernel
-from .utils import test_env
+from .utils import test_env, skip_win32
TIMEOUT = 30
@@ -67,7 +65,7 @@
km = self._get_tcp_km()
self._run_lifecycle(km)
- @dec.skip_win32
+ @skip_win32
def test_ipc_lifecycle(self):
km = self._get_ipc_km()
self._run_lifecycle(km)
@@ -82,8 +80,8 @@
'key', 'signature_scheme',
])
self.assertEqual(keys, expected)
-
- @dec.skip_win32
+
+ @skip_win32
def test_signal_kernel_subprocesses(self):
self._install_test_kernel()
km, kc = start_new_kernel(kernel_name='signaltest')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/tests/test_kernelspec.py
new/jupyter_client-5.1.0/jupyter_client/tests/test_kernelspec.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/test_kernelspec.py
2017-02-10 14:29:06.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/test_kernelspec.py
2017-05-18 19:29:10.000000000 +0200
@@ -13,12 +13,13 @@
import sys
import unittest
+import pytest
+
if str is bytes: # py2
StringIO = io.BytesIO
else:
StringIO = io.StringIO
-from ipython_genutils.testing.decorators import onlyif
from ipython_genutils.tempdir import TemporaryDirectory
from jupyter_client import kernelspec
from jupyter_core import paths
@@ -123,7 +124,9 @@
self.ksm.log.removeHandler(handler)
self.assertNotIn("may not be found", captured)
- @onlyif(os.name != 'nt' and not os.access('/usr/local/share', os.W_OK),
"needs Unix system without root privileges")
+ @pytest.mark.skipif(
+ not (os.name != 'nt' and not os.access('/usr/local/share', os.W_OK)),
+ reason="needs Unix system without root privileges")
def test_cant_install_kernel_spec(self):
with self.assertRaises(OSError):
self.ksm.install_kernel_spec(self.installable_kernel,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/tests/test_multikernelmanager.py
new/jupyter_client-5.1.0/jupyter_client/tests/test_multikernelmanager.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/test_multikernelmanager.py
2017-01-06 14:35:54.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/test_multikernelmanager.py
2017-05-18 19:29:10.000000000 +0200
@@ -4,12 +4,11 @@
import time
from unittest import TestCase
-from ipython_genutils.testing import decorators as dec
-
from traitlets.config.loader import Config
from ..localinterfaces import localhost
from jupyter_client import KernelManager
from jupyter_client.multikernelmanager import MultiKernelManager
+from .utils import skip_win32
class TestKernelManager(TestCase):
@@ -75,12 +74,12 @@
km = self._get_tcp_km()
self._run_cinfo(km, 'tcp', localhost())
- @dec.skip_win32
+ @skip_win32
def test_ipc_lifecycle(self):
km = self._get_ipc_km()
self._run_lifecycle(km)
- @dec.skip_win32
+ @skip_win32
def test_ipc_cinfo(self):
km = self._get_ipc_km()
self._run_cinfo(km, 'ipc', 'test')
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/tests/test_public_api.py
new/jupyter_client-5.1.0/jupyter_client/tests/test_public_api.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/test_public_api.py
2017-01-06 14:35:54.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/test_public_api.py
2017-05-18 19:29:10.000000000 +0200
@@ -4,8 +4,6 @@
# Copyright (c) Jupyter Development Team.
# Distributed under the terms of the Modified BSD License.
-import nose.tools as nt
-
from jupyter_client import launcher, connect
import jupyter_client
@@ -13,17 +11,17 @@
def test_kms():
for base in ("", "Multi"):
KM = base + "KernelManager"
- nt.assert_in(KM, dir(jupyter_client))
+ assert KM in dir(jupyter_client)
def test_kcs():
for base in ("", "Blocking"):
KM = base + "KernelClient"
- nt.assert_in(KM, dir(jupyter_client))
+ assert KM in dir(jupyter_client)
def test_launcher():
for name in launcher.__all__:
- nt.assert_in(name, dir(jupyter_client))
+ assert name in dir(jupyter_client)
def test_connect():
for name in connect.__all__:
- nt.assert_in(name, dir(jupyter_client))
+ assert name in dir(jupyter_client)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client/tests/test_session.py
new/jupyter_client-5.1.0/jupyter_client/tests/test_session.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/test_session.py
2017-02-10 14:29:06.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/test_session.py
2017-05-18 19:29:10.000000000 +0200
@@ -8,6 +8,8 @@
import uuid
from datetime import datetime
+import pytest
+
import zmq
from zmq.tests import BaseZMQTestCase
@@ -16,7 +18,6 @@
from jupyter_client import session as ss
from jupyter_client import jsonutil
-from ipython_genutils.testing.decorators import skipif, module_not_available
from ipython_genutils.py3compat import string_types
def _bad_packer(obj):
@@ -286,9 +287,8 @@
session = ss.Session(packer='pickle')
self._datetime_test(session)
- @skipif(module_not_available('msgpack'))
def test_datetimes_msgpack(self):
- import msgpack
+ msgpack = pytest.importorskip('msgpack')
session = ss.Session(
pack=msgpack.packb,
@@ -320,3 +320,15 @@
A.close()
B.close()
ctx.term()
+
+ def test_clone(self):
+ s = self.session
+ s._add_digest('initial')
+ s2 = s.clone()
+ assert s2.session == s.session
+ assert s2.digest_history == s.digest_history
+ assert s2.digest_history is not s.digest_history
+ digest = 'abcdef'
+ s._add_digest(digest)
+ assert digest in s.digest_history
+ assert digest not in s2.digest_history
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/jupyter_client/tests/utils.py
new/jupyter_client-5.1.0/jupyter_client/tests/utils.py
--- old/jupyter_client-5.0.1/jupyter_client/tests/utils.py 2017-01-06
14:35:54.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/tests/utils.py 2017-05-18
19:29:10.000000000 +0200
@@ -3,13 +3,20 @@
"""
import os
pjoin = os.path.join
+import sys
try:
from unittest.mock import patch
except ImportError:
from mock import patch
+import pytest
+
from ipython_genutils.tempdir import TemporaryDirectory
+
+skip_win32 = pytest.mark.skipif(sys.platform.startswith('win'),
reason="Windows")
+
+
class test_env(object):
"""Set Jupyter path variables to a temporary directory
@@ -46,11 +53,11 @@
validate_message(reply, 'execute_reply', msg_id)
busy = kc.get_iopub_msg(timeout=TIMEOUT)
validate_message(busy, 'status', msg_id)
- nt.assert_equal(busy['content']['execution_state'], 'busy')
+ assert busy['content']['execution_state'] == 'busy'
if not kwargs.get('silent'):
execute_input = kc.get_iopub_msg(timeout=TIMEOUT)
validate_message(execute_input, 'execute_input', msg_id)
- nt.assert_equal(execute_input['content']['code'], code)
+ assert execute_input['content']['code'] == code
return msg_id, reply['content']
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/jupyter_client/threaded.py
new/jupyter_client-5.1.0/jupyter_client/threaded.py
--- old/jupyter_client-5.0.1/jupyter_client/threaded.py 2017-01-06
14:35:54.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client/threaded.py 2017-06-22
09:57:44.000000000 +0200
@@ -141,14 +141,17 @@
class IOLoopThread(Thread):
"""Run a pyzmq ioloop in a thread to send and receive messages
"""
+ _exiting = False
+
def __init__(self, loop):
super(IOLoopThread, self).__init__()
self.daemon = True
- atexit.register(self._notice_exit)
self.ioloop = loop or ioloop.IOLoop()
- def _notice_exit(self):
- self._exiting = True
+ @staticmethod
+ @atexit.register
+ def _notice_exit():
+ IOLoopThread._exiting = True
def run(self):
"""Run my loop, ignoring EINTR events in the poller"""
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client.egg-info/PKG-INFO
new/jupyter_client-5.1.0/jupyter_client.egg-info/PKG-INFO
--- old/jupyter_client-5.0.1/jupyter_client.egg-info/PKG-INFO 1970-01-01
01:00:00.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client.egg-info/PKG-INFO 2017-06-22
14:13:49.000000000 +0200
@@ -0,0 +1,21 @@
+Metadata-Version: 1.1
+Name: jupyter-client
+Version: 5.1.0
+Summary: Jupyter protocol implementation and client libraries
+Home-page: http://jupyter.org
+Author: Jupyter Development Team
+Author-email: [email protected]
+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-5.0.1/jupyter_client.egg-info/SOURCES.txt
new/jupyter_client-5.1.0/jupyter_client.egg-info/SOURCES.txt
--- old/jupyter_client-5.0.1/jupyter_client.egg-info/SOURCES.txt
1970-01-01 01:00:00.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client.egg-info/SOURCES.txt
2017-06-22 14:13:49.000000000 +0200
@@ -0,0 +1,68 @@
+CONTRIBUTING.md
+COPYING.md
+MANIFEST.in
+README.md
+setup.cfg
+setup.py
+docs/Makefile
+docs/changelog.rst
+docs/conf.py
+docs/environment.yml
+docs/index.rst
+docs/kernels.rst
+docs/make.bat
+docs/messaging.rst
+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/runapp.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/entry_points.txt
+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/signalkernel.py
+jupyter_client/tests/test_adapter.py
+jupyter_client/tests/test_client.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
+jupyter_client/tests/utils.py
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client.egg-info/dependency_links.txt
new/jupyter_client-5.1.0/jupyter_client.egg-info/dependency_links.txt
--- old/jupyter_client-5.0.1/jupyter_client.egg-info/dependency_links.txt
1970-01-01 01:00:00.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client.egg-info/dependency_links.txt
2017-06-22 14:13:49.000000000 +0200
@@ -0,0 +1 @@
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client.egg-info/entry_points.txt
new/jupyter_client-5.1.0/jupyter_client.egg-info/entry_points.txt
--- old/jupyter_client-5.0.1/jupyter_client.egg-info/entry_points.txt
1970-01-01 01:00:00.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client.egg-info/entry_points.txt
2017-06-22 14:13:49.000000000 +0200
@@ -0,0 +1,4 @@
+[console_scripts]
+jupyter-kernelspec = jupyter_client.kernelspecapp:KernelSpecApp.launch_instance
+jupyter-run = jupyter_client.runapp:RunApp.launch_instance
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client.egg-info/requires.txt
new/jupyter_client-5.1.0/jupyter_client.egg-info/requires.txt
--- old/jupyter_client-5.0.1/jupyter_client.egg-info/requires.txt
1970-01-01 01:00:00.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client.egg-info/requires.txt
2017-06-22 14:13:49.000000000 +0200
@@ -0,0 +1,9 @@
+traitlets
+jupyter_core
+pyzmq>=13
+python-dateutil>=2.1
+
+[test]
+ipykernel
+ipython
+pytest
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/jupyter_client-5.0.1/jupyter_client.egg-info/top_level.txt
new/jupyter_client-5.1.0/jupyter_client.egg-info/top_level.txt
--- old/jupyter_client-5.0.1/jupyter_client.egg-info/top_level.txt
1970-01-01 01:00:00.000000000 +0100
+++ new/jupyter_client-5.1.0/jupyter_client.egg-info/top_level.txt
2017-06-22 14:13:49.000000000 +0200
@@ -0,0 +1 @@
+jupyter_client
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/scripts/jupyter-kernelspec
new/jupyter_client-5.1.0/scripts/jupyter-kernelspec
--- old/jupyter_client-5.0.1/scripts/jupyter-kernelspec 2017-01-06
14:35:54.000000000 +0100
+++ new/jupyter_client-5.1.0/scripts/jupyter-kernelspec 1970-01-01
01:00:00.000000000 +0100
@@ -1,8 +0,0 @@
-#!/usr/bin/env python
-from jupyter_client.kernelspecapp import KernelSpecApp
-
-def main():
- KernelSpecApp.launch_instance()
-
-if __name__ == '__main__':
- main()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/setup.cfg
new/jupyter_client-5.1.0/setup.cfg
--- old/jupyter_client-5.0.1/setup.cfg 2017-02-10 14:29:06.000000000 +0100
+++ new/jupyter_client-5.1.0/setup.cfg 2017-06-22 14:13:50.000000000 +0200
@@ -1,5 +1,10 @@
[bdist_wheel]
-universal=1
+universal = 1
[nosetests]
-warningfilters=default
+warningfilters = default
+
+[egg_info]
+tag_build =
+tag_date = 0
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/jupyter_client-5.0.1/setup.py
new/jupyter_client-5.1.0/setup.py
--- old/jupyter_client-5.0.1/setup.py 2017-02-20 16:32:46.000000000 +0100
+++ new/jupyter_client-5.1.0/setup.py 2017-05-18 19:29:10.000000000 +0200
@@ -82,7 +82,7 @@
]
extras_require = setuptools_args['extras_require'] = {
- 'test': ['ipykernel', 'ipython', 'nose_warnings_filters'],
+ 'test': ['ipykernel', 'ipython', 'pytest'],
}
if 'setuptools' in sys.modules: