Python warnings.filterwarnings()とは?警告の表示を制御する方法
warnings.filterwarnings()は、どの警告をどう扱うかを決める関数です。
「この警告だけ消す」「警告を例外にする」といった制御ができます。
5つのアクション
import warnings
def risky():
warnings.warn("注意")
warnings.simplefilter("always")
risky()
risky()
実行結果:
w4.py:4: UserWarning: 注意
warnings.warn("注意")
w4.py:4: UserWarning: 注意
warnings.warn("注意")
2回とも表示されました。既定では1回しか出ません。
| アクション | 動き |
|---|---|
"default" |
同じ場所から1回だけ(既定) |
"always" |
毎回表示 |
"ignore" |
表示しない |
"error" |
例外にする |
"once" |
プログラム全体で1回だけ |
警告を例外にする
warnings.simplefilter("error")
try:
risky()
except UserWarning as e:
print("UserWarning が例外に:", e)
実行結果:
UserWarning が例外に: 注意
警告がraiseされるようになります。
これはCIで非常に有効です。非推奨のAPIを使ったらテストが失敗するようにできます。
$ python3 -W error::DeprecationWarning -m pytest
警告を放置すると、ライブラリの更新である日突然動かなくなります。例外にしておけば事前に気づけます。
simplefilterとfilterwarningsの違い
warnings.simplefilter("ignore") # すべて
warnings.filterwarnings("ignore", message="無視したい") # 条件付き
simplefilter() |
filterwarnings() |
|
|---|---|---|
| 対象 | すべての警告 | 条件で絞れる |
| 指定できるもの | アクションとカテゴリ | メッセージ・モジュールも |
simplefilter("ignore")はすべての警告を消します。強力すぎるので、本番コードでは避けてください。
メッセージで絞る
import warnings
warnings.resetwarnings()
warnings.filterwarnings("ignore", message="無視したい")
def a():
warnings.warn("無視したいメッセージ")
def b():
warnings.warn("表示したいメッセージ")
a()
b()
実行結果:
w4.py:10: UserWarning: 表示したいメッセージ
warnings.warn("表示したいメッセージ")
a()の警告だけ消えました。
messageは正規表現で、先頭からの一致です。"無視したい"が"無視したいメッセージ"の先頭に一致しています。
部分一致にしたいなら".*"を先頭に付けてください。
warnings.filterwarnings("ignore", message=".*したいメッセージ")
カテゴリで絞る
warnings.resetwarnings()
warnings.filterwarnings("error", category=DeprecationWarning)
def c():
warnings.warn("非推奨", DeprecationWarning)
try:
c()
except DeprecationWarning as e:
print("DeprecationWarning が例外に:", e)
実行結果:
DeprecationWarning が例外に: 非推奨
種類ごとに扱いを変えられます。
実務でよく使う組み合わせです。
warnings.filterwarnings("error", category=DeprecationWarning) # 開発中は厳しく
warnings.filterwarnings("ignore", category=ResourceWarning) # これは無視
モジュールで絞る
warnings.filterwarnings("ignore", module="oldlib")
特定のライブラリの警告だけ消せます。
自分では直せない外部ライブラリの警告が大量に出るとき、そこだけ黙らせて自分のコードの警告は見る——という使い方ができます。
moduleも正規表現です。
順番が重要
フィルタは後から追加したものが優先されます。
import warnings
warnings.resetwarnings()
warnings.filterwarnings("ignore") # 全部消す
warnings.filterwarnings("always", category=UserWarning) # ただしUserWarningは出す
warnings.warn("これは出る")
warnings.warn("これは出ない", DeprecationWarning)
実行結果:
w6.py:7: UserWarning: これは出る
warnings.warn("これは出る")
リストの先頭から順に照合し、最初に一致したものが適用されます。あとから追加したものが先頭に入るため、後勝ちになります。
「フィルタを書いたのに効かない」ときは、あとで別のフィルタに上書きされていないか確認してください。
コマンドラインからの指定
$ python3 -W ignore app.py # すべて無視
$ python3 -W error app.py # すべて例外に
$ python3 -W default app.py # 既定の抑制を解除
$ python3 -W error::DeprecationWarning app.py # 種類を指定
コードを変えずに切り替えられます。
環境変数でも指定できます。
$ PYTHONWARNINGS=error::DeprecationWarning python3 app.py
CIの設定ファイルに書いておけば、本番コードを汚さずに厳しくできます。
filterwarnings()のまとめ
- アクションは
default・always・ignore・error・once errorでCIを厳しくできるsimplefilter()は全体、filterwarnings()は条件付きmessage・moduleは先頭一致の正規表現- あとから追加したフィルタが優先される
- コマンドラインの
-Wでも指定できる




