pdb — El Depurador de Python

Código fuente: Lib/unittest/mock.py


El módulo pdb define un depurador de código fuente interactivo para programas Python. Soporta el establecimiento de puntos de ruptura (condicionales) y pasos sencillos a nivel de línea de código fuente, inspección de marcos de pila, listado de código fuente, y evaluación de código Python arbitrario en el contexto de cualquier marco de pila. También soporta depuración post-mortem y puede ser llamado bajo control del programa.

El depurador es extensible – en realidad se define como la clase Pdb. Esto no está actualmente documentado pero se entiende fácilmente leyendo la fuente. La interfaz de extensión usa los módulos bdb y cmd.

Ver también

Module faulthandler

Used to dump Python tracebacks explicitly, on a fault, after a timeout, or on a user signal.

Module traceback

Standard interface to extract, format and print stack traces of Python programs.

The typical usage to break into the debugger is to insert:

import pdb; pdb.set_trace()

Or:

breakpoint()

at the location you want to break into the debugger, and then run the program. You can then step through the code following this statement, and continue running without the debugger using the continue command.

Distinto en la versión 3.7: La breakpoint() incorporada cuando se llama con los valores por defecto, puede ser usado en lugar del import pdb; pdb.set_trace().

def double(x):
   breakpoint()
   return x * 2
val = 3
print(f"{val} * 2 is {double(val)}")

The debugger’s prompt is (Pdb), which is the indicator that you are in debug mode:

> ...(3)double()
-> return x * 2
(Pdb) p x
3
(Pdb) continue
3 * 2 is 6

Distinto en la versión 3.3: La finalización de tabulación a través del módulo readline está disponible para comandos y argumentos de comando, por ejemplo. Los nombres globales y locales actuales se ofrecen como argumentos del comando p.

You can also invoke pdb from the command line to debug other scripts. For example:

python -m pdb myscript.py

When invoked as a module, pdb will automatically enter post-mortem debugging if the program being debugged exits abnormally. After post-mortem debugging (or after normal exit of the program), pdb will restart the program. Automatic restarting preserves pdb’s state (such as breakpoints) and in most cases is more useful than quitting the debugger upon program’s exit.

Distinto en la versión 3.2: Added the -c option to execute commands as if given in a .pdbrc file; see Comandos del depurador.

Distinto en la versión 3.7: Added the -m option to execute modules similar to the way python -m does. As with a script, the debugger will pause execution just before the first line of the module.

Typical usage to execute a statement under control of the debugger is:

>>> import pdb
>>> def f(x):
...     print(1 / x)
>>> pdb.run("f(2)")
> <string>(1)<module>()
(Pdb) continue
0.5
>>>

El uso típico para inspeccionar un programa que se ha estrellado es:

>>> import pdb
>>> def f(x):
...     print(1 / x)
...
>>> f(0)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in f
ZeroDivisionError: division by zero
>>> pdb.pm()
> <stdin>(2)f()
(Pdb) p x
0
(Pdb)

El módulo define las siguientes funciones; cada una de ellas entra en el depurador de una manera ligeramente diferente:

pdb.run(statement, globals=None, locals=None)

Ejecutar el statement (dado como una cadena o un objeto de código) bajo el control del depurador. El prompt del depurador aparece antes de que se ejecute cualquier código; puedes establecer puntos de ruptura y escribir continue, o puedes pasar por la declaración usando step o next (todos estos comandos se explican más abajo). Los argumentos opcionales globals y locals especifican el entorno en el que se ejecuta el código; por defecto se utiliza el diccionario del módulo __main__. (Ver la explicación de las funciones incorporadas exec() o eval()).

pdb.runeval(expression, globals=None, locals=None)

Evaluate the expression (given as a string or a code object) under debugger control. When runeval() returns, it returns the value of the expression. Otherwise this function is similar to run().

pdb.runcall(function, *args, **kwds)

Llama a la function (un objeto de función o método, no una cadena) con los argumentos dados. Cuando runcall() retorna, retorna lo que sea que la llamada de la función haya retornado. El aviso del depurador aparece tan pronto como se introduce la función.

pdb.set_trace(*, header=None)

