Impresión de excepciones de hilos daemónicos en Python

Python no imprime los mensajes de rastreo de las excepciones generadas en los hilos del demonio

Por ejemplo, este código crea un hilo demoníaco y genera una excepción en el nuevo hilo:

def error_raiser(): raise Exception import threading thread = threading.Thread(target=error_raiser) thread.daemon = True thread.start() 

pero no imprime un rastreo (No da salida).

Sin embargo, si el subproceso no se establece como un subproceso de daemon, Python imprimirá el rastreo. Aquí está el mismo código con una línea comentada:

 def error_raiser(): raise Exception import threading thread = threading.Thread(target=error_raiser) # thread.daemon = True thread.start() 

y la salida:

 Exception in Thread-1: Traceback (most recent call last): File "C:\Python26\lib\threading.py", line 525, in __bootstrap_inner self.run() File "C:\Python26\lib\threading.py", line 477, in run self.__target(*self.__args, **self.__kwargs) File "test.py", line 2, in error_raiser raise Exception Exception 

Ejecutando este código en Python 2.6.2 y Python 3.0.1 y da los mismos resultados. Curiosamente, sin embargo, si ejecuto el código importándolo en el shell de IPython, se muestra la excepción si el hilo es demoníaco o no.

De acuerdo con la documentación, el único significado de la bandera ‘demonio’ ​​es que “todo el progtwig Python se cierra cuando solo quedan los hilos del demonio”. Esto me haría creer que no imprimir una traza después de una excepción es un error en Python, a menos que me haya perdido algo en la documentación.

¿Esto es un error o me perdí algo en la documentación y este comportamiento es intencional? Si es intencional, ¿cómo puedo forzar a Python para que imprima el rastreo en los hilos del demonio sin usar IPython?

Según Wikipedia, por definición, un demonio debería separarse del controlador tty, así que creo que es correcto que no se muestre una excepción (y, después de todo, un demonio debería seguir funcionando incluso si cierra el shell que lo lanzó).
Ver aqui

En cuanto a cómo imprimir el rastreo, creo que un simple bash / except_then_log_to_file haría el truco 🙂

¿Esto es un error o me perdí algo en la documentación y este comportamiento es intencional?

Básicamente, usted mismo ha declarado la razón, sin darse cuenta:

De acuerdo con la documentación, el único significado de la bandera ‘demonio’ ​​es que “todo el progtwig Python se cierra cuando solo quedan los hilos del demonio”.

Si tienes un hilo no demoníaco, Python lo espera después de thread.start() . Esta espera incluye todo lo que hace, incluida la generación y el manejo de excepciones.

Si tienes un hilo demoníaco, Python no lo espera después de thread.start() . En cambio, en ausencia de instrucciones adicionales, Python sale inmediatamente. Eso significa que su hilo nunca tiene la oportunidad de subir o manejar la excepción.


Si es intencional, ¿cómo puedo forzar a Python para que imprima el rastreo en los hilos del demonio sin usar IPython?

Para un subproceso de daemon , es intrascendente lo que se supone que debe hacer tu subproceso. Si se le hubiera ordenado imprimir algo, habría sucedido lo mismo.

Eso también significa que no tiene forma de esperar condicionalmente una acción del demonio. Ya sea que establezca thread.daemon = False y obtenga todas las trazas, así como todas las impresiones, E / S y otras acciones. O establece thread.daemon = True y no obtiene ningún rastreo, ni impresiones, E / S u otras acciones, después de que todos los demás subprocesos estén muertos.


Curiosamente, sin embargo, si ejecuto el código importándolo en el shell de IPython, se muestra la excepción si el hilo es demoníaco o no.

Lo que pasa con los proyectiles es que nunca salen a menos que los mates. Dado que el intérprete de la shell no sale mientras espera su entrada, cualquier subproceso del daemon comenzó a permanecer vivo.