Hello community,

here is the log from the commit of package python-metakernel for 
openSUSE:Factory checked in at 2019-06-01 09:56:24
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-metakernel (Old)
 and      /work/SRC/openSUSE:Factory/.python-metakernel.new.5148 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "python-metakernel"

Sat Jun  1 09:56:24 2019 rev:2 rq:706397 version:0.23.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/python-metakernel/python-metakernel.changes      
2019-05-22 11:05:35.246579415 +0200
+++ 
/work/SRC/openSUSE:Factory/.python-metakernel.new.5148/python-metakernel.changes
    2019-06-01 09:56:28.203181507 +0200
@@ -1,0 +2,20 @@
+Wed May 29 20:10:40 UTC 2019 - Todd R <toddrme2...@gmail.com>
+
+- Update to 0.23.0
+  * Clean up configurability handling and docs 
+  * fix handling of kernel class
+  * export the metakernel app
+  * Add settings handling
+  * switch to powershell on windows
+  * clean up interrupt behavior and error handling
+  * clean up stdin handler
+  * clean up replwrap prompt handling
+  * avoid double printing output
+  * add support for cr printing
+  * Fix handling metadata in _formatter
+  * Define cluster_size and cluster_rank on host kernel
+  * kernel.parent can be None in some situations
+  * Allow help and info to return mime-type data
+  * Adjustment for newer jedi
+
+-------------------------------------------------------------------

Old:
----
  metakernel-0.20.14.tar.gz

New:
----
  metakernel-0.23.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ python-metakernel.spec ++++++
--- /var/tmp/diff_new_pack.iPLD1n/_old  2019-06-01 09:56:28.723181329 +0200
+++ /var/tmp/diff_new_pack.iPLD1n/_new  2019-06-01 09:56:28.727181328 +0200
@@ -17,35 +17,26 @@
 
 
 %{?!python_module:%define python_module() python-%{**} python3-%{**}}
-# Tests require an active terminal
 %bcond_with     test
 Name:           python-metakernel
-Version:        0.20.14
+Version:        0.23.0
 Release:        0
 Summary:        Metakernel for Jupyter
 License:        BSD-3-Clause
 Group:          Development/Languages/Python
 URL:            https://github.com/Calysto/metakernel
 Source:         
https://files.pythonhosted.org/packages/source/m/metakernel/metakernel-%{version}.tar.gz
-BuildRequires:  %{python_module ipykernel}
-BuildRequires:  %{python_module ipython}
-BuildRequires:  %{python_module jupyter_client}
-BuildRequires:  %{python_module jupyter_core}
 BuildRequires:  %{python_module setuptools}
 BuildRequires:  fdupes
 BuildRequires:  python-rpm-macros
-Requires:       jupyter-ipykernel
-Requires:       jupyter-jupyter_client
-Requires:       jupyter-jupyter_core
+Requires:       python-ipykernel
 Requires:       python-ipython
+Requires:       python-jupyter_client
+Requires:       python-jupyter_core
 Requires:       python-pexpect >= 4.2
 Provides:       python-jupyter_metakernel = %{version}
-Obsoletes:      python-jupyter_metakernel <= %{version}
+Obsoletes:      python-jupyter_metakernel < %{version}
 BuildArch:      noarch
-%if %{with test}
-BuildRequires:  %{python_module pexpect >= 4.2}
-BuildRequires:  bash
-%endif
 %ifpython3
 Provides:       jupyter-metakernel = %{version}
 %endif
@@ -74,10 +65,10 @@
 %fdupes %{buildroot}%{$python_sitelib}
 }
 
-%if %{with test}
-%check
-%python_exec setup.py test
-%endif
+# Tests require an active terminal
+# %%check
+# %%python_exec setup.py test
+# %%endif
 
 %files %{python_files}
 %doc CONTRIBUTORS.rst HISTORY.rst README.rst

++++++ metakernel-0.20.14.tar.gz -> metakernel-0.23.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/PKG-INFO 
new/metakernel-0.23.0/PKG-INFO
--- old/metakernel-0.20.14/PKG-INFO     2018-01-23 22:30:35.000000000 +0100
+++ new/metakernel-0.23.0/PKG-INFO      2019-05-10 20:02:16.000000000 +0200
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: metakernel
-Version: 0.20.14
+Version: 0.23.0
 Summary: Metakernel for Jupyter
 Home-page: https://github.com/Calysto/metakernel
 Author: Steven Silvester
 Author-email: steven.silves...@ieee.org
 License: UNKNOWN
-Description: A Jupyter/IPython kernel template which includes core magic 
functions (including help, command and file path completion, parallel and 
distributed processing, downloads, and much more).
+Description: A Jupyter kernel base class in Python which includes core magic 
functions (including help, command and file path completion, parallel and 
distributed processing, downloads, and much more).
         
         .. image:: https://badge.fury.io/py/metakernel.png/
             :target: http://badge.fury.io/py/metakernel
@@ -17,9 +17,15 @@
         .. image:: https://travis-ci.org/Calysto/metakernel.svg
           :target: https://travis-ci.org/Calysto/metakernel
         
+        .. image:: 
https://anaconda.org/conda-forge/metakernel/badges/version.svg
+            :target: https://anaconda.org/conda-forge/metakernel
         
-        See IPython's docs on `wrapper kernels
-        <http://ipython.org/ipython-doc/dev/development/wrapperkernels.html>`_.
+        .. image:: 
https://anaconda.org/conda-forge/metakernel/badges/downloads.svg
+            :target: https://anaconda.org/conda-forge/metakernel
+        
+        
+        See Jupyter's docs on `wrapper kernels
+        <http://jupyter-client.readthedocs.io/en/stable/wrapperkernels.html>`_.
         
         Additional magics can be installed within the new kernel package under 
a `magics` subpackage.
         
@@ -55,25 +61,44 @@
         
         Installation
         ----------------
-        You can install Metakernel through `pip`:
+        You can install Metakernel through ``pip``:
+        
+        .. code::bash
+        
+         pip install metakernel --upgrade
+        
+        Installing `metakernel` from the `conda-forge` channel can be achieved 
by adding `conda-forge` to your channels with:
+        
+        .. code::bash
+        
+         conda config --add channels conda-forge
+        
+        Once the `conda-forge` channel has been enabled, `metakernel` can be 
installed with:
         
+        .. code::bash
         
-        `pip install metakernel --upgrade`
+         conda install metakernel
+        
+        It is possible to list all of the versions of `metakernel` available 
on your platform with:
+        
+        .. code::bash
+        
+         conda search metakernel --channel conda-forge
         
         
         Use MetaKernel Magics in IPython
         --------------------------------
         
-        Although MetaKernel is a system for building new kernels, you can use 
a subset of the magics in the IPython kernel. 
+        Although MetaKernel is a system for building new kernels, you can use 
a subset of the magics in the IPython kernel.
         
-        .. code-block:: python
+        .. code:: python
         
          from metakernel import register_ipython_magics
          register_ipython_magics()
         
-        Put the following in your (or a system-wide) ipython_config.py file:
+        Put the following in your (or a system-wide) ``ipython_config.py`` 
file:
         
