1 """Simple function for embedding an IPython kernel 2 """ 3 # ----------------------------------------------------------------------------- 4 # Imports 5 # ----------------------------------------------------------------------------- 6 7 import sys 8 9 from IPython.utils.frame import extract_module_locals 10 11 from .kernelapp import IPKernelApp 12 13 # ----------------------------------------------------------------------------- 14 # Code 15 # ----------------------------------------------------------------------------- 16 17 18 def embed_kernel(module=None, local_ns=None, **kwargs): 19 """Embed and start an IPython kernel in a given scope. 20 21 Parameters 22 ---------- 23 module : ModuleType, optional 24 The module to load into IPython globals (default: caller) 25 local_ns : dict, optional 26 The namespace to load into IPython user namespace (default: caller) 27 kwargs : dict, optional 28 Further keyword args are relayed to the IPKernelApp constructor, 29 allowing configuration of the Kernel. Will only have an effect 30 on the first embed_kernel call for a given process. 31 32 """ 33 # get the app if it exists, or set it up if it doesn't 34 if IPKernelApp.initialized(): 35 app = IPKernelApp.instance() 36 else: 37 app = IPKernelApp.instance(**kwargs) 38 app.initialize([]) 39 # Undo unnecessary sys module mangling from init_sys_modules. 40 # This would not be necessary if we could prevent it 41 # in the first place by using a different InteractiveShell 42 # subclass, as in the regular embed case. 43 main = app.kernel.shell._orig_sys_modules_main_mod 44 if main is not None: 45 sys.modules[app.kernel.shell._orig_sys_modules_main_name] = main 46 47 # load the calling scope if not given 48 (caller_module, caller_locals) = extract_module_locals(1) 49 if module is None: 50 module = caller_module 51 if local_ns is None: 52 local_ns = caller_locals 53 54 app.kernel.user_module = module 55 app.kernel.user_ns = local_ns 56 app.shell.set_completer_frame() # type:ignore[union-attr] 57 app.start() 58