Entra en el depurador en el marco de la pila de llamadas. Esto es útil para codificar duramente un punto de interrupción en un punto dado de un programa, incluso si el código no se depura de otra manera (por ejemplo, cuando una afirmación falla). Si se da, se imprime el header en la consola justo antes de que comience la depuración.

Distinto en la versión 3.7: El argumento de la palabra clave header.

pdb.post_mortem(traceback=None)

Ingresa a la depuración post-mortem del objeto traceback dado. Si no se da un traceback, utiliza el de la excepción que se está manejando actualmente (una excepción debe ser manejada si se va a utilizar el predeterminado).

pdb.pm()

Enter post-mortem debugging of the exception found in sys.last_exc.

Las funciones run* y set_trace() son alias para instanciar la clase Pdb y llamar al método del mismo nombre. Si quieres acceder a más funciones, tienes que hacerlo tú mismo:

class pdb.Pdb(completekey='tab', stdin=None, stdout=None, skip=None, nosigint=False, readrc=True)

Pdb es la clase de depuración.

Los argumentos completekey, stdin y stdout se pasan a la subyacente cmd.Cmd class; ver la descripción allí.

El argumento skip, si se da, debe ser un iterable de los patrones de nombre de los módulos de estilo global. El depurador no entrará en marcos que se originen en un módulo que coincida con uno de estos patrones. [1]

By default, Pdb sets a handler for the SIGINT signal (which is sent when the user presses Ctrl-C on the console) when you give a continue command. This allows you to break into the debugger again by pressing Ctrl-C. If you want Pdb not to touch the SIGINT handler, set nosigint to true.

El argumento * readrc * por defecto es verdadero y controla si Pdb cargará archivos .pdbrc desde el sistema de archivos.

Ejemplo de llamada para permitir el rastreo con skip:

import pdb; pdb.Pdb(skip=['django.*']).set_trace()

Levanta una auditing event pdb.Pdb sin argumentos.

Distinto en la versión 3.1: Added the skip parameter.

Distinto en la versión 3.2: Added the nosigint parameter. Previously, a SIGINT handler was never set by Pdb.

Distinto en la versión 3.6: El argumento readrc.

run(statement, globals=None, locals=None)
runeval(expression, globals=None, locals=None)
runcall(function, *args, **kwds)
set_trace()

Véase la documentación para las funciones explicadas anteriormente.

Comandos del depurador

Los comandos reconocidos por el depurador se enumeran a continuación. La mayoría de los comandos pueden abreviarse a una o dos letras como se indica; por ejemplo, h(elp) significa que se puede usar h o help para introducir el comando de ayuda (pero no he o hel, ni H o Help o HELP). Los argumentos de los comandos deben estar separados por espacios en blanco (espacios o tabulaciones). Los argumentos opcionales están encerrados entre corchetes ([]) en la sintaxis del comando; los corchetes no deben escribirse. Las alternativas en la sintaxis de los comandos están separadas por una barra vertical (|).

Introducir una línea en blanco repite el último comando introducido. Excepción: si el último comando fue un list comando, las siguientes 11 líneas están listadas.

Se supone que los comandos que el depurador no reconoce son declaraciones en Python y se ejecutan en el contexto del programa que se está depurando. Las declaraciones en Python también pueden ser precedidas por un signo de exclamación (!). Esta es una manera poderosa de inspeccionar el programa que se está depurando; incluso es posible cambiar una variable o llamar a una función. Cuando se produce una excepción en una sentencia de este tipo, se imprime el nombre de la excepción pero no se cambia el estado del depurador.

Distinto en la versión 3.13: Expressions/Statements whose prefix is a pdb command are now correctly identified and executed.

El depurador soporta aliases. Los alias pueden tener parámetros que permiten un cierto nivel de adaptabilidad al contexto que se está examinando.

Multiple commands may be entered on a single line, separated by ;;. (A single ; is not used as it is the separator for multiple commands in a line that is passed to the Python parser.) No intelligence is applied to separating the commands; the input is split at the first ;; pair, even if it is in the middle of a quoted string. A workaround for strings with double semicolons is to use implicit string concatenation ';'';' or ";"";".

To set a temporary global variable, use a convenience variable. A convenience variable is a variable whose name starts with $. For example, $foo = 1 sets a global variable $foo which you can use in the debugger session. The convenience variables are cleared when the program resumes execution so it’s less likely to interfere with your program compared to using normal variables like foo = 1.

