Buttons840
Buttons840

Reputation: 9637

How can I interactively debug exceptions in Python using something besides IDLE?

When I'm using IDLE to run a script, if the script encounters an exception and execution stops, then I'm left with a interactive shell, which I can use to investigate the application state at the time of the exception. This is really nice, but otherwise I find IDLE lacking as an editor. Is there a way I can get this "drop to interactive shell on exceptions" behavior without using IDLE?enter image description here

Upvotes: 6

Views: 3142

Answers (6)

Richard
Richard

Reputation: 61289

Run your script as follows:

python -m pdb myscript.py

The console will show you:

> /home/user/dir/myscript.py(2)<module>()

-> first_line(of_my_script) (Pdb)

Type continue

Wait for things to explode:

TypeError: invalid type comparison
Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
> /home/user/problemscript.py(567)na_op()
-> raise TypeError("invalid type comparison")
(Pdb)

From here on out, you're basically in a MUD and a surprising number of the standard commands apply.

Type where or w to see where you are on the stack:

(Pdb) w
-> return df[df['type']=='dev'][['Dist','Count']].as_matrix()
  /home/user/core/ops.py(603)wrapper()
-> res = na_op(values, other)
> /home/user/core/ops.py(567)na_op()
-> raise TypeError("invalid type comparison")

See that little > arrow? That's where we are in the stack.

Use list or l to look around:

(Pdb) list
564               try:
565                   result = getattr(x, name)(y)
566                   if result is NotImplemented:
567  >>                     raise TypeError("invalid type comparison")
568               except (AttributeError):
569  ->                 result = op(x, y)
570   
571           return result
572   
573       def wrapper(self, other):
574           if isinstance(other, pd.Series):

To move around in the stack continue MUDing and use up (u) or down (d).

Use args (a) to examine what arguments the current function was called with:

(Pdb) args
dat = array([], shape=(0, 3), dtype=float64)
dev_classes = {81, 82, 21, 22, 23, 24, 31}

Use p to print out the contents of a variable (or pp to pretty-print (or handle your character's basic needs)):

(Pdb) p df
Empty DataFrame
Columns: [Dist, type, Count]
Index: []

Use interact to enter the code at the current point in the stack. Ctrl+D brings you back in to PDB.

Go forth! It will take many brave and mighty adventurers to turn back the assembled goblin hordes, now surrounding the city. Will you be the one to defeat the Goblin King, to reclaim the land for the races?

Upvotes: 4

Phil Cooper
Phil Cooper

Reputation: 5877

IMHO, If you are working in python and not using IPython you are wasting your time (in the literal sense).

In it, you can turn pdb on or off by just typeing the "magic" command pdb. The new qtconsole (my favorite) and notebook options make this killer environment even better.

Upvotes: 1

WeaselFox
WeaselFox

Reputation: 7380

I suggest using eclipse with pydev. It has many debug options, I dont see any advantage in using a shell for debugging. Try it and you may, I say.

Upvotes: 6

Marcin
Marcin

Reputation: 49826

Run your script from inside the python command interpreter (import it), and when there is an exception do import pdb; pdb.pm() to get a debugger at the point after the exception was raised.

Upvotes: 1

Fabian
Fabian

Reputation: 4348

You can use the pdb module.

import pdb
try:
    i = 0
    i = i + 'a string'
except Exception, err:
    pdb.set_trace()

Upvotes: 3

Charles Duffy
Charles Duffy

Reputation: 295393

python -i yourscript will drop to an interactive shell when yourscript exits. At this point you can run:

>>> import pdb
>>> pdb.pm()

...and get an interactive debugging shell.

See the PDB documentation.

Upvotes: 3

Related Questions