232

So I am running a Python script within which I am calling Python's debugger, PDB by writing:

import ipdb; ipdb.set_trace()

(iPython's version of PDB, though for the matter I don't think it makes a difference; I use it for the colored output only).

Now, when I get to the debugger I want to execute a multi-line statement such as an if clause or a for loop but as soon as I type

if condition:

and hit the return key, I get the error message *** SyntaxError: invalid syntax (<stdin>, line 1)

How can one execute multi-line statements within PDB? If not possible is there a way around this to still executing an if clause or a for loop?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Mike
  • 2,321
  • 3
  • 14
  • 3

6 Answers6

319

You could do this while in pdb to launch a temporary interactive Python session with all the local variables available:

(pdb) !import code; code.interact(local=vars())
Python 2.6.5 (r265:79063, Apr 16 2010, 13:57:41) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
(InteractiveConsole)
>>> 

When you're done, use Ctrl-D to return to the regular pdb prompt.

Just don't hit Ctrl-C, that will terminate the entire pdb session.

Marius Gedminas
  • 11,010
  • 4
  • 41
  • 39
  • 80
    It seems the same can be achieved using the pdb `interact` command ([as I learned from this bug tracker message](http://bugs.python.org/msg215963)). – gerrit Jun 11 '14 at 15:15
  • 3
    Why is the `!` needed in the `import` statement? – Indradhanush Gupta Nov 14 '14 at 09:06
  • 24
    It's probably not needed, but I have a habit of prefixing all Python statements in pdb with `!`, to avoid accidents. E.g. `c = 42` in pdb would *continue* execution instead of assigning to variable `c`. – Marius Gedminas Nov 14 '14 at 14:10
  • 8
    @MariusGedminas the most frustrating thing with PDB! Would be nice if *their* commands had to be prefixed... – Ian Clark Apr 22 '15 at 07:31
  • Note: Ctrl-D seems to be the right way to exit `interact` too, but it does not play well with Spyder for me. – Josiah Yoder Jun 08 '18 at 19:40
  • If you have to stick on python 2 for some reason (Okay, I know it is a bad idea), `interact` doesn't work but this works. – aleph0 Sep 14 '18 at 00:42
  • @SanoberSayyed Ctrl+D is a very Linux thing. Are you on Windows? Try Ctrl+Z, followed by Enter. – Marius Gedminas Oct 03 '19 at 15:00
155

In python3 ipdb (and pdb) have a command called interact. It can be used to:

Start an interactive interpreter (using the code module) whose global namespace contains all the (global and local) names found in the current scope.

To use it, simply enter interact at the pdb prompt. Among other things, it's useful for applying code spanning multiple lines, and also for avoiding accidental triggering of other pdb commands.

Antony Hatchkins
  • 31,947
  • 10
  • 111
  • 111
vaer-k
  • 10,923
  • 11
  • 42
  • 59
58

My recommendation is to use IPython embedding.

ipdb> from IPython import embed; embed()
C S
  • 1,363
  • 1
  • 17
  • 26
fx-kirin
  • 1,906
  • 1
  • 20
  • 33
  • 4
    If you're having value is not defined error in list comprehension, try to use from IPython `import embed; embed(user_ns=locals())`. – fx-kirin Jan 29 '19 at 05:41
  • 3
    this works far better for me than the accepted answer. For example - it allows proper editing of multiline - like going back up a few lines and fixing something, so you don't have to rewrite your entire multi-line expression again... I'm passing the locals as @fx-kirin suggested. – ZeDuS Nov 12 '19 at 08:05
  • 1
    I set up an alias so I can just type "e" to activate this in pdb: in `.pbdrc`, put `alias e !from IPython import embed; embed(user_ns=locals())`. In case you're using pdbpp (pdb++), do not put it in `.pbdrc.py`, it will not work - create a `.pbdrc` file. I prefer this to `interact()` because it works even when I'm copy & pasting code that ends up having the "wrong" set of indentations. – ru111 Jan 10 '23 at 14:14
39

Inside the Python (2.7.1) interpreter or debugger (import pdb), you can execute a multi-line statement with the following syntax.

for i in range(5): print("Hello"); print("World"); print(i)

Note: When I'm inside the interpreter, I have to hit return twice before the code will execute. Inside the debugger, however, I only have to hit return once.

Garrett Hyde
  • 5,409
  • 8
  • 49
  • 55
7

There is the special case if you want a couple of commands be executed when hitting a break point. Then there is the debugger command commands. It allows you to enter multiple lines of commands and then end the whole sequence with the end key word. More with (pdb) help commands.

ThomasH
  • 22,276
  • 13
  • 61
  • 62
2

I don't know if you can do this, that'd be a great feature for ipdb though. You can use list comprehensions of course, and execute simple multi-line expressions like:

if y == 3: print y; print y; print y;

You could also write some functions beforehand to do whatever it is you need done that would normally take multiple lines.

Zach Kelling
  • 52,505
  • 13
  • 109
  • 108