There are three preset convenience variables:

  • $_frame: the current frame you are debugging

  • $_retval: the return value if the frame is returning

  • $_exception: the exception if the frame is raising an exception

Nuevo en la versión 3.12.

If a file .pdbrc exists in the user’s home directory or in the current directory, it is read with 'utf-8' encoding and executed as if it had been typed at the debugger prompt, with the exception that empty lines and lines starting with # are ignored. This is particularly useful for aliases. If both files exist, the one in the home directory is read first and aliases defined there can be overridden by the local file.

Distinto en la versión 3.2: .pdbrc puede ahora contener comandos que continúan depurando, como continue o next. Anteriormente, estos comandos no tenían ningún efecto.

Distinto en la versión 3.11: .pdbrc es ahora leído con codificación 'utf-8'. Antes, era leído con la codificación correspondiente a la configuración regional del sistema.

h(elp) [command]

Sin argumento, imprime la lista de comandos disponibles. Con un command como argumento, imprime la ayuda sobre ese comando. help pdb muestra la documentación completa (el docstring del módulo pdb). Como el argumento command debe ser un identificador, hay que introducir help exec para obtener ayuda sobre el comando !.

w(here)

Print a stack trace, with the most recent frame at the bottom. An arrow (>) indicates the current frame, which determines the context of most commands.

d(own) [count]

Mueve los niveles del marco actual count (por defecto uno) hacia abajo en el trazado de la pila (stack trace) (a un marco más nuevo).

u(p) [count]

Mueve el marco actual count (por defecto uno) niveles hacia arriba en el trazado de la pila (stack trace) (a un marco más antiguo).

b(reak) [([filename:]lineno | function) [, condition]]

Con un argumento lineno, establece una ruptura allí en el archivo actual. Con un argumento function, establece una ruptura en la primera declaración ejecutable dentro de esa función. El número de línea puede ir precedido de un nombre de archivo y dos puntos, para especificar un punto de interrupción en otro archivo (probablemente uno que aún no se haya cargado). El archivo se busca en sys.path. Observe que a cada punto de interrupción se le asigna un número al que se refieren todos los demás comandos de puntos de interrupción.

Si un segundo argumento está presente, es una expresión que debe ser evaluada como verdadera antes de que el punto de ruptura sea honrado.

Sin argumento, enumere todas las interrupciones, incluyendo para cada punto de interrupción, el número de veces que se ha alcanzado ese punto de interrupción, el conteo de ignorancia actual y la condición asociada, si la hay.

tbreak [([filename:]lineno | function) [, condition]]

Punto de interrupción temporal, que se elimina automáticamente cuando se ejecuta por primera vez. Los argumentos son los mismos que para break.

cl(ear) [filename:lineno | bpnumber ...]

Con el argumento filename:lineno, despeja todos los puntos de interrupción en esta línea. Con una lista de números de puntos de interrupción separados por espacios, despeja esos puntos de interrupción. Sin el argumento, despeja todos los puntos de interrupción (pero primero pide confirmación).

disable bpnumber [bpnumber ...]

Deshabilitar los puntos de ruptura interrupción como una lista de números de puntos de ruptura separados por espacios. Desactivar un punto de interrupción significa que no puede hacer que el programa detenga la ejecución, pero a diferencia de borrar un punto de interrupción, permanece en la lista de puntos de interrupción y puede ser (re)activado.

enable bpnumber [bpnumber ...]

Habilitar los puntos de interrupción especificados.

ignore bpnumber [count]

Set the ignore count for the given breakpoint number. If count is omitted, the ignore count is set to 0. A breakpoint becomes active when the ignore count is zero. When non-zero, the count is decremented each time the breakpoint is reached and the breakpoint is not disabled and any associated condition evaluates to true.

condition bpnumber [condition]

Establece una nueva condition para el punto de interrupción, una expresión que debe evaluarse como verdadera antes de que el punto de ruptura sea honrado. Si la condición está ausente, se elimina cualquier condición existente, es decir, el punto de ruptura se hace incondicional.

commands [bpnumber]

