Uploaded Test files
This commit is contained in:
parent
f584ad9d97
commit
2e81cb7d99
16627 changed files with 2065359 additions and 102444 deletions
8
venv/Lib/site-packages/ipykernel/inprocess/__init__.py
Normal file
8
venv/Lib/site-packages/ipykernel/inprocess/__init__.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
from .channels import (
|
||||
InProcessChannel,
|
||||
InProcessHBChannel,
|
||||
)
|
||||
|
||||
from .client import InProcessKernelClient
|
||||
from .manager import InProcessKernelManager
|
||||
from .blocking import BlockingInProcessKernelClient
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
93
venv/Lib/site-packages/ipykernel/inprocess/blocking.py
Normal file
93
venv/Lib/site-packages/ipykernel/inprocess/blocking.py
Normal file
|
@ -0,0 +1,93 @@
|
|||
""" Implements a fully blocking kernel client.
|
||||
|
||||
Useful for test suites and blocking terminal interfaces.
|
||||
"""
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (C) 2012 The IPython Development Team
|
||||
#
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING.txt, distributed as part of this software.
|
||||
#-----------------------------------------------------------------------------
|
||||
import sys
|
||||
try:
|
||||
from queue import Queue, Empty # Py 3
|
||||
except ImportError:
|
||||
from Queue import Queue, Empty # Py 2
|
||||
|
||||
# IPython imports
|
||||
from traitlets import Type
|
||||
|
||||
# Local imports
|
||||
from .channels import (
|
||||
InProcessChannel,
|
||||
)
|
||||
from .client import InProcessKernelClient
|
||||
|
||||
class BlockingInProcessChannel(InProcessChannel):
|
||||
|
||||
def __init__(self, *args, **kwds):
|
||||
super(BlockingInProcessChannel, self).__init__(*args, **kwds)
|
||||
self._in_queue = Queue()
|
||||
|
||||
def call_handlers(self, msg):
|
||||
self._in_queue.put(msg)
|
||||
|
||||
def get_msg(self, block=True, timeout=None):
|
||||
""" Gets a message if there is one that is ready. """
|
||||
if timeout is None:
|
||||
# Queue.get(timeout=None) has stupid uninteruptible
|
||||
# behavior, so wait for a week instead
|
||||
timeout = 604800
|
||||
return self._in_queue.get(block, timeout)
|
||||
|
||||
def get_msgs(self):
|
||||
""" Get all messages that are currently ready. """
|
||||
msgs = []
|
||||
while True:
|
||||
try:
|
||||
msgs.append(self.get_msg(block=False))
|
||||
except Empty:
|
||||
break
|
||||
return msgs
|
||||
|
||||
def msg_ready(self):
|
||||
""" Is there a message that has been received? """
|
||||
return not self._in_queue.empty()
|
||||
|
||||
|
||||
class BlockingInProcessStdInChannel(BlockingInProcessChannel):
|
||||
def call_handlers(self, msg):
|
||||
""" Overridden for the in-process channel.
|
||||
|
||||
This methods simply calls raw_input directly.
|
||||
"""
|
||||
msg_type = msg['header']['msg_type']
|
||||
if msg_type == 'input_request':
|
||||
_raw_input = self.client.kernel._sys_raw_input
|
||||
prompt = msg['content']['prompt']
|
||||
print(prompt, end='', file=sys.__stdout__)
|
||||
sys.__stdout__.flush()
|
||||
self.client.input(_raw_input())
|
||||
|
||||
class BlockingInProcessKernelClient(InProcessKernelClient):
|
||||
|
||||
# The classes to use for the various channels.
|
||||
shell_channel_class = Type(BlockingInProcessChannel)
|
||||
iopub_channel_class = Type(BlockingInProcessChannel)
|
||||
stdin_channel_class = Type(BlockingInProcessStdInChannel)
|
||||
|
||||
def wait_for_ready(self):
|
||||
# Wait for kernel info reply on shell channel
|
||||
while True:
|
||||
msg = self.shell_channel.get_msg(block=True)
|
||||
if msg['msg_type'] == 'kernel_info_reply':
|
||||
self._handle_kernel_info_reply(msg)
|
||||
break
|
||||
|
||||
# Flush IOPub channel
|
||||
while True:
|
||||
try:
|
||||
msg = self.iopub_channel.get_msg(block=True, timeout=0.2)
|
||||
print(msg['msg_type'])
|
||||
except Empty:
|
||||
break
|
97
venv/Lib/site-packages/ipykernel/inprocess/channels.py
Normal file
97
venv/Lib/site-packages/ipykernel/inprocess/channels.py
Normal file
|
@ -0,0 +1,97 @@
|
|||
"""A kernel client for in-process kernels."""
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from jupyter_client.channelsabc import HBChannelABC
|
||||
|
||||
from .socket import DummySocket
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Channel classes
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class InProcessChannel(object):
|
||||
"""Base class for in-process channels."""
|
||||
proxy_methods = []
|
||||
|
||||
def __init__(self, client=None):
|
||||
super(InProcessChannel, self).__init__()
|
||||
self.client = client
|
||||
self._is_alive = False
|
||||
|
||||
def is_alive(self):
|
||||
return self._is_alive
|
||||
|
||||
def start(self):
|
||||
self._is_alive = True
|
||||
|
||||
def stop(self):
|
||||
self._is_alive = False
|
||||
|
||||
def call_handlers(self, msg):
|
||||
""" This method is called in the main thread when a message arrives.
|
||||
|
||||
Subclasses should override this method to handle incoming messages.
|
||||
"""
|
||||
raise NotImplementedError('call_handlers must be defined in a subclass.')
|
||||
|
||||
def flush(self, timeout=1.0):
|
||||
pass
|
||||
|
||||
|
||||
def call_handlers_later(self, *args, **kwds):
|
||||
""" Call the message handlers later.
|
||||
|
||||
The default implementation just calls the handlers immediately, but this
|
||||
method exists so that GUI toolkits can defer calling the handlers until
|
||||
after the event loop has run, as expected by GUI frontends.
|
||||
"""
|
||||
self.call_handlers(*args, **kwds)
|
||||
|
||||
def process_events(self):
|
||||
""" Process any pending GUI events.
|
||||
|
||||
This method will be never be called from a frontend without an event
|
||||
loop (e.g., a terminal frontend).
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
|
||||
|
||||
class InProcessHBChannel(object):
|
||||
"""A dummy heartbeat channel interface for in-process kernels.
|
||||
|
||||
Normally we use the heartbeat to check that the kernel process is alive.
|
||||
When the kernel is in-process, that doesn't make sense, but clients still
|
||||
expect this interface.
|
||||
"""
|
||||
|
||||
time_to_dead = 3.0
|
||||
|
||||
def __init__(self, client=None):
|
||||
super(InProcessHBChannel, self).__init__()
|
||||
self.client = client
|
||||
self._is_alive = False
|
||||
self._pause = True
|
||||
|
||||
def is_alive(self):
|
||||
return self._is_alive
|
||||
|
||||
def start(self):
|
||||
self._is_alive = True
|
||||
|
||||
def stop(self):
|
||||
self._is_alive = False
|
||||
|
||||
def pause(self):
|
||||
self._pause = True
|
||||
|
||||
def unpause(self):
|
||||
self._pause = False
|
||||
|
||||
def is_beating(self):
|
||||
return not self._pause
|
||||
|
||||
|
||||
HBChannelABC.register(InProcessHBChannel)
|
187
venv/Lib/site-packages/ipykernel/inprocess/client.py
Normal file
187
venv/Lib/site-packages/ipykernel/inprocess/client.py
Normal file
|
@ -0,0 +1,187 @@
|
|||
"""A client for in-process kernels."""
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Copyright (C) 2012 The IPython Development Team
|
||||
#
|
||||
# Distributed under the terms of the BSD License. The full license is in
|
||||
# the file COPYING, distributed as part of this software.
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Imports
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
# IPython imports
|
||||
from ipykernel.inprocess.socket import DummySocket
|
||||
from traitlets import Type, Instance, default
|
||||
from jupyter_client.clientabc import KernelClientABC
|
||||
from jupyter_client.client import KernelClient
|
||||
|
||||
# Local imports
|
||||
from .channels import (
|
||||
InProcessChannel,
|
||||
InProcessHBChannel,
|
||||
)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Main kernel Client class
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class InProcessKernelClient(KernelClient):
|
||||
"""A client for an in-process kernel.
|
||||
|
||||
This class implements the interface of
|
||||
`jupyter_client.clientabc.KernelClientABC` and allows
|
||||
(asynchronous) frontends to be used seamlessly with an in-process kernel.
|
||||
|
||||
See `jupyter_client.client.KernelClient` for docstrings.
|
||||
"""
|
||||
|
||||
# The classes to use for the various channels.
|
||||
shell_channel_class = Type(InProcessChannel)
|
||||
iopub_channel_class = Type(InProcessChannel)
|
||||
stdin_channel_class = Type(InProcessChannel)
|
||||
control_channel_class = Type(InProcessChannel)
|
||||
hb_channel_class = Type(InProcessHBChannel)
|
||||
|
||||
kernel = Instance('ipykernel.inprocess.ipkernel.InProcessKernel',
|
||||
allow_none=True)
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Channel management methods
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
@default('blocking_class')
|
||||
def _default_blocking_class(self):
|
||||
from .blocking import BlockingInProcessKernelClient
|
||||
return BlockingInProcessKernelClient
|
||||
|
||||
def get_connection_info(self):
|
||||
d = super(InProcessKernelClient, self).get_connection_info()
|
||||
d['kernel'] = self.kernel
|
||||
return d
|
||||
|
||||
def start_channels(self, *args, **kwargs):
|
||||
super(InProcessKernelClient, self).start_channels()
|
||||
self.kernel.frontends.append(self)
|
||||
|
||||
@property
|
||||
def shell_channel(self):
|
||||
if self._shell_channel is None:
|
||||
self._shell_channel = self.shell_channel_class(self)
|
||||
return self._shell_channel
|
||||
|
||||
@property
|
||||
def iopub_channel(self):
|
||||
if self._iopub_channel is None:
|
||||
self._iopub_channel = self.iopub_channel_class(self)
|
||||
return self._iopub_channel
|
||||
|
||||
@property
|
||||
def stdin_channel(self):
|
||||
if self._stdin_channel is None:
|
||||
self._stdin_channel = self.stdin_channel_class(self)
|
||||
return self._stdin_channel
|
||||
|
||||
@property
|
||||
def control_channel(self):
|
||||
if self._control_channel is None:
|
||||
self._control_channel = self.control_channel_class(self)
|
||||
return self._control_channel
|
||||
|
||||
@property
|
||||
def hb_channel(self):
|
||||
if self._hb_channel is None:
|
||||
self._hb_channel = self.hb_channel_class(self)
|
||||
return self._hb_channel
|
||||
|
||||
# Methods for sending specific messages
|
||||
# -------------------------------------
|
||||
|
||||
def execute(self, code, silent=False, store_history=True,
|
||||
user_expressions={}, allow_stdin=None):
|
||||
if allow_stdin is None:
|
||||
allow_stdin = self.allow_stdin
|
||||
content = dict(code=code, silent=silent, store_history=store_history,
|
||||
user_expressions=user_expressions,
|
||||
allow_stdin=allow_stdin)
|
||||
msg = self.session.msg('execute_request', content)
|
||||
self._dispatch_to_kernel(msg)
|
||||
return msg['header']['msg_id']
|
||||
|
||||
def complete(self, code, cursor_pos=None):
|
||||
if cursor_pos is None:
|
||||
cursor_pos = len(code)
|
||||
content = dict(code=code, cursor_pos=cursor_pos)
|
||||
msg = self.session.msg('complete_request', content)
|
||||
self._dispatch_to_kernel(msg)
|
||||
return msg['header']['msg_id']
|
||||
|
||||
def inspect(self, code, cursor_pos=None, detail_level=0):
|
||||
if cursor_pos is None:
|
||||
cursor_pos = len(code)
|
||||
content = dict(code=code, cursor_pos=cursor_pos,
|
||||
detail_level=detail_level,
|
||||
)
|
||||
msg = self.session.msg('inspect_request', content)
|
||||
self._dispatch_to_kernel(msg)
|
||||
return msg['header']['msg_id']
|
||||
|
||||
def history(self, raw=True, output=False, hist_access_type='range', **kwds):
|
||||
content = dict(raw=raw, output=output,
|
||||
hist_access_type=hist_access_type, **kwds)
|
||||
msg = self.session.msg('history_request', content)
|
||||
self._dispatch_to_kernel(msg)
|
||||
return msg['header']['msg_id']
|
||||
|
||||
def shutdown(self, restart=False):
|
||||
# FIXME: What to do here?
|
||||
raise NotImplementedError('Cannot shutdown in-process kernel')
|
||||
|
||||
def kernel_info(self):
|
||||
"""Request kernel info."""
|
||||
msg = self.session.msg('kernel_info_request')
|
||||
self._dispatch_to_kernel(msg)
|
||||
return msg['header']['msg_id']
|
||||
|
||||
def comm_info(self, target_name=None):
|
||||
"""Request a dictionary of valid comms and their targets."""
|
||||
if target_name is None:
|
||||
content = {}
|
||||
else:
|
||||
content = dict(target_name=target_name)
|
||||
msg = self.session.msg('comm_info_request', content)
|
||||
self._dispatch_to_kernel(msg)
|
||||
return msg['header']['msg_id']
|
||||
|
||||
def input(self, string):
|
||||
if self.kernel is None:
|
||||
raise RuntimeError('Cannot send input reply. No kernel exists.')
|
||||
self.kernel.raw_input_str = string
|
||||
|
||||
def is_complete(self, code):
|
||||
msg = self.session.msg('is_complete_request', {'code': code})
|
||||
self._dispatch_to_kernel(msg)
|
||||
return msg['header']['msg_id']
|
||||
|
||||
def _dispatch_to_kernel(self, msg):
|
||||
""" Send a message to the kernel and handle a reply.
|
||||
"""
|
||||
kernel = self.kernel
|
||||
if kernel is None:
|
||||
raise RuntimeError('Cannot send request. No kernel exists.')
|
||||
|
||||
stream = DummySocket()
|
||||
self.session.send(stream, msg)
|
||||
msg_parts = stream.recv_multipart()
|
||||
kernel.dispatch_shell(stream, msg_parts)
|
||||
|
||||
idents, reply_msg = self.session.recv(stream, copy=False)
|
||||
self.shell_channel.call_handlers_later(reply_msg)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# ABC Registration
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
KernelClientABC.register(InProcessKernelClient)
|
8
venv/Lib/site-packages/ipykernel/inprocess/constants.py
Normal file
8
venv/Lib/site-packages/ipykernel/inprocess/constants.py
Normal file
|
@ -0,0 +1,8 @@
|
|||
"""Shared constants.
|
||||
"""
|
||||
|
||||
# Because inprocess communication is not networked, we can use a common Session
|
||||
# key everywhere. This is not just the empty bytestring to avoid tripping
|
||||
# certain security checks in the rest of Jupyter that assumes that empty keys
|
||||
# are insecure.
|
||||
INPROCESS_KEY = b'inprocess'
|
192
venv/Lib/site-packages/ipykernel/inprocess/ipkernel.py
Normal file
192
venv/Lib/site-packages/ipykernel/inprocess/ipkernel.py
Normal file
|
@ -0,0 +1,192 @@
|
|||
"""An in-process kernel"""
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from contextlib import contextmanager
|
||||
import logging
|
||||
import sys
|
||||
|
||||
from IPython.core.interactiveshell import InteractiveShellABC
|
||||
from ipykernel.jsonutil import json_clean
|
||||
from traitlets import Any, Enum, Instance, List, Type, default
|
||||
from ipykernel.ipkernel import IPythonKernel
|
||||
from ipykernel.zmqshell import ZMQInteractiveShell
|
||||
|
||||
from .constants import INPROCESS_KEY
|
||||
from .socket import DummySocket
|
||||
from ..iostream import OutStream, BackgroundSocket, IOPubThread
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Main kernel class
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class InProcessKernel(IPythonKernel):
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# InProcessKernel interface
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
# The frontends connected to this kernel.
|
||||
frontends = List(
|
||||
Instance('ipykernel.inprocess.client.InProcessKernelClient',
|
||||
allow_none=True)
|
||||
)
|
||||
|
||||
# The GUI environment that the kernel is running under. This need not be
|
||||
# specified for the normal operation for the kernel, but is required for
|
||||
# IPython's GUI support (including pylab). The default is 'inline' because
|
||||
# it is safe under all GUI toolkits.
|
||||
gui = Enum(('tk', 'gtk', 'wx', 'qt', 'qt4', 'inline'),
|
||||
default_value='inline')
|
||||
|
||||
raw_input_str = Any()
|
||||
stdout = Any()
|
||||
stderr = Any()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Kernel interface
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
shell_class = Type(allow_none=True)
|
||||
shell_streams = List()
|
||||
control_stream = Any()
|
||||
_underlying_iopub_socket = Instance(DummySocket, ())
|
||||
iopub_thread = Instance(IOPubThread)
|
||||
|
||||
@default('iopub_thread')
|
||||
def _default_iopub_thread(self):
|
||||
thread = IOPubThread(self._underlying_iopub_socket)
|
||||
thread.start()
|
||||
return thread
|
||||
|
||||
iopub_socket = Instance(BackgroundSocket)
|
||||
|
||||
@default('iopub_socket')
|
||||
def _default_iopub_socket(self):
|
||||
return self.iopub_thread.background_socket
|
||||
|
||||
stdin_socket = Instance(DummySocket, ())
|
||||
|
||||
def __init__(self, **traits):
|
||||
super(InProcessKernel, self).__init__(**traits)
|
||||
|
||||
self._underlying_iopub_socket.observe(self._io_dispatch, names=['message_sent'])
|
||||
self.shell.kernel = self
|
||||
|
||||
def execute_request(self, stream, ident, parent):
|
||||
""" Override for temporary IO redirection. """
|
||||
with self._redirected_io():
|
||||
super(InProcessKernel, self).execute_request(stream, ident, parent)
|
||||
|
||||
def start(self):
|
||||
""" Override registration of dispatchers for streams. """
|
||||
self.shell.exit_now = False
|
||||
|
||||
def _abort_queues(self):
|
||||
""" The in-process kernel doesn't abort requests. """
|
||||
pass
|
||||
|
||||
def _input_request(self, prompt, ident, parent, password=False):
|
||||
# Flush output before making the request.
|
||||
self.raw_input_str = None
|
||||
sys.stderr.flush()
|
||||
sys.stdout.flush()
|
||||
|
||||
# Send the input request.
|
||||
content = json_clean(dict(prompt=prompt, password=password))
|
||||
msg = self.session.msg(u'input_request', content, parent)
|
||||
for frontend in self.frontends:
|
||||
if frontend.session.session == parent['header']['session']:
|
||||
frontend.stdin_channel.call_handlers(msg)
|
||||
break
|
||||
else:
|
||||
logging.error('No frontend found for raw_input request')
|
||||
return str()
|
||||
|
||||
# Await a response.
|
||||
while self.raw_input_str is None:
|
||||
frontend.stdin_channel.process_events()
|
||||
return self.raw_input_str
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Protected interface
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
@contextmanager
|
||||
def _redirected_io(self):
|
||||
""" Temporarily redirect IO to the kernel.
|
||||
"""
|
||||
sys_stdout, sys_stderr = sys.stdout, sys.stderr
|
||||
sys.stdout, sys.stderr = self.stdout, self.stderr
|
||||
yield
|
||||
sys.stdout, sys.stderr = sys_stdout, sys_stderr
|
||||
|
||||
#------ Trait change handlers --------------------------------------------
|
||||
|
||||
def _io_dispatch(self, change):
|
||||
""" Called when a message is sent to the IO socket.
|
||||
"""
|
||||
ident, msg = self.session.recv(self.iopub_socket, copy=False)
|
||||
for frontend in self.frontends:
|
||||
frontend.iopub_channel.call_handlers(msg)
|
||||
|
||||
#------ Trait initializers -----------------------------------------------
|
||||
|
||||
@default('log')
|
||||
def _default_log(self):
|
||||
return logging.getLogger(__name__)
|
||||
|
||||
@default('session')
|
||||
def _default_session(self):
|
||||
from jupyter_client.session import Session
|
||||
return Session(parent=self, key=INPROCESS_KEY)
|
||||
|
||||
@default('shell_class')
|
||||
def _default_shell_class(self):
|
||||
return InProcessInteractiveShell
|
||||
|
||||
@default('stdout')
|
||||
def _default_stdout(self):
|
||||
return OutStream(self.session, self.iopub_thread, u'stdout')
|
||||
|
||||
@default('stderr')
|
||||
def _default_stderr(self):
|
||||
return OutStream(self.session, self.iopub_thread, u'stderr')
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Interactive shell subclass
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class InProcessInteractiveShell(ZMQInteractiveShell):
|
||||
|
||||
kernel = Instance('ipykernel.inprocess.ipkernel.InProcessKernel',
|
||||
allow_none=True)
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# InteractiveShell interface
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
def enable_gui(self, gui=None):
|
||||
"""Enable GUI integration for the kernel."""
|
||||
from ipykernel.eventloops import enable_gui
|
||||
if not gui:
|
||||
gui = self.kernel.gui
|
||||
enable_gui(gui, kernel=self.kernel)
|
||||
self.active_eventloop = gui
|
||||
|
||||
|
||||
def enable_matplotlib(self, gui=None):
|
||||
"""Enable matplotlib integration for the kernel."""
|
||||
if not gui:
|
||||
gui = self.kernel.gui
|
||||
return super(InProcessInteractiveShell, self).enable_matplotlib(gui)
|
||||
|
||||
def enable_pylab(self, gui=None, import_all=True, welcome_message=False):
|
||||
"""Activate pylab support at runtime."""
|
||||
if not gui:
|
||||
gui = self.kernel.gui
|
||||
return super(InProcessInteractiveShell, self).enable_pylab(gui, import_all,
|
||||
welcome_message)
|
||||
|
||||
InteractiveShellABC.register(InProcessInteractiveShell)
|
81
venv/Lib/site-packages/ipykernel/inprocess/manager.py
Normal file
81
venv/Lib/site-packages/ipykernel/inprocess/manager.py
Normal file
|
@ -0,0 +1,81 @@
|
|||
"""A kernel manager for in-process kernels."""
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from traitlets import Instance, DottedObjectName, default
|
||||
from jupyter_client.managerabc import KernelManagerABC
|
||||
from jupyter_client.manager import KernelManager
|
||||
from jupyter_client.session import Session
|
||||
|
||||
from .constants import INPROCESS_KEY
|
||||
|
||||
|
||||
class InProcessKernelManager(KernelManager):
|
||||
"""A manager for an in-process kernel.
|
||||
|
||||
This class implements the interface of
|
||||
`jupyter_client.kernelmanagerabc.KernelManagerABC` and allows
|
||||
(asynchronous) frontends to be used seamlessly with an in-process kernel.
|
||||
|
||||
See `jupyter_client.kernelmanager.KernelManager` for docstrings.
|
||||
"""
|
||||
|
||||
# The kernel process with which the KernelManager is communicating.
|
||||
kernel = Instance('ipykernel.inprocess.ipkernel.InProcessKernel',
|
||||
allow_none=True)
|
||||
# the client class for KM.client() shortcut
|
||||
client_class = DottedObjectName('ipykernel.inprocess.BlockingInProcessKernelClient')
|
||||
|
||||
@default('blocking_class')
|
||||
def _default_blocking_class(self):
|
||||
from .blocking import BlockingInProcessKernelClient
|
||||
return BlockingInProcessKernelClient
|
||||
|
||||
@default('session')
|
||||
def _default_session(self):
|
||||
# don't sign in-process messages
|
||||
return Session(key=INPROCESS_KEY, parent=self)
|
||||
|
||||
#--------------------------------------------------------------------------
|
||||
# Kernel management methods
|
||||
#--------------------------------------------------------------------------
|
||||
|
||||
def start_kernel(self, **kwds):
|
||||
from ipykernel.inprocess.ipkernel import InProcessKernel
|
||||
self.kernel = InProcessKernel(parent=self, session=self.session)
|
||||
|
||||
def shutdown_kernel(self):
|
||||
self.kernel.iopub_thread.stop()
|
||||
self._kill_kernel()
|
||||
|
||||
def restart_kernel(self, now=False, **kwds):
|
||||
self.shutdown_kernel()
|
||||
self.start_kernel(**kwds)
|
||||
|
||||
@property
|
||||
def has_kernel(self):
|
||||
return self.kernel is not None
|
||||
|
||||
def _kill_kernel(self):
|
||||
self.kernel = None
|
||||
|
||||
def interrupt_kernel(self):
|
||||
raise NotImplementedError("Cannot interrupt in-process kernel.")
|
||||
|
||||
def signal_kernel(self, signum):
|
||||
raise NotImplementedError("Cannot signal in-process kernel.")
|
||||
|
||||
def is_alive(self):
|
||||
return self.kernel is not None
|
||||
|
||||
def client(self, **kwargs):
|
||||
kwargs['kernel'] = self.kernel
|
||||
return super(InProcessKernelManager, self).client(**kwargs)
|
||||
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# ABC Registration
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
KernelManagerABC.register(InProcessKernelManager)
|
68
venv/Lib/site-packages/ipykernel/inprocess/socket.py
Normal file
68
venv/Lib/site-packages/ipykernel/inprocess/socket.py
Normal file
|
@ -0,0 +1,68 @@
|
|||
""" Defines a dummy socket implementing (part of) the zmq.Socket interface. """
|
||||
|
||||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
import abc
|
||||
import warnings
|
||||
try:
|
||||
from queue import Queue # Py 3
|
||||
except ImportError:
|
||||
from Queue import Queue # Py 2
|
||||
|
||||
import zmq
|
||||
|
||||
from traitlets import HasTraits, Instance, Int
|
||||
from ipython_genutils.py3compat import with_metaclass
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Generic socket interface
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class SocketABC(with_metaclass(abc.ABCMeta, object)):
|
||||
|
||||
@abc.abstractmethod
|
||||
def recv_multipart(self, flags=0, copy=True, track=False):
|
||||
raise NotImplementedError
|
||||
|
||||
@abc.abstractmethod
|
||||
def send_multipart(self, msg_parts, flags=0, copy=True, track=False):
|
||||
raise NotImplementedError
|
||||
|
||||
@classmethod
|
||||
def register(cls, other_cls):
|
||||
if other_cls is not DummySocket:
|
||||
warnings.warn("SocketABC is deprecated since ipykernel version 4.5.0.",
|
||||
DeprecationWarning, stacklevel=2)
|
||||
abc.ABCMeta.register(cls, other_cls)
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Dummy socket class
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class DummySocket(HasTraits):
|
||||
""" A dummy socket implementing (part of) the zmq.Socket interface. """
|
||||
|
||||
queue = Instance(Queue, ())
|
||||
message_sent = Int(0) # Should be an Event
|
||||
context = Instance(zmq.Context)
|
||||
def _context_default(self):
|
||||
return zmq.Context()
|
||||
|
||||
#-------------------------------------------------------------------------
|
||||
# Socket interface
|
||||
#-------------------------------------------------------------------------
|
||||
|
||||
def recv_multipart(self, flags=0, copy=True, track=False):
|
||||
return self.queue.get_nowait()
|
||||
|
||||
def send_multipart(self, msg_parts, flags=0, copy=True, track=False):
|
||||
msg_parts = list(map(zmq.Message, msg_parts))
|
||||
self.queue.put_nowait(msg_parts)
|
||||
self.message_sent += 1
|
||||
|
||||
def flush(self, timeout=1.0):
|
||||
"""no-op to comply with stream API"""
|
||||
pass
|
||||
|
||||
SocketABC.register(DummySocket)
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
110
venv/Lib/site-packages/ipykernel/inprocess/tests/test_kernel.py
Normal file
110
venv/Lib/site-packages/ipykernel/inprocess/tests/test_kernel.py
Normal file
|
@ -0,0 +1,110 @@
|
|||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from ipykernel.inprocess.blocking import BlockingInProcessKernelClient
|
||||
from ipykernel.inprocess.manager import InProcessKernelManager
|
||||
from ipykernel.inprocess.ipkernel import InProcessKernel
|
||||
from ipykernel.tests.utils import assemble_output
|
||||
from IPython.testing.decorators import skipif_not_matplotlib
|
||||
from IPython.utils.io import capture_output
|
||||
from ipython_genutils import py3compat
|
||||
|
||||
if py3compat.PY3:
|
||||
from io import StringIO
|
||||
else:
|
||||
from StringIO import StringIO
|
||||
|
||||
|
||||
def _init_asyncio_patch():
|
||||
"""set default asyncio policy to be compatible with tornado
|
||||
|
||||
Tornado 6 (at least) is not compatible with the default
|
||||
asyncio implementation on Windows
|
||||
|
||||
Pick the older SelectorEventLoopPolicy on Windows
|
||||
if the known-incompatible default policy is in use.
|
||||
|
||||
do this as early as possible to make it a low priority and overrideable
|
||||
|
||||
ref: https://github.com/tornadoweb/tornado/issues/2608
|
||||
|
||||
FIXME: if/when tornado supports the defaults in asyncio,
|
||||
remove and bump tornado requirement for py38
|
||||
"""
|
||||
if sys.platform.startswith("win") and sys.version_info >= (3, 8):
|
||||
import asyncio
|
||||
try:
|
||||
from asyncio import (
|
||||
WindowsProactorEventLoopPolicy,
|
||||
WindowsSelectorEventLoopPolicy,
|
||||
)
|
||||
except ImportError:
|
||||
pass
|
||||
# not affected
|
||||
else:
|
||||
if type(asyncio.get_event_loop_policy()) is WindowsProactorEventLoopPolicy:
|
||||
# WindowsProactorEventLoopPolicy is not compatible with tornado 6
|
||||
# fallback to the pre-3.8 default of Selector
|
||||
asyncio.set_event_loop_policy(WindowsSelectorEventLoopPolicy())
|
||||
|
||||
|
||||
class InProcessKernelTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
_init_asyncio_patch()
|
||||
self.km = InProcessKernelManager()
|
||||
self.km.start_kernel()
|
||||
self.kc = self.km.client()
|
||||
self.kc.start_channels()
|
||||
self.kc.wait_for_ready()
|
||||
|
||||
@skipif_not_matplotlib
|
||||
def test_pylab(self):
|
||||
"""Does %pylab work in the in-process kernel?"""
|
||||
kc = self.kc
|
||||
kc.execute('%pylab')
|
||||
out, err = assemble_output(kc.iopub_channel)
|
||||
self.assertIn('matplotlib', out)
|
||||
|
||||
def test_raw_input(self):
|
||||
""" Does the in-process kernel handle raw_input correctly?
|
||||
"""
|
||||
io = StringIO('foobar\n')
|
||||
sys_stdin = sys.stdin
|
||||
sys.stdin = io
|
||||
try:
|
||||
if py3compat.PY3:
|
||||
self.kc.execute('x = input()')
|
||||
else:
|
||||
self.kc.execute('x = raw_input()')
|
||||
finally:
|
||||
sys.stdin = sys_stdin
|
||||
assert self.km.kernel.shell.user_ns.get('x') == 'foobar'
|
||||
|
||||
def test_stdout(self):
|
||||
""" Does the in-process kernel correctly capture IO?
|
||||
"""
|
||||
kernel = InProcessKernel()
|
||||
|
||||
with capture_output() as io:
|
||||
kernel.shell.run_cell('print("foo")')
|
||||
assert io.stdout == 'foo\n'
|
||||
|
||||
kc = BlockingInProcessKernelClient(kernel=kernel, session=kernel.session)
|
||||
kernel.frontends.append(kc)
|
||||
kc.execute('print("bar")')
|
||||
out, err = assemble_output(kc.iopub_channel)
|
||||
assert out == 'bar\n'
|
||||
|
||||
def test_getpass_stream(self):
|
||||
"Tests that kernel getpass accept the stream parameter"
|
||||
kernel = InProcessKernel()
|
||||
kernel._allow_stdin = True
|
||||
kernel._input_request = lambda *args, **kwargs : None
|
||||
|
||||
kernel.getpass(stream='non empty')
|
|
@ -0,0 +1,115 @@
|
|||
# Copyright (c) IPython Development Team.
|
||||
# Distributed under the terms of the Modified BSD License.
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import unittest
|
||||
|
||||
from ipykernel.inprocess.blocking import BlockingInProcessKernelClient
|
||||
from ipykernel.inprocess.manager import InProcessKernelManager
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# Test case
|
||||
#-----------------------------------------------------------------------------
|
||||
|
||||
class InProcessKernelManagerTestCase(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.km = InProcessKernelManager()
|
||||
|
||||
def tearDown(self):
|
||||
if self.km.has_kernel:
|
||||
self.km.shutdown_kernel()
|
||||
|
||||
def test_interface(self):
|
||||
""" Does the in-process kernel manager implement the basic KM interface?
|
||||
"""
|
||||
km = self.km
|
||||
assert not km.has_kernel
|
||||
|
||||
km.start_kernel()
|
||||
assert km.has_kernel
|
||||
assert km.kernel is not None
|
||||
|
||||
kc = km.client()
|
||||
assert not kc.channels_running
|
||||
|
||||
kc.start_channels()
|
||||
assert kc.channels_running
|
||||
|
||||
old_kernel = km.kernel
|
||||
km.restart_kernel()
|
||||
self.assertIsNotNone(km.kernel)
|
||||
assert km.kernel != old_kernel
|
||||
|
||||
km.shutdown_kernel()
|
||||
assert not km.has_kernel
|
||||
|
||||
self.assertRaises(NotImplementedError, km.interrupt_kernel)
|
||||
self.assertRaises(NotImplementedError, km.signal_kernel, 9)
|
||||
|
||||
kc.stop_channels()
|
||||
assert not kc.channels_running
|
||||
|
||||
def test_execute(self):
|
||||
""" Does executing code in an in-process kernel work?
|
||||
"""
|
||||
km = self.km
|
||||
km.start_kernel()
|
||||
kc = km.client()
|
||||
kc.start_channels()
|
||||
kc.wait_for_ready()
|
||||
kc.execute('foo = 1')
|
||||
assert km.kernel.shell.user_ns['foo'] == 1
|
||||
|
||||
def test_complete(self):
|
||||
""" Does requesting completion from an in-process kernel work?
|
||||
"""
|
||||
km = self.km
|
||||
km.start_kernel()
|
||||
kc = km.client()
|
||||
kc.start_channels()
|
||||
kc.wait_for_ready()
|
||||
km.kernel.shell.push({'my_bar': 0, 'my_baz': 1})
|
||||
kc.complete('my_ba', 5)
|
||||
msg = kc.get_shell_msg()
|
||||
assert msg['header']['msg_type'] == 'complete_reply'
|
||||
self.assertEqual(sorted(msg['content']['matches']),
|
||||
['my_bar', 'my_baz'])
|
||||
|
||||
def test_inspect(self):
|
||||
""" Does requesting object information from an in-process kernel work?
|
||||
"""
|
||||
km = self.km
|
||||
km.start_kernel()
|
||||
kc = km.client()
|
||||
kc.start_channels()
|
||||
kc.wait_for_ready()
|
||||
km.kernel.shell.user_ns['foo'] = 1
|
||||
kc.inspect('foo')
|
||||
msg = kc.get_shell_msg()
|
||||
assert msg['header']['msg_type'] == 'inspect_reply'
|
||||
content = msg['content']
|
||||
assert content['found']
|
||||
text = content['data']['text/plain']
|
||||
self.assertIn('int', text)
|
||||
|
||||
def test_history(self):
|
||||
""" Does requesting history from an in-process kernel work?
|
||||
"""
|
||||
km = self.km
|
||||
km.start_kernel()
|
||||
kc = km.client()
|
||||
kc.start_channels()
|
||||
kc.wait_for_ready()
|
||||
kc.execute('1')
|
||||
kc.history(hist_access_type='tail', n=1)
|
||||
msg = kc.shell_channel.get_msgs()[-1]
|
||||
assert msg['header']['msg_type'] == 'history_reply'
|
||||
history = msg['content']['history']
|
||||
assert len(history) == 1
|
||||
assert history[0][2] == '1'
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
Loading…
Add table
Add a link
Reference in a new issue