web-dev-qa-db-ja.com

Pythonでは、警告が例外であるかのようにどのようにキャッチされますか?

pythonコードで使用しているサードパーティライブラリ(Cで記述)が警告を発行しています。tryexceptを使用できるようにしたいです。これらの警告を適切に処理する構文。これを行う方法はありますか?

79
Boris Gorelik

pythonハンドブックから引用するには( 27.6.4。Testing Warnings ):

import warnings

def fxn():
    warnings.warn("deprecated", DeprecationWarning)

with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")
    # Trigger a warning.
    fxn()
    # Verify some things
    assert len(w) == 1
    assert issubclass(w[-1].category, DeprecationWarning)
    assert "deprecated" in str(w[-1].message)
37
Bobby Powers

警告をエラーとして処理するには、これを使用します:

import warnings
warnings.filterwarnings("error")

この後、エラーと同じ警告をキャッチできます。これは動作します:

try:
    some_heavy_calculations()
except RuntimeWarning:
    import ipdb; ipdb.set_trace()

追伸コメントのベストアンサーにスペルミス:filterwarnignsではなくfilterwarningsが含まれているため、この回答を追加しました。

92
niekas

スクリプトを単に警告で失敗させたい場合は、次を使用できます。

python -W error foobar.py
14
azmeuk

カスタム警告のみで作業する方法をより明確にするバリエーションがあります。

import warnings
with warnings.catch_warnings(record=True) as w:
    # Cause all warnings to always be triggered.
    warnings.simplefilter("always")

    # Call some code that triggers a custom warning.
    functionThatRaisesWarning()

    # ignore any non-custom warnings that may be in the list
    w = filter(lambda i: issubclass(i.category, UserWarning), w)

    if len(w):
        # do something with the first warning
        email_admins(w[0].message)
14
mcqwerty

場合によっては、ctypesを使用して警告をエラーに変換する必要があります。例えば:

str(b'test')  # no error
import warnings
warnings.simplefilter('error', BytesWarning)
str(b'test')  # still no error
import ctypes
ctypes.c_int.in_dll(ctypes.pythonapi, 'Py_BytesWarningFlag').value = 2
str(b'test')  # this raises an error
3
Collin Anderson