Gibt es eine Möglichkeit, eine Systemexit Ausnahme von sys.exit angehoben zu verhindern () von erwischt zu werden?

StackOverflow https://stackoverflow.com/questions/173278

Frage

Die docs sagen, dass sys.exit () aufgerufen wird eine Systemexit Ausnahme auslöst, die in der äußeren Ebenen aufgefangen werden kann. Ich habe eine Situation, in der ich will endgültig und ohne Frage Ausfahrt aus dem Innern eines Testfall, aber das Unittest-Modul fängt Systemexit und verhindert, dass die Ausfahrt. Dies ist in der Regel groß, aber die spezifische Situation, die ich behandeln werde versuchen, ist eine, wo unser Test-Framework erkannt haben, dass es so konfiguriert ist, eine nicht-Test-Datenbank zu zeigen. In diesem Fall möchte ich an der Ausführung keine weiteren Tests beenden und zu verhindern. Natürlich, da der Unittest Systemexit einfängt und glücklich auf seine Art und Weise weiter, es mich zu vereiteln.

Die einzige Option, die ich von so weit gedacht ist ctypes oder etwas ähnliches nennen Ausfahrt (3) direkt verwenden, aber dies scheint wie ein ziemlich fugly Hack für etwas, das wirklich einfach sein sollte.

War es hilfreich?

Lösung

können Sie rufen os._exit() direkt zu verlassen, ohne eine Ausnahme zu werfen :

import os
os._exit(1)

Dies umgeht alle der Python Shutdown Logik, wie das atexit Modul und wird nicht durch die Ausnahmebehandlung Logik ausführen, die Sie in dieser Situation zu vermeiden versuchen. Das Argument ist der Exit-Code, der durch den Prozess zurückgeführt wird.

Andere Tipps

Wie Jerub sagte os._exit(1) ist Ihre Antwort. Aber, wenn man bedenkt es umgeht alle Bereinigungsverfahren, einschließlich finally: Blöcke, Schließen von Dateien, usw., und sollte wirklich unter allen Umständen vermieden werden, darf ich eine „safer-ish“ Art und Weise, es zu benutzen?

Wenn Sie Problem ist SystemExit an äußeren Ebenen gefangen (dh Unittest), dann sein die äußere Ebene selbst! Wickeln Sie Ihre Haupt-Code in einem Try / außer Block , fangen Systemexit und rufen os._exit es, und nur da! auf diese Weise können sys.exit normalerweise irgendwo im Code aufrufen können, lassen Sie es sprudeln auf der obersten Ebene, anmutig alle Dateien zu schließen und alle Bereinigungen ausgeführt wird, und und Aufruf os._exit.

Sie können auch die Ausgänge sind die „Notfall“ diejenigen wählen. Der folgende Code ist ein Beispiel für einen solchen Ansatz:

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!
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top