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でも指定できる

あわせて読みたい

プログラミング学習に興味がある方は、まずは無料体験会へ

無料体験会・お申し込みはこちら