console.py 3.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  1. from functools import wraps
  2. from collections import OrderedDict
  3. def _embed_ipython_shell(namespace={}, banner=''):
  4. """Start an IPython Shell"""
  5. try:
  6. from IPython.terminal.embed import InteractiveShellEmbed
  7. from IPython.terminal.ipapp import load_default_config
  8. except ImportError:
  9. from IPython.frontend.terminal.embed import InteractiveShellEmbed
  10. from IPython.frontend.terminal.ipapp import load_default_config
  11. @wraps(_embed_ipython_shell)
  12. def wrapper(namespace=namespace, banner=''):
  13. config = load_default_config()
  14. # Always use .instace() to ensure _instance propagation to all parents
  15. # this is needed for <TAB> completion works well for new imports
  16. # and clear the instance to always have the fresh env
  17. # on repeated breaks like with inspect_response()
  18. InteractiveShellEmbed.clear_instance()
  19. shell = InteractiveShellEmbed.instance(
  20. banner1=banner, user_ns=namespace, config=config)
  21. shell()
  22. return wrapper
  23. def _embed_bpython_shell(namespace={}, banner=''):
  24. """Start a bpython shell"""
  25. import bpython
  26. @wraps(_embed_bpython_shell)
  27. def wrapper(namespace=namespace, banner=''):
  28. bpython.embed(locals_=namespace, banner=banner)
  29. return wrapper
  30. def _embed_ptpython_shell(namespace={}, banner=''):
  31. """Start a ptpython shell"""
  32. import ptpython.repl
  33. @wraps(_embed_ptpython_shell)
  34. def wrapper(namespace=namespace, banner=''):
  35. print(banner)
  36. ptpython.repl.embed(locals=namespace)
  37. return wrapper
  38. def _embed_standard_shell(namespace={}, banner=''):
  39. """Start a standard python shell"""
  40. import code
  41. try: # readline module is only available on unix systems
  42. import readline
  43. except ImportError:
  44. pass
  45. else:
  46. import rlcompleter
  47. readline.parse_and_bind("tab:complete")
  48. @wraps(_embed_standard_shell)
  49. def wrapper(namespace=namespace, banner=''):
  50. code.interact(banner=banner, local=namespace)
  51. return wrapper
  52. DEFAULT_PYTHON_SHELLS = OrderedDict([
  53. ('ptpython', _embed_ptpython_shell),
  54. ('ipython', _embed_ipython_shell),
  55. ('bpython', _embed_bpython_shell),
  56. ('python', _embed_standard_shell),
  57. ])
  58. def get_shell_embed_func(shells=None, known_shells=None):
  59. """Return the first acceptable shell-embed function
  60. from a given list of shell names.
  61. """
  62. if shells is None: # list, preference order of shells
  63. shells = DEFAULT_PYTHON_SHELLS.keys()
  64. if known_shells is None: # available embeddable shells
  65. known_shells = DEFAULT_PYTHON_SHELLS.copy()
  66. for shell in shells:
  67. if shell in known_shells:
  68. try:
  69. # function test: run all setup code (imports),
  70. # but dont fall into the shell
  71. return known_shells[shell]()
  72. except ImportError:
  73. continue
  74. def start_python_console(namespace=None, banner='', shells=None):
  75. """Start Python console bound to the given namespace.
  76. Readline support and tab completion will be used on Unix, if available.
  77. """
  78. if namespace is None:
  79. namespace = {}
  80. try:
  81. shell = get_shell_embed_func(shells)
  82. if shell is not None:
  83. shell(namespace=namespace, banner=banner)
  84. except SystemExit: # raised when using exit() in python code.interact
  85. pass