sys.exit()から発生したSystemExit例外がキャッチされないようにする方法はありますか?
-
05-07-2019 - |
質問
ドキュメントでは、sys.exit()を呼び出すと、外部レベルでキャッチできるSystemExit例外が発生すると述べています。テストケース内から明確かつ間違いなく終了したい状況がありますが、unittestモジュールはSystemExitをキャッチし、終了を防ぎます。これは通常素晴らしいことですが、私が処理しようとしている特定の状況は、テストフレームワークが非テストデータベースを指すように構成されていることを検出した状況です。この場合、終了して、それ以上のテストが実行されないようにします。もちろん、unittestはSystemExitをトラップし、その方法で喜んで続行するため、私を妨害しています。
これまで考えてきた唯一のオプションは、ctypesまたはexit(3)を直接呼び出すのに似たものを使用することですが、これは本当にシンプルなものに対する非常に厄介なハックのようです。
解決
os._exit()
<を呼び出すことができます。 / a>例外をスローせずに直接終了するには:
import os
os._exit(1)
これは、 atexit
モジュールなどのすべてのPythonシャットダウンロジックをバイパスし、この状況で回避しようとしている例外処理ロジックを実行しません。引数は、プロセスによって返される終了コードです。
他のヒント
Jerubが言ったように、 os._exit(1)
があなたの答えです。しかし、 finally:
ブロック、ファイルのクローズなどを含む all クリーンアップ手順をバイパスすることを考慮し、すべてのコストで本当に回避する必要があります。 ish&quot;使い方は?
問題が 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!