Licence CC BY-NC-ND, Thierry Parmentelat & Arnaud Legout
from IPython.display import HTML
HTML(filename="_static/style.html")
le debugger Python : pdb#
breakpoint()#
pour mettre un point d’arrêt dans un programme on peut utiliser breakpoint()
def fact(n):
if n<=1:
breakpoint()
return 1
else:
return n * fact(n-1)
raccourcis
clavier |
quoi |
|---|---|
l (lowercase L) |
list source |
w |
show stack |
n |
next statement (stay in same function) |
s |
step into (dive into function call) |
c |
continue |
p |
# si on exécute, le programme s'arrête
# et on peut ensuite exécuter pas à pas,
# inspecter la pile et les variables, ...
# fact(3)
pdb.run()#
le module pdb permet de debugger facilement un programme Python
import pdb
import mymodule
pdb.run('mymodule.test()')
lance le debugger depuis la console sur la fonction
test()
pdb.pm() - post-mortem#
import pdb
import mymodule
mymodule.test()
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "./mymodule.py", line 4, in test
test2()
…
pdb.pm()
lance le debugger en post-mortem
sous IPython#
dans ipython (ou dans un notebook), vous pouvez utiliser la magic %%debug
magic de cellule
rappelez-vous que avec un seul % on a affaire à une magic de ligne
et avec deux pourcents %% c’est une magique de cellule
donc nous ici on utilise presque toujours le double pourcent
def fact(n):
print(f"in fact with {n=}")
if n <= 1:
return 1
else:
return n * fact(n-1)
%%debug
fact(3)
NOTE: Enter 'c' at the ipdb> prompt to continue execution.
> <string>(2)<module>()
---------------------------------------------------------------------------
StdinNotImplementedError Traceback (most recent call last)
File ~/.asdf/installs/python/3.12.10/lib/python3.12/bdb.py:100, in Bdb.trace_dispatch(self, frame, event, arg)
98 return # None
99 if event == 'line':
--> 100 return self.dispatch_line(frame)
101 if event == 'call':
102 return self.dispatch_call(frame, arg)
File ~/.asdf/installs/python/3.12.10/lib/python3.12/bdb.py:124, in Bdb.dispatch_line(self, frame)
117 """Invoke user function and return trace function for line event.
118
119 If the debugger stops on the current line, invoke
120 self.user_line(). Raise BdbQuit if self.quitting is set.
121 Return self.trace_dispatch to continue tracing in this scope.
122 """
123 if self.stop_here(frame) or self.break_here(frame):
--> 124 self.user_line(frame)
125 if self.quitting: raise BdbQuit
126 return self.trace_dispatch
File ~/.asdf/installs/python/3.12.10/lib/python3.12/pdb.py:329, in Pdb.user_line(self, frame)
327 self._wait_for_mainpyfile = False
328 if self.bp_commands(frame):
--> 329 self.interaction(frame, None)
File ~/checkouts/readthedocs.org/user_builds/flotpython-slides/envs/jb1/lib/python3.12/site-packages/IPython/core/debugger.py:522, in Pdb.interaction(self, frame, tb_or_exc)
520 assert tb is not None, "main exception must have a traceback"
521 with self._hold_exceptions(_chained_exceptions):
--> 522 OldPdb.interaction(self, frame, tb)
523 else:
524 OldPdb.interaction(self, frame, tb_or_exc)
File ~/.asdf/installs/python/3.12.10/lib/python3.12/pdb.py:428, in Pdb.interaction(self, frame, traceback)
422 # We should print the stack entry if and only if the user input
423 # is expected, and we should print it right before the user input.
424 # We achieve this by appending _pdbcmd_print_frame_status to the
425 # command queue. If cmdqueue is not exausted, the user input is
426 # not expected and we will not print the stack entry.
427 self.cmdqueue.append('_pdbcmd_print_frame_status')
--> 428 self._cmdloop()
429 # If _pdbcmd_print_frame_status is not used, pop it out
430 if self.cmdqueue and self.cmdqueue[-1] == '_pdbcmd_print_frame_status':
File ~/checkouts/readthedocs.org/user_builds/flotpython-slides/envs/jb1/lib/python3.12/site-packages/IPython/core/debugger.py:1253, in InterruptiblePdb._cmdloop(self)
1249 try:
1250 # keyboard interrupts allow for an easy way to cancel
1251 # the current command, so allow them during interactive input
1252 self.allow_kbdint = True
-> 1253 self.cmdloop()
1254 self.allow_kbdint = False
1255 break
File ~/checkouts/readthedocs.org/user_builds/flotpython-slides/envs/jb1/lib/python3.12/site-packages/IPython/core/debugger.py:1239, in InterruptiblePdb.cmdloop(self, intro)
1237 """Wrap cmdloop() such that KeyboardInterrupt stops the debugger."""
1238 try:
-> 1239 return OldPdb.cmdloop(self, intro=intro)
1240 except KeyboardInterrupt:
1241 self.stop_here = lambda frame: False # type: ignore[method-assign]
File ~/.asdf/installs/python/3.12.10/lib/python3.12/cmd.py:126, in Cmd.cmdloop(self, intro)
124 if self.use_rawinput:
125 try:
--> 126 line = input(self.prompt)
127 except EOFError:
128 line = 'EOF'
File ~/checkouts/readthedocs.org/user_builds/flotpython-slides/envs/jb1/lib/python3.12/site-packages/ipykernel/kernelbase.py:1274, in Kernel.raw_input(self, prompt)
1272 if not self._allow_stdin:
1273 msg = "raw_input was called, but this frontend does not support input requests."
-> 1274 raise StdinNotImplementedError(msg)
1275 return self._input_request(
1276 str(prompt),
1277 self._parent_ident["shell"],
1278 self.get_parent("shell"),
1279 password=False,
1280 )
StdinNotImplementedError: raw_input was called, but this frontend does not support input requests.