Especifique una lista de comandos para el número del punto de interrupción bpnumber. Los comandos mismos aparecen en las siguientes líneas. Escriba una línea que contenga sólo end para terminar los comandos. Un ejemplo:

(Pdb) commands 1
(com) p some_variable
(com) end
(Pdb)

Para eliminar todos los comandos de un punto de interrupción, escribe commands y sigue inmediatamente con end , es decir, no des órdenes.

Sin el argumento bpnumber, commands se refiere al último punto de interrupción establecido.

Puede utilizar los comandos de punto de interrupción para iniciar el programa de nuevo. Simplemente usa el comando continue, o step, o cualquier otro comando que reanude la ejecución.

Al especificar cualquier comando que reanude la ejecución (actualmente continue, step, next, return, jump, quit y sus abreviaturas) se termina la lista de comandos (como si ese comando fuera inmediatamente seguido de end.) Esto se debe a que cada vez que se reanuda la ejecución (incluso con un simple siguiente o paso), puede encontrarse con otro punto de interrupción, que podría tener su propia lista de comandos, lo que conduce a ambigüedades sobre qué lista ejecutar.

If you use the silent command in the command list, the usual message about stopping at a breakpoint is not printed. This may be desirable for breakpoints that are to print a specific message and then continue. If none of the other commands print anything, you see no sign that the breakpoint was reached.

s(tep)

Ejecutar la línea actual, detenerse en la primera ocasión posible (ya sea en una función que se llame o en la siguiente línea de la función actual).

n(ext)

Continúe la ejecución hasta que se alcance la siguiente línea de la función actual o vuelva. (La diferencia entre next y step es que step se detiene dentro de una función llamada, mientras que next ejecuta las funciones llamadas a (casi) toda velocidad, deteniéndose sólo en la siguiente línea de la función actual).

unt(il) [lineno]

Sin argumento, continúe la ejecución hasta que se alcance la línea con un número mayor que el actual.

With lineno, continue execution until a line with a number greater or equal to lineno is reached. In both cases, also stop when the current frame returns.

Distinto en la versión 3.2: Permita dar un número de línea explícito.

r(eturn)

Continúe la ejecución hasta que vuelva la función actual.

c(ont(inue))

Continúa la ejecución, sólo se detiene cuando se encuentra un punto de ruptura.

j(ump) lineno

Establezca la siguiente línea que será ejecutada. Sólo disponible en el marco de más bajo. Esto te permite saltar hacia atrás y ejecutar el código de nuevo, o saltar hacia adelante para saltar el código que no quieres ejecutar.

Cabe señalar que no todos los saltos están permitidos – por ejemplo, no es posible saltar en medio de un bucle for o fuera de una cláusula finally.

l(ist) [first[, last]]

Enumere el código fuente del archivo actual. Sin argumentos, enumere 11 líneas alrededor de la línea actual o continúe la lista anterior. Con . como argumento, enumere 11 líneas alrededor de la línea actual. Con un argumento, enumere 11 líneas alrededor de esa línea. Con dos argumentos, enumere el rango dado; si el segundo argumento es menor que el primero, se interpreta como un conteo.

La línea actual en el cuadro actual se indica con ->. Si se está depurando una excepción, la línea donde la excepción fue originalmente planteada o propagada se indica con >>, si difiere de la línea actual.

Distinto en la versión 3.2: Added the >> marker.

ll | longlist

Enumere todos los códigos fuente de la función o marco actual. Las líneas interesantes están marcadas como list.

Nuevo en la versión 3.2.

a(rgs)

Print the arguments of the current function and their current values.

p expression

Evaluate expression in the current context and print its value.

Nota

print() también se puede usar, pero no es un comando de depuración — esto ejecuta la función Python print().

pp expression

Like the p command, except the value of expression is pretty-printed using the pprint module.

whatis expression

Print the type of expression.

source expression

Try to get source code of expression and display it.

Nuevo en la versión 3.2.

display [expression]

Display the value of expression if it changed, each time execution stops in the current frame.

Without expression, list all display expressions for the current frame.

Nota

Display evaluates expression and compares to the result of the previous evaluation of expression, so when the result is mutable, display may not be able to pick up the changes.

Example:

lst = []
breakpoint()
pass
lst.append(1)
print(lst)