-        .. code-block:: python
+        .. code:: python
         
          # /etc/ipython/ipython_config.py
          c = get_config()
@@ -83,6 +108,102 @@
          ]
          c.InteractiveShellApp.exec_lines = startup
         
+        Use MetaKernel Languages in Parallel
+        
+        To use a MetaKernel language in parallel, do the following:
+        
+        1. Make sure that the Python module `ipyparallel` is installed. In the 
shell, type:
+        
+        .. code:: bash
+        
+          pip install ipyparallel
+        
+        
+        2. To enable the extension in the notebook, in the shell, type:
+        
+        .. code:: bash
+        
+          ipcluster nbextension enable
+        
+        
+        3. To start up a cluster, with 10 nodes, on a local IP address, in the 
shell, type:
+        
+        .. code:: bash
+        
+          ipcluster start --n=10 --ip=192.168.1.108
+        
+        
+        4. Initialize the code to use the 10 nodes, inside the notebook from a 
host kernel ``MODULE`` and ``CLASSNAME`` (can be any metakernel kernel):
+        
+        .. code:: bash
+        
+          %parallel MODULE CLASSNAME
+        
+        
+        For example:
+        
+        .. code:: bash
+        
+          %parallel calysto_scheme CalystoScheme
+        
+        
+        5. Run code in parallel, inside the notebook, type:
+        
+        Execute a single line, in parallel:
+        
+        .. code:: bash
+        
+          %px (+ 1 1)
+        
+        
+        Or execute the entire cell, in parallel:
+        
+        .. code:: bash
+        
+          %%px
+          (* cluster_rank cluster_rank)
+        
+        
+        Results come back in a Python list (Scheme vector), in 
``cluster_rank`` order. (This will be a JSON representation in the future).
+        
+        Therefore, the above would produce the result:
+        
+        .. code:: bash
+        
+          #10(0 1 4 9 16 25 36 49 64 81)
+        
+        You can get the results back in any of the parallel magics (``%px``, 
``%%px``, or ``%pmap``) in the host kernel by accessing the variable ``_`` 
(single underscore), or by using the ``--set_variable VARIABLE`` flag, like so:
+        
+        .. code:: bash
+        
+          %%px --set_variable results
+          (* cluster_rank cluster_rank)
+        
+        
+        Then, in the next cell, you can access ``results``.
+        
+        Notice that you can use the variable ``cluster_rank`` to partition 
parts of a problem so that each node is working on something different.
+        
+        In the examples above, use ``-e`` to evaluate the code in the host 
kernel as well. Note that ``cluster_rank`` is not defined on the host machine, 
and that this assumes the host kernel is the same as the parallel machines.
+        
+        
+        Configuration
+        -------------
+        ``Metakernel`` implementations can subclasses can be configured by the 
user.  The
+        configuration file name is determined by the ``app_name`` property of 
the subclass.
+        For example, in the ``Octave`` kernel, it is ``octave_kernel``.  The 
user of the kernel can add an ``octave_kernel_config.py`` file to their
+        ``jupyter`` config path.  The base ``MetaKernel`` class offers 
``plot_settings`` as a configurable trait.  Subclasses can defined other traits 
that they wish to make
+        configurable.
+        
+        As an example:
+        
+        .. code:: bash
+        
+            cat ~/.jupyter/octave_kernel_config.py
+            # use Qt as the default backend for plots
+            c.OctaveKernel.plot_settings = dict(backend='qt')
+        
+        
         Documentation
         -----------------------
         
@@ -101,13 +222,11 @@
         
         .. _History: 
https://github.com/Calysto/metakernel/blob/master/HISTORY.rst
         
-        
-        
 Platform: UNKNOWN
 Classifier: Framework :: IPython
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 2
 Classifier: Topic :: System :: Shells
-Requires: ipykernel (< 6.0)
+Requires: ipykernel
 Requires: pexpect (>= 4.2)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/README.rst 
new/metakernel-0.23.0/README.rst
--- old/metakernel-0.20.14/README.rst   2018-01-23 21:06:42.000000000 +0100
+++ new/metakernel-0.23.0/README.rst    2019-05-10 20:01:47.000000000 +0200
@@ -1,4 +1,4 @@
-A Jupyter/IPython kernel template which includes core magic functions 
(including help, command and file path completion, parallel and distributed 
processing, downloads, and much more).
+A Jupyter kernel base class in Python which includes core magic functions 
(including help, command and file path completion, parallel and distributed 
processing, downloads, and much more).
 
 .. image:: https://badge.fury.io/py/metakernel.png/
     :target: http://badge.fury.io/py/metakernel
@@ -9,9 +9,15 @@
 .. image:: https://travis-ci.org/Calysto/metakernel.svg
   :target: https://travis-ci.org/Calysto/metakernel
 
+.. image:: https://anaconda.org/conda-forge/metakernel/badges/version.svg
+    :target: https://anaconda.org/conda-forge/metakernel
 
-See IPython's docs on `wrapper kernels
-<http://ipython.org/ipython-doc/dev/development/wrapperkernels.html>`_.
+.. image:: https://anaconda.org/conda-forge/metakernel/badges/downloads.svg
+    :target: https://anaconda.org/conda-forge/metakernel
+
+
+See Jupyter's docs on `wrapper kernels
+<http://jupyter-client.readthedocs.io/en/stable/wrapperkernels.html>`_.
 
 Additional magics can be installed within the new kernel package under a 
`magics` subpackage.
 
@@ -47,25 +53,44 @@
 
 Installation
 ----------------
-You can install Metakernel through `pip`:
+You can install Metakernel through ``pip``:
+
+.. code::bash
+
+ pip install metakernel --upgrade
+
+Installing `metakernel` from the `conda-forge` channel can be achieved by 
adding `conda-forge` to your channels with:
+
+.. code::bash
+
+ conda config --add channels conda-forge
+
+Once the `conda-forge` channel has been enabled, `metakernel` can be installed 
with:
 
+.. code::bash
 
-`pip install metakernel --upgrade`
+ conda install metakernel
+
+It is possible to list all of the versions of `metakernel` available on your 
platform with:
+
+.. code::bash
+
+ conda search metakernel --channel conda-forge
 
 
 Use MetaKernel Magics in IPython
 --------------------------------
 
-Although MetaKernel is a system for building new kernels, you can use a subset 
of the magics in the IPython kernel. 
+Although MetaKernel is a system for building new kernels, you can use a subset 
of the magics in the IPython kernel.
 
-.. code-block:: python
+.. code:: python
 
  from metakernel import register_ipython_magics
  register_ipython_magics()
 
-Put the following in your (or a system-wide) ipython_config.py file:
+Put the following in your (or a system-wide) ``ipython_config.py`` file:
 
-.. code-block:: python
+.. code:: python
 
  # /etc/ipython/ipython_config.py
  c = get_config()
@@ -75,6 +100,102 @@
  ]
  c.InteractiveShellApp.exec_lines = startup
 
