commit python-jupyter_client for openSUSE:Factory
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 - toddrme2178@gmail.com + +- 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: 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-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:
participants (1)
-
root@hilbert.suse.de