[BangPypers] using IPython from pdb

Jeffrey Jose jeffjosejeff at gmail.com
Sat Feb 6 15:15:03 CET 2010


[ caution, huge email follows ]

Hey Senthil,
I was under the impression that everyone here used and loved IPython. Boy,
was I wrong.
I wont attempt to convince you folks why you should use IPython, but here a
few features that I love in IPython which are not there (or not  very
obvious) in vanilla python interpreter.

note: I'm using ">>" for prompt, you can always customize your IPython
interpreter.

*Tab completion*. I cant live without it.
>> import sys
>> sy<TAB>
>> sys.<TAB>
sys.foo sys.bar sys.baz

>> sys.getsi<TAB>
>> sys.getsizeof

*Documentation* and *Function Signature*
>> sys.getsizeof?
*Type*:             builtin_function_or_method
*Base Class*:  <type 'builtin_function_or_method'>
*String Form*:  <built-in function getsizeof>
*Namespace*:   Interactive
*Docstring*:
     getsizeof(object, default) -> int

     Return the size of object in bytes

*Source Code*
>> import multiprocessing
>> multiprocessing.os?
*[Doc, Function Signature etc]*

>> multiprocessing.os??
*[opens the source code if you wanna browse around]*


Those are the top 3 things that I love about IPython interpreter. And ever
since I found them, I haven't gone back to vanilla python interpreter.

Senthil wrote,

* I am really not sure as how using IPython from pdb can help during
debugging? I tried it, I loose all the pdb's capabilities when I enter into
the IPython shell. How do people normally use it?
*

Yes, you're right. You loose all capabilities of pdb when you're in IPython
(there's a solution, i'll get to that later)
Here's my typical IPython from pdb session for debugging.

1. Insert import pdb;pdb.set_trace() the place where I suspect the problem
is. Assume the very next line throws a huge error.
2. Run the code, drop into pdb
3. Invoke IPython from pdb
>> whos
# Shows all the variables in the current context
4. Poke around a lil bit, see what's the values of variables are, etc etc.
Pretty normal stuff. Couple this with IPython's excellent introspective
power you can rip apart and dig each and everything.
>> import more_modules
>> try_different_things(); try_different_logic();
5. Execute the "next line" and expect it to throw the error. See the error,
if you want, retry the same line, try different arguments. Note: You havent
progressed a line at all, you're just trying out stuff at this moment
6. Once you're done your bit, you *get out of IPython. Cntrl-D*
7*. *Back in pdb, use all of pdb's power. Step in, Execute next line, set
more breakpoints, etc etc
8. Hit "c" to proceed to next breakpoint.
9. Repeat Steps 3 -> 8

I've never had to use print statements for debugging ever since I found pdb.
With print, you can print only a couple of variables, with IPython (pdb
actually) you have access to the entire namespace. IPython just makes
working with the huge namespace a breeze.

If you arent bored already, I'll explain a unique (weird ?) way I write code
these days.
Normally, we have 2 windows open. One python interpreter and your fav text
editor. You try out stuff before to type it in your text editor.
Here's a different approach.

Step 1: Start coding before you even try out a single bit on python
interpreter.
# myCode.py
import re
regex = re.compile(r'^b')
myList = ['foo', 'bar', 'baz']

for item in myList:
   import pdb;pdb.set_trace()

Step 2. Drop into pdb and then to IPython
Step 3. Try out your stuff *here*. You dont have to setup *myList*, *item,
regex *etc. You have everything ready waiting for you.
Step 4:
>> item
*'foo'*

>> regex
*<_sre.SRE_Patten object at 0x123123>*

>> regex.<TAB>
>> regex.mat<TAB>
>> regex.match?
*[read, find what it is, nope .. not what I wanted]*

>> regex.<TAB>
>> regex.sea<TAB>
>> regex.search?
*[ah ha!]*

>> regex.search(item)
>> Cntrl-D

(pdb) c

>> regex.search(item)
*<_sre.SRE_Match object at 0x123123>*

*# phew, my re pattern works, awesome. I didnt have to setup dummy values
and then try it out etc.*
*# If re pattern didnt work the first time, I can make a new re patten and
try it out here. Again, I am not dealing with dummy values, but its the
actual values from the code -- foo, bar, baz (think if you're reading from a
file, querying database etc.) work with real values, not dummy*

*# Again, not knowing whether it is regex.search or regex.match to use didnt
stop you from starting to code.*
*
*I call it breakpoint induced coding. Extremely helpful when you're
modifying someone else's code and you have no idea wht the heck all the code
before this was doing. Insert a breakpoint (at the potential place you'd
edit/add code) and start from there.

# someonesCode.py
import m1, m2, m3;

call_function_1()
call_function_2()
do_extreme_stuff()
call_another_setof_functions()

def do_extreme_stuff():
  s1
  s2
  potential_bug
  s3


Step 1.
s1
s2
*import pdb;pdb.set_trace()*
potential_bug
s3

Step 2: pdb -> IPython
>> whos
* #see what the variables are, what's the status of the program right now
etc*

>> try_a_much_better_approach()
>> make_sure_it_works_and_doesnt_break_anything()

Step 3: Go back to text editor and put in your stuff there.
Step 4: Peace.


If you're still reading, hope I havent confused you.


Jeff


More information about the BangPypers mailing list