diff --git a/IPython/frontend/qt/console/frontend_widget.py b/IPython/frontend/qt/console/frontend_widget.py index a3e4c21..16f75f6 100644 --- a/IPython/frontend/qt/console/frontend_widget.py +++ b/IPython/frontend/qt/console/frontend_widget.py @@ -216,7 +216,7 @@ class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin): See parent class :meth:`execute` docstring for full details. """ - msg_id = self.kernel_client.shell_channel.execute(source, hidden) + msg_id = self.kernel_client.execute(source, hidden) self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'user') self._hidden = hidden if not hidden: @@ -358,7 +358,7 @@ class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin): # generate uuid, which would be used as an indication of whether or # not the unique request originated from here (can use msg id ?) local_uuid = str(uuid.uuid1()) - msg_id = self.kernel_client.shell_channel.execute('', + msg_id = self.kernel_client.execute('', silent=True, user_expressions={ local_uuid:expr }) self._callback_dict[local_uuid] = callback self._request_info['execute'][msg_id] = self._ExecutionRequest(msg_id, 'silent_exec_callback') @@ -671,7 +671,7 @@ class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin): # Send the metadata request to the kernel name = '.'.join(context) - msg_id = self.kernel_client.shell_channel.object_info(name) + msg_id = self.kernel_client.object_info(name) pos = self._get_cursor().position() self._request_info['call_tip'] = self._CallTipRequest(msg_id, pos) return True @@ -682,7 +682,7 @@ class FrontendWidget(HistoryConsoleWidget, BaseFrontendMixin): context = self._get_context() if context: # Send the completion request to the kernel - msg_id = self.kernel_client.shell_channel.complete( + msg_id = self.kernel_client.complete( '.'.join(context), # text self._get_input_buffer_cursor_line(), # line self._get_input_buffer_cursor_column(), # cursor_pos diff --git a/IPython/kernel/channels.py b/IPython/kernel/channels.py index 64e165a..9d04795 100644 --- a/IPython/kernel/channels.py +++ b/IPython/kernel/channels.py @@ -81,6 +81,7 @@ class ZMQSocketChannel(Thread): stream = None _address = None _exiting = False + proxy_methods = [] def __init__(self, context, session, address): """Create a channel. @@ -175,6 +176,14 @@ class ShellChannel(ZMQSocketChannel): command_queue = None # flag for whether execute requests should be allowed to call raw_input: allow_stdin = True + proxy_methods = [ + 'execute', + 'complete', + 'object_info', + 'history', + 'kernel_info', + 'shutdown', + ] def __init__(self, context, session, address): super(ShellChannel, self).__init__(context, session, address) @@ -451,6 +460,7 @@ class StdInChannel(ZMQSocketChannel): """The stdin channel to handle raw_input requests that the kernel makes.""" msg_queue = None + proxy_methods = ['input'] def __init__(self, context, session, address): super(StdInChannel, self).__init__(context, session, address) diff --git a/IPython/kernel/client.py b/IPython/kernel/client.py index 51ed4a2..ead8e44 100644 --- a/IPython/kernel/client.py +++ b/IPython/kernel/client.py @@ -69,6 +69,34 @@ class KernelClient(LoggingConfigurable, ConnectionFileMixin): _stdin_channel = Any _hb_channel = Any + # def __init__(self, *args, **kwargs): + # super(KernelClient, self).__init__(*args, **kwargs) + # # setup channel proxy methods, e.g. + # # Client.execute => shell_channel.execute + # for channel in ['shell', 'iopub', 'stdin', 'hb']: + # cls = getattr(self, '%s_channel_class' % channel) + # for method in cls.proxy_methods: + # setattr(self, method, self._proxy_method(channel, method)) + # + #-------------------------------------------------------------------------- + # Channel proxy methods + #-------------------------------------------------------------------------- + + def _get_msg(channel, *args, **kwargs): + return channel.get_msg(*args, **kwargs) + + def get_shell_msg(self, *args, **kwargs): + """Get a message from the shell channel""" + return self.shell_channel.get_msg(*args, **kwargs) + + def get_iopub_msg(self, *args, **kwargs): + """Get a message from the iopub channel""" + return self.iopub_channel.get_msg(*args, **kwargs) + + def get_stdin_msg(self, *args, **kwargs): + """Get a message from the stdin channel""" + return self.stdin_channel.get_msg(*args, **kwargs) + #-------------------------------------------------------------------------- # Channel management methods #-------------------------------------------------------------------------- @@ -84,10 +112,16 @@ class KernelClient(LoggingConfigurable, ConnectionFileMixin): """ if shell: self.shell_channel.start() + for method in self.shell_channel.proxy_methods: + setattr(self, method, getattr(self.shell_channel, method)) if iopub: self.iopub_channel.start() + for method in self.iopub_channel.proxy_methods: + setattr(self, method, getattr(self.iopub_channel, method)) if stdin: self.stdin_channel.start() + for method in self.stdin_channel.proxy_methods: + setattr(self, method, getattr(self.stdin_channel, method)) self.shell_channel.allow_stdin = True else: self.shell_channel.allow_stdin = False diff --git a/IPython/kernel/tests/test_message_spec.py b/IPython/kernel/tests/test_message_spec.py index 42c5648..a8fc5c6 100644 --- a/IPython/kernel/tests/test_message_spec.py +++ b/IPython/kernel/tests/test_message_spec.py @@ -63,20 +63,15 @@ def flush_channels(kc=None): def execute(code='', kc=None, **kwargs): """wrapper for doing common steps for validating an execution request""" - if kc is None: - kc = KC - shell = kc.shell_channel - sub = kc.iopub_channel - - msg_id = shell.execute(code=code, **kwargs) - reply = shell.get_msg(timeout=2) + msg_id = KC.execute(code=code, **kwargs) + reply = KC.get_shell_msg(timeout=2) list(validate_message(reply, 'execute_reply', msg_id)) - busy = sub.get_msg(timeout=2) + busy = KC.get_iopub_msg(timeout=2) list(validate_message(busy, 'status', msg_id)) nt.assert_equal(busy['content']['execution_state'], 'busy') if not kwargs.get('silent'): - pyin = sub.get_msg(timeout=2) + pyin = KC.get_iopub_msg(timeout=2) list(validate_message(pyin, 'pyin', msg_id)) nt.assert_equal(pyin['content']['code'], code) @@ -302,9 +297,8 @@ def validate_message(msg, msg_type=None, parent=None): def test_execute(): flush_channels() - shell = KC.shell_channel - msg_id = shell.execute(code='x=1') - reply = shell.get_msg(timeout=2) + msg_id = KC.execute(code='x=1') + reply = KC.get_shell_msg(timeout=2) for tst in validate_message(reply, 'execute_reply', msg_id): yield tst @@ -383,10 +377,8 @@ def test_user_expressions(): def test_oinfo(): flush_channels() - shell = KC.shell_channel - - msg_id = shell.object_info('a') - reply = shell.get_msg(timeout=2) + msg_id = KC.object_info('a') + reply = KC.get_shell_msg(timeout=2) for tst in validate_message(reply, 'object_info_reply', msg_id): yield tst @@ -395,12 +387,10 @@ def test_oinfo(): def test_oinfo_found(): flush_channels() - shell = KC.shell_channel - msg_id, reply = execute(code='a=5') - msg_id = shell.object_info('a') - reply = shell.get_msg(timeout=2) + msg_id = KC.object_info('a') + reply = KC.get_shell_msg(timeout=2) for tst in validate_message(reply, 'object_info_reply', msg_id): yield tst content = reply['content'] @@ -413,12 +403,10 @@ def test_oinfo_found(): def test_oinfo_detail(): flush_channels() - shell = KC.shell_channel - msg_id, reply = execute(code='ip=get_ipython()') - msg_id = shell.object_info('ip.object_inspect', detail_level=2) - reply = shell.get_msg(timeout=2) + msg_id = KC.object_info('ip.object_inspect', detail_level=2) + reply = KC.get_shell_msg(timeout=2) for tst in validate_message(reply, 'object_info_reply', msg_id): yield tst content = reply['content'] @@ -432,10 +420,8 @@ def test_oinfo_detail(): def test_oinfo_not_found(): flush_channels() - shell = KC.shell_channel - - msg_id = shell.object_info('dne') - reply = shell.get_msg(timeout=2) + msg_id = KC.object_info('dne') + reply = KC.get_shell_msg(timeout=2) for tst in validate_message(reply, 'object_info_reply', msg_id): yield tst content = reply['content'] @@ -446,12 +432,10 @@ def test_oinfo_not_found(): def test_complete(): flush_channels() - shell = KC.shell_channel - msg_id, reply = execute(code="alpha = albert = 5") - msg_id = shell.complete('al', 'al', 2) - reply = shell.get_msg(timeout=2) + msg_id = KC.complete('al', 'al', 2) + reply = KC.get_shell_msg(timeout=2) for tst in validate_message(reply, 'complete_reply', msg_id): yield tst matches = reply['content']['matches'] @@ -463,10 +447,8 @@ def test_complete(): def test_kernel_info_request(): flush_channels() - shell = KC.shell_channel - - msg_id = shell.kernel_info() - reply = shell.get_msg(timeout=2) + msg_id = KC.kernel_info() + reply = KC.get_shell_msg(timeout=2) for tst in validate_message(reply, 'kernel_info_reply', msg_id): yield tst diff --git a/IPython/kernel/zmq/tests/test_embed_kernel.py b/IPython/kernel/zmq/tests/test_embed_kernel.py index 9b2b87e..da1dc61 100644 --- a/IPython/kernel/zmq/tests/test_embed_kernel.py +++ b/IPython/kernel/zmq/tests/test_embed_kernel.py @@ -106,22 +106,20 @@ def test_embed_kernel_basic(): ]) with setup_kernel(cmd) as client: - shell = client.shell_channel - # oinfo a (int) - msg_id = shell.object_info('a') - msg = shell.get_msg(block=True, timeout=2) + msg_id = client.object_info('a') + msg = client.get_shell_msg(block=True, timeout=2) content = msg['content'] nt.assert_true(content['found']) - msg_id = shell.execute("c=a*2") - msg = shell.get_msg(block=True, timeout=2) + msg_id = client.execute("c=a*2") + msg = client.get_shell_msg(block=True, timeout=2) content = msg['content'] nt.assert_equal(content['status'], u'ok') # oinfo c (should be 10) - msg_id = shell.object_info('c') - msg = shell.get_msg(block=True, timeout=2) + msg_id = client.object_info('c') + msg = client.get_shell_msg(block=True, timeout=2) content = msg['content'] nt.assert_true(content['found']) nt.assert_equal(content['string_form'], u'10') @@ -139,25 +137,23 @@ def test_embed_kernel_namespace(): ]) with setup_kernel(cmd) as client: - shell = client.shell_channel - # oinfo a (int) - msg_id = shell.object_info('a') - msg = shell.get_msg(block=True, timeout=2) + msg_id = client.object_info('a') + msg = client.get_shell_msg(block=True, timeout=2) content = msg['content'] nt.assert_true(content['found']) nt.assert_equal(content['string_form'], u'5') # oinfo b (str) - msg_id = shell.object_info('b') - msg = shell.get_msg(block=True, timeout=2) + msg_id = client.object_info('b') + msg = client.get_shell_msg(block=True, timeout=2) content = msg['content'] nt.assert_true(content['found']) nt.assert_equal(content['string_form'], u'hi there') # oinfo c (undefined) - msg_id = shell.object_info('c') - msg = shell.get_msg(block=True, timeout=2) + msg_id = client.object_info('c') + msg = client.get_shell_msg(block=True, timeout=2) content = msg['content'] nt.assert_false(content['found']) @@ -177,17 +173,16 @@ def test_embed_kernel_reentrant(): ]) with setup_kernel(cmd) as client: - shell = client.shell_channel for i in range(5): - msg_id = shell.object_info('count') - msg = shell.get_msg(block=True, timeout=2) + msg_id = client.object_info('count') + msg = client.get_shell_msg(block=True, timeout=2) content = msg['content'] nt.assert_true(content['found']) nt.assert_equal(content['string_form'], unicode(i)) # exit from embed_kernel - shell.execute("get_ipython().exit_now = True") - msg = shell.get_msg(block=True, timeout=2) + client.execute("get_ipython().exit_now = True") + msg = client.get_shell_msg(block=True, timeout=2) time.sleep(0.2)