+Use MetaKernel Languages in Parallel
+
+To use a MetaKernel language in parallel, do the following:
+
+1. Make sure that the Python module `ipyparallel` is installed. In the shell, 
type:
+
+.. code:: bash
+
+  pip install ipyparallel
+
+
+2. To enable the extension in the notebook, in the shell, type:
+
+.. code:: bash
+
+  ipcluster nbextension enable
+
+
+3. To start up a cluster, with 10 nodes, on a local IP address, in the shell, 
type:
+
+.. code:: bash
+
+  ipcluster start --n=10 --ip=192.168.1.108
+
+
+4. Initialize the code to use the 10 nodes, inside the notebook from a host 
kernel ``MODULE`` and ``CLASSNAME`` (can be any metakernel kernel):
+
+.. code:: bash
+
+  %parallel MODULE CLASSNAME
+
+
+For example:
+
+.. code:: bash
+
+  %parallel calysto_scheme CalystoScheme
+
+
+5. Run code in parallel, inside the notebook, type:
+
+Execute a single line, in parallel:
+
+.. code:: bash
+
+  %px (+ 1 1)
+
+
+Or execute the entire cell, in parallel:
+
+.. code:: bash
+
+  %%px
+  (* cluster_rank cluster_rank)
+
+
+Results come back in a Python list (Scheme vector), in ``cluster_rank`` order. 
(This will be a JSON representation in the future).
+
+Therefore, the above would produce the result:
+
+.. code:: bash
+
+  #10(0 1 4 9 16 25 36 49 64 81)
+
+You can get the results back in any of the parallel magics (``%px``, ``%%px``, 
or ``%pmap``) in the host kernel by accessing the variable ``_`` (single 
underscore), or by using the ``--set_variable VARIABLE`` flag, like so:
+
+.. code:: bash
+
+  %%px --set_variable results
+  (* cluster_rank cluster_rank)
+
+
+Then, in the next cell, you can access ``results``.
+
+Notice that you can use the variable ``cluster_rank`` to partition parts of a 
problem so that each node is working on something different.
+
+In the examples above, use ``-e`` to evaluate the code in the host kernel as 
well. Note that ``cluster_rank`` is not defined on the host machine, and that 
this assumes the host kernel is the same as the parallel machines.
+
+
+Configuration
+-------------
+``Metakernel`` implementations can subclasses can be configured by the user.  
The
+configuration file name is determined by the ``app_name`` property of the 
subclass.
+For example, in the ``Octave`` kernel, it is ``octave_kernel``.  The user of 
the kernel can add an ``octave_kernel_config.py`` file to their
+``jupyter`` config path.  The base ``MetaKernel`` class offers 
``plot_settings`` as a configurable trait.  Subclasses can defined other traits 
that they wish to make
+configurable.
+
+As an example:
+
+.. code:: bash
+
+    cat ~/.jupyter/octave_kernel_config.py
+    # use Qt as the default backend for plots
+    c.OctaveKernel.plot_settings = dict(backend='qt')
+
+
 Documentation
 -----------------------
 
@@ -92,5 +213,3 @@
 .. _online: http://Calysto.github.io/metakernel/
 
 .. _History: https://github.com/Calysto/metakernel/blob/master/HISTORY.rst
-
-
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel/__init__.py 
new/metakernel-0.23.0/metakernel/__init__.py
--- old/metakernel-0.20.14/metakernel/__init__.py       2018-01-23 
22:18:33.000000000 +0100
+++ new/metakernel-0.23.0/metakernel/__init__.py        2019-05-10 
20:02:08.000000000 +0200
@@ -1,5 +1,6 @@
 from ._metakernel import (
-    ExceptionWrapper, MetaKernel, IPythonKernel, register_ipython_magics, 
get_metakernel)
+    ExceptionWrapper, MetaKernel, IPythonKernel, register_ipython_magics, 
get_metakernel,
+    MetaKernelApp)
 from . import pexpect
 from .replwrap import REPLWrapper, u
 from .process_metakernel import ProcessMetaKernel
@@ -8,6 +9,6 @@
 
 __all__ = ['Magic', 'MetaKernel', 'option']
 
-__version__ = '0.20.14'
+__version__ = '0.23.0'
 
 del magic, _metakernel, parser, process_metakernel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel/_metakernel.py 
new/metakernel-0.23.0/metakernel/_metakernel.py
--- old/metakernel-0.20.14/metakernel/_metakernel.py    2018-01-23 
21:41:36.000000000 +0100
+++ new/metakernel-0.23.0/metakernel/_metakernel.py     2019-05-10 
20:01:47.000000000 +0200
@@ -17,11 +17,13 @@
 
 warnings.filterwarnings('ignore', module='IPython.html.widgets')
 
+from jupyter_core.paths import jupyter_config_path, jupyter_config_dir
 from IPython.paths import get_ipython_dir
 from ipykernel.kernelapp import IPKernelApp
 from ipykernel.kernelbase import Kernel
 from ipykernel.comm import CommManager
 from traitlets.config import Application
+from traitlets import Dict, Unicode
 
 try:
     from ipywidgets.widgets.widget import Widget
@@ -78,6 +80,7 @@
 
 
 class MetaKernel(Kernel):
+    app_name = 'metakernel'
     identifier_regex = r'[^\d\W][\w\.]*'
     func_call_regex = r'([^\d\W][\w\.]*)\([^\)\()]*\Z'
     magic_prefixes = dict(magic='%', shell='!', help='?')
@@ -85,7 +88,7 @@
     help_links = [
         {
             'text': "MetaKernel Magics",
-            'url': 
"https://github.com/calysto/metakernel/blob/master/metakernel/magics/README.md";,
+            'url': 
"https://metakernel.readthedocs.io/en/latest/source/README.html";,
         },
     ]
     language_info = {
@@ -101,10 +104,12 @@
         # 'file_extension': '.py',
         'help_links': help_links,
     }
+    plot_settings = Dict(dict(backend='inline')).tag(config=True)
+
     meta_kernel = None
 
     @classmethod
-    def run_as_main(cls):
+    def run_as_main(cls, *args, **kwargs):
         """Launch or install a metakernel.
 
         Modules implementing a metakernel subclass can use the following lines:
@@ -112,7 +117,8 @@
             if __name__ == '__main__':
                 MetaKernelSubclass.run_as_main()
         """
-        MetaKernelApp.launch_instance(kernel_class=cls)
+        kwargs['app_name'] = cls.app_name
+        MetaKernelApp.launch_instance(kernel_class=cls, *args, **kwargs)
 
     def __init__(self, *args, **kwargs):
         super(MetaKernel, self).__init__(*args, **kwargs)
@@ -130,6 +136,8 @@
                 sys.stdout.write = self.Write
             except:
                 pass  # Can't change stdout
+        self.redirect_to_log = False
+        self.shell = None
         self.sticky_magics = OrderedDict()
         self._i = None
         self._ii = None
@@ -144,7 +152,6 @@
         self.comm_manager.register_target('ipython.widget',
             lazy_import_handle_comm_opened)
 
-        self.plot_settings = dict(backend='inline')
         self.hist_file = get_history_file(self)
         self.parser = Parser(self.identifier_regex, self.func_call_regex,
                              self.magic_prefixes, self.help_suffix)
@@ -156,6 +163,21 @@
         self.reload_magics()
         # provide a way to get the current instance
         self.set_variable("kernel", self)
