この記事について
この記事は、生成AIを活用した自動生成フローで作成しています。Python公式のtomllibの仕様を確認し、架空のTOML設定ファイルを読み取り専用で点検するサンプルを作成しました。隔離LinuxコンテナのPython 3.13.5で19件の単体テスト、構文検査、CLI正常系とファイル不存在の異常系を実行しています。検証ステータス:🧪 Linux / Python 3.13.5でローカル実行・19テスト成功。Windows/macOS未検証。Codex CLIとGitHub Actionsは未実行。
対応環境・できること・制限事項
| 項目 | 内容 |
|---|---|
| Python | 3.11以降。追加のpipパッケージ不要 |
| 実測環境 | 隔離Linuxコンテナ / Python 3.13.5、2026年10月29日 |
| 入力 | 架空のdemo.toml。64KiB以下の通常ファイル |
| 動作 | 読み取りのみ。ネットワーク通信やファイル修正なし |
| 未確認 | Windows/macOS、実業務アプリの設定適合性 |
まず試す
Daily Codeの完成版とREADMEを使い、架空の設定だけで試します。公開リンクの実ブラウザ操作は今回未実施です。
demo.tomlとcheck_toml.pyを同じフォルダへ置く。Python 3.11以降で
python3 check_toml.py demo.tomlを実行し、STATUS=VALIDと終了コード0を確認する(Windowsでは後述のpy -3)。元ファイルをコピーし、
retries = 2をretries = "2"に変更して再実行する。期待結果はINVALID_RETRIESと終了コード2。
注意: ここに示した操作は既存サンプルの試験設計です。2026年10月29日の隔離Linux試験19件PASSという過去の実測と、今回の新しい実機試験未実施を区別します。
「設定ファイルは読めたのに、アプリを起動したら失敗した」。こんなトラブルでは、ファイルの文法が正しいこととアプリが期待する設定値であることを分けて調べるのが近道です。今回はPython標準ライブラリtomllibを使い、設定を変更せずに構文・必須項目・型を順番に検査する小さなCLIを作ります。
例にするのは、架空のアプリが読む次のdemo.tomlです。実際のAPIキー、社内URL、パスワードは使用しません。
[app] name = "demo" enabled = true retries = 2
構文が正しくても設定値の型は別に確認する
tomllibはTOML 1.0.0の内容をPythonの辞書などへ変換します。enabled = trueならPythonのbool、retries = 2ならintです。ところがretries = "2"と書いてもTOMLの構文としては成立します。引用符を付けたことで値の型が文字列へ変わるため、整数を要求するアプリには適しません。
そこで検査を二段階に分けます。第一段階でTOMLとして読めるか、第二段階で[app]のnameが空でない文字列、enabledが真偽値、retriesが0〜10の整数かを確認します。0〜10はこの教材の独自ルールで、TOML規格上の制限ではありません。
Python公式の「tomllib — TOMLファイルの解析」は、tomllibがPython 3.11で追加されたこと、読み取り用で書き出しには対応しないこと、文法違反でTOMLDecodeErrorを出すことを説明しています。今回はこの性質を利用し、設定の自動修正やアプリの起動は行いません。
自分のPCで試す
完全版はDaily Code Samples:TOML設定の事前検査にあります。README.md、check_toml.py、test_check_toml.py、demo.tomlの4ファイルを同じフォルダへ置きます。Windowsならpy -3、Linux/macOSならpython3など、Python 3.11以降を起動できるコマンドに読み替えてください。
Windows PowerShellで同じ教材を試す(未実測)
WindowsではPowerShellを開き、サンプル4ファイルを置いたフォルダへ移動します。最初にpy -3 --versionでPythonが3.11以降か確認してください。py -3が3.10以前を選ぶ環境ではtomllibを使えません。複数のPythonがある場合はpy -0pで候補を調べ、3.11以降の環境を明示してから進めます。
py -3 --version py -3 .\check_toml.py .\demo.toml $LASTEXITCODE
期待する表示はLinuxの正常例と同じSTATUS=VALID CHECKS=APP_NAME_ENABLED_RETRIESです。ただしWindows上での実行確認は行っていません。PowerShellの$LASTEXITCODEで終了コードを確認できます。コマンドが見つからない場合はPython Launcherの有無とPATHを調べ、管理者権限の取得や未知のインストーラー実行を急がないでください。
比較用ファイルは元を上書きせずに作ります。
Copy-Item -LiteralPath .\demo.toml -Destination .\demo-copy.toml notepad .\demo-copy.toml
メモ帳でretries = 2だけをretries = "2"に変更し、保存後に次を実行します。
py -3 .\check_toml.py .\demo-copy.toml $LASTEXITCODE
期待結果はSTATUS=INVALID ISSUE=INVALID_RETRIESと終了コード2です。正常系は終了コード0、ファイルを読めない場合は3です。ここで示したWindows操作は未実測であり、実際の値は読者の環境で確認してください。ファイル編集とメモ帳起動は読者自身が行うローカル操作であり、この原稿作成では実行していません。
まず動かす:正常な設定を読む
ターミナルでサンプルのフォルダへ移動し、次を実行します。
python3 check_toml.py demo.toml
Linux / Python 3.13.5で実際に確認した出力は次の1行です。終了コードは0でした。
STATUS=VALID CHECKS=APP_NAME_ENABLED_RETRIES
このメッセージは、教材の3項目について構文と型の検査を通ったことを示します。設定値そのものは画面に出しません。また、STATUS=VALIDはアプリの起動成功や設定内容の安全性まで保証する表示ではありません。未知のキーは今回の教材では許容し、その意味は判定しません。
仕組み:読んだ後で必須項目を調べる
完成版の中心を短く抜き出すと、次の考え方です。これは説明用の抜粋で、ファイルサイズ・入出力例外・終了コードの処理はGitHubの完成版にあります。
import tomllib
with open("demo.toml", "rb") as f:
data = tomllib.load(f)
app = data.get("app")
if not isinstance(app, dict):
raise ValueError("[app]がありません")
if type(app.get("enabled")) is not bool:
raise ValueError("enabledの型が違います")
if type(app.get("retries")) is not int:
raise ValueError("retriesの型が違います")
tomllib.load()はバイナリモードで開いたファイルを受け取ります。完成版は最大64KiBを読み取ってからUTF-8でデコードし、tomllib.loads()へ渡す構成にしています。公式資料は、信頼できないTOMLを無制限に解析するとCPUやメモリを多く消費し得ると注意しています。サイズ制限はその対策の一つですが、すべての悪意ある入力に対する完全な防御ではありません。
type(value) is intを使うのは、Pythonでboolがintのサブクラスだからです。isinstance(True, int)は真になります。retries = trueを整数として誤って受け入れないよう、ここでは厳密に型を比べます。
1か所変える:数値を文字列にする
付属のdemo.tomlはそのまま残し、別名のコピーを作ってretries = 2をretries = "2"に変更します。両方ともTOMLとしては正しいものの、後者は整数ではありません。
[app] name = "demo" enabled = true retries = "2"
コピーしたファイルをdemo-copy.tomlとして保存した場合の実行例です。
python3 check_toml.py demo-copy.toml
期待する出力は次のとおりです。この手順そのもののCLI実行は未実施ですが、単体テストで文字列型の不合格を確認しています。
STATUS=INVALID ISSUE=INVALID_RETRIES
終了コードは2になる設計です。実際の運用では、元の文字列を勝手に整数へ変換すると入力ミスを隠すことがあります。ここでは「間違った型」を検出した段階で止め、設定の持ち主が修正する方針です。
失敗を三つの層で切り分ける
| 表示 | 意味と確認箇所 |
|---|---|
INVALID_TOML | 重複キーや文法エラー。設定内容は画面に出さない |
INVALID_UTF8 | UTF-8として解釈できないバイト列 |
MISSING_APP_TABLE | [app]テーブルがない |
MISSING_NAME / INVALID_NAME | nameがない、空、文字列以外 |
INVALID_ENABLED | enabledがtrue/falseではなく文字列など |
INVALID_RETRIES | retriesが整数以外、または0〜10の範囲外 |
FILE_TOO_LARGE | 教材独自の64KiB上限超過 |
SYMLINK_NOT_ALLOWED | シンボリックリンクは対象外 |
NOT_REGULAR_FILE / READ_FAILED | ファイルがない、通常ファイルでない、権限など |
このように、TOML構文の不正、アプリ向けの型・必須項目の不正、ファイルを読めない問題を分けると、調査の順番が明確になります。終了コードは有効0、内容不適合2、入出力失敗3です。なお、コマンド引数の指定間違いもargparseの標準処理では2になります。
19件のテストで確認したこと
隔離Linuxコンテナ / Python 3.13.5で次を実行しました。
python3 -m unittest discover -p 'test_*.py' -v python3 -m py_compile check_toml.py test_check_toml.py python3 check_toml.py demo.toml
19テストすべてPASS、構文検査PASS、正常CLIは終了コード0でした。存在しないファイルを渡した場合はSTATUS=IO_ERROR ISSUE=NOT_REGULAR_FILEで終了コード3でした。単体テストでは、キーの重複、UTF-8不正、空文字、真偽値と整数の混同、サイズ上限、シンボリックリンク、エラー時に架空の値を表示しないことなどを確認しています。Codex CLIは今回の実行環境では見つからず、Codexによる実装・検証は行っていません。GitHub Actionsも請求制限を踏まえて実行していません。
仕事で使うときの注意点
実際のpyproject.tomlやアプリ設定へこのサンプルをそのまま適用すると、[app]という教材用テーブルがないため失敗します。汎用のTOMLバリデータではなく、自分のアプリが要求する設定を定義する例として使ってください。対象が[database]なら、必須キーや型をアプリの仕様に合わせて別途設計する必要があります。
また、設定には秘密情報が含まれることがあります。サンプルは値を出力しませんが、実ファイルを公開リポジトリへ登録したり、設定全体をAIへ貼り付けたりしないでください。ファイルパスがコマンド履歴に残る可能性もあります。シンボリックリンク拒否は簡易的な事前確認で、読み取り直前にファイルが置き換えられる競合まで完全に防ぐものではありません。
まとめ:構文と型の二段階で確認する
TOMLの構文が正しいことは、設定がアプリの期待どおりであることを意味しません。tomllibで安全に読み取れる範囲を決め、必要な項目と型を明示し、失敗時には値を表示せず終了コードで伝える。この小さな手順を、実際の設定投入前チェックの考え方として使えます。
