visual studio portable para online hacer gui debugger debug como code python debugging traceback

studio - python debugger portable



Cómo limitar el rastreo de python a archivos específicos (3)

Como otros sugirieron, podrías usar sys.excepthook :

Esta función imprime un seguimiento dado y una excepción a sys.stderr .

Cuando se produce una excepción y no se captura, el intérprete llama a sys.excepthook con tres argumentos, la clase de excepción, la instancia de excepción y un objeto de rastreo. En una sesión interactiva, esto sucede justo antes de que se devuelva el control al indicador; en un programa Python esto sucede justo antes de que el programa salga. El manejo de tales excepciones de nivel superior se puede personalizar asignando otra función de tres argumentos a sys.excepthook .

(énfasis mío)

Es posible filtrar un rastreo extraído por extract_tb (o funciones similares del módulo de traceback ) en función de directorios específicos.

Dos funciones que pueden ayudar:

from os.path import join, abspath from traceback import extract_tb, format_list, format_exception_only def spotlight(*show): '''''' Return a function to be set as new sys.excepthook. It will SHOW traceback entries for files from these directories. '''''' show = tuple(join(abspath(p), '''') for p in show) def _check_file(name): return name and name.startswith(show) def _print(type, value, tb): show = (fs for fs in extract_tb(tb) if _check_file(fs.filename)) fmt = format_list(show) + format_exception_only(type, value) print(''''.join(fmt), end='''', file=sys.stderr) return _print def shadow(*hide): '''''' Return a function to be set as new sys.excepthook. It will HIDE traceback entries for files from these directories. '''''' hide = tuple(join(abspath(p), '''') for p in hide) def _check_file(name): return name and not name.startswith(hide) def _print(type, value, tb): show = (fs for fs in extract_tb(tb) if _check_file(fs.filename)) fmt = format_list(show) + format_exception_only(type, value) print(''''.join(fmt), end='''', file=sys.stderr) return _print

Ambos usan el traceback.extract_tb . Devuelve "una lista de entradas de seguimiento de pila" preprocesadas "extraídas del objeto de rastreo" ; todos ellos son instancias de traceback.FrameSummary (una tupla con nombre). Cada objeto traceback.FrameSummary tiene un campo de filename que almacena la ruta absoluta del archivo correspondiente. Verificamos si comienza con alguna de las rutas de directorio proporcionadas como argumentos de función separados para determinar si necesitaremos excluir la entrada (o conservarla).

Aquí hay un ejemplo :

El módulo de enum de la biblioteca estándar no permite reutilizar claves,

import enum enum.Enum(''Faulty'', ''a a'', module=__name__)

rendimientos

Traceback (most recent call last): File "/home/vaultah/so/shadows/main.py", line 23, in <module> enum.Enum(''Faulty'', ''a a'', module=__name__) File "/home/vaultah/cpython/Lib/enum.py", line 243, in __call__ return cls._create_(value, names, module=module, qualname=qualname, type=type, start=start) File "/home/vaultah/cpython/Lib/enum.py", line 342, in _create_ classdict[member_name] = member_value File "/home/vaultah/cpython/Lib/enum.py", line 72, in __setitem__ raise TypeError(''Attempted to reuse key: %r'' % key) TypeError: Attempted to reuse key: ''a''

Podemos restringir las entradas de seguimiento de pila a nuestro código (en /home/vaultah/so/shadows/main.py ).

import sys, enum sys.excepthook = spotlight(''/home/vaultah/so/shadows'') enum.Enum(''Faulty'', ''a a'', module=__name__)

y

import sys, enum sys.excepthook = shadow(''/home/vaultah/cpython/Lib'') enum.Enum(''Faulty'', ''a a'', module=__name__)

dar el mismo resultado:

File "/home/vaultah/so/shadows/main.py", line 22, in <module> enum.Enum(''Faulty'', ''a a'', module=__name__) TypeError: Attempted to reuse key: ''a''

Hay una manera de excluir todos los directorios del sitio (donde se instalan los paquetes de terceros - vea site.getsitepackages )

import sys, site, jinja2 sys.excepthook = shadow(*site.getsitepackages()) jinja2.Template(''{%}'') # jinja2.exceptions.TemplateSyntaxError: unexpected ''}'' # Generates ~30 lines, but will only display 4

Nota: No olvide restaurar sys.excepthook desde sys .__ excepthook__ . Desafortunadamente, no podrá "restaurar parches" mediante un administrador de contexto.

Escribo mucho código Python que utiliza bibliotecas externas. Con frecuencia escribiré un error, y cuando ejecuto el código obtengo una larga y larga respuesta en la consola de Python. El 99.999999% del tiempo se debe a un error de codificación en mi código, no a un error en el paquete. Pero el rastro regresa hasta la línea de error en el código del paquete, y o bien se necesita mucho desplazamiento en el rastreo para encontrar el código que escribí, o el rastreo está tan profundo en el paquete que mi propio código no lo hace. Ni siquiera aparecen en la traza.

¿Hay alguna forma de "poner en una caja negra" el código del paquete, o de alguna manera solo mostrar las líneas de rastreo de mi código? Me gustaría poder especificar en el sistema los directorios o archivos desde los que deseo ver el rastreo.


traceback.extract_tb (tb) devolvería una tupla de marcos de error en el formato (archivo, línea_no, tipo, error_statement), puede jugar con eso para formatear la traza. Consulte también https://pymotw.com/2/sys/exceptions.html

import sys import traceback def handle_exception(ex_type, ex_info, tb): print ex_type, ex_info, traceback.extract_tb(tb) sys.excepthook = handle_exception


Para imprimir su propio stacktrace, deberá manejar usted mismo todas las excepciones no manejadas; Así es como el sys.excepthook vuelve práctico.

La firma para esta función es sys.excepthook(type, value, traceback) y su trabajo es:

Esta función imprime un sys.stderr dado y una excepción a sys.stderr .

Por lo tanto, siempre que pueda jugar con el rastreo y solo extraer la parte que le interesa debería estar bien. Los marcos de prueba lo hacen con mucha frecuencia; tienen funciones de assert personalizadas que generalmente no aparecen en el rastreo, en otras palabras, omiten los marcos que pertenecen al marco de prueba. Además, en esos casos, las pruebas suelen iniciarse también en el marco de la prueba.

Terminas con un rastreo que se ve así:

[ custom assert code ] + ... [ code under test ] ... + [ test runner code ]

Cómo identificar su código.

Puedes agregar un global a tu código:

__mycode = True

Luego para identificar los marcos:

def is_mycode(tb): globals = tb.tb_frame.f_globals return globals.has_key(''__mycode'')

Cómo extraer tus marcos.

  1. omita los marcos que no le interesan (por ejemplo, código de confirmación personalizado)
  2. identificar cuántos marcos forman parte de su código -> length
  3. extraer marcos de length

    def mycode_traceback_levels(tb): length = 0 while tb and is_mycode(tb): tb = tb.tb_next length += 1 return length

Controlador de ejemplo.

def handle_exception(type, value, tb): # 1. skip custom assert code, e.g. # while tb and is_custom_assert_code(tb): # tb = tb.tb_next # 2. only display your code length = mycode_traceback_levels(tb) print ''''.join(traceback.format_exception(type, value, tb, length))

instalar el controlador:

sys.excepthook = handle_exception

¿Qué sigue?

Puede ajustar la length para agregar uno o más niveles si aún desea información sobre dónde se encuentra la falla fuera de su propio código.

vea también https://gist.github.com/dnozay/b599a96dc2d8c69b84c6