Python tomllib: прочитать TOML без зависимостей

Категория: Python · Язык: Python · Обновлено:

tomllib — стандартный TOML-парсер Python 3.11+. Он читает pyproject.toml и другие конфиги без сторонних пакетов, но умеет только разбирать TOML: для записи нужна отдельная библиотека вроде tomli-w. На Python 3.10 тот же API даёт пакет tomli.

Разобрать TOML из строки

loads() принимает строку, а load() — бинарный файловый объект. Результат — обычный словарь:

Python
import tomllib

raw = b"""
[project]
name = "demo"
requires-python = ">=3.11"
dependencies = ["httpx>=0.27", "pydantic>=2"]
"""

config = tomllib.loads(raw.decode("utf-8"))
print(config["project"]["name"])            # demo
print(config["project"]["dependencies"])    # ['httpx>=0.27', 'pydantic>=2']
print(config["project"]["requires-python"]) # >=3.11

Ключи TOML становятся ключами словаря, массивы — списками, даты — объектами datetime. Вложенные таблицы [tool.demo] дают вложенные словари, поэтому к ним обращаются последовательно: config["tool"]["demo"].

Прочитать файл конфигурации

Файл открывайте в режиме "rb": tomllib.load() не принимает текстовый поток. Пример создаёт временный файл, читает его и удаляет:

Python
import tomllib
from pathlib import Path

config_path = Path("demo.toml")
config_path.write_text('[tool.demo]\nenabled = true\n', encoding="utf-8")

with config_path.open("rb") as fh:
    config = tomllib.load(fh)

print(config["tool"]["demo"]["enabled"])  # True
config_path.unlink()

Для реального pyproject.toml замените имя файла и проверьте его существование. Отсутствующий файл даёт FileNotFoundError, а синтаксическая ошибка — tomllib.TOMLDecodeError, который наследуется от ValueError. Ловите оба случая отдельно, чтобы не скрывать проблему с путём за ошибкой формата.

tomllib не выполняет код из файла, но значения всё равно стоит валидировать: например, не подставлять путь из конфига в команду оболочки без проверки. Для записи TOML используйте tomli-w; стандартная библиотека намеренно оставляет только чтение.

Документация: tomllib, TOML v1.0.0.