tomllib em Python: como ler arquivos TOML

Aprenda a ler arquivos TOML em Python com o módulo tomllib da biblioteca padrão: pyproject.toml, configurações, datas nativas, erros e tomli-w para escrever.

10 Oct 2026 7 min de leitura Equipe Python Dev BR

O módulo tomllib do Python lê arquivos TOML — incluindo o pyproject.toml que virou padrão de projeto — direto da biblioteca padrão, sem instalar nada, a partir do Python 3.11. Ele é a escolha certa para ler configurações, metadados de projetos e arquivos gerados por ferramentas como uv, Poetry e Ruff. A limitação importante: tomllib só faz leitura; para escrever TOML você precisa da biblioteca externa tomli-w.

A regra prática é: tomllib.load(arquivo_binario) para ler um arquivo e tomllib.loads(texto) para ler uma string. O resultado é sempre um dicionário Python comum, com tipos nativos preservados — números continuam int ou float, booleanos continuam bool e datas viram objetos datetime. Este guia mostra o uso completo com exemplos executáveis.

O que é TOML e por que ele importa

TOML (Tom’s Obvious, Minimal Language) é um formato de configuração pensado para ser legível por humanos e fácil de interpretar por máquinas. Ele virou o formato de configuração de facto do ecossistema Python: o pyproject.toml é o padrão oficial para metadados de projetos, e ferramentas como uv, Poetry, Ruff, pytest e mypy guardam suas configurações em seções [tool.*] do mesmo arquivo.

Antes do Python 3.11, ler TOML exigia a dependência externa tomli. Desde então, o parser entrou para a biblioteca padrão com o nome tomllib, e praticamente todo script que precisa inspecionar um projeto Python pode fazer isso sem instalar nada.

Se você trabalha com gerenciadores de pacotes modernos, já lida com TOML todos os dias — inclusive com o novo lockfile padronizado pylock.toml.

Como abrir um arquivo TOML com tomllib

O uso mais comum é ler um arquivo. O detalhe que pega muita gente: o arquivo precisa ser aberto em modo binário ('rb'), não em modo texto:

import tomllib

with open("pyproject.toml", "rb") as f:
    dados = tomllib.load(f)

print(dados["project"]["name"])

Se você abrir em modo texto ('r'), o tomllib levanta um TypeError imediato:

import tomllib

try:
    with open("pyproject.toml", "r", encoding="utf-8") as f:  # modo texto: errado
        tomllib.load(f)
except TypeError as erro:
    print("TypeError:", erro)
# TypeError: File must be opened in binary mode, e.g. use `open('foo.toml', 'rb')`

Esse requisito existe porque o TOML deve ser UTF-8, e o parser faz o decode ele mesmo.

Exemplo prático: lendo um pyproject.toml

Considere um pyproject.toml de um projeto fictício, o alerta-vagas, um bot que monitora vagas de Python:

[project]
name = "alerta-vagas"
version = "1.4.0"
requires-python = ">=3.11"
dependencies = [
    "httpx>=0.27",
    "pydantic>=2.7",
]

[project.scripts]
alerta-vagas = "alerta_vagas.cli:main"

[tool.ruff]
line-length = 100
target-version = "py311"

[tool.ruff.lint]
select = ["E", "F", "I"]

Ler esse arquivo e navegar pelos dados é só acessar dicionários aninhados:

import tomllib

with open("pyproject.toml", "rb") as f:
    dados = tomllib.load(f)

projeto = dados["project"]
print(projeto["name"], projeto["version"])     # alerta-vagas 1.4.0
print(projeto["requires-python"])               # >=3.11
print(len(projeto["dependencies"]), "dependências")  # 2 dependências
print(dados["tool"]["ruff"]["line-length"])     # 100
print(dados["tool"]["ruff"]["lint"]["select"])  # ['E', 'F', 'I']

Cada tabela [secao] vira um dicionário, e tabelas como [tool.ruff.lint] viram dicionários dentro de dicionários. Repare que tipos são preservados: line-length vem como int, não como string.

Ler TOML de uma string com loads

Quando o conteúdo TOML está em uma string — comum em testes e em valores embutidos no código — use tomllib.loads:

import tomllib

texto = """
title = "Monitor de preços"
ativo = true
intervalo_segundos = 300
produtos = ["notebook", "monitor", "teclado"]

[servidor]
host = "0.0.0.0"
port = 8080

[servidor.tls]
habilitado = false

[alertas.email]
para = ["[email protected]"]
"""

cfg = tomllib.loads(texto)
print(cfg["title"], cfg["intervalo_segundos"], cfg["produtos"][0])
print(cfg["servidor"]["host"], cfg["servidor"]["port"])
print(cfg["servidor"]["tls"]["habilitado"])
print(type(cfg["servidor"]["port"]).__name__, type(cfg["ativo"]).__name__)
# Monitor de preços 300 notebook
# 0.0.0.0 8080
# False
# int bool

Esse padrão de tabela aninhada ([servidor.tls]) é o que a maioria das ferramentas usa para organizar configurações sem repetir prefixos.

Tipos suportados: TOML para Python

O tomllib converte cada tipo TOML para o equivalente natural em Python:

