30

I'm not sure if what I'm asking is possible at all, but since python is an interpreter it might be. I'm trying to make changes in an open-source project but because there are no types in python it's difficult to know what the variables have as data and what they do. You can't just look up the documentation on the var's type since you can't be sure what type it is. I want to drop to the terminal so I can quickly examine the types of the variables and what they do by typing help(var) or print(var). I could do this by changing the code and then re-running the program each time but that would be much slower.

Let's say I have a program:

def foo():
    a = 5
    my_debug_shell()
    print a

foo()

my_debug_shell is the function I'm asking about. It would drop me to the '>>>' shell of the python interpreter where I can type help(a), and it would tell me that a is an integer. Then I type 'a=7', and some 'continue' command, and the program goes on to print 7, not 5, because I changed it.

sashoalm
  • 75,001
  • 122
  • 434
  • 781
  • Similar: [Simpler way to put PDB breakpoints in Python code?](http://stackoverflow.com/q/6980749/55075) at SO – kenorb May 15 '15 at 11:29

6 Answers6

42

http://docs.python.org/library/pdb.html

import pdb
pdb.set_trace()
Amber
  • 507,862
  • 82
  • 626
  • 550
  • This is clean, but requires twice as many lines as the one-liner approach that consists in generating an exception which is automatically caught by the debugger. :) – Eric O. Lebigot Apr 24 '11 at 08:47
  • @EOL it does, however, ensure that you don't forget to turn on the debugger when running the program. – Amber Apr 24 '11 at 16:23
  • 1
    The same thing with the IPython debugger is even more convenient (replace `pdb` with `ipdb`). – Eric O. Lebigot Jan 31 '16 at 16:48
  • 1
    After the program breaks, you are put into an interactive debugger (with the prompt `(Pdb) `). Enter the command `interact` to be put into the Python shell (with the prompt `>>> `). Enter `?` in the debugger to see all available debugger commands. – anishpatel Apr 27 '17 at 20:30
31

Here is a solution that doesn't require code changes:

python -m pdb prog.py <prog_args>
(pdb) b 3
Breakpoint 1 at prog.py:3
(pdb) c
...
(pdb) p a
5
(pdb) a=7
(pdb) ...

In short:

  • start your program under debugger control
  • set a break point at a given line of code
  • let the program run up to that point
  • you get an interactive prompt that let's you do what you want (type 'help' for all options)
ThomasH
  • 22,276
  • 13
  • 61
  • 62
  • That's what I was trying to describe with my answer. – Matthew Schinckel Apr 25 '11 at 01:13
  • @Matthew I thought as much, but wanted to provide more detail and make explicit that you don't have to change the code you're debugging. – ThomasH Apr 25 '11 at 11:59
  • +1: Even though this approach requires explicit line numbers (as opposed to a '1/0' exception-raising breakpoint), it indeed has the advantage of not requiring any modification of the original code. – Eric O. Lebigot Apr 27 '11 at 09:06
  • Where/how do you set breakpoint with this method? I'm confused. – David Jan 23 '15 at 00:28
  • 2
    @David Just see the code sample above: `python -m pdb ...` starts the program under debugger control, `b ` sets the breakpoint. Type `help` at the debugger promt for all commands. – ThomasH Jan 26 '15 at 15:24
11

Python 3.7 has a new builtin way of setting breakpoints.

breakpoint()

The implementation of breakpoint() will import pdb and call pdb.set_trace().

Remember to include the braces (), since breakpoint is a function, not a keyword.

Kaka Ruto
  • 4,581
  • 1
  • 31
  • 39
10

A one-line partial solution is simply to put 1/0 where you want the breakpoint: this will raise an exception, which will be caught by the debugger. Two advantages of this approach are:

  • Breakpoints set this way are robust against code modification (no dependence on a particular line number);

  • One does not need to import pdb in every program to be debugged; one can instead directly insert "breakpoints" where needed.

In order to catch the exception automatically, you can simply do python -m pdb prog.py… and then type c(ontinue) in order to start the program. When the 1/0 is reached, the program exits, but variables can be inspected as usual with the pdb debugger (p my_var). Now, this does not allow you to fix things and keep running the program. Instead you can try to fix the bug and run the program again.

If you want to use the powerful IPython shell, ipython -pdb prog.py… does the same thing, but leads to IPython's better debugger interface. Alternatively, you can do everything from within the IPython shell:

  • In IPython, set up the "debug on exception" mode of IPython (%pdb).
  • Run the program from IPython with %run prog.py…. When an exception occurs, the debugger is automatically activated and you can inspect variables, etc.

The advantage of this latter approach is that (1) the IPython shell is almost a must; and (2) once it is installed, debugging can easily be done through it (instead of directly through the pdb module). The full documentation is available on the IPython pages.

Eric O. Lebigot
  • 91,433
  • 48
  • 218
  • 260
  • I also saw that there is a way to embed a call to IPython in the source code: `from IPython.Shell import IPShellEmbed ipshell = IPShellEmbed() ipshell() # this call anywhere in your program will start IPython` – sashoalm Apr 24 '11 at 08:34
  • @EOL, the first approach is interesting but when I tried it, the debugger catch the exception then exit python if I use 'python proj.py'. If I use python -m pdb prog.py, then it stops at the first line. How this 1/0 breakpoint helps on debugging? – Hong Aug 15 '17 at 15:21
  • Good question. I added two important points for the `-m pdb`option: (1) one must type "c" to start the program and (2) the program aborts when there is an exception but you can still have a look at the variables and try to figure out what is going on. – Eric O. Lebigot Aug 15 '17 at 18:10
2

You can run the program using pdb, and add breakpoints before starting execution.

In reality though, it's usually just as fast to edit the code and put in the set_trace() call, as another user stated.

Matthew Schinckel
  • 35,041
  • 6
  • 86
  • 121
0

Not sure what the real question is. Python gives you the 'pdb' debugger (google yourself) and in addition you can add logging and debug output as needed.