82

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.

1
  • 2
    You could use pdb, IDE debuggers, or print for that. Commented Apr 8, 2011 at 16:14

5 Answers 5

78

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()
Sign up to request clarification or add additional context in comments.

9 Comments

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 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.
is it possible to wrap or enclose the interactiveconsole within a widget in PyQt5?
@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!
@phihag: readline doesen't seems to exist anymore. Is the up/down/history feature still avaiable through some standard library?
|
22

In ipython 0.13+ you need to do this:

from IPython import embed

embed()

1 Comment

For a really long time I had been using import ipdb; ipdb.set_trace(). I have found the ultimate tool embed(). Thanks!
7

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).

Comments

4

Using IPython you just have to call:

from IPython.Shell import IPShellEmbed; IPShellEmbed()()

2 Comments

In fact, you should use import IPython; IPython.embed();. See this issue.
Yeah that is what I use today too, 3 years later =)
2

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).

1 Comment

A similar approach that would place the script's globals in the global namespace instead of a module namespace: exec(open("test.py").read())

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.