Debugger i IPython

IPythona używam od dłuższego czasu, jednak do tej pory nie udało mi się zmusić jednego z jego komponentów do współpracy. Tym komponentem jest debugger, który można uaktywnić w interpreterze poprzez wydanie komendy %ipdb on. Debugger włączy się automatycznie przy wystąpieniu wyjątku.

Zasadniczo jednak, częściej korzystałem z pdb poprzez wstawienie w kodzie linii import pdb; pdb.set_trace():

 1 class MainModel(ModelMT):
 2     status_bar_message = _("Idle")
 3 
 4     __observables__ = ("status_bar_message",)
 5 
 6     def __init__(self, filename=None):
 7         ModelMT.__init__(self)
 8         import pdb; pdb.set_trace()
 9         self.discs = gtk.TreeStore(str, gobject.TYPE_STRING)
10 
11         itr = self.discs.append(None, None)

Powodowało to uruchomienie debuggera przy pierwszym wykonaniu się tego kodu. Jednakże debugger IPythonowy posiada kilka miłych cech, które skłoniły mnie do próby wykorzystania go, zamiast standardowego. Bez powodzenia, dopóki nie natrafiłem na PyPi na modulik (wręcz snippet :)) ipdb. Krótkie easy_install ipdb i już mogłem się cieszyć IPythonowym debuggerem :) Wywołuje się go identycznie jak pdb:

 1 class MainModel(ModelMT):
 2     status_bar_message = _("Idle")
 3 
 4     __observables__ = ("status_bar_message",)
 5 
 6     def __init__(self, filename=None):
 7         ModelMT.__init__(self)
 8         import ipdb; ipdb.set_trace()
 9         self.discs = gtk.TreeStore(str, gobject.TYPE_STRING)
10 
11         itr = self.discs.append(None, None)

Oprócz tego, co standardowo potrafi pdb, ipdb oferuje kolorowanie składni, podpowiadanie składni (czyli tzw. tab-completion), ładne wyświetlanie tracebacków. Poniżej znajduje się przykładowa sesja z ipdb.

gryf@mslug ~/Devel/Python/pyGTKtalog $ ./gtktalog.py
> /home/gryf/Devel/Python/pyGTKtalog/pygtktalog/models/main.py(25)__init__()
     24         import
ipdb; ipdb.set_trace()
---> 25         self.discs = gtk.TreeStore(str, gobject.TYPE_STRING)
     26

ipdb> ?

Documented commands (type help <topic>):
========================================
EOF    bt         cont      enable  jump  pdef   r        tbreak   w
a      c          continue  exit    l     pdoc   restart  u        whatis
alias  cl         d         h       list  pinfo  return   unalias  where
args   clear      debug     help    n     pp     run      unt
b      commands   disable   ignore  next  q      s        until
break  condition  down      j       p     quit   step     up

Miscellaneous help topics:
==========================
exec  pdb

Undocumented commands:
======================
retval  rv

ipdb>  l
     20     __observables__ = ("status_bar_message",)
     21
     22     def
__init__(self,
filename=None):
     23         ModelMT.__init__(self)
     24         import
ipdb; ipdb.set_trace()
---> 25         self.discs = gtk.TreeStore(str, gobject.TYPE_STRING)
     26
     27         itr =
self.discs.append(None, None)
     28         self.discs.set_value(itr, 0, gtk.STOCK_DIRECTORY)
     29         self.discs.set_value(itr, 1, "foobar")
     30

ipdb> n
> /home/gryf/Devel/Python/pyGTKtalog/pygtktalog/models/main.py(27)__init__()
     26
---> 27         itr = self.discs.append(None, None)
     28         self.discs.set_value(itr, 0, gtk.STOCK_DIRECTORY)

ipdb> p self.disks
<gtk.TreeStore object at 0x88763c4 (GtkTreeStore at 0x81c9c88)>
ipdb> p self.disks.
Display all 147 possibilities? (y or n)
ipdb> n
> /home/gryf/Devel/Python/pyGTKtalog/pygtktalog/models/main.py(28)__init__()
     27         itr =
self.discs.append(None, None)
---> 28         self.discs.set_value(itr, 0, gtk.STOCK_DIRECTORY)
     29         self.discs.set_value(itr, 1, "foobar")

ipdb> n
> /home/gryf/Devel/Python/pyGTKtalog/pygtktalog/models/main.py(29)__init__()
     28         self.discs.set_value(itr, 0, gtk.STOCK_DIRECTORY)
---> 29         self.discs.set_value(itr, 1, "foobar")
     30

ipdb> n
> /home/gryf/Devel/Python/pyGTKtalog/pygtktalog/models/main.py(31)__init__()
     30
---> 31         for
nr, name in
enumerate(('foo', 'bar', 'baz')):
     32             self.discs.append(itr, (gtk.STOCK_FILE, "%s %d" % (name, nr)))

ipdb> self.discs.set_value(itr, 1, "nie do konca przemyslany tekst")
None
ipdb> c

, Etykiety: programowanie, python