tipos - sintaxis except python
¿Cómo puedo modificar un objeto de rastreo de Python al generar una excepción? (5)
¿Qué hay de no cambiar la traza? Las dos cosas que solicita se pueden hacer con mayor facilidad de una manera diferente.
- Si la excepción de la biblioteca está atrapada en el código del desarrollador y en su lugar se lanza una nueva excepción, el rastreo original se lanzará, por supuesto. Esta es la forma en que generalmente se manejan las excepciones ... si solo permite que se genere la excepción original pero la elimine para eliminar todos los marcos "superiores", la excepción real no tendrá sentido ya que la última línea en el rastreo no lo haría. Ser capaz de levantar la excepción.
- Para eliminar los últimos marcos, puede solicitar que sus tracebacks se acorten ... cosas como traceback.print_exception () toman un parámetro "límite" que puede usar para omitir las últimas entradas.
Dicho esto, debería ser bastante posible munge the tracebacks si realmente necesitas ... pero ¿dónde lo harías? Si en algún código de envoltorio en el nivel más alto, simplemente puede agarrar el rastreo, tomar un trozo para eliminar las partes que no desea, y luego usar las funciones en el módulo de "rastreo" para formatear / imprimir como desee.
Estoy trabajando en una biblioteca de Python utilizada por desarrolladores externos para escribir extensiones para nuestra aplicación principal.
Me gustaría saber si es posible modificar el rastreo al generar excepciones, por lo que el último marco de pila es la llamada a la función de biblioteca en el código del desarrollador, en lugar de la línea en la biblioteca que generó la excepción. También hay algunos marcos en la parte inferior de la pila que contienen referencias a las funciones utilizadas al cargar por primera vez el código que, idealmente, me gustaría eliminar también.
Gracias de antemano por cualquier consejo!
Echa un vistazo a lo que hace jinja2 aquí:
https://github.com/mitsuhiko/jinja2/blob/5b498453b5898257b2287f14ef6c363799f1405a/jinja2/debug.py
Es feo, pero parece hacer lo que necesitas hacer. No copiaré y pegaré el ejemplo aquí porque es largo.
Este código puede ser de su interés.
Toma un rastreo y elimina el primer archivo, que no debe mostrarse. Entonces simula el comportamiento de Python:
Traceback (most recent call last):
solo se mostrará si el rastreo contiene más de un archivo. Esto parece exactamente como si mi marco adicional no estuviera allí.
Aquí mi código, asumiendo que hay un text
cadena:
try:
exec(text)
except:
# we want to format the exception as if no frame was on top.
exp, val, tb = sys.exc_info()
listing = traceback.format_exception(exp, val, tb)
# remove the entry for the first frame
del listing[1]
files = [line for line in listing if line.startswith(" File")]
if len(files) == 1:
# only one file, remove the header.
del listing[0]
print("".join(listing), file=sys.stderr)
sys.exit(1)
Puede eliminar la parte superior del rastreo fácilmente subiendo con el elemento tb_next del rastreo:
except:
ei = sys.exc_info()
raise ei[0], ei[1], ei[2].tb_next
tb_next es un atributo read_only, por lo que no conozco una forma de eliminar cosas de la parte inferior. Es posible que pueda atornillar con el mecanismo de propiedades para permitir el acceso a la propiedad, pero no sé cómo hacerlo.
También podría estar interesado en PEP-3134 , que se implementa en python 3 y le permite abordar una excepción / rastreo en una excepción ascendente.
Esto no es exactamente lo mismo que modificar el rastreo, pero probablemente sea la forma ideal de transmitir la "versión corta" a los usuarios de la biblioteca mientras se tenga la "versión larga" disponible.