sys.exit()から発生したSystemExit例外がキャッチされないようにする方法はありますか?

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

質問

ドキュメントでは、sys.exit()を呼び出すと、外部レベルでキャッチできるSystemExit例外が発生すると述べています。テストケース内から明確かつ間違いなく終了したい状況がありますが、unittestモジュールはSystemExitをキャッチし、終了を防ぎます。これは通常素晴らしいことですが、私が処理しようとしている特定の状況は、テストフレームワークが非テストデータベースを指すように構成されていることを検出した状況です。この場合、終了して、それ以上のテストが実行されないようにします。もちろん、unittestはSystemExitをトラップし、その方法で喜んで続行するため、私を妨害しています。

これまで考えてきた唯一のオプションは、ctypesまたはexit(3)を直接呼び出すのに似たものを使用することですが、これは本当にシンプルなものに対する非常に厄介なハックのようです。

他のヒント

Jerubが言ったように、 os._exit(1)があなたの答えです。しかし、 finally:ブロック、ファイルのクローズなどを含む all クリーンアップ手順をバイパスすることを考慮し、すべてのコストで本当に回避する必要があります。 ish"使い方は?

問題が SystemExit が外側のレベル(つまり、unittest)で捕捉されている場合、 自分で外側のレベルになります! メインをラップしますtry / exceptブロックでコードを作成し、SystemExitをキャッチして、そこにos._exitを呼び出し、および only を呼び出します!この方法で sys.exit 通常、コード内の任意の場所で、最上位にバブルし、すべてのファイルを正常に閉じてすべてのクリーンアップを実行し、os._exitを呼び出して then します。

「非常事態」となる出口を選択することもできます。もの。以下のコードはそのようなアプローチの例です:

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!
scroll top