77

Is it possible to start an interactive Python shell inside a Python program?

I want to use such an interactive Python shell (which is running inside my program's execution) to inspect some program-internal variables.

srikavineehari
  • 2,502
  • 1
  • 11
  • 21
zJay
  • 2,889
  • 3
  • 22
  • 19

5 Answers5

76

The code module provides an interactive console:

import readline # optional, will allow Up/Down/History in the console
import code
variables = globals().copy()
variables.update(locals())
shell = code.InteractiveConsole(variables)
shell.interact()
phihag
  • 278,196
  • 72
  • 453
  • 469
  • 3
    Note that `vars` is a built-in function. Also, in Python 3.5+, you can create a "compound" dictionary from two existing dictionaries using dict expansion: `variables = {**globals(), **locals()}`. – kyrill Oct 25 '17 at 17:54
  • 1
    @kyrill Fixed the former point. Since there still is a significant number of Python<3.5 users, I'll keep the dictionary compounding as is for now. – phihag Oct 25 '17 at 17:56
  • 2
    is it possible to wrap or enclose the interactiveconsole within a widget in PyQt5? – Ash Feb 08 '18 at 19:12
  • @Ash That sounds like a great question (although you probably only need *an* interactive console, not necessarily this specific module). Go ahead and [ask it](https://stackoverflow.com/questions/ask)! – phihag Feb 08 '18 at 21:25
  • @phihag: `readline` doesen't seems to exist anymore. Is the up/down/history feature still avaiable through some standard library? – Skandix Mar 27 '18 at 13:34
  • @Skandix `readline` [exists just fine even in the cutting-edge Python](https://docs.python.org/dev/library/readline.html). If it fails to import, please ask a new question (and maybe point me to it). – phihag Mar 27 '18 at 13:41
  • is there a command I can use in the shell to return execution to the program? – Alfie Mar 10 '20 at 08:41
  • @Alfie As in any other shell, you can press `Ctrl`+`D` to end the shell. – phihag Mar 10 '20 at 12:13
  • @Alfie If you want to do it on Windows, use `Ctrl`+`Z` and `Enter` instead of `Ctrl`+`D`. – Arthur Khazbs Jun 08 '20 at 00:30
20

In ipython 0.13+ you need to do this:

from IPython import embed

embed()
lubosz
  • 848
  • 10
  • 12
6

I've had this code for a long time, I hope you can put it to use.

To inspect/use variables, just put them into the current namespace. As an example, I can access var1 and var2 from the command line.

var1 = 5
var2 = "Mike"
# Credit to effbot.org/librarybook/code.htm for loading variables into current namespace
def keyboard(banner=None):
    import code, sys

    # use exception trick to pick up the current frame
    try:
        raise None
    except:
        frame = sys.exc_info()[2].tb_frame.f_back

    # evaluate commands in current namespace
    namespace = frame.f_globals.copy()
    namespace.update(frame.f_locals)

    code.interact(banner=banner, local=namespace)


if __name__ == '__main__':
  keyboard()

However if you wanted to strictly debug your application, I'd highly suggest using an IDE or pdb(python debugger).

Mike Lewis
  • 63,433
  • 20
  • 141
  • 111
5

Using IPython you just have to call:

from IPython.Shell import IPShellEmbed; IPShellEmbed()()
Fábio Diniz
  • 10,077
  • 3
  • 38
  • 45
1

Another trick (besides the ones already suggested) is opening an interactive shell and importing your (perhaps modified) python script. Upon importing, most of the variables, functions, classes and so on (depending on how the whole thing is prepared) are available, and you could even create objects interactively from command line. So, if you have a test.py file, you could open Idle or other shell, and type import test (if it is in current working directory).

heltonbiker
  • 26,657
  • 28
  • 137
  • 252
  • 2
    A similar approach that would place the script's globals in the global namespace instead of a module namespace: `exec(open("test.py").read())` – mic_e May 02 '13 at 08:48