diff --git a/IPython/kernel/__init__.py b/IPython/kernel/__init__.py index ecbf0b1..38b24ec 100644 --- a/IPython/kernel/__init__.py +++ b/IPython/kernel/__init__.py @@ -1,4 +1,5 @@ """IPython kernel bases and utilities""" +from .connect import * +from .launcher import * from .kernelmanagerabc import * -from .util import * diff --git a/IPython/kernel/util.py b/IPython/kernel/connect.py similarity index 74% rename from IPython/kernel/util.py rename to IPython/kernel/connect.py index b9c4815..865bfd2 100644 --- a/IPython/kernel/util.py +++ b/IPython/kernel/connect.py @@ -1,4 +1,4 @@ -"""Utilities for working with kernels and their connection files +"""Utilities for connecting to kernels Authors: @@ -337,233 +337,3 @@ def tunnel_to_kernel(connection_info, sshserver, sshkey=None): return tuple(lports) - -#----------------------------------------------------------------------------- -# Launching Kernels -#----------------------------------------------------------------------------- - -def swallow_argv(argv, aliases=None, flags=None): - """strip frontend-specific aliases and flags from an argument list - - For use primarily in frontend apps that want to pass a subset of command-line - arguments through to a subprocess, where frontend-specific flags and aliases - should be removed from the list. - - Parameters - ---------- - - argv : list(str) - The starting argv, to be filtered - aliases : container of aliases (dict, list, set, etc.) - The frontend-specific aliases to be removed - flags : container of flags (dict, list, set, etc.) - The frontend-specific flags to be removed - - Returns - ------- - - argv : list(str) - The argv list, excluding flags and aliases that have been stripped - """ - - if aliases is None: - aliases = set() - if flags is None: - flags = set() - - stripped = list(argv) # copy - - swallow_next = False - was_flag = False - for a in argv: - if swallow_next: - swallow_next = False - # last arg was an alias, remove the next one - # *unless* the last alias has a no-arg flag version, in which - # case, don't swallow the next arg if it's also a flag: - if not (was_flag and a.startswith('-')): - stripped.remove(a) - continue - if a.startswith('-'): - split = a.lstrip('-').split('=') - alias = split[0] - if alias in aliases: - stripped.remove(a) - if len(split) == 1: - # alias passed with arg via space - swallow_next = True - # could have been a flag that matches an alias, e.g. `existing` - # in which case, we might not swallow the next arg - was_flag = alias in flags - elif alias in flags and len(split) == 1: - # strip flag, but don't swallow next, as flags don't take args - stripped.remove(a) - - # return shortened list - return stripped - - -def make_ipkernel_cmd(code, executable=None, extra_arguments=[], **kw): - """Build Popen command list for launching an IPython kernel. - - Parameters - ---------- - code : str, - A string of Python code that imports and executes a kernel entry point. - - executable : str, optional (default sys.executable) - The Python executable to use for the kernel process. - - extra_arguments : list, optional - A list of extra arguments to pass when executing the launch code. - - Returns - ------- - - A Popen command list - """ - - # Build the kernel launch command. - if executable is None: - executable = sys.executable - arguments = [ executable, '-c', code, '-f', '{connection_file}' ] - arguments.extend(extra_arguments) - - # Spawn a kernel. - if sys.platform == 'win32': - - # If the kernel is running on pythonw and stdout/stderr are not been - # re-directed, it will crash when more than 4KB of data is written to - # stdout or stderr. This is a bug that has been with Python for a very - # long time; see http://bugs.python.org/issue706263. - # A cleaner solution to this problem would be to pass os.devnull to - # Popen directly. Unfortunately, that does not work. - if executable.endswith('pythonw.exe'): - arguments.append('--no-stdout') - arguments.append('--no-stderr') - - return arguments - - -def launch_kernel(cmd, stdin=None, stdout=None, stderr=None, - independent=False, - cwd=None, ipython_kernel=True, - **kw - ): - """ Launches a localhost kernel, binding to the specified ports. - - Parameters - ---------- - cmd : Popen list, - A string of Python code that imports and executes a kernel entry point. - - stdin, stdout, stderr : optional (default None) - Standards streams, as defined in subprocess.Popen. - - independent : bool, optional (default False) - If set, the kernel process is guaranteed to survive if this process - dies. If not set, an effort is made to ensure that the kernel is killed - when this process dies. Note that in this case it is still good practice - to kill kernels manually before exiting. - - cwd : path, optional - The working dir of the kernel process (default: cwd of this process). - - ipython_kernel : bool, optional - Whether the kernel is an official IPython one, - and should get a bit of special treatment. - - Returns - ------- - - Popen instance for the kernel subprocess - """ - - # Popen will fail (sometimes with a deadlock) if stdin, stdout, and stderr - # are invalid. Unfortunately, there is in general no way to detect whether - # they are valid. The following two blocks redirect them to (temporary) - # pipes in certain important cases. - - # If this process has been backgrounded, our stdin is invalid. Since there - # is no compelling reason for the kernel to inherit our stdin anyway, we'll - # place this one safe and always redirect. - redirect_in = True - _stdin = PIPE if stdin is None else stdin - - # If this process in running on pythonw, we know that stdin, stdout, and - # stderr are all invalid. - redirect_out = sys.executable.endswith('pythonw.exe') - if redirect_out: - _stdout = PIPE if stdout is None else stdout - _stderr = PIPE if stderr is None else stderr - else: - _stdout, _stderr = stdout, stderr - - # Spawn a kernel. - if sys.platform == 'win32': - from IPython.zmq.parentpoller import ParentPollerWindows - # Create a Win32 event for interrupting the kernel. - interrupt_event = ParentPollerWindows.create_interrupt_event() - if ipython_kernel: - cmd += [ '--interrupt=%i' % interrupt_event ] - - # If the kernel is running on pythonw and stdout/stderr are not been - # re-directed, it will crash when more than 4KB of data is written to - # stdout or stderr. This is a bug that has been with Python for a very - # long time; see http://bugs.python.org/issue706263. - # A cleaner solution to this problem would be to pass os.devnull to - # Popen directly. Unfortunately, that does not work. - if cmd[0].endswith('pythonw.exe'): - if stdout is None: - cmd.append('--no-stdout') - if stderr is None: - cmd.append('--no-stderr') - - # Launch the kernel process. - if independent: - proc = Popen(cmd, - creationflags=512, # CREATE_NEW_PROCESS_GROUP - stdin=_stdin, stdout=_stdout, stderr=_stderr) - else: - if ipython_kernel: - try: - from _winapi import DuplicateHandle, GetCurrentProcess, \ - DUPLICATE_SAME_ACCESS - except: - from _subprocess import DuplicateHandle, GetCurrentProcess, \ - DUPLICATE_SAME_ACCESS - pid = GetCurrentProcess() - handle = DuplicateHandle(pid, pid, pid, 0, - True, # Inheritable by new processes. - DUPLICATE_SAME_ACCESS) - cmd +=[ '--parent=%i' % handle ] - - - proc = Popen(cmd, - stdin=_stdin, stdout=_stdout, stderr=_stderr, cwd=cwd) - - # Attach the interrupt event to the Popen objet so it can be used later. - proc.win32_interrupt_event = interrupt_event - - else: - if independent: - proc = Popen(cmd, preexec_fn=lambda: os.setsid(), - stdin=_stdin, stdout=_stdout, stderr=_stderr, cwd=cwd) - else: - if ipython_kernel: - cmd += ['--parent=1'] - proc = Popen(cmd, - stdin=_stdin, stdout=_stdout, stderr=_stderr, cwd=cwd) - - # Clean up pipes created to work around Popen bug. - if redirect_in: - if stdin is None: - proc.stdin.close() - if redirect_out: - if stdout is None: - proc.stdout.close() - if stderr is None: - proc.stderr.close() - - return proc - diff --git a/IPython/kernel/tests/test_util.py b/IPython/kernel/tests/test_launcher.py similarity index 100% rename from IPython/kernel/tests/test_util.py rename to IPython/kernel/tests/test_launcher.py diff --git a/IPython/lib/kernel.py b/IPython/lib/kernel.py index aee1d55..63d940a 100644 --- a/IPython/lib/kernel.py +++ b/IPython/lib/kernel.py @@ -1,12 +1,12 @@ """[DEPRECATED] Utilities for connecting to kernels -Moved to IPython.kernel.util +Moved to IPython.kernel.connect """ import warnings -warnings.warn("IPython.lib.kernel moved to IPython.kernel in IPython 0.14", +warnings.warn("IPython.lib.kernel moved to IPython.kernel.connect in IPython 0.14", DeprecationWarning ) -from IPython.kernel.util import * +from IPython.kernel.connect import *