pass - python try except example
¿Hay alguna manera de evitar que se capture una excepción de SystemExit generada a partir de sys.exit()? (2)
Como dijo Jerub, os._exit(1)
es tu respuesta. Pero, considerando que elude todos los procedimientos de limpieza, incluyendo finally:
bloques, archivos de cierre, etc., y realmente debe evitarse a toda costa, ¿puedo presentar una forma "más segura" de usarlo?
Si tu problema es que SystemExit
sea atrapado en los niveles externos (es decir, unittest), ¡entonces sé el nivel externo tú mismo! Envuelve tu código principal en un bloque try / except, atrapa SystemExit, y llama a os._exit allí, ¡ y solo allí! De esta manera, puede llamar a sys.exit
normalmente en cualquier parte del código, dejarlo pasar al nivel superior, cerrar con gracia todos los archivos y ejecutar todas las limpiezas, y luego llamar a os._exit.
Incluso puede elegir qué salidas son las de "emergencia". El siguiente código es un ejemplo de dicho enfoque:
import sys, os
EMERGENCY = 255 # can be any number actually
try:
# wrap your whole code here ...
# ... some code
if x: sys.exit()
# ... some more code
if y: sys.exit(EMERGENCY) # use only for emergency exits
# ...
except SystemExit as e:
if e.code != EMERGENCY:
raise # normal exit, let unittest catch it
else:
os._exit(EMERGENCY) # try to stop *that*, sucker!
Los documentos dicen que al llamar a sys.exit () se genera una excepción SystemExit que se puede atrapar en niveles externos. Tengo una situación en la que quiero salir definitiva e incuestionablemente desde el interior de un caso de prueba; sin embargo, el módulo unittest detecta SystemExit e impide la salida. Esto normalmente es genial, pero la situación específica que trato de manejar es una en la que nuestro marco de prueba ha detectado que está configurado para apuntar a una base de datos que no es de prueba. En este caso, quiero salir e impedir que se ejecuten más pruebas. Por supuesto, dado que Unittest atrapa el SystemExit y continúa felizmente en su camino, me está frustrando.
La única opción en la que he pensado hasta ahora es usar ctypes o algo similar para llamar a exit (3) directamente, pero esto parece ser un truco bastante fugitivo para algo que debería ser realmente simple.
Puede llamar a os._exit()
para salir directamente, sin lanzar una excepción:
import os
os._exit(1)
Esto omite toda la lógica de apagado de python, como el módulo atexit
, y no se ejecutará a través de la lógica de manejo de excepciones que está tratando de evitar en esta situación. El argumento es el código de salida que será devuelto por el proceso.