Python で TOML ファイルを読み書きする(tomllib, tomli)
TOML(Tom’s Obvious, Minimal Language)は、設定ファイル向けに設計されたフォーマットだ。Python 3.11 から標準ライブラリに tomllib が追加され、TOML の読み込みを外部ライブラリなしで行えるようになった。書き込みには tomli_w などのサードパーティライブラリを使う。
TOML の基本構文
TOML はセクション(テーブル)をブラケットで区切り、キーと値を = で結ぶシンプルな形式を取る。
[database]
host = "localhost"
port = 5432
name = "myapp"
[logging]
level = "DEBUG"
file = "app.log"YAML や JSON と比べた特徴として、型が明示的である点が挙げられる。文字列は必ずクォートで囲む必要があり、YAML のような暗黙の型変換が起こらない。
tomllib で読み込む(Python 3.11 以降)
Python 3.11 以降では、標準ライブラリの tomllib をそのまま使える。
import tomllib
with open("config.toml", "rb") as f:
data = tomllib.load(f)
print(data)
tomllib.load() はバイナリモード("rb")でファイルを開く必要がある点に注意しよう。テキストモードで開くと TypeError が発生する。
文字列から読み込む場合は tomllib.loads() を使う。
import tomllib
toml_str = """
[server]
host = "0.0.0.0"
port = 8080
[features]
auth = true
cache_ttl = 3600
"""
data = tomllib.loads(toml_str)
print(data["server"]["host"]) # 0.0.0.0
print(data["features"]["cache_ttl"]) # 3600
Python 3.10 以前では tomli を使う
Python 3.10 以前の環境では、tomllib は使えない。代わりにサードパーティの tomli をインストールする。API は tomllib と完全に互換性があるため、移行も容易だ。
pip install tomliバージョンに応じて import 先を切り替えるイディオムが広く使われている。
import sys
if sys.version_info >= (3, 11):
import tomllib
else:
import tomli as tomllib
with open("config.toml", "rb") as f:
data = tomllib.load(f)
このパターンは pyproject.toml を読み込むツール類でもよく見かける書き方だ。
TOML ファイルに書き込む
tomllib(および tomli)は読み込み専用であり、書き込み機能を持たない。TOML を書き出すには tomli_w を使う。
pip install tomli-wimport tomli_w
config = {
"database": {
"host": "localhost",
"port": 5432,
"name": "myapp",
},
"features": {
"auth": True,
"cache_ttl": 3600,
},
}
with open("output.toml", "wb") as f:
tomli_w.dump(config, f)
# 文字列として取得する場合
toml_str = tomli_w.dumps(config)
print(toml_str)
書き込みもバイナリモード("wb")で行う必要がある。出力は次のようになる。
[database]
host = "localhost"
port = 5432
name = "myapp"
[features]
auth = true
cache_ttl = 3600TOML の型システム
TOML は型が厳密に定義されており、YAML のような暗黙の変換が起こらない。これは設定ファイルとしての信頼性を高めている。
| TOML 型 | Python 型 |
|---|---|
| 文字列 | str |
| 整数 | int |
| 浮動小数点 | float |
| 真偽値 | bool |
| 日時 | datetime |
| 配列 | list |
| テーブル | dict |
日時の扱いは TOML の特徴的な機能の一つだ。
import tomllib
toml_str = """
[event]
name = "launch"
date = 2025-01-15T10:00:00+09:00
"""
data = tomllib.loads(toml_str)
print(data["event"]["date"])
# 2025-01-15 10:00:00+09:00
print(type(data["event"]["date"]))
# <class 'datetime.datetime'>
クォートなしで日時を書くだけで datetime オブジェクトに変換されるため、日時の設定が多いアプリケーションでは便利に使える。
pyproject.toml との関係
TOML が Python で特に重要なのは、pyproject.toml がパッケージ管理の標準設定ファイルとして採用されているからだ。PEP 518 でビルドシステムの設定に TOML が選ばれ、PEP 621 でプロジェクトメタデータの記述にも使われるようになった。
[project]
name = "mypackage"
version = "1.0.0"
description = "A sample package"
requires-python = ">=3.9"
dependencies = [
"requests>=2.28",
"pyyaml>=6.0",
]
[build-system]
requires = ["setuptools>=68.0"]
build-backend = "setuptools.build_meta"自作パッケージの設定を読み込むような場面では、tomllib を直接使って pyproject.toml をパースすることもある。
import tomllib
with open("pyproject.toml", "rb") as f:
pyproject = tomllib.load(f)
version = pyproject["project"]["version"]
deps = pyproject["project"]["dependencies"]
print(f"v{version}, dependencies: {deps}")
YAML との使い分け
設定ファイルのフォーマット選択は、プロジェクトの性質によって判断が変わる。
型が明確で曖昧さが少なく、フラットな構成の設定ファイルに向いている。pyproject.toml など Python エコシステムとの親和性が高い
深いネスト構造やアンカー・エイリアスを使った定義の再利用に対応しており、Kubernetes の設定など複雑な構成管理に適している
シンプルなアプリケーション設定なら TOML、複雑な構成管理なら YAML という使い分けが一般的になりつつある。Python の標準ライブラリに読み込み機能が組み込まれている点も、TOML を選ぶ大きな理由の一つだろう。