Display won’t realize lst has been changed because the result of evaluation is modified in place by lst.append(1) before being compared:

> example.py(3)<module>()
-> pass
(Pdb) display lst
display lst: []
(Pdb) n
> example.py(4)<module>()
-> lst.append(1)
(Pdb) n
> example.py(5)<module>()
-> print(lst)
(Pdb)

You can do some tricks with copy mechanism to make it work:

> example.py(3)<module>()
-> pass
(Pdb) display lst[:]
display lst[:]: []
(Pdb) n
> example.py(4)<module>()
-> lst.append(1)
(Pdb) n
> example.py(5)<module>()
-> print(lst)
display lst[:]: [1]  [old: []]
(Pdb)

Nuevo en la versión 3.2.

undisplay [expression]

Do not display expression anymore in the current frame. Without expression, clear all display expressions for the current frame.

Nuevo en la versión 3.2.

interact

Start an interactive interpreter (using the code module) whose global namespace contains all the (global and local) names found in the current scope. Use exit() or quit() to exit the interpreter and return to the debugger.

Nota

Because interact creates a new global namespace with the current global and local namespace for execution, assignment to variables will not affect the original namespaces. However, modification to the mutable objects will be reflected in the original namespaces.

Nuevo en la versión 3.2.

Distinto en la versión 3.13: exit() and quit() can be used to exit the interact command.

Distinto en la versión 3.13: interact directs its output to the debugger’s output channel rather than sys.stderr.

alias [name [command]]

Create an alias called name that executes command. The command must not be enclosed in quotes. Replaceable parameters can be indicated by %1, %2, … and %9, while %* is replaced by all the parameters. If command is omitted, the current alias for name is shown. If no arguments are given, all aliases are listed.

Los alias pueden anidarse y pueden contener cualquier cosa que se pueda teclear legalmente en el prompt de pdb. Tenga en cuenta que los comandos internos de pdb pueden ser anulados por los alias. Dicho comando se oculta hasta que se elimina el alias. El alias se aplica de forma recursiva a la primera palabra de la línea de comandos; todas las demás palabras de la línea se dejan en paz.

Como ejemplo, aquí hay dos alias útiles (especialmente cuando se colocan en el archivo .pdbrc):

# Print instance variables (usage "pi classInst")
alias pi for k in %1.__dict__.keys(): print(f"%1.{k} = {%1.__dict__[k]}")
# Print instance variables in self
alias ps pi self
unalias name

Delete the specified alias name.

! statement

Execute the (one-line) statement in the context of the current stack frame. The exclamation point can be omitted unless the first word of the statement resembles a debugger command, e.g.:

(Pdb) ! n=42
(Pdb)

To set a global variable, you can prefix the assignment command with a global statement on the same line, e.g.:

(Pdb) global list_options; list_options = ['-l']
(Pdb)
run [args ...]
restart [args ...]

Restart the debugged Python program. If args is supplied, it is split with shlex and the result is used as the new sys.argv. History, breakpoints, actions and debugger options are preserved. restart is an alias for run.

q(uit)

Salga del depurador. El programa que se está ejecutando fue abortado.

debug code

Enter a recursive debugger that steps through code (which is an arbitrary expression or statement to be executed in the current environment).

retval

Print the return value for the last return of the current function.

exceptions [excnumber]

List or jump between chained exceptions.

When using pdb.pm() or Pdb.post_mortem(...) with a chained exception instead of a traceback, it allows the user to move between the chained exceptions using exceptions command to list exceptions, and exception <number> to switch to that exception.

Example:

def out():
    try:
        middle()
    except Exception as e:
        raise ValueError("reraise middle() error") from e

def middle():
    try:
        return inner(0)
    except Exception as e:
        raise ValueError("Middle fail")

def inner(x):
    1 / x

 out()

calling pdb.pm() will allow to move between exceptions:

> example.py(5)out()
-> raise ValueError("reraise middle() error") from e

(Pdb) exceptions
  0 ZeroDivisionError('division by zero')
  1 ValueError('Middle fail')
> 2 ValueError('reraise middle() error')

(Pdb) exceptions 0
> example.py(16)inner()
-> 1 / x

(Pdb) up
> example.py(10)middle()
-> return inner(0)

Nuevo en la versión 3.13.

Notas de pie de página