You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

shell.py 3.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. import os
  2. import select
  3. import sys
  4. import traceback
  5. from django.core.management import BaseCommand, CommandError
  6. from django.utils.datastructures import OrderedSet
  7. class Command(BaseCommand):
  8. help = (
  9. "Runs a Python interactive interpreter. Tries to use IPython or "
  10. "bpython, if one of them is available. Any standard input is executed "
  11. "as code."
  12. )
  13. requires_system_checks = False
  14. shells = ['ipython', 'bpython', 'python']
  15. def add_arguments(self, parser):
  16. parser.add_argument(
  17. '--no-startup', action='store_true',
  18. help='When using plain Python, ignore the PYTHONSTARTUP environment variable and ~/.pythonrc.py script.',
  19. )
  20. parser.add_argument(
  21. '-i', '--interface', choices=self.shells,
  22. help='Specify an interactive interpreter interface. Available options: "ipython", "bpython", and "python"',
  23. )
  24. parser.add_argument(
  25. '-c', '--command',
  26. help='Instead of opening an interactive shell, run a command as Django and exit.',
  27. )
  28. def ipython(self, options):
  29. from IPython import start_ipython
  30. start_ipython(argv=[])
  31. def bpython(self, options):
  32. import bpython
  33. bpython.embed()
  34. def python(self, options):
  35. import code
  36. # Set up a dictionary to serve as the environment for the shell, so
  37. # that tab completion works on objects that are imported at runtime.
  38. imported_objects = {}
  39. try: # Try activating rlcompleter, because it's handy.
  40. import readline
  41. except ImportError:
  42. pass
  43. else:
  44. # We don't have to wrap the following import in a 'try', because
  45. # we already know 'readline' was imported successfully.
  46. import rlcompleter
  47. readline.set_completer(rlcompleter.Completer(imported_objects).complete)
  48. # Enable tab completion on systems using libedit (e.g. macOS).
  49. # These lines are copied from Python's Lib/site.py.
  50. readline_doc = getattr(readline, '__doc__', '')
  51. if readline_doc is not None and 'libedit' in readline_doc:
  52. readline.parse_and_bind("bind ^I rl_complete")
  53. else:
  54. readline.parse_and_bind("tab:complete")
  55. # We want to honor both $PYTHONSTARTUP and .pythonrc.py, so follow system
  56. # conventions and get $PYTHONSTARTUP first then .pythonrc.py.
  57. if not options['no_startup']:
  58. for pythonrc in OrderedSet([os.environ.get("PYTHONSTARTUP"), os.path.expanduser('~/.pythonrc.py')]):
  59. if not pythonrc:
  60. continue
  61. if not os.path.isfile(pythonrc):
  62. continue
  63. with open(pythonrc) as handle:
  64. pythonrc_code = handle.read()
  65. # Match the behavior of the cpython shell where an error in
  66. # PYTHONSTARTUP prints an exception and continues.
  67. try:
  68. exec(compile(pythonrc_code, pythonrc, 'exec'), imported_objects)
  69. except Exception:
  70. traceback.print_exc()
  71. code.interact(local=imported_objects)
  72. def handle(self, **options):
  73. # Execute the command and exit.
  74. if options['command']:
  75. exec(options['command'])
  76. return
  77. # Execute stdin if it has anything to read and exit.
  78. # Not supported on Windows due to select.select() limitations.
  79. if sys.platform != 'win32' and not sys.stdin.isatty() and select.select([sys.stdin], [], [], 0)[0]:
  80. exec(sys.stdin.read())
  81. return
  82. available_shells = [options['interface']] if options['interface'] else self.shells
  83. for shell in available_shells:
  84. try:
  85. return getattr(self, shell)(options)
  86. except ImportError:
  87. pass
  88. raise CommandError("Couldn't import {} interface.".format(shell))