Skip to content

Commit

Permalink
spec installer to _metakernel module; run_as_main.
Browse files Browse the repository at this point in the history
All classes are tightly coupled anyways and having everything together
avoids having to create a weird InstallerApp subclass on the fly.

Also drop pretense of import working in absence of IPython and Jupyter,
this was already not the case due to the import in metakernel.config.
  • Loading branch information
anntzer committed May 28, 2016
1 parent 888054a commit 0e029fd
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 85 deletions.
3 changes: 1 addition & 2 deletions metakernel/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from ._metakernel import (
MetaKernel, MetaKernelApp, IPythonKernel,
register_ipython_magics, get_metakernel)
MetaKernel, IPythonKernel, register_ipython_magics, get_metakernel)
from . import pexpect
from .replwrap import REPLWrapper, u
from .process_metakernel import ProcessMetaKernel
Expand Down
105 changes: 67 additions & 38 deletions metakernel/_metakernel.py
Original file line number Diff line number Diff line change
@@ -1,48 +1,43 @@
from __future__ import print_function

import base64
import codecs
import glob
import imp
import inspect
import json
import logging
import os
import pkgutil
import subprocess
from subprocess import CalledProcessError
import sys
import warnings

warnings.filterwarnings('ignore', module='IPython.html.widgets')

try:
try:
from ipykernel.kernelapp import IPKernelApp
from ipykernel.kernelbase import Kernel
from ipykernel.comm import CommManager
from IPython.paths import get_ipython_dir
except ImportError:
from IPython.kernel.zmq.kernelapp import IPKernelApp
from IPython.kernel.zmq.kernelbase import Kernel
from IPython.kernel.comm import CommManager
from IPython.utils.path import get_ipython_dir
from IPython.display import HTML
try:
from ipywidgets.widgets.widget import Widget
except ImportError:
try:
from IPython.html.widgets import Widget
except ImportError:
Widget = None
from IPython.core.formatters import IPythonDisplayFormatter
except ImportError as e:
warnings.warn(
"Cannot load module {name} so metakernel will not be available to "
"IPython/jupyter.".format(name=getattr(e, 'name', '')))
# This module won't be useful without IPython
# (other parts of metakernel may be useful)
# but we make it loadable anyway
Kernel = object
import os
import sys
import glob
import base64
import imp
import inspect
import logging
import codecs
from IPython.paths import get_ipython_dir
from ipykernel.kernelapp import IPKernelApp
from ipykernel.kernelbase import Kernel
from ipykernel.comm import CommManager
from ipywidgets.widgets.widget import Widget
from traitlets.config import Application
_module_name = 'jupyter'
except ImportError:
from IPython.utils.path import get_ipython_dir
from IPython.kernel.zmq.kernelapp import IPKernelApp
from IPython.kernel.zmq.kernelbase import Kernel
from IPython.kernel.comm import CommManager
from IPython.html.widgets import Widget
from IPython.config import Application
_module_name = 'IPython'

from IPython.core.formatters import IPythonDisplayFormatter
from IPython.display import HTML
from IPython.utils.tempdir import TemporaryDirectory

from .config import get_history_file, get_local_magics_dir
from .utils.installer import BaseInstallerApp
from .parser import Parser

PY3 = (sys.version_info[0] >= 3)
Expand Down Expand Up @@ -87,6 +82,17 @@ class MetaKernel(Kernel):
}
meta_kernel = None

@classmethod
def run_as_main(cls):
"""Launch or install a metakernel.
Modules implementing a metakernel subclass can use the following lines:
if __name__ == '__main__':
MetaKernelSubclass.run_as_main()
"""
_MetaKernelApp.launch_instance(kernel_class=cls)

def __init__(self, *args, **kwargs):
super(MetaKernel, self).__init__(*args, **kwargs)
if MetaKernel.meta_kernel is None:
Expand Down Expand Up @@ -651,16 +657,39 @@ def _get_sticky_magics(self):
return retval


class MetaKernelApp(IPKernelApp):
class _MetaKernelApp(IPKernelApp):

@property
def subcommands(self):
# Slightly awkward way to pass the actual kernel class to the install
# subcommand.

class KernelInstallerApp(BaseInstallerApp):
class KernelInstallerApp(Application):
kernel_class = self.kernel_class

def initialize(self, argv=None):
self.argv = argv

def start(self):
kernel_spec = self.kernel_class.kernel_json
with TemporaryDirectory() as td:
dirname = os.path.join(td, kernel_spec['name'])
os.mkdir(dirname)
with open(os.path.join(dirname, 'kernel.json'), 'w') as f:
json.dump(kernel_spec, f, sort_keys=True)
filenames = ['logo-64x64.png', 'logo-32x32.png']
for filename in filenames:
data = pkgutil.get_data(__name__.split('.')[0],
'images/' + filename)
with open(os.path.join(dirname, filename), 'wb') as f:
f.write(data)
try:
subprocess.check_call(
[sys.executable, '-m', _module_name,
'kernelspec', 'install'] + self.argv + [dirname])
except CalledProcessError as exc:
sys.exit(exc.returncode)

return {'install': (KernelInstallerApp, 'Install this kernel')}


Expand Down
39 changes: 0 additions & 39 deletions metakernel/utils/installer.py

This file was deleted.

3 changes: 1 addition & 2 deletions metakernel_bash/metakernel_bash.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,4 @@ def repr(self, data):


if __name__ == '__main__':
from metakernel import MetaKernelApp
MetaKernelApp.launch_instance(kernel_class=MetaKernelBash)
MetaKernelBash.run_as_main()
3 changes: 1 addition & 2 deletions metakernel_echo/metakernel_echo.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,4 @@ def repr(self, data):


if __name__ == '__main__':
from metakernel import MetaKernelApp
MetaKernelApp.launch_instance(kernel_class=MetaKernelEcho)
MetaKernelEcho.run_as_main()
3 changes: 1 addition & 2 deletions metakernel_python/metakernel_python.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,5 +69,4 @@ def get_kernel_help_on(self, info, level=0, none_on_fail=False):


if __name__ == '__main__':
from metakernel import MetaKernelApp
MetaKernelApp.launch_instance(kernel_class=MetaKernelPython)
MetaKernelPython.run_as_main()

0 comments on commit 0e029fd

Please sign in to comment.