137

Is there a way to programmatically force a Python script to drop into a REPL at an arbitrary point in its execution, even if the script was launched from the command line?

I'm writing a quick and dirty plotting program, which I want to read data from stdin or a file, plot it, and then drop into the REPL to allow for the plot to be customized.

the Tin Man
  • 158,662
  • 42
  • 215
  • 303
dsimcha
  • 67,514
  • 53
  • 213
  • 334

7 Answers7

150

I frequently use this:

def interact():
    import code
    code.InteractiveConsole(locals=globals()).interact()
Jason R. Coombs
  • 41,115
  • 10
  • 83
  • 93
126

You could try using the interactive option for python:

python -i program.py

This will execute the code in program.py, then go to the REPL. Anything you define or import in the top level of program.py will be available.

Alex
  • 2,152
  • 2
  • 17
  • 20
51

Here's how you should do it (IPython > v0.11):

import IPython
IPython.embed()

For IPython <= v0.11:

from IPython.Shell import IPShellEmbed

ipshell = IPShellEmbed()

ipshell() # this call anywhere in your program will start IPython

You should use IPython, the Cadillac of Python REPLs. See http://ipython.org/ipython-doc/stable/interactive/reference.html#embedding-ipython

From the documentation:

It can also be useful in scientific computing situations where it is common to need to do some automatic, computationally intensive part and then stop to look at data, plots, etc. Opening an IPython instance will give you full access to your data and functions, and you can resume program execution once you are done with the interactive part (perhaps to stop again later, as many times as needed).

NicolasP
  • 765
  • 3
  • 9
joeforker
  • 40,459
  • 37
  • 151
  • 246
  • 4
    IPython is great, but if the OP wants a solution that only uses built-in Python, Jason's code.InteractiveConsole() solution is how you "should" do it. :-) – Ben Hoyt Sep 08 '09 at 22:56
  • This is the only method that could actually read local variables when placed in arbitrary locations in the code for me – corazza Feb 07 '21 at 19:21
  • Is there a way to stop the script from the ipython repl? I've put the call to `embed()` in a tight loop! – kristianp Mar 21 '23 at 00:42
  • What difference or benefit does IPython provide over the `code` module? – Erich Apr 04 '23 at 22:29
19

You can launch the debugger:

import pdb;pdb.set_trace() 

Not sure what you want the REPL for, but the debugger is very similar.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 4
    I would suspect that he would like to make live changes to a running process, à la Lisp. – Pinochle Sep 08 '09 at 19:59
  • 1
    Is there any way to resume executing the script that launched you into pdb? – Jeff Welling Dec 11 '13 at 20:37
  • 1
    I tend to write code snippet in VIM instaed of Python save it and then do a !python -i % for example . Or pdb . Thats a good use case. – Nishant Jan 02 '14 at 14:03
  • Since Python 3.7 you can call the `breakpoint()` built-in function to achieve the same effect. – Jasha Oct 23 '20 at 23:49
  • @JeffWelling The [pdb documentation](https://docs.python.org/3/library/pdb.html) provides a more thorough answer, but `continue` can be used to resume. `c` is a shorthand alternative. – Erich Apr 04 '23 at 22:29
18

To get use of iPython and functionality of debugger you should use ipdb,

You can use it in the same way as pdb, with the addition of :

import ipdb
ipdb.set_trace()
Alex Chamberlain
  • 4,147
  • 2
  • 22
  • 49
bluszcz
  • 4,054
  • 4
  • 33
  • 52
1

I just did this in one of my own scripts (it runs inside an automation framework that is a huge PITA to instrument):

x = 0 # exit loop counter
while x == 0:
    user_input = raw_input("Please enter a command, or press q to quit: ")
    if user_input[0] == "q":
        x = 1
    else:
        try:
            print eval(user_input)
        except:
            print "I can't do that, Dave."
            continue

Just place this wherever you want a breakpoint, and you can check the state using the same syntax as the python interpreter (although it doesn't seem to let you do module imports). It's not very elegant, but it doesn't require any other setup.

razorboy
  • 11
  • 2
0

Great answers above, but if you would like this functionality in your IDE. Using Visual Studio Code (v1.5.*) with Python Setup:

  1. Highlight the lines you would like to run and
  • right click and select Run Selection/Line in Interactive Window from the drop down.
  • Press shift + enter on your keyboard.

enter image description here

  1. Right click on the Python file you want to execute in the file explorer and select Run Current File in Interactive Window

enter image description here

This will launch an interactive session, with linting, code completion and syntax highlighting:

enter image description here

enter image description here

Enter the code you would like to evaluate, and hit shift + enter on your keyboard to execute.

Enjoy Python!

Tony Cronin
  • 1,623
  • 1
  • 24
  • 30
  • 1
    This is beautiful _tear drops_. If there's anything more useful than an IPython REPL, is a Jupyter Notebook. You can execute your script in parts if you select and "shift+enter" each. Visual Vim selection works a threat if you don't wanna use the mouse. I did had to negate `"-python.execSelectionInTerminal"` in my keybindings and copy it with `"jupyter.execSelectionInteractive"` instead for the code to run in the notebook instead of a terminal. – Chema Apr 25 '23 at 02:05