Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Give kernel providers opportunity to load configuration #20

Merged
merged 1 commit into from
Aug 27, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions jupyter_kernel_mgmt/discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import logging
import six

from traitlets.config import Application
try:
from json import JSONDecodeError
except ImportError:
Expand Down Expand Up @@ -44,6 +45,14 @@ def launch_async(self, name, cwd=None):
"""
raise NotImplementedError()

def load_config(self, config=None):
"""Loads the configuration corresponding to the hosting application. This method
is called during KernelFinder initialization prior to any other methods.
Provider is responsible for interpreting the `config` parameter (when present) which will be
an instance of Config: https://traitlets.readthedocs.io/en/stable/config.html#the-main-concepts
"""
pass


class KernelSpecProvider(KernelProviderBase):
"""Offers kernel types from installed kernelspec directories.
Expand Down Expand Up @@ -140,6 +149,15 @@ class KernelFinder(object):
def __init__(self, providers):
self.providers = providers

# If there's an application singleton, pass its configurables to the provider. If
# no application, still give provider a chance to handle configuration loading.
config = None
if Application.initialized():
config = Application.instance().config

for provider in providers:
provider.load_config(config=config)

@classmethod
def from_entrypoints(cls):
"""Load all kernel providers advertised by entry points.
Expand Down
49 changes: 49 additions & 0 deletions jupyter_kernel_mgmt/tests/test_discovery.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
from jupyter_kernel_mgmt.managerabc import KernelManagerABC
from jupyter_kernel_mgmt.subproc.manager import KernelManager
from jupyter_core import paths
from traitlets import List, Unicode
from traitlets.config import Application, SingletonConfigurable
from .utils import test_env
from .test_kernelspec import install_sample_kernel

Expand Down Expand Up @@ -63,6 +65,35 @@ def get_connection_info(self):
return {}


class ProviderApplication(Application):
name = 'ProviderApplication'
my_app = Unicode('my_app', config=True,)


class ProviderConfig(SingletonConfigurable):
my_argv = List(Unicode(), ['default_argv'], config=True,)
my_foo = Unicode('foo.bar', config=True,)


class TestConfigKernelProvider(DummyKernelProvider):
"""A dummy kernel provider for testing KernelFinder with configuration loading"""
id = 'config'

config = None
argv = ['dummy_config_kernel'] # will be replace by config item

def find_kernels(self):
argv = self.argv
if self.config:
argv = self.config.my_argv
assert self.config.my_foo == 'foo.bar' # verify default config value

yield 'sample', {'argv': argv}

def load_config(self, config=None):
self.config = ProviderConfig.instance(config=config)


class KernelDiscoveryTests(unittest.TestCase):

def setUp(self):
Expand Down Expand Up @@ -134,3 +165,21 @@ def test_kernel_spec_provider_subclass():

conn_info, manager = kf.launch('dummy_kspec/dummy_kspec1')
assert isinstance(manager, DummyKernelManager)

def test_load_config(self):
# create fake application
app = ProviderApplication()
app.launch_instance(argv=["--ProviderConfig.my_argv=['xxx','yyy']"])

kf = discovery.KernelFinder(providers=[TestConfigKernelProvider()])
dummy_kspecs = list(kf.find_kernels())

count = 0
found_argv = []
for name, spec in dummy_kspecs:
if name == 'config/sample':
found_argv = spec['argv']
count += 1

assert count == 1
assert found_argv == ['xxx', 'yyy']