Tipo no TOMLTipo resultante em PythonExemplo
String básicastrnome = "Diego"
Inteirointport = 8080
Ponto flutuantefloatimposto = 0.17
Booleanoboolativo = true
Arraylisttags = ["a", "b"]
Tabeladict[servidor]
Offset date-timedatetime.datetime2026-10-10T09:30:00-03:00
Local datedatetime.date2026-10-24
Local timedatetime.time09:00:00

As datas são o diferencial em relação ao JSON: TOML tem tipos de data nativos, e o tomllib já devolve objetos prontos:

import tomllib

pedido = """
data_hora = 2026-10-10T09:30:00-03:00
prazo = 2026-10-24
janela = 09:00:00
"""

doc = tomllib.loads(pedido)
print(doc["data_hora"])   # 2026-10-10 09:30:00-03:00
print(doc["prazo"])       # 2026-10-24
print(doc["janela"])      # 09:00:00

Isso elimina o trabalho manual de parsear strings de data que arquivos JSON exigem.

Tratamento de erros: TOMLDecodeError

Arquivos com sintaxe inválida geram tomllib.TOMLDecodeError. Trate-o como qualquer exceção de parsing:

import tomllib

arquivo_corrompido = """
[tool.exemplo
chave = "valor"
"""

try:
    tomllib.loads(arquivo_corrompido)
except tomllib.TOMLDecodeError as erro:
    print("Erro de TOML:", erro)
# Erro de TOML: Expected ']' at the end of a table declaration (at line 2, column 14)

A mensagem inclui linha e coluna do problema, o que facilita corrigir arquivos de configuração grandes. Para um tratamento de erros mais amplo em scripts que leem configuração do usuário, combine com o guia de tratamento de erros em Python.

E escrever TOML? tomllib não escreve

O tomllib é deliberadamente somente leitura. Quando você precisa gerar um arquivo TOML a partir de dicionários, a saída padrão é a biblioteca tomli-w:

$ pip install tomli-w
import tomli_w

config = {"tool": {"meu_script": {"retries": 3, "timeout": 30}}}
with open("config.toml", "wb") as f:
    tomli_w.dump(config, f)

Para o caso mais comum — o pyproject.toml — a recomendação prática é diferente: deixe as ferramentas gerarem e atualizarem o arquivo por você. O comando uv init cria o pyproject.toml completo, uv add mantém as dependências em dia, e o Poetry faz o mesmo no fluxo dele. Escrever pyproject.toml na mão raramente é necessário.

Python 3.10 ou mais antigo: use tomli

Se o seu script precisa rodar também em versões antigas do Python, o padrão recomendado é o fallback para a tomli, que tem a mesma API:

try:
    import tomllib  # Python 3.11+
except ModuleNotFoundError:  # Python 3.10 ou mais antigo
    import tomli as tomllib

with open("pyproject.toml", "rb") as f:
    dados = tomllib.load(f)
print("ok", dados["project"]["name"])

Assim o mesmo código funciona em qualquer versão com pip disponível para instalar a tomli quando necessário.

tomllib, JSON ou configparser: quando usar cada um

CritérioTOML + tomllibJSONconfigparser (INI)
Suporte na stdlibSim (Python 3.11+)SimSim
Tipos nativos (datas, números)SimNão (tudo vira string de data)Limitado
Comentários no arquivoSimNãoSim
Aninhamento profundoSim (tabelas)SimFraco
Escrita pela stdlibNãoSim (json.dump)Sim
Uso típicopyproject.toml, configs de ferramentasAPIs, troca de dadosConfigs legadas simples

Para arquivos de configuração editados por humanos, TOML costuma ganhar. Para trocar dados entre sistemas, JSON segue sendo o padrão. Segredos e variáveis de ambiente não devem ficar em nenhum desses arquivos — para isso, veja como usar python-dotenv e pydantic-settings.

Projeto prático: relatório de dependências do pyproject.toml

Um uso real e frequente do tomllib: um script de automação que analisa os projetos de uma pasta e resume as dependências declaradas:

import tomllib
from pathlib import Path

def resumir_projeto(caminho: Path) -> str:
    with open(caminho, "rb") as f:
        dados = tomllib.load(f)

    projeto = dados["project"]
    deps = projeto.get("dependencies", [])
    req = projeto.get("requires-python", "não declarado")
    return f"{projeto['name']} v{projeto['version']}: {len(deps)} deps, Python {req}"

for pyproject in sorted(Path(".").glob("*/pyproject.toml")):
    print(resumir_projeto(pyproject))
# alerta-vagas v1.4.0: 2 deps, Python >=3.11

Com pathlib para achar os arquivos e tomllib para interpretá-los, o script roda em qualquer máquina com Python 3.11, sem uma única dependência externa — útil para CI, auditorias de projetos e automação de rotinas com Python.

Conclusão

O tomllib remove a última desculpa para não ler TOML em Python: desde a versão 3.11, o parser está na biblioteca padrão, devolve dicionários com tipos nativos (inclusive datas) e reporta erros com linha e coluna. Lembre-se das três regras de ouro: abra o arquivo em modo binário, use loads para strings e conte com a tomli-w quando precisar escrever. Para configurações editadas por pessoas, TOML é hoje a escolha padrão do ecossistema Python — e agora você consegue consumi-lo com zero dependências.

E
Equipe Python Dev BR

Contribuidor do Python Dev BR

Artigos relacionados