embed.py 2.1 KB

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