From d3e2f7320e018212ef4966c693941ca5a9bed933 2013-08-15 04:20:37 From: Min RK Date: 2013-08-15 04:20:37 Subject: [PATCH] Merge pull request #4016 from takluyver/IPython-start-funcs Fix IPython.start_* functions start_kernel() didn't work at all (#4005), and I found while investigating that passing user_ns to either start_ipython() or start_kernel() had no effect, because the Application wasn't passing it on to the Shell. This is a simple fix for the most pressing issues. We should think about any other parameters that we want to be passed through from our top level API, e.g. possibly user_module. closes #4005 --- diff --git a/IPython/core/shellapp.py b/IPython/core/shellapp.py index ff3b5e6..af087bc 100644 --- a/IPython/core/shellapp.py +++ b/IPython/core/shellapp.py @@ -34,7 +34,7 @@ from IPython.utils import py3compat from IPython.utils.contexts import preserve_keys from IPython.utils.path import filefind from IPython.utils.traitlets import ( - Unicode, Instance, List, Bool, CaselessStrEnum + Unicode, Instance, List, Bool, CaselessStrEnum, Dict ) #----------------------------------------------------------------------------- @@ -197,6 +197,12 @@ class InteractiveShellApp(Configurable): """ ) shell = Instance('IPython.core.interactiveshell.InteractiveShellABC') + + user_ns = Dict(default_value=None) + def _user_ns_changed(self, name, old, new): + if self.shell is not None: + self.shell.user_ns = new + self.shell.init_user_ns() def init_path(self): """Add current working directory, '', to sys.path""" diff --git a/IPython/kernel/zmq/kernelapp.py b/IPython/kernel/zmq/kernelapp.py index b5ef0b9..3b100fd 100644 --- a/IPython/kernel/zmq/kernelapp.py +++ b/IPython/kernel/zmq/kernelapp.py @@ -393,6 +393,7 @@ class IPKernelApp(BaseIPythonApplication, InteractiveShellApp): stdin_socket=self.stdin_socket, log=self.log, profile_dir=self.profile_dir, + user_ns=self.user_ns, ) kernel.record_ports(self.ports) self.kernel = kernel @@ -458,6 +459,7 @@ class IPKernelApp(BaseIPythonApplication, InteractiveShellApp): except KeyboardInterrupt: pass +launch_new_instance = IPKernelApp.launch_instance def main(): """Run an IPKernel as an application""" diff --git a/IPython/kernel/zmq/tests/test_start_kernel.py b/IPython/kernel/zmq/tests/test_start_kernel.py new file mode 100644 index 0000000..0ba37ce --- /dev/null +++ b/IPython/kernel/zmq/tests/test_start_kernel.py @@ -0,0 +1,17 @@ +import nose.tools as nt + +from .test_embed_kernel import setup, teardown, setup_kernel + +TIMEOUT = 15 + +def test_ipython_start_kernel_userns(): + cmd = ('from IPython import start_kernel\n' + 'ns = {"tre": 123}\n' + 'start_kernel(user_ns=ns)') + + with setup_kernel(cmd) as client: + msg_id = client.object_info('tre') + msg = client.get_shell_msg(block=True, timeout=TIMEOUT) + content = msg['content'] + assert content['found'] + nt.assert_equal(content['string_form'], u'123') \ No newline at end of file diff --git a/IPython/terminal/ipapp.py b/IPython/terminal/ipapp.py index cf0d96e..02ba278 100755 --- a/IPython/terminal/ipapp.py +++ b/IPython/terminal/ipapp.py @@ -334,7 +334,7 @@ class TerminalIPythonApp(BaseIPythonApplication, InteractiveShellApp): # so the banner shows *before* all extension loading stuff. self.shell = TerminalInteractiveShell.instance(parent=self, display_banner=False, profile_dir=self.profile_dir, - ipython_dir=self.ipython_dir) + ipython_dir=self.ipython_dir, user_ns=self.user_ns) self.shell.configurables.append(self) def init_banner(self):