Hello community, here is the log from the commit of package python-jupyter_ipykernel for openSUSE:Factory checked in at 2018-09-11 17:16:51 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-jupyter_ipykernel (Old) and /work/SRC/openSUSE:Factory/.python-jupyter_ipykernel.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-jupyter_ipykernel" Tue Sep 11 17:16:51 2018 rev:10 rq:634266 version:4.9.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-jupyter_ipykernel/python-jupyter_ipykernel.changes 2018-02-27 16:59:53.195860727 +0100 +++ /work/SRC/openSUSE:Factory/.python-jupyter_ipykernel.new/python-jupyter_ipykernel.changes 2018-09-11 17:16:59.371438520 +0200 @@ -1,0 +2,10 @@ +Fri Sep 7 15:19:52 UTC 2018 - toddrme2...@gmail.com + +- Update to version 4.9.0 + * Python 3.3 is no longer supported (:ghpull:`336`) + * Flush stdout/stderr in KernelApp before replacing (:ghpull:`314`) + * Allow preserving stdout and stderr in KernelApp (:ghpull:`315`) + * Override writable method on OutStream (:ghpull:`316`) + * Add metadata to help display matplotlib figures legibly (:ghpull:`336`) + +------------------------------------------------------------------- Old: ---- ipykernel-4.8.2.tar.gz python-jupyter_ipykernel-doc.changes python-jupyter_ipykernel-doc.spec New: ---- ipykernel-4.9.0.tar.gz ipykernel.pdf ipykernel.zip ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-jupyter_ipykernel.spec ++++++ --- /var/tmp/diff_new_pack.D1alrO/_old 2018-09-11 17:17:00.767436375 +0200 +++ /var/tmp/diff_new_pack.D1alrO/_new 2018-09-11 17:17:00.767436375 +0200 @@ -18,13 +18,16 @@ %{?!python_module:%define python_module() python-%{**} python3-%{**}} Name: python-jupyter_ipykernel -Version: 4.8.2 +Version: 4.9.0 Release: 0 Summary: IPython Kernel for Jupyter License: BSD-3-Clause Group: Development/Languages/Python Url: https://github.com/ipython/ipykernel -Source: https://files.pythonhosted.org/packages/source/i/ipykernel/ipykernel-%{version}.tar.gz +Source0: https://files.pythonhosted.org/packages/source/i/ipykernel/ipykernel-%{version}.tar.gz +# Please make sure you update the documentation files at every release +Source1: https://media.readthedocs.org/pdf/ipykernel/stable/ipykernel.pdf +Source2: https://media.readthedocs.org/htmlzip/ipykernel/stable/ipykernel.zip BuildRequires: %{python_module devel} BuildRequires: %{python_module jupyter_client} BuildRequires: %{python_module jupyter_ipython >= 4.0.0} @@ -34,6 +37,20 @@ BuildRequires: fdupes BuildRequires: hicolor-icon-theme BuildRequires: python-rpm-macros +BuildRequires: unzip +# SECTION test requirements +BuildRequires: %{python_module jupyter_client} +BuildRequires: %{python_module jupyter_ipython >= 4.0.0} +BuildRequires: %{python_module nose} +BuildRequires: %{python_module nose_warnings_filters} +BuildRequires: %{python_module tornado >= 4.0} +BuildRequires: %{python_module traitlets >= 4.1.0} +BuildRequires: python-mock +BuildRequires: python-typing +%if 0%{?suse_version} <= 1320 +Requires: python3-typing +%endif +# /SECTION Requires: python-jupyter_client Requires: python-jupyter_ipython >= 4.0.0 Requires: python-tornado >= 4.0 @@ -46,13 +63,26 @@ Requires: python-typing %endif BuildArch: noarch + %python_subpackages %description This package provides the IPython kernel for Jupyter. +%package -n python-jupyter_ipykernel-doc +Summary: Documentation for python-jupyter_ipykernel +Group: Documentation/Other +Provides: %{python_module jupyter_ipykernel-doc = %{version}} + +%description -n python-jupyter_ipykernel-doc +Documentation and help files for python-jupyter_ipykernel. + %prep %setup -q -n ipykernel-%{version} +cp %{SOURCE1} . +unzip %{SOURCE2} -d docs +mv docs/ipykernel-* docs/html +rm docs/html/.buildinfo %build %python_build @@ -75,17 +105,19 @@ --prefix %{buildroot}%{_prefix} } -%post -n %{python3_prefix}-jupyter_ipykernel -%icon_theme_cache_post - -%postun -n %{python3_prefix}-jupyter_ipykernel -%icon_theme_cache_postun +%check +%python_expand nosetests-%{$python_bin_suffix} %files %{python_files} -%defattr(-,root,root,-) -%doc COPYING.md README.md +%doc README.md +%license COPYING.md %{python_sitelib}/* %{_datadir}/jupyter/kernels/python_%{python_bin_suffix}/ %python3_only %{_datadir}/icons/hicolor/*/apps/JupyterIPyKernel.* +%files -n python-jupyter_ipykernel-doc +%license COPYING.md +%doc ipykernel.pdf +%doc docs/html + %changelog ++++++ ipykernel-4.8.2.tar.gz -> ipykernel-4.9.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/PKG-INFO new/ipykernel-4.9.0/PKG-INFO --- old/ipykernel-4.8.2/PKG-INFO 2018-02-19 17:18:51.000000000 +0100 +++ new/ipykernel-4.9.0/PKG-INFO 2018-08-29 20:43:51.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 1.1 Name: ipykernel -Version: 4.8.2 +Version: 4.9.0 Summary: IPython Kernel for Jupyter Home-page: http://ipython.org Author: IPython Development Team diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/docs/changelog.rst new/ipykernel-4.9.0/docs/changelog.rst --- old/ipykernel-4.8.2/docs/changelog.rst 2018-02-19 17:17:59.000000000 +0100 +++ new/ipykernel-4.9.0/docs/changelog.rst 2018-08-29 20:43:03.000000000 +0200 @@ -1,6 +1,21 @@ Changes in IPython kernel ========================= +4.9 +--- + +4.9.0 +***** + +`4.9.0 on GitHub <https://github.com/ipython/ipykernel/milestones/4.9>`__ + +- Python 3.3 is no longer supported (:ghpull:`336`) +- Flush stdout/stderr in KernelApp before replacing (:ghpull:`314`) +- Allow preserving stdout and stderr in KernelApp (:ghpull:`315`) +- Override writable method on OutStream (:ghpull:`316`) +- Add metadata to help display matplotlib figures legibly (:ghpull:`336`) + + 4.8 --- diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/Embedding/inprocess_qtconsole.py new/ipykernel-4.9.0/examples/Embedding/inprocess_qtconsole.py --- old/ipykernel-4.8.2/examples/Embedding/inprocess_qtconsole.py 2015-04-09 10:09:32.000000000 +0200 +++ new/ipykernel-4.9.0/examples/Embedding/inprocess_qtconsole.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,46 +0,0 @@ -from __future__ import print_function -import os - -from IPython.qt.console.rich_ipython_widget import RichIPythonWidget -from IPython.qt.inprocess import QtInProcessKernelManager -from IPython.lib import guisupport - - -def print_process_id(): - print('Process ID is:', os.getpid()) - - -def main(): - # Print the ID of the main process - print_process_id() - - app = guisupport.get_app_qt4() - - # Create an in-process kernel - # >>> print_process_id() - # will print the same process ID as the main process - kernel_manager = QtInProcessKernelManager() - kernel_manager.start_kernel() - kernel = kernel_manager.kernel - kernel.gui = 'qt4' - kernel.shell.push({'foo': 43, 'print_process_id': print_process_id}) - - kernel_client = kernel_manager.client() - kernel_client.start_channels() - - def stop(): - kernel_client.stop_channels() - kernel_manager.shutdown_kernel() - app.exit() - - control = RichIPythonWidget() - control.kernel_manager = kernel_manager - control.kernel_client = kernel_client - control.exit_requested.connect(stop) - control.show() - - guisupport.start_event_loop_qt4(app) - - -if __name__ == '__main__': - main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/Embedding/inprocess_terminal.py new/ipykernel-4.9.0/examples/Embedding/inprocess_terminal.py --- old/ipykernel-4.8.2/examples/Embedding/inprocess_terminal.py 2015-04-09 10:09:32.000000000 +0200 +++ new/ipykernel-4.9.0/examples/Embedding/inprocess_terminal.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,31 +0,0 @@ -from __future__ import print_function -import os - -from IPython.kernel.inprocess import InProcessKernelManager -from IPython.terminal.console.interactiveshell import ZMQTerminalInteractiveShell - - -def print_process_id(): - print('Process ID is:', os.getpid()) - - -def main(): - print_process_id() - - # Create an in-process kernel - # >>> print_process_id() - # will print the same process ID as the main process - kernel_manager = InProcessKernelManager() - kernel_manager.start_kernel() - kernel = kernel_manager.kernel - kernel.gui = 'qt4' - kernel.shell.push({'foo': 43, 'print_process_id': print_process_id}) - client = kernel_manager.client() - client.start_channels() - - shell = ZMQTerminalInteractiveShell(manager=kernel_manager, client=client) - shell.mainloop() - - -if __name__ == '__main__': - main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/Embedding/internal_ipkernel.py new/ipykernel-4.9.0/examples/Embedding/internal_ipkernel.py --- old/ipykernel-4.8.2/examples/Embedding/internal_ipkernel.py 2015-09-22 09:39:51.000000000 +0200 +++ new/ipykernel-4.9.0/examples/Embedding/internal_ipkernel.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,55 +0,0 @@ -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -import sys - -from IPython.lib.kernel import connect_qtconsole -from IPython.kernel.zmq.kernelapp import IPKernelApp - -#----------------------------------------------------------------------------- -# Functions and classes -#----------------------------------------------------------------------------- -def mpl_kernel(gui): - """Launch and return an IPython kernel with matplotlib support for the desired gui - """ - kernel = IPKernelApp.instance() - kernel.initialize(['python', '--matplotlib=%s' % gui, - #'--log-level=10' - ]) - return kernel - - -class InternalIPKernel(object): - - def init_ipkernel(self, backend): - # Start IPython kernel with GUI event loop and mpl support - self.ipkernel = mpl_kernel(backend) - # To create and track active qt consoles - self.consoles = [] - - # This application will also act on the shell user namespace - self.namespace = self.ipkernel.shell.user_ns - - # Example: a variable that will be seen by the user in the shell, and - # that the GUI modifies (the 'Counter++' button increments it): - self.namespace['app_counter'] = 0 - #self.namespace['ipkernel'] = self.ipkernel # dbg - - def print_namespace(self, evt=None): - print("\n***Variables in User namespace***") - for k, v in self.namespace.items(): - if not k.startswith('_'): - print('%s -> %r' % (k, v)) - sys.stdout.flush() - - def new_qt_console(self, evt=None): - """start a new qtconsole connected to our kernel""" - return connect_qtconsole(self.ipkernel.abs_connection_file, profile=self.ipkernel.profile) - - def count(self, evt=None): - self.namespace['app_counter'] += 1 - - def cleanup_consoles(self, evt=None): - for c in self.consoles: - c.kill() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/Embedding/ipkernel_qtapp.py new/ipykernel-4.9.0/examples/Embedding/ipkernel_qtapp.py --- old/ipykernel-4.8.2/examples/Embedding/ipkernel_qtapp.py 2015-04-09 10:09:32.000000000 +0200 +++ new/ipykernel-4.9.0/examples/Embedding/ipkernel_qtapp.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,75 +0,0 @@ -#!/usr/bin/env python -"""Example integrating an IPython kernel into a GUI App. - -This trivial GUI application internally starts an IPython kernel, to which Qt -consoles can be connected either by the user at the command line or started -from the GUI itself, via a button. The GUI can also manipulate one variable in -the kernel's namespace, and print the namespace to the console. - -Play with it by running the script and then opening one or more consoles, and -pushing the 'Counter++' and 'Namespace' buttons. - -Upon exit, it should automatically close all consoles opened from the GUI. - -Consoles attached separately from a terminal will not be terminated, though -they will notice that their kernel died. -""" -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- - -from PyQt4 import Qt - -from internal_ipkernel import InternalIPKernel - -#----------------------------------------------------------------------------- -# Functions and classes -#----------------------------------------------------------------------------- -class SimpleWindow(Qt.QWidget, InternalIPKernel): - - def __init__(self, app): - Qt.QWidget.__init__(self) - self.app = app - self.add_widgets() - self.init_ipkernel('qt') - - def add_widgets(self): - self.setGeometry(300, 300, 400, 70) - self.setWindowTitle('IPython in your app') - - # Add simple buttons: - console = Qt.QPushButton('Qt Console', self) - console.setGeometry(10, 10, 100, 35) - self.connect(console, Qt.SIGNAL('clicked()'), self.new_qt_console) - - namespace = Qt.QPushButton('Namespace', self) - namespace.setGeometry(120, 10, 100, 35) - self.connect(namespace, Qt.SIGNAL('clicked()'), self.print_namespace) - - count = Qt.QPushButton('Count++', self) - count.setGeometry(230, 10, 80, 35) - self.connect(count, Qt.SIGNAL('clicked()'), self.count) - - # Quit and cleanup - quit = Qt.QPushButton('Quit', self) - quit.setGeometry(320, 10, 60, 35) - self.connect(quit, Qt.SIGNAL('clicked()'), Qt.qApp, Qt.SLOT('quit()')) - - self.app.connect(self.app, Qt.SIGNAL("lastWindowClosed()"), - self.app, Qt.SLOT("quit()")) - - self.app.aboutToQuit.connect(self.cleanup_consoles) - -#----------------------------------------------------------------------------- -# Main script -#----------------------------------------------------------------------------- - -if __name__ == "__main__": - app = Qt.QApplication([]) - # Create our window - win = SimpleWindow(app) - win.show() - - # Very important, IPython-specific step: this gets GUI event loop - # integration going, and it replaces calling app.exec_() - win.ipkernel.start() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/Embedding/ipkernel_wxapp.py new/ipykernel-4.9.0/examples/Embedding/ipkernel_wxapp.py --- old/ipykernel-4.8.2/examples/Embedding/ipkernel_wxapp.py 2015-04-09 10:09:32.000000000 +0200 +++ new/ipykernel-4.9.0/examples/Embedding/ipkernel_wxapp.py 1970-01-01 01:00:00.000000000 +0100 @@ -1,119 +0,0 @@ -#!/usr/bin/env python -"""Example integrating an IPython kernel into a GUI App. - -This trivial GUI application internally starts an IPython kernel, to which Qt -consoles can be connected either by the user at the command line or started -from the GUI itself, via a button. The GUI can also manipulate one variable in -the kernel's namespace, and print the namespace to the console. - -Play with it by running the script and then opening one or more consoles, and -pushing the 'Counter++' and 'Namespace' buttons. - -Upon exit, it should automatically close all consoles opened from the GUI. - -Consoles attached separately from a terminal will not be terminated, though -they will notice that their kernel died. - -Ref: Modified from wxPython source code wxPython/samples/simple/simple.py -""" -#----------------------------------------------------------------------------- -# Imports -#----------------------------------------------------------------------------- -import sys - -import wx - -from internal_ipkernel import InternalIPKernel - -#----------------------------------------------------------------------------- -# Functions and classes -#----------------------------------------------------------------------------- - -class MyFrame(wx.Frame, InternalIPKernel): - """ - This is MyFrame. It just shows a few controls on a wxPanel, - and has a simple menu. - """ - - def __init__(self, parent, title): - wx.Frame.__init__(self, parent, -1, title, - pos=(150, 150), size=(350, 285)) - - # Create the menubar - menuBar = wx.MenuBar() - - # and a menu - menu = wx.Menu() - - # add an item to the menu, using \tKeyName automatically - # creates an accelerator, the third param is some help text - # that will show up in the statusbar - menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample") - - # bind the menu event to an event handler - self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT) - - # and put the menu on the menubar - menuBar.Append(menu, "&File") - self.SetMenuBar(menuBar) - - self.CreateStatusBar() - - # Now create the Panel to put the other controls on. - panel = wx.Panel(self) - - # and a few controls - text = wx.StaticText(panel, -1, "Hello World!") - text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)) - text.SetSize(text.GetBestSize()) - qtconsole_btn = wx.Button(panel, -1, "Qt Console") - ns_btn = wx.Button(panel, -1, "Namespace") - count_btn = wx.Button(panel, -1, "Count++") - close_btn = wx.Button(panel, -1, "Quit") - - # bind the button events to handlers - self.Bind(wx.EVT_BUTTON, self.new_qt_console, qtconsole_btn) - self.Bind(wx.EVT_BUTTON, self.print_namespace, ns_btn) - self.Bind(wx.EVT_BUTTON, self.count, count_btn) - self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, close_btn) - - # Use a sizer to layout the controls, stacked vertically and with - # a 10 pixel border around each - sizer = wx.BoxSizer(wx.VERTICAL) - for ctrl in [text, qtconsole_btn, ns_btn, count_btn, close_btn]: - sizer.Add(ctrl, 0, wx.ALL, 10) - panel.SetSizer(sizer) - panel.Layout() - - # Start the IPython kernel with gui support - self.init_ipkernel('wx') - - def OnTimeToClose(self, evt): - """Event handler for the button click.""" - print("See ya later!") - sys.stdout.flush() - self.cleanup_consoles(evt) - self.Close() - # Not sure why, but our IPython kernel seems to prevent normal WX - # shutdown, so an explicit exit() call is needed. - sys.exit() - - -class MyApp(wx.App): - def OnInit(self): - frame = MyFrame(None, "Simple wxPython App") - self.SetTopWindow(frame) - frame.Show(True) - self.ipkernel = frame.ipkernel - return True - -#----------------------------------------------------------------------------- -# Main script -#----------------------------------------------------------------------------- - -if __name__ == '__main__': - app = MyApp(redirect=False, clearSigInt=False) - - # Very important, IPython-specific step: this gets GUI event loop - # integration going, and it replaces calling app.MainLoop() - app.ipkernel.start() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/embedding/inprocess_qtconsole.py new/ipykernel-4.9.0/examples/embedding/inprocess_qtconsole.py --- old/ipykernel-4.8.2/examples/embedding/inprocess_qtconsole.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ipykernel-4.9.0/examples/embedding/inprocess_qtconsole.py 2018-08-29 20:43:01.000000000 +0200 @@ -0,0 +1,46 @@ +from __future__ import print_function +import os + +from IPython.qt.console.rich_ipython_widget import RichIPythonWidget +from IPython.qt.inprocess import QtInProcessKernelManager +from IPython.lib import guisupport + + +def print_process_id(): + print('Process ID is:', os.getpid()) + + +def main(): + # Print the ID of the main process + print_process_id() + + app = guisupport.get_app_qt4() + + # Create an in-process kernel + # >>> print_process_id() + # will print the same process ID as the main process + kernel_manager = QtInProcessKernelManager() + kernel_manager.start_kernel() + kernel = kernel_manager.kernel + kernel.gui = 'qt4' + kernel.shell.push({'foo': 43, 'print_process_id': print_process_id}) + + kernel_client = kernel_manager.client() + kernel_client.start_channels() + + def stop(): + kernel_client.stop_channels() + kernel_manager.shutdown_kernel() + app.exit() + + control = RichIPythonWidget() + control.kernel_manager = kernel_manager + control.kernel_client = kernel_client + control.exit_requested.connect(stop) + control.show() + + guisupport.start_event_loop_qt4(app) + + +if __name__ == '__main__': + main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/embedding/inprocess_terminal.py new/ipykernel-4.9.0/examples/embedding/inprocess_terminal.py --- old/ipykernel-4.8.2/examples/embedding/inprocess_terminal.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ipykernel-4.9.0/examples/embedding/inprocess_terminal.py 2018-08-29 20:43:01.000000000 +0200 @@ -0,0 +1,31 @@ +from __future__ import print_function +import os + +from IPython.kernel.inprocess import InProcessKernelManager +from IPython.terminal.console.interactiveshell import ZMQTerminalInteractiveShell + + +def print_process_id(): + print('Process ID is:', os.getpid()) + + +def main(): + print_process_id() + + # Create an in-process kernel + # >>> print_process_id() + # will print the same process ID as the main process + kernel_manager = InProcessKernelManager() + kernel_manager.start_kernel() + kernel = kernel_manager.kernel + kernel.gui = 'qt4' + kernel.shell.push({'foo': 43, 'print_process_id': print_process_id}) + client = kernel_manager.client() + client.start_channels() + + shell = ZMQTerminalInteractiveShell(manager=kernel_manager, client=client) + shell.mainloop() + + +if __name__ == '__main__': + main() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/embedding/internal_ipkernel.py new/ipykernel-4.9.0/examples/embedding/internal_ipkernel.py --- old/ipykernel-4.8.2/examples/embedding/internal_ipkernel.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ipykernel-4.9.0/examples/embedding/internal_ipkernel.py 2018-08-29 20:43:01.000000000 +0200 @@ -0,0 +1,55 @@ +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +import sys + +from IPython.lib.kernel import connect_qtconsole +from IPython.kernel.zmq.kernelapp import IPKernelApp + +#----------------------------------------------------------------------------- +# Functions and classes +#----------------------------------------------------------------------------- +def mpl_kernel(gui): + """Launch and return an IPython kernel with matplotlib support for the desired gui + """ + kernel = IPKernelApp.instance() + kernel.initialize(['python', '--matplotlib=%s' % gui, + #'--log-level=10' + ]) + return kernel + + +class InternalIPKernel(object): + + def init_ipkernel(self, backend): + # Start IPython kernel with GUI event loop and mpl support + self.ipkernel = mpl_kernel(backend) + # To create and track active qt consoles + self.consoles = [] + + # This application will also act on the shell user namespace + self.namespace = self.ipkernel.shell.user_ns + + # Example: a variable that will be seen by the user in the shell, and + # that the GUI modifies (the 'Counter++' button increments it): + self.namespace['app_counter'] = 0 + #self.namespace['ipkernel'] = self.ipkernel # dbg + + def print_namespace(self, evt=None): + print("\n***Variables in User namespace***") + for k, v in self.namespace.items(): + if not k.startswith('_'): + print('%s -> %r' % (k, v)) + sys.stdout.flush() + + def new_qt_console(self, evt=None): + """start a new qtconsole connected to our kernel""" + return connect_qtconsole(self.ipkernel.abs_connection_file, profile=self.ipkernel.profile) + + def count(self, evt=None): + self.namespace['app_counter'] += 1 + + def cleanup_consoles(self, evt=None): + for c in self.consoles: + c.kill() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/embedding/ipkernel_qtapp.py new/ipykernel-4.9.0/examples/embedding/ipkernel_qtapp.py --- old/ipykernel-4.8.2/examples/embedding/ipkernel_qtapp.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ipykernel-4.9.0/examples/embedding/ipkernel_qtapp.py 2018-08-29 20:43:01.000000000 +0200 @@ -0,0 +1,75 @@ +#!/usr/bin/env python +"""Example integrating an IPython kernel into a GUI App. + +This trivial GUI application internally starts an IPython kernel, to which Qt +consoles can be connected either by the user at the command line or started +from the GUI itself, via a button. The GUI can also manipulate one variable in +the kernel's namespace, and print the namespace to the console. + +Play with it by running the script and then opening one or more consoles, and +pushing the 'Counter++' and 'Namespace' buttons. + +Upon exit, it should automatically close all consoles opened from the GUI. + +Consoles attached separately from a terminal will not be terminated, though +they will notice that their kernel died. +""" +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- + +from PyQt4 import Qt + +from internal_ipkernel import InternalIPKernel + +#----------------------------------------------------------------------------- +# Functions and classes +#----------------------------------------------------------------------------- +class SimpleWindow(Qt.QWidget, InternalIPKernel): + + def __init__(self, app): + Qt.QWidget.__init__(self) + self.app = app + self.add_widgets() + self.init_ipkernel('qt') + + def add_widgets(self): + self.setGeometry(300, 300, 400, 70) + self.setWindowTitle('IPython in your app') + + # Add simple buttons: + console = Qt.QPushButton('Qt Console', self) + console.setGeometry(10, 10, 100, 35) + self.connect(console, Qt.SIGNAL('clicked()'), self.new_qt_console) + + namespace = Qt.QPushButton('Namespace', self) + namespace.setGeometry(120, 10, 100, 35) + self.connect(namespace, Qt.SIGNAL('clicked()'), self.print_namespace) + + count = Qt.QPushButton('Count++', self) + count.setGeometry(230, 10, 80, 35) + self.connect(count, Qt.SIGNAL('clicked()'), self.count) + + # Quit and cleanup + quit = Qt.QPushButton('Quit', self) + quit.setGeometry(320, 10, 60, 35) + self.connect(quit, Qt.SIGNAL('clicked()'), Qt.qApp, Qt.SLOT('quit()')) + + self.app.connect(self.app, Qt.SIGNAL("lastWindowClosed()"), + self.app, Qt.SLOT("quit()")) + + self.app.aboutToQuit.connect(self.cleanup_consoles) + +#----------------------------------------------------------------------------- +# Main script +#----------------------------------------------------------------------------- + +if __name__ == "__main__": + app = Qt.QApplication([]) + # Create our window + win = SimpleWindow(app) + win.show() + + # Very important, IPython-specific step: this gets GUI event loop + # integration going, and it replaces calling app.exec_() + win.ipkernel.start() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/examples/embedding/ipkernel_wxapp.py new/ipykernel-4.9.0/examples/embedding/ipkernel_wxapp.py --- old/ipykernel-4.8.2/examples/embedding/ipkernel_wxapp.py 1970-01-01 01:00:00.000000000 +0100 +++ new/ipykernel-4.9.0/examples/embedding/ipkernel_wxapp.py 2018-08-29 20:43:01.000000000 +0200 @@ -0,0 +1,119 @@ +#!/usr/bin/env python +"""Example integrating an IPython kernel into a GUI App. + +This trivial GUI application internally starts an IPython kernel, to which Qt +consoles can be connected either by the user at the command line or started +from the GUI itself, via a button. The GUI can also manipulate one variable in +the kernel's namespace, and print the namespace to the console. + +Play with it by running the script and then opening one or more consoles, and +pushing the 'Counter++' and 'Namespace' buttons. + +Upon exit, it should automatically close all consoles opened from the GUI. + +Consoles attached separately from a terminal will not be terminated, though +they will notice that their kernel died. + +Ref: Modified from wxPython source code wxPython/samples/simple/simple.py +""" +#----------------------------------------------------------------------------- +# Imports +#----------------------------------------------------------------------------- +import sys + +import wx + +from internal_ipkernel import InternalIPKernel + +#----------------------------------------------------------------------------- +# Functions and classes +#----------------------------------------------------------------------------- + +class MyFrame(wx.Frame, InternalIPKernel): + """ + This is MyFrame. It just shows a few controls on a wxPanel, + and has a simple menu. + """ + + def __init__(self, parent, title): + wx.Frame.__init__(self, parent, -1, title, + pos=(150, 150), size=(350, 285)) + + # Create the menubar + menuBar = wx.MenuBar() + + # and a menu + menu = wx.Menu() + + # add an item to the menu, using \tKeyName automatically + # creates an accelerator, the third param is some help text + # that will show up in the statusbar + menu.Append(wx.ID_EXIT, "E&xit\tAlt-X", "Exit this simple sample") + + # bind the menu event to an event handler + self.Bind(wx.EVT_MENU, self.OnTimeToClose, id=wx.ID_EXIT) + + # and put the menu on the menubar + menuBar.Append(menu, "&File") + self.SetMenuBar(menuBar) + + self.CreateStatusBar() + + # Now create the Panel to put the other controls on. + panel = wx.Panel(self) + + # and a few controls + text = wx.StaticText(panel, -1, "Hello World!") + text.SetFont(wx.Font(14, wx.SWISS, wx.NORMAL, wx.BOLD)) + text.SetSize(text.GetBestSize()) + qtconsole_btn = wx.Button(panel, -1, "Qt Console") + ns_btn = wx.Button(panel, -1, "Namespace") + count_btn = wx.Button(panel, -1, "Count++") + close_btn = wx.Button(panel, -1, "Quit") + + # bind the button events to handlers + self.Bind(wx.EVT_BUTTON, self.new_qt_console, qtconsole_btn) + self.Bind(wx.EVT_BUTTON, self.print_namespace, ns_btn) + self.Bind(wx.EVT_BUTTON, self.count, count_btn) + self.Bind(wx.EVT_BUTTON, self.OnTimeToClose, close_btn) + + # Use a sizer to layout the controls, stacked vertically and with + # a 10 pixel border around each + sizer = wx.BoxSizer(wx.VERTICAL) + for ctrl in [text, qtconsole_btn, ns_btn, count_btn, close_btn]: + sizer.Add(ctrl, 0, wx.ALL, 10) + panel.SetSizer(sizer) + panel.Layout() + + # Start the IPython kernel with gui support + self.init_ipkernel('wx') + + def OnTimeToClose(self, evt): + """Event handler for the button click.""" + print("See ya later!") + sys.stdout.flush() + self.cleanup_consoles(evt) + self.Close() + # Not sure why, but our IPython kernel seems to prevent normal WX + # shutdown, so an explicit exit() call is needed. + sys.exit() + + +class MyApp(wx.App): + def OnInit(self): + frame = MyFrame(None, "Simple wxPython App") + self.SetTopWindow(frame) + frame.Show(True) + self.ipkernel = frame.ipkernel + return True + +#----------------------------------------------------------------------------- +# Main script +#----------------------------------------------------------------------------- + +if __name__ == '__main__': + app = MyApp(redirect=False, clearSigInt=False) + + # Very important, IPython-specific step: this gets GUI event loop + # integration going, and it replaces calling app.MainLoop() + app.ipkernel.start() diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/ipykernel/_version.py new/ipykernel-4.9.0/ipykernel/_version.py --- old/ipykernel-4.8.2/ipykernel/_version.py 2018-02-19 17:18:28.000000000 +0100 +++ new/ipykernel-4.9.0/ipykernel/_version.py 2018-08-29 20:43:03.000000000 +0200 @@ -1,4 +1,4 @@ -version_info = (4, 8, 2) +version_info = (4, 9, 0) __version__ = '.'.join(map(str, version_info)) kernel_protocol_version_info = (5, 1) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/ipykernel/comm/manager.py new/ipykernel-4.9.0/ipykernel/comm/manager.py --- old/ipykernel-4.8.2/ipykernel/comm/manager.py 2016-11-30 10:07:29.000000000 +0100 +++ new/ipykernel-4.9.0/ipykernel/comm/manager.py 2018-08-29 20:43:01.000000000 +0200 @@ -66,7 +66,7 @@ try: return self.comms[comm_id] except KeyError: - self.log.warn("No such comm: %s", comm_id) + self.log.warning("No such comm: %s", comm_id) if self.log.isEnabledFor(logging.DEBUG): # don't create the list of keys if debug messages aren't enabled self.log.debug("Current comms: %s", list(self.comms.keys())) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/ipykernel/iostream.py new/ipykernel-4.9.0/ipykernel/iostream.py --- old/ipykernel-4.8.2/ipykernel/iostream.py 2017-12-12 16:23:23.000000000 +0100 +++ new/ipykernel-4.9.0/ipykernel/iostream.py 2018-08-29 20:43:01.000000000 +0200 @@ -276,7 +276,7 @@ topic = None encoding = 'UTF-8' - def __init__(self, session, pub_thread, name, pipe=None): + def __init__(self, session, pub_thread, name, pipe=None, echo=None): if pipe is not None: warnings.warn("pipe argument to OutStream is deprecated and ignored", DeprecationWarning) @@ -296,6 +296,13 @@ self._flush_pending = False self._io_loop = pub_thread.io_loop self._new_buffer() + self.echo = None + + if echo: + if hasattr(echo, 'read') and hasattr(echo, 'write'): + self.echo = echo + else: + raise ValueError("echo argument must be a file like object") def _is_master_process(self): return os.getpid() == self._master_pid @@ -353,6 +360,15 @@ unless the thread has been destroyed (e.g. forked subprocess). """ self._flush_pending = False + + if self.echo is not None: + try: + self.echo.flush() + except OSError as e: + if self.echo is not sys.__stderr__: + print("Flush failed: {}".format(e), + file=sys.__stderr__) + data = self._flush_buffer() if data: # FIXME: this disables Session's fork-safe check, @@ -364,6 +380,14 @@ parent=self.parent_header, ident=self.topic) def write(self, string): + if self.echo is not None: + try: + self.echo.write(string) + except OSError as e: + if self.echo is not sys.__stderr__: + print("Write failed: {}".format(e), + file=sys.__stderr__) + if self.pub_thread is None: raise ValueError('I/O operation on closed file') else: @@ -390,6 +414,9 @@ for string in sequence: self.write(string) + def writable(self): + return True + def _flush_buffer(self): """clear the current buffer and return the current buffer data. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/ipykernel/kernelapp.py new/ipykernel-4.9.0/ipykernel/kernelapp.py --- old/ipykernel-4.8.2/ipykernel/kernelapp.py 2018-02-16 12:58:10.000000000 +0100 +++ new/ipykernel-4.9.0/ipykernel/kernelapp.py 2018-08-29 20:43:01.000000000 +0200 @@ -139,6 +139,7 @@ # streams, etc. no_stdout = Bool(False, help="redirect stdout to the null device").tag(config=True) no_stderr = Bool(False, help="redirect stderr to the null device").tag(config=True) + quiet = Bool(True, help="Only send stdout/stderr to output stream").tag(config=True) outstream_class = DottedObjectName('ipykernel.iostream.OutStream', help="The importstring for the OutStream factory").tag(config=True) displayhook_class = DottedObjectName('ipykernel.displayhook.ZMQDisplayHook', @@ -322,8 +323,18 @@ """Redirect input streams and set a display hook.""" if self.outstream_class: outstream_factory = import_item(str(self.outstream_class)) - sys.stdout = outstream_factory(self.session, self.iopub_thread, u'stdout') - sys.stderr = outstream_factory(self.session, self.iopub_thread, u'stderr') + sys.stdout.flush() + + e_stdout = None if self.quiet else sys.__stdout__ + e_stderr = None if self.quiet else sys.__stderr__ + + sys.stdout = outstream_factory(self.session, self.iopub_thread, + u'stdout', + echo=e_stdout) + sys.stderr.flush() + sys.stderr = outstream_factory(self.session, self.iopub_thread, + u'stderr', + echo=e_stderr) if self.displayhook_class: displayhook_factory = import_item(str(self.displayhook_class)) self.displayhook = displayhook_factory(self.session, self.iopub_socket) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/ipykernel/kernelbase.py new/ipykernel-4.9.0/ipykernel/kernelbase.py --- old/ipykernel-4.8.2/ipykernel/kernelbase.py 2018-01-16 19:24:31.000000000 +0100 +++ new/ipykernel-4.9.0/ipykernel/kernelbase.py 2018-08-29 20:43:01.000000000 +0200 @@ -225,7 +225,7 @@ handler = self.shell_handlers.get(msg_type, None) if handler is None: - self.log.warn("Unknown message type: %r", msg_type) + self.log.warning("Unknown message type: %r", msg_type) else: self.log.debug("%s: %s", msg_type, msg) self.pre_handler_hook() @@ -563,7 +563,7 @@ #--------------------------------------------------------------------------- def apply_request(self, stream, ident, parent): - self.log.warn("""apply_request is deprecated in kernel_base, moving to ipyparallel.""") + self.log.warning("apply_request is deprecated in kernel_base, moving to ipyparallel.") try: content = parent[u'content'] bufs = parent[u'buffers'] @@ -595,7 +595,7 @@ def abort_request(self, stream, ident, parent): """abort a specific msg by id""" - self.log.warn("abort_request is deprecated in kernel_base. It os only part of IPython parallel") + self.log.warning("abort_request is deprecated in kernel_base. It os only part of IPython parallel") msg_ids = parent['content'].get('msg_ids', None) if isinstance(msg_ids, string_types): msg_ids = [msg_ids] @@ -611,7 +611,7 @@ def clear_request(self, stream, idents, parent): """Clear our namespace.""" - self.log.warn("clear_request is deprecated in kernel_base. It os only part of IPython parallel") + self.log.warning("clear_request is deprecated in kernel_base. It os only part of IPython parallel") content = self.do_clear() self.session.send(stream, 'clear_reply', ident=idents, parent=parent, content = content) @@ -728,7 +728,7 @@ try: ident, reply = self.session.recv(self.stdin_socket, 0) except Exception: - self.log.warn("Invalid Message:", exc_info=True) + self.log.warning("Invalid Message:", exc_info=True) except KeyboardInterrupt: # re-raise KeyboardInterrupt, to truncate traceback raise KeyboardInterrupt diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/ipykernel/pylab/backend_inline.py new/ipykernel-4.9.0/ipykernel/pylab/backend_inline.py --- old/ipykernel-4.8.2/ipykernel/pylab/backend_inline.py 2017-10-30 14:30:42.000000000 +0100 +++ new/ipykernel-4.9.0/ipykernel/pylab/backend_inline.py 2018-08-29 20:43:03.000000000 +0200 @@ -7,6 +7,7 @@ import matplotlib from matplotlib.backends.backend_agg import new_figure_manager, FigureCanvasAgg # analysis: ignore +from matplotlib import colors from matplotlib._pylab_helpers import Gcf from IPython.core.getipython import get_ipython @@ -33,7 +34,10 @@ close = InlineBackend.instance().close_figures try: for figure_manager in Gcf.get_all_fig_managers(): - display(figure_manager.canvas.figure) + display( + figure_manager.canvas.figure, + metadata=_fetch_figure_metadata(figure_manager.canvas.figure) + ) finally: show._to_draw = [] # only call close('all') if any to close @@ -72,7 +76,7 @@ if not hasattr(fig, 'show'): # Queue up `fig` for display - fig.show = lambda *a: display(fig) + fig.show = lambda *a: display(fig, metadata=_fetch_figure_metadata(fig)) # If matplotlib was manually set to non-interactive mode, this function # should be a no-op (otherwise we'll generate duplicate plots, since a user @@ -124,7 +128,7 @@ active = set([fm.canvas.figure for fm in Gcf.get_all_fig_managers()]) for fig in [ fig for fig in show._to_draw if fig in active ]: try: - display(fig) + display(fig, metadata=_fetch_figure_metadata(fig)) except Exception as e: # safely show traceback if in IPython, else raise ip = get_ipython() @@ -163,3 +167,30 @@ ip.events.register('post_run_cell', configure_once) _enable_matplotlib_integration() + +def _fetch_figure_metadata(fig): + """Get some metadata to help with displaying a figure.""" + # determine if a background is needed for legibility + if _is_transparent(fig.get_facecolor()): + # the background is transparent + ticksLight = _is_light([label.get_color() + for axes in fig.axes + for axis in (axes.xaxis, axes.yaxis) + for label in axis.get_ticklabels()]) + if ticksLight.size and (ticksLight == ticksLight[0]).all(): + # there are one or more tick labels, all with the same lightness + return {'needs_background': 'dark' if ticksLight[0] else 'light'} + + return None + +def _is_light(color): + """Determines if a color (or each of a sequence of colors) is light (as + opposed to dark). Based on ITU BT.601 luminance formula (see + https://stackoverflow.com/a/596241).""" + rgbaArr = colors.to_rgba_array(color) + return rgbaArr[:,:3].dot((.299, .587, .114)) > .5 + +def _is_transparent(color): + """Determine transparency from alpha.""" + rgba = colors.to_rgba(color) + return rgba[3] < .5 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/setup.cfg new/ipykernel-4.9.0/setup.cfg --- old/ipykernel-4.8.2/setup.cfg 2017-12-06 11:41:42.000000000 +0100 +++ new/ipykernel-4.9.0/setup.cfg 2018-08-29 20:43:01.000000000 +0200 @@ -1,6 +1,9 @@ [bdist_wheel] universal=0 +[metadata] +license_file = COPYING.md + [nosetests] warningfilters= default |.* |DeprecationWarning |ipykernel.* error |.*invalid.* |DeprecationWarning |matplotlib.* diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/ipykernel-4.8.2/setup.py new/ipykernel-4.9.0/setup.py --- old/ipykernel-4.8.2/setup.py 2018-02-08 17:54:43.000000000 +0100 +++ new/ipykernel-4.9.0/setup.py 2018-08-29 20:43:03.000000000 +0200 @@ -16,8 +16,8 @@ import sys v = sys.version_info -if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,3)): - error = "ERROR: %s requires Python version 2.7 or 3.3 or above." % name +if v[:2] < (2,7) or (v[0] >= 3 and v[:2] < (3,4)): + error = "ERROR: %s requires Python version 2.7 or 3.4 or above." % name print(error, file=sys.stderr) sys.exit(1) @@ -101,12 +101,13 @@ glob(pjoin('data_kernelspec', '*'))), ] + +setuptools_args['python_requires'] = '>=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*' + extras_require = setuptools_args['extras_require'] = { 'test:python_version=="2.7"': ['mock'], - # pytest 3.3 doesn't work on Python 3.3 - 'test:python_version=="3.3"': ['pytest==3.2.*'], - 'test:python_version!="3.3"': ['pytest>=3.2'], 'test': [ + 'pytest', 'pytest-cov', 'nose', # nose because there are still a few nose.tools imports hanging around ],