Iniciar el depurador de Python automáticamente en caso de error

Esta es una pregunta que me he preguntado durante bastante tiempo, pero nunca he encontrado una solución adecuada. Si ejecuto un script y me cruzo, digamos un IndexError, python imprime la línea, la ubicación y la descripción rápida del error y sale. ¿Es posible iniciar automáticamente pdb cuando se encuentra un error? No estoy en contra de tener una statement de importación adicional en la parte superior del archivo, ni unas pocas líneas de código adicionales.

Puede usar traceback.print_exc para imprimir el rastreo de excepciones. Luego use sys.exc_info para extraer el rastreo y finalmente llame a pdb.post_mortem con ese rastreo

import pdb, traceback, sys def bombs(): a = [] print a[0] if __name__ == '__main__': try: bombs() except: extype, value, tb = sys.exc_info() traceback.print_exc() pdb.post_mortem(tb) 

Si desea iniciar una línea de comando interactiva con code.interact utilizando los locales del marco donde se originó la excepción, puede hacerlo

 import traceback, sys, code def bombs(): a = [] print a[0] if __name__ == '__main__': try: bombs() except: type, value, tb = sys.exc_info() traceback.print_exc() last_frame = lambda tb=tb: last_frame(tb.tb_next) if tb.tb_next else tb frame = last_frame().tb_frame ns = dict(frame.f_globals) ns.update(frame.f_locals) code.interact(local=ns) 
 python -m pdb -c continue myscript.py 

Si no proporciona la -c continue , deberá ingresar ‘c’ (para Continuar) cuando comience la ejecución. Luego se ejecutará hasta el punto de error y le dará control allí. Como lo menciona eqzx , esta bandera es una nueva adición a Python 3.2, por lo que se requiere ingresar ‘c’ para las versiones anteriores de Python (consulte https://docs.python.org/3/library/pdb.html ).

Usa el siguiente módulo:

 import sys def info(type, value, tb): if hasattr(sys, 'ps1') or not sys.stderr.isatty(): # we are in interactive mode or we don't have a tty-like # device, so we call the default hook sys.__excepthook__(type, value, tb) else: import traceback, pdb # we are NOT in interactive mode, print the exception... traceback.print_exception(type, value, tb) print # ...then start the debugger in post-mortem mode. # pdb.pm() # deprecated pdb.post_mortem(tb) # more "modern" sys.excepthook = info 

Nómbrelo como debug (o como quieras) y colócalo en algún lugar de tu ruta de python.

Ahora, al inicio de su script, simplemente agregue una import debug .

Ipython tiene un comando para alternar este comportamiento: % pdb . Hace exactamente lo que describió, tal vez incluso un poco más (brindándole información más detallada sobre resúmenes de resaltado de syntax y código). ¡Definitivamente vale la pena intentarlo!

Este no es el depurador, pero probablemente sea tan útil (?)

Sé que escuché a Guido mencionar esto en un discurso en alguna parte.

Acabo de marcar python – ?, y si usas el comando -i puedes interactuar donde se detuvo tu script.

Así que dado este guión:

 testlist = [1,2,3,4,5, 0] prev_i = None for i in testlist: if not prev_i: prev_i = i else: result = prev_i/i 

Usted puede obtener esta salida!

 PS D:\> python -i debugtest.py Traceback (most recent call last): File "debugtest.py", line 10, in  result = prev_i/i ZeroDivisionError: integer division or modulo by zero >>> >>> >>> prev_i 1 >>> i 0 >>> 

Para ser honesto, no he usado esto, pero debería serlo, parece muy útil.

IPython hace esto simple en la línea de comandos:

 python myscript.py arg1 arg2 

se puede reescribir a

 ipython --pdb myscript.py -- arg1 arg2 

O, de manera similar, si llama a un módulo:

 python -m mymodule arg1 arg2 

se puede reescribir a

 ipython --pdb -m mymodule -- arg1 arg2 

Tenga en cuenta que -- para evitar que IPython lea los argumentos del script como propios.

Esto también tiene la ventaja de invocar al depurador IPython mejorado (ipdb) en lugar de pdb.

Si está utilizando el entorno IPython, solo puede usar% debug y el shell lo llevará de vuelta a la línea ofensiva con el entorno ipdb para inspecciones, etc. Otra opción como se señaló anteriormente es usar iPython magic% pdb, que efectivamente lo hace. lo mismo.

Puedes poner esta línea en tu código:

 import pdb ; pdb.set_trace() 

Más información: Inicie el depurador de Python en cualquier línea

Para que se ejecute sin tener que escribir c al principio, use:

 python -m pdb -cc  

Pdb tiene sus propios argumentos de línea de comando: -cc ejecutará el comando c (ontinue) al inicio de la ejecución y el progtwig se ejecutará ininterrumpidamente hasta el error.

Si está usando ipython , después de iniciar el tipo %pdb

 In [1]: %pdb Automatic pdb calling has been turned ON 

python -m pdb script.py en python2.7 presione continuar para iniciarse, se ejecutará el error y se interrumpirá allí para la depuración.

Coloque un punto de interrupción dentro del constructor de la clase de excepción superior en la jerarquía, y la mayoría de las veces verá dónde se generó el error.

Poner un punto de interrupción significa lo que quieras que signifique: puedes usar un IDE, pdb.set_trace , o lo que sea

Si está ejecutando un módulo:

 python -m mymodule 

Y ahora desea ingresar pdb cuando se produce una excepción, haga esto:

 PYTHONPATH="." python -m pdb -cc mymodule/__main__.py 

(o extender su PYTHONPATH ). Se necesita PYTHONPATH para que el módulo se encuentre en la ruta, ya que ahora está ejecutando el módulo pdb .