+        # Run command line filenames, if given:
+        if self.parent is not None and self.parent.extra_args:
+            level = self.log.level
+            self.log.setLevel("INFO")
+            self.redirect_to_log = True
+            self.Write("Executing files...")
+            for filename in self.parent.extra_args:
+                self.Write("    %s..." % filename)
+                try:
+                    self.do_execute_file(filename)
+                except Exception as exc:
+                    self.log.info("    %s" % (exc,))
+            self.Write("Executing files: done!")
+            self.log.setLevel(level)
+            self.redirect_to_log = False
 
     def makeSubkernel(self, kernel):
         """
@@ -315,11 +337,18 @@
             else:
                 level = 1
             text = self.get_help_on(code, level)
-            self.log.debug(text)
             if text:
-                self.payload = [{"data": {"text/plain": text},
-                                 "start_line_number": 0,
-                                 "source": "page"}]
+                content = {
+                    "start_line_number": 0,
+                    "source": "page",
+                }
+                if isinstance(text, dict):
+                    content["data"] = text ## {mime-type: ..., mime-type:...}
+                    self.log.debug(str(text))
+                else:
+                    content["data"] = {"text/plain": text}
+                    self.log.debug(text)
+                self.payload = [content]
 
         elif info['magic'] or self.sticky_magics:
             retval = None
@@ -399,8 +428,8 @@
                     return
                 content = {
                     'execution_count': self.execution_count,
-                    'data': data,
-                    'metadata': {},
+                    'data': data[0],
+                    'metadata': data[1],
                 }
                 if not silent:
                     if Widget and isinstance(retval, Widget):
@@ -529,10 +558,14 @@
              cursor_pos=cursor_pos)
 
         if docstring:
-            content["data"] = {"text/plain": docstring}
             content["status"] = "ok"
             content["found"] = True
-            self.log.debug(docstring)
+            if isinstance(docstring, dict): ## {"text/plain": ..., mime-type: 
...}
+                content["data"] = docstring
+                self.log.debug(str(docstring))
+            else:
+                content["data"] = {"text/plain": docstring}
+                self.log.debug(docstring)
 
         return content
 
@@ -549,13 +582,13 @@
         # Make a metakernel/magics if it doesn't exist:
         local_magics_dir = get_local_magics_dir()
         # Search all of the places there could be magics:
-        paths = [local_magics_dir,
-                 os.path.join(os.path.dirname(os.path.abspath(__file__)), 
"magics")]
         try:
-            paths += [os.path.join(os.path.dirname(
+            paths = [os.path.join(os.path.dirname(
                 os.path.abspath(inspect.getfile(self.__class__))), "magics")]
         except:
-            pass
+            paths = []
+        paths += [local_magics_dir,
+                  os.path.join(os.path.dirname(os.path.abspath(__file__)), 
"magics")]
         for magic_dir in paths:
             sys.path.append(magic_dir)
             magic_files.extend(glob.glob(os.path.join(magic_dir, "*.py")))
@@ -602,8 +635,8 @@
                     self.Error(e)
                     return
                 content = {
-                    'data': data,
-                    'metadata': {}
+                    'data': data[0],
+                    'metadata': data[1]
                 }
                 self.send_response(
                     self.iopub_socket,
@@ -628,13 +661,19 @@
         stream_content = {
             'name': 'stdout', 'text': message}
         self.log.debug('Print: %s' % message)
-        self.send_response(self.iopub_socket, 'stream', stream_content)
+        if self.redirect_to_log:
+            self.log.info(message)
+        else:
+            self.send_response(self.iopub_socket, 'stream', stream_content)
 
     def Write(self, message):
         stream_content = {
             'name': 'stdout', 'text': message}
         self.log.debug('Write: %s' % message)
-        self.send_response(self.iopub_socket, 'stream', stream_content)
+        if self.redirect_to_log:
+            self.log.info(message)
+        else:
+            self.send_response(self.iopub_socket, 'stream', stream_content)
 
     def Error(self, *args, **kwargs):
         message = format_message(*args, **kwargs)
@@ -643,7 +682,16 @@
             'name': 'stderr',
             'text': RED + message + NORMAL
         }
-        self.send_response(self.iopub_socket, 'stream', stream_content)
+        if self.redirect_to_log:
+            self.log.info(message)
+        else:
+            self.send_response(self.iopub_socket, 'stream', stream_content)
+
+    def send_response(self, *args, **kwargs):
+        ### if we are running via %parallel, we might not have a
+        ### session
+        if self.session:
+            super(MetaKernel, self).send_response(*args, **kwargs)
 
     def call_magic(self, line):
         """
@@ -687,6 +735,24 @@
 
 class MetaKernelApp(IPKernelApp):
 
+    config_dir = Unicode()
+
+    def _config_dir_default(self):
+        return jupyter_config_dir()
+
+    @property
+    def config_file_paths(self):
+        path = jupyter_config_path()
+        if self.config_dir not in path:
+            path.insert(0, self.config_dir)
+        path.insert(0, os.getcwd())
+        return path
+
+    @classmethod
+    def launch_instance(cls, *args, **kwargs):
+        cls.name = kwargs.pop('app_name', 'metakernel')
+        super(MetaKernelApp, cls).launch_instance(*args, **kwargs)
+
     @property
     def subcommands(self):
         # Slightly awkward way to pass the actual kernel class to the install
@@ -699,7 +765,7 @@
                 self.argv = argv
 
             def start(self):
-                kernel_spec = self.kernel_class.kernel_json
+                kernel_spec = self.kernel_class().kernel_json
                 with TemporaryDirectory() as td:
                     dirname = os.path.join(td, kernel_spec['name'])
                     os.mkdir(dirname)
@@ -767,14 +833,19 @@
         if obj:
             reprs[mimetype] = obj
 
-    retval = {}
+    format_dict = {}
+    metadata_dict = {}
     for (mimetype, value) in reprs.items():
+        metadata = None
         try:
             value = value()
         except Exception:
             pass
         if not value:
             continue
+        if isinstance(value, tuple):
+            metadata = value[1]
+            value = value[0]
         if isinstance(value, bytes):
             try:
                 value = value.decode('utf-8')
@@ -782,10 +853,12 @@
                 value = base64.encodestring(value)
                 value = value.decode('utf-8')
         try:
-            retval[mimetype] = str(value)
+            format_dict[mimetype] = str(value)
         except:
-            retval[mimetype] = value
-    return retval
+            format_dict[mimetype] = value
+        if metadata is not None:
+            metadata_dict[mimetype] = metadata
+    return (format_dict, metadata_dict)
 
 
 def format_message(*args, **kwargs):
Binary files old/metakernel-0.20.14/metakernel/images/logo-512x512.png and 
new/metakernel-0.23.0/metakernel/images/logo-512x512.png differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel/magic.py 
new/metakernel-0.23.0/metakernel/magic.py
--- old/metakernel-0.20.14/metakernel/magic.py  2018-01-23 21:41:36.000000000 
+0100
+++ new/metakernel-0.23.0/metakernel/magic.py   2019-04-30 11:15:55.000000000 
+0200
@@ -12,6 +12,7 @@
     # python3
     _maxsize = sys.maxsize
 
+
 class MagicOptionParser(optparse.OptionParser):
     def error(self, msg):
         raise Exception('Magic Parse error: "%s"' % msg)
@@ -24,7 +25,18 @@
     ## FIXME: override help to also stop processing
     ## currently --help gives syntax error
 
+
 class Magic(object):
+    """
+    Base class to define magics for MetaKernel based kernels.
+
+    Users can redefine the default magics provided by Metakernel
+    by creating a module with the exact same name as the
+    Metakernel magic.
+
+    For example, you can override %matplotlib in your kernel by
+    writing a new magic inside magics/matplotlib_magic.py
+    """
 
     def __init__(self, kernel):
         self.kernel = kernel
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/metakernel-0.20.14/metakernel/magics/parallel_magic.py 
new/metakernel-0.23.0/metakernel/magics/parallel_magic.py
--- old/metakernel-0.20.14/metakernel/magics/parallel_magic.py  2018-01-23 
21:41:36.000000000 +0100
+++ new/metakernel-0.23.0/metakernel/magics/parallel_magic.py   2019-04-30 
11:15:55.000000000 +0200
@@ -40,7 +40,7 @@
 
             %parallel bash_kernel BashKernel 
             %parallel bash_kernel BashKernel -k bash
-            %parallel bash_kernel BashKernel --i [0,2:5,9,...]
+            %parallel bash_kernel BashKernel -i [0,2:5,9,...]
 
         cluster_size and cluster_rank variables are set upon 
         initialization of the remote node (if the kernel 
@@ -144,6 +144,9 @@
         self.client[:].scatter('cluster_rank', self.client.ids, flatten=True)
         self.view["kernels['%s'].set_variable(\"cluster_rank\", cluster_rank)" 
% (
             kernel_name)]
+        ## So that these are available in the host kernel:
+        self.kernel.set_variable("cluster_size", len(self.client))
+        self.kernel.set_variable("cluster_rank", -1)
         self.retval = None
 
     @option(
@@ -155,7 +158,11 @@
         help=('evaluate code in the current kernel, too. The current ' +
               'kernel should be of the same language as the cluster.')
     )
-    def line_px(self, expression, kernel_name=None, evaluate=False):
+    @option(
+        '-s', '--set_variable', action='store', default=None,
+        help='set the variable with the parallel results rather than returning 
them'
+    )
+    def line_px(self, expression, kernel_name=None, evaluate=False, 
set_variable=None):
         """
         %px EXPRESSION - send EXPRESSION to the cluster.
 
@@ -172,6 +179,7 @@
 
         Use %parallel to initialize the cluster.
         """
+        results = None
         expression = str(expression)
         if kernel_name is None:
             kernel_name = self.kernel_name
@@ -179,7 +187,7 @@
             count = 1
             while count <= 5:
                 try:
-                    self.retval = 
self.view["kernels['%s'].do_execute_direct(\"%s\")" % (
+                    results = 
self.view["kernels['%s'].do_execute_direct(\"%s\")" % (
                         kernel_name, self._clean_code(expression))]
                     break
                 except:
@@ -191,10 +199,15 @@
             self.retry = False
         else:
             try:
-                self.retval = 
self.view["kernels['%s'].do_execute_direct(\"%s\")" % (
+                results = self.view["kernels['%s'].do_execute_direct(\"%s\")" 
% (
                     kernel_name, self._clean_code(expression))]
             except Exception as e:
-                self.retval = str(e)
+                results = str(e)
+        if set_variable is None:
+            self.retval = results
+        else:
+            self.kernel.set_variable(set_variable, results)
+            self.retval = None
         if evaluate:
             self.code = expression
 
@@ -211,7 +224,11 @@
         help=('evaluate code in the current kernel, too. The current ' +
               'kernel should be of the same language as the cluster.')
     )
-    def cell_px(self, kernel_name=None, evaluate=False):
+    @option(
+        '-s', '--set_variable', action='store', default=None,
+        help='set the variable with the parallel results rather than returning 
them'
+    )
+    def cell_px(self, kernel_name=None, evaluate=False, set_variable=None):
         """
         %%px - send cell to the cluster.
 
@@ -224,11 +241,20 @@
         """
         if kernel_name is None:
             kernel_name = self.kernel_name
-        self.retval = self.view["kernels['%s'].do_execute_direct(\"%s\")" % (
+        results = self.view["kernels['%s'].do_execute_direct(\"%s\")" % (
             kernel_name, self._clean_code(self.code))]
+        if set_variable is None:
+            self.retval = results
+        else:
+            self.kernel.set_variable(set_variable, results)
+            self.retval = None
         self.evaluate = evaluate
 
-    def line_pmap(self, function_name, args, kernel_name=None):
+    @option(
+        '-s', '--set_variable', action='store', default=None,
+        help='set the variable with the parallel results rather than returning 
them'
+    )
+    def line_pmap(self, function_name, args, kernel_name=None, 
set_variable=None):
         """
         %pmap FUNCTION [ARGS1,ARGS2,...] - ("parallel map") call a FUNCTION on 
args
 
@@ -276,7 +302,12 @@
             from IPython.parallel.util import interactive
         f = interactive(lambda arg, kname=kernel_name, fname=function_name: \
                         kernels[kname].do_function_direct(fname, arg))
-        self.retval = self.view_load_balanced.map_async(f, eval(args))
+        results = self.view_load_balanced.map_async(f, eval(args))
+        if set_variable is None:
+            self.retval = results
+        else:
+            self.kernel.set_variable(set_variable, results)
+            self.retval = None
 
     def post_process(self, retval):
         try:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel/magics/python_magic.py 
new/metakernel-0.23.0/metakernel/magics/python_magic.py
--- old/metakernel-0.20.14/metakernel/magics/python_magic.py    2018-01-23 
21:41:36.000000000 +0100
+++ new/metakernel-0.23.0/metakernel/magics/python_magic.py     2019-04-30 
11:15:55.000000000 +0200
@@ -156,7 +156,15 @@
         position = (info['line_num'], info['column'])
         interpreter = Interpreter(text, [self.env])
 
-        if jedi.__version__ >= LooseVersion('0.10.0'):
+        if jedi.__version__ >= LooseVersion('0.12.0'):
+            lines = split_lines(text)
+            name = get_on_completion_name(
+                interpreter._module_node,
+                lines,
+                position
+            )
+            before = text[:len(text) - len(name)]
+        elif jedi.__version__ >= LooseVersion('0.10.0'):
             lines = split_lines(text)
             name = get_on_completion_name(
                 interpreter._get_module_node(),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel/magics/shell_magic.py 
new/metakernel-0.23.0/metakernel/magics/shell_magic.py
--- old/metakernel-0.20.14/metakernel/magics/shell_magic.py     2018-01-23 
21:41:36.000000000 +0100
+++ new/metakernel-0.23.0/metakernel/magics/shell_magic.py      2019-05-03 
13:32:40.000000000 +0200
@@ -3,7 +3,7 @@
 
 from __future__ import print_function
 from metakernel import Magic, pexpect
-from metakernel.replwrap import cmd, bash
+from metakernel.replwrap import powershell, bash
 import os
 
 
@@ -57,8 +57,8 @@
 
         if not self.cmd:
             if os.name == 'nt':
-                self.cmd = 'cmd'
-                self.repl = cmd()
+                self.cmd = 'powershell'
+                self.repl = powershell()
             elif pexpect.which('bash'):
                 self.cmd = 'bash'
                 self.repl = bash()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel/process_metakernel.py 
new/metakernel-0.23.0/metakernel/process_metakernel.py
--- old/metakernel-0.20.14/metakernel/process_metakernel.py     2018-01-23 
21:41:36.000000000 +0100
+++ new/metakernel-0.23.0/metakernel/process_metakernel.py      2019-05-04 
11:33:12.000000000 +0200
@@ -4,6 +4,7 @@
 from .replwrap import REPLWrapper, bash
 from subprocess import check_output
 import re
+import sys
 
 __version__ = '0.0'
 
@@ -71,6 +72,7 @@
 
         interrupted = False
         output = ''
+        error = None
         stream_handler = self.Print if not silent else None
         try:
             output = wrapper.run_command(code.rstrip(), timeout=None,
@@ -82,7 +84,11 @@
         except EOF:
             self.Print(child.before)
             self.do_shutdown(True)
-            return
+            error = RuntimeError('End of File')
+            tb = 'End of File'
+        except Exception as e:
+            ex_type, error, tb = sys.exc_info()
+            self.Error(str(e))
 
         if interrupted:
             self.kernel_resp = {
@@ -99,6 +105,15 @@
                 'ename': '', 'evalue': str(exitcode),
                 'traceback': trace,
             }
+
+        elif error:
+            self.kernel_resp = {
+                'status': 'error',
+                'execution_count': self.execution_count,
+                'ename': '', 'evalue': str(error),
+                'traceback': str(tb),
+            }
+
         else:
             self.kernel_resp = {
                 'status': 'ok',
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel/replwrap.py 
new/metakernel-0.23.0/metakernel/replwrap.py
--- old/metakernel-0.20.14/metakernel/replwrap.py       2018-01-23 
21:41:36.000000000 +0100
+++ new/metakernel-0.23.0/metakernel/replwrap.py        2019-05-03 
13:32:40.000000000 +0200
@@ -3,6 +3,7 @@
 import re
 import signal
 import os
+import time
 import atexit
 
 from . import pexpect
@@ -42,13 +43,15 @@
         as positional parameters, so you can use ``{}`` style formatting to
         insert them into the command.
     :param str new_prompt_regex: The more unique prompt to expect after the 
change.
-    :param str stdin_prompt_regex: The regex for a stdin prompt from the 
+    :param str stdin_prompt_regex: The regex for a stdin prompt from the
         child process.  The prompt itself will be sent to the `stdin_handler`,
         so any sentinel value inserted will have to be removed by the caller.
     :param str extra_init_cmd: Commands to do extra initialisation, such as
       disabling pagers.
     :param str prompt_emit_cmd: Optional kernel command that emits the prompt
       when one is not emitted by default (typically happens on Windows only)
+    :param bool force_prompt_on_continuation: Whether to force a prompt when
+    we need to interrupt a continuation prompt.
     :param bool echo: Whether the child should echo, or in the case
     of Windows, whether the child does echo.
     """
@@ -59,6 +62,7 @@
                  stdin_prompt_regex=PEXPECT_STDIN_PROMPT,
                  extra_init_cmd=None,
                  prompt_emit_cmd=None,
+                 force_prompt_on_continuation=False,
                  echo=False):
         if isinstance(cmd_or_spawn, basestring):
             self.child = pexpect.spawnu(cmd_or_spawn, echo=echo,
@@ -82,6 +86,7 @@
 
         self.echo = echo
         self.prompt_emit_cmd = prompt_emit_cmd
+        self._force_prompt_on_continuation = force_prompt_on_continuation
 
         if prompt_change_cmd is None:
             self.prompt_regex = u(prompt_regex)
@@ -117,25 +122,71 @@
     def _expect_prompt(self, timeout=None):
         """Expect a prompt from the child.
         """
-        stream_handler = self._stream_handler
-        stdin_handler = self._stdin_handler
         expects = [self.prompt_regex, self.continuation_prompt_regex,
                    self.stdin_prompt_regex]
-        if stream_handler:
-            expects += [u(self.child.crlf)]
         if self.prompt_emit_cmd:
             self.sendline(self.prompt_emit_cmd)
+
+        if self._stream_handler:
+            return self._expect_prompt_stream(expects, timeout)
+
         while True:
             pos = self.child.expect(expects, timeout=timeout)
-            if pos == 2 and stdin_handler:
-                resp = stdin_handler(self.child.before + self.child.after)
+            if pos < 2:
+                return pos
+            elif not self._stdin_handler:
+                raise ValueError('Stdin Requested but not stdin handler 
available')
+
+            resp = self._stdin_handler(line + self.child.after)
+            self.sendline(resp)
+
+    def _expect_prompt_stream(self, expects, timeout=None):
+        """Expect a prompt with streaming output.
+        """
+        expects += [u(self.child.crlf)]
+        stream_handler = self._stream_handler
+        stdin_handler = self._stdin_handler
+        t0 = time.time()
+        if timeout == -1:
+            timeout = 30
+        got_cr = False
+
+        while True:
+            if timeout is not None and time.time() - t0 > timeout:
+                raise pexpect.TIMEOUT('Timed out')
+
+            line_timeout = 0.2
+            try:
+                pos = self.child.expect(expects, timeout=line_timeout)
+            except pexpect.TIMEOUT:
+                while 1:
+                    try:
+                        self.child.expect([u('\r')], timeout=0)
+                        stream_handler('\r', end='')
+                        if got_cr:
+                            stream_handler(self.child.before, end='')
+                        got_cr = True
+                    except pexpect.TIMEOUT:
+                        break
+                continue
+
+            # Handle cr state
+            line = self.child.before
+            if got_cr:
+                line = '\r' + line
+            got_cr = False
+
+            if pos == 2:
+                if not stdin_handler:
+                    raise ValueError('Stdin Requested but not stdin handler 
available')
+                resp = stdin_handler(line + self.child.after)
                 self.sendline(resp)
-            elif pos == 3:  # End of line received
-                stream_handler(self.child.before)
+            elif pos == 3:  # End of line
+                stream_handler(line)
             else:
-                if len(self.child.before) != 0 and stream_handler:
+                if len(line) != 0:
                     # prompt received, but partial line precedes it
-                    stream_handler(self.child.before)
+                    stream_handler(line)
                 break
         return pos
 
@@ -149,6 +200,10 @@
         :param int timeout: How long to wait for the next prompt. -1 means the
           default from the :class:`pexpect.spawn` object (default 30 seconds).
           None means to wait indefinitely.
+        :param func stream_handler - A function that accepts a string to print 
and
+        and optional line ending.
+        :param stdin_handler - A function that prompts the user for input and
+        returns a response.
         """
         # Split up multiline commands and feed them in bit-by-bit
         cmdlines = command.splitlines()
@@ -172,11 +227,14 @@
         # Command was fully submitted, now wait for the next prompt
         if self._expect_prompt(timeout=timeout) == 1:
             # We got the continuation prompt - command was incomplete
-            self.interrupt()
+            self.interrupt(continuation=True)
             raise ValueError("Continuation prompt found - input was 
incomplete:\n" + command)
+
+        if self._stream_handler:
+            return u''
         return u''.join(res + [self.child.before])
 
-    def interrupt(self):
+    def interrupt(self, continuation=False):
         """Interrupt the process and wait for a prompt.
 
         Returns
@@ -187,12 +245,15 @@
             self.child.sendintr()
         else:
             self.child.kill(signal.SIGINT)
+        if continuation and self._force_prompt_on_continuation:
+            self.sendline(self.prompt_change_cmd or '')
         while 1:
             try:
                 self._expect_prompt(timeout=-1)
                 break
             except KeyboardInterrupt:
                 pass
+
         return self.child.before
 
     def terminate(self):
@@ -244,8 +305,6 @@
                        extra_init_cmd=extra_init_cmd)
 
 
-def cmd(command='cmd', prompt_regex=re.compile(r'[A-Z]:\\.*>')):
-    """"Start a cmd shell and return a :class:`REPLWrapper` object."""
-    if not os.name == 'nt':
-        raise OSError('cmd only available on Windows')
-    return REPLWrapper(command, prompt_regex, None, echo=True)
+def powershell(command='powershell', prompt_regex='>'):
+    """"Start a powershell and return a :class:`REPLWrapper` object."""
+    return REPLWrapper(command, prompt_regex, 'Function prompt {{ "{0}" }}', 
echo=True)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/metakernel-0.20.14/metakernel/tests/test_process_metakernel.py 
new/metakernel-0.23.0/metakernel/tests/test_process_metakernel.py
--- old/metakernel-0.20.14/metakernel/tests/test_process_metakernel.py  
2018-01-23 21:41:36.000000000 +0100
+++ new/metakernel-0.23.0/metakernel/tests/test_process_metakernel.py   
2019-04-30 11:15:55.000000000 +0200
@@ -22,3 +22,7 @@
     
     html = HTML("some html")
     kernel.Display(html)
+
+    kernel.do_execute(r'for i in {1..3};do echo -ne "$i\r"; sleep 1; done', 
None)
+    text = get_log_text(kernel)
+    assert r'1\r2\r3\r' in text
\ No newline at end of file
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel/tests/test_replwrap.py 
new/metakernel-0.23.0/metakernel/tests/test_replwrap.py
--- old/metakernel-0.20.14/metakernel/tests/test_replwrap.py    2018-01-23 
21:41:36.000000000 +0100
+++ new/metakernel-0.23.0/metakernel/tests/test_replwrap.py     2019-04-30 
11:15:55.000000000 +0200
@@ -2,6 +2,7 @@
 import unittest
 import re
 import os
+import sys
 
 from metakernel import pexpect, replwrap
 
@@ -59,7 +60,7 @@
         if platform.python_implementation() == 'PyPy':
             raise unittest.SkipTest("This test fails on PyPy because of REPL 
differences")
 
-        p = replwrap.python()
+        p = replwrap.python(sys.executable)
         res = p.run_command('4+7')
         assert res.strip() == '11'
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel.egg-info/PKG-INFO 
new/metakernel-0.23.0/metakernel.egg-info/PKG-INFO
--- old/metakernel-0.20.14/metakernel.egg-info/PKG-INFO 2018-01-23 
22:30:35.000000000 +0100
+++ new/metakernel-0.23.0/metakernel.egg-info/PKG-INFO  2019-05-10 
20:02:16.000000000 +0200
@@ -1,12 +1,12 @@
 Metadata-Version: 1.1
 Name: metakernel
-Version: 0.20.14
+Version: 0.23.0
 Summary: Metakernel for Jupyter
 Home-page: https://github.com/Calysto/metakernel
 Author: Steven Silvester
 Author-email: steven.silves...@ieee.org
 License: UNKNOWN
-Description: A Jupyter/IPython kernel template which includes core magic 
functions (including help, command and file path completion, parallel and 
distributed processing, downloads, and much more).
+Description: A Jupyter kernel base class in Python which includes core magic 
functions (including help, command and file path completion, parallel and 
distributed processing, downloads, and much more).
         
         .. image:: https://badge.fury.io/py/metakernel.png/
             :target: http://badge.fury.io/py/metakernel
@@ -17,9 +17,15 @@
         .. image:: https://travis-ci.org/Calysto/metakernel.svg
           :target: https://travis-ci.org/Calysto/metakernel
         
+        .. image:: 
https://anaconda.org/conda-forge/metakernel/badges/version.svg
+            :target: https://anaconda.org/conda-forge/metakernel
         
-        See IPython's docs on `wrapper kernels
-        <http://ipython.org/ipython-doc/dev/development/wrapperkernels.html>`_.
+        .. image:: 
https://anaconda.org/conda-forge/metakernel/badges/downloads.svg
+            :target: https://anaconda.org/conda-forge/metakernel
+        
+        
+        See Jupyter's docs on `wrapper kernels
+        <http://jupyter-client.readthedocs.io/en/stable/wrapperkernels.html>`_.
         
         Additional magics can be installed within the new kernel package under 
a `magics` subpackage.
         
@@ -55,25 +61,44 @@
         
         Installation
         ----------------
-        You can install Metakernel through `pip`:
+        You can install Metakernel through ``pip``:
+        
+        .. code::bash
+        
+         pip install metakernel --upgrade
+        
+        Installing `metakernel` from the `conda-forge` channel can be achieved 
by adding `conda-forge` to your channels with:
+        
+        .. code::bash
+        
+         conda config --add channels conda-forge
+        
+        Once the `conda-forge` channel has been enabled, `metakernel` can be 
installed with:
         
+        .. code::bash
         
-        `pip install metakernel --upgrade`
+         conda install metakernel
+        
+        It is possible to list all of the versions of `metakernel` available 
on your platform with:
+        
+        .. code::bash
+        
+         conda search metakernel --channel conda-forge
         
         
         Use MetaKernel Magics in IPython
         --------------------------------
         
-        Although MetaKernel is a system for building new kernels, you can use 
a subset of the magics in the IPython kernel. 
+        Although MetaKernel is a system for building new kernels, you can use 
a subset of the magics in the IPython kernel.
         
-        .. code-block:: python
+        .. code:: python
         
          from metakernel import register_ipython_magics
          register_ipython_magics()
         
-        Put the following in your (or a system-wide) ipython_config.py file:
+        Put the following in your (or a system-wide) ``ipython_config.py`` 
file:
         
-        .. code-block:: python
+        .. code:: python
         
          # /etc/ipython/ipython_config.py
          c = get_config()
@@ -83,6 +108,102 @@
          ]
          c.InteractiveShellApp.exec_lines = startup
         
+        Use MetaKernel Languages in Parallel
+        
+        To use a MetaKernel language in parallel, do the following:
+        
+        1. Make sure that the Python module `ipyparallel` is installed. In the 
shell, type:
+        
+        .. code:: bash
+        
+          pip install ipyparallel
+        
+        
+        2. To enable the extension in the notebook, in the shell, type:
+        
+        .. code:: bash
+        
+          ipcluster nbextension enable
+        
+        
+        3. To start up a cluster, with 10 nodes, on a local IP address, in the 
shell, type:
+        
+        .. code:: bash
+        
+          ipcluster start --n=10 --ip=192.168.1.108
+        
+        
+        4. Initialize the code to use the 10 nodes, inside the notebook from a 
host kernel ``MODULE`` and ``CLASSNAME`` (can be any metakernel kernel):
+        
+        .. code:: bash
+        
+          %parallel MODULE CLASSNAME
+        
+        
+        For example:
+        
+        .. code:: bash
+        
+          %parallel calysto_scheme CalystoScheme
+        
+        
+        5. Run code in parallel, inside the notebook, type:
+        
+        Execute a single line, in parallel:
+        
+        .. code:: bash
+        
+          %px (+ 1 1)
+        
+        
+        Or execute the entire cell, in parallel:
+        
+        .. code:: bash
+        
+          %%px
+          (* cluster_rank cluster_rank)
+        
+        
+        Results come back in a Python list (Scheme vector), in 
``cluster_rank`` order. (This will be a JSON representation in the future).
+        
+        Therefore, the above would produce the result:
+        
+        .. code:: bash
+        
+          #10(0 1 4 9 16 25 36 49 64 81)
+        
+        You can get the results back in any of the parallel magics (``%px``, 
``%%px``, or ``%pmap``) in the host kernel by accessing the variable ``_`` 
(single underscore), or by using the ``--set_variable VARIABLE`` flag, like so:
+        
+        .. code:: bash
+        
+          %%px --set_variable results
+          (* cluster_rank cluster_rank)
+        
+        
+        Then, in the next cell, you can access ``results``.
+        
+        Notice that you can use the variable ``cluster_rank`` to partition 
parts of a problem so that each node is working on something different.
+        
+        In the examples above, use ``-e`` to evaluate the code in the host 
kernel as well. Note that ``cluster_rank`` is not defined on the host machine, 
and that this assumes the host kernel is the same as the parallel machines.
+        
+        
+        Configuration
+        -------------
+        ``Metakernel`` implementations can subclasses can be configured by the 
user.  The
+        configuration file name is determined by the ``app_name`` property of 
the subclass.
+        For example, in the ``Octave`` kernel, it is ``octave_kernel``.  The 
user of the kernel can add an ``octave_kernel_config.py`` file to their
+        ``jupyter`` config path.  The base ``MetaKernel`` class offers 
``plot_settings`` as a configurable trait.  Subclasses can defined other traits 
that they wish to make
+        configurable.
+        
+        As an example:
+        
+        .. code:: bash
+        
+            cat ~/.jupyter/octave_kernel_config.py
+            # use Qt as the default backend for plots
+            c.OctaveKernel.plot_settings = dict(backend='qt')
+        
+        
         Documentation
         -----------------------
         
@@ -101,13 +222,11 @@
         
         .. _History: 
https://github.com/Calysto/metakernel/blob/master/HISTORY.rst
         
-        
-        
 Platform: UNKNOWN
 Classifier: Framework :: IPython
 Classifier: License :: OSI Approved :: BSD License
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 2
 Classifier: Topic :: System :: Shells
-Requires: ipykernel (< 6.0)
+Requires: ipykernel
 Requires: pexpect (>= 4.2)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel.egg-info/SOURCES.txt 
new/metakernel-0.23.0/metakernel.egg-info/SOURCES.txt
--- old/metakernel-0.20.14/metakernel.egg-info/SOURCES.txt      2018-01-23 
22:30:35.000000000 +0100
+++ new/metakernel-0.23.0/metakernel.egg-info/SOURCES.txt       2019-05-10 
20:02:16.000000000 +0200
@@ -21,6 +21,7 @@
 metakernel.egg-info/requires.txt
 metakernel.egg-info/top_level.txt
 metakernel/images/logo-32x32.png
+metakernel/images/logo-512x512.png
 metakernel/images/logo-64x64.png
 metakernel/magics/__init__.py
 metakernel/magics/activity_magic.py
@@ -109,6 +110,7 @@
 metakernel_bash/README.md
 metakernel_bash/metakernel_bash.py
 metakernel_bash/setup.py
+metakernel_bash/__pycache__/metakernel_bash.cpython-37.pyc
 metakernel_echo/README.md
 metakernel_echo/metakernel_echo.py
 metakernel_echo/setup.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel.egg-info/requires.txt 
new/metakernel-0.23.0/metakernel.egg-info/requires.txt
--- old/metakernel-0.20.14/metakernel.egg-info/requires.txt     2018-01-23 
22:30:35.000000000 +0100
+++ new/metakernel-0.23.0/metakernel.egg-info/requires.txt      2019-05-10 
20:02:16.000000000 +0200
@@ -1,2 +1,2 @@
-ipykernel<6.0
+ipykernel
 pexpect>=4.2
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel_bash/README.md 
new/metakernel-0.23.0/metakernel_bash/README.md
--- old/metakernel-0.20.14/metakernel_bash/README.md    2018-01-23 
21:06:42.000000000 +0100
+++ new/metakernel-0.23.0/metakernel_bash/README.md     2019-04-30 
11:15:55.000000000 +0200
@@ -11,7 +11,7 @@
 Then, you need to install the metakernel bash kernel spec:
 
 ```shell
-python metakernel_bash install
+python -m metakernel_bash install
 ```
 
 ## Running
Binary files 
old/metakernel-0.20.14/metakernel_bash/__pycache__/metakernel_bash.cpython-37.pyc
 and 
new/metakernel-0.23.0/metakernel_bash/__pycache__/metakernel_bash.cpython-37.pyc
 differ
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel_echo/README.md 
new/metakernel-0.23.0/metakernel_echo/README.md
--- old/metakernel-0.20.14/metakernel_echo/README.md    2018-01-23 
21:06:42.000000000 +0100
+++ new/metakernel-0.23.0/metakernel_echo/README.md     2019-04-30 
11:15:55.000000000 +0200
@@ -11,7 +11,7 @@
 Then, you need to install the metakernel echo kernel spec:
 
 ```shell
-python metakernel_echo install
+python -m metakernel_echo install
 ```
 
 ## Running
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/metakernel_python/README.md 
new/metakernel-0.23.0/metakernel_python/README.md
--- old/metakernel-0.20.14/metakernel_python/README.md  2018-01-23 
21:06:42.000000000 +0100
+++ new/metakernel-0.23.0/metakernel_python/README.md   2019-04-30 
11:15:55.000000000 +0200
@@ -11,7 +11,7 @@
 Then, you need to install the metakernel kernel spec:
 
 ```shell
-python metakernel_python install
+python -m metakernel_python install
 ```
 
 ## Running
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/metakernel-0.20.14/setup.cfg 
new/metakernel-0.23.0/setup.cfg
--- old/metakernel-0.20.14/setup.cfg    2018-01-23 22:30:35.000000000 +0100
+++ new/metakernel-0.23.0/setup.cfg     2019-05-10 20:02:16.000000000 +0200
@@ -9,6 +9,9 @@
 [wheel]
 universal = 1
 
+[metadata]
+license_file = LICENSE.txt
+
 [egg_info]
 tag_build = 
 tag_date = 0


Reply via email to