pyproject.toml Explicado
pyproject.toml é o arquivo de configuração único para projetos Python modernos. Ele contém metadados do pacote, dependências, configurações de build e configuração de ferramentas (ruff, pytest, mypy) em um único arquivo TOML.
Receita
Cartão de receita de referência rápida - pronto para copiar e colar.
[project]
name = "myapp"
version = "0.1.0"
requires-python = ">=3.14"
dependencies = ["fastapi>=0.115"]
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.ruff]
line-length = 88
target-version = "py314"Quando usar isso:
- Iniciando qualquer nova biblioteca ou aplicação Python
- Consolidando arquivos
setup.cfg,setup.pyeruff.tomldispersos - Configurando backends de build, linters e test runners em um só lugar
Exemplo de Trabalho
[project]
name = "invoice-api"
version = "0.1.0"
description = "Invoice management API"
readme = "README.md"
requires-python = ">=3.14"
license = "MIT"
authors = [{ name = "Ada Lovelace", email = "ada@example.com" }]
dependencies = [
"fastapi>=0.115",
"uvicorn[standard]>=0.34",
"pydantic>=2",
"sqlalchemy>=2.0",
]
[project.optional-dependencies]
dev = ["pytest>=8", "ruff>=0.9", "mypy>=1.14"]
[project.scripts]
invoice-api = "invoice_api.cli:main"
[build-system]
requires = ["hatchling"]
build-backend = "hatchling.build"
[tool.hatch.build.targets.wheel]
packages = ["src/invoice_api"]
[tool.ruff]
line-length = 88
target-version = "py314"
[tool.ruff.lint]
select = ["E", "F", "I", "UP"]
[tool.pytest.ini_options]
testpaths = ["tests"]uv sync --group dev
uv run pytest
uv run ruff check .O que isso demonstra:
- Bloco PEP 621
[project]com metadados, dependências e pontos de entrada [build-system]informa aos instaladores qual backend constrói wheels- Seções
[tool.*]configuram ruff e pytest sem arquivos de configuração separados [project.scripts]cria um comando CLI na instalação
Mergulho Profundo
Como Funciona
- PEP 518 introduziu
[build-system]- todo instalador lê isso primeiro - PEP 621 padronizou metadados
[project](substitui os argumentos desetup.py) - Ferramentas leem suas próprias seções
[tool.<name>]- nenhum registro central é necessário - Um arquivo significa uma única fonte de verdade para humanos e CI
Seções Chave
| Seção | Propósito |
|---|---|
[project] | Nome, versão, dependências, scripts, classificadores |
[build-system] | Backend de build (hatchling, setuptools, poetry-core) |
[dependency-groups] | Grupos de desenvolvimento/documentação/teste (PEP 735) |
[tool.ruff] | Configuração do linter e formatter |
[tool.pytest.ini_options] | Descoberta de testes e marcadores |
[tool.mypy] | Configurações do verificador de tipos |
[tool.uv] | Configuração de índice e workspace específica do uv |
Notas Python
# Versão dinâmica do VCS (hatchling)
[project]
dynamic = ["version"]
[tool.hatch.version]
source = "vcs"# Workspace Monorepo (uv)
[tool.uv.workspace]
members = ["packages/*"]Armadilhas
[build-system]Ausente -pip install .falha com erros opacos. Correção: sempre incluarequiresebuild-backend.- Configuração Duplicada em
setup.pyepyproject.toml- as ferramentas leem arquivos diferentes. Correção: migre completamente parapyproject.toml; exclua os arquivos legados. - Descoberta de Pacote Incorreta - wheel vazio sem módulos. Correção: configure
packagesem[tool.hatch.build.targets.wheel]ou use o layoutsrc/. requires-pythonmuito restrito ou muito amplo - as instalações falham ou rodam em versões não suportadas. Correção: corresponda ao limite inferior da sua matriz de CI.- Segredos em
[tool.*]- tokens comprometidos no git. Correção: use variáveis de ambiente; mantenha apenas padrões não secretos no TOML.
Alternativas
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
Apenas setup.py | Projeto legado intocado | Novos projetos (padrão depreciado) |
setup.cfg | Projetos muito antigos do setuptools | Você precisa de configuração de ferramenta além de metadados |
| Arquivos de configuração divididos | A ferramenta não tem suporte a pyproject.toml | A ferramenta suporta [tool.*] (prefira um arquivo) |
FAQs
Eu ainda preciso do setup.py?
Não para a maioria dos projetos. pyproject.toml com um backend de build o substitui completamente.
Onde vão as dependências de desenvolvimento?
Use [dependency-groups] (PEP 735) ou [project.optional-dependencies] para grupos opcionais.
Posso configurar várias ferramentas em um único arquivo?
Sim. Cada seção [tool.*] é independente. ruff, pytest, mypy e hatch coexistem.
Qual backend de build devo escolher?
hatchling para a maioria dos pacotes. Use setuptools para extensões legadas. Use maturin para extensões Rust.
Como funcionam os pontos de entrada?
[project.scripts] mapeia nomes de CLI para chamáveis módulo:função. Instalado no bin/ do venv ao pip install.
pyproject.toml é obrigatório para aplicações?
Não estritamente, mas é o padrão para declaração de dependências, configuração de ferramentas e reprodutibilidade.
Como especifico apenas Python 3.14?
requires-python = ">=3.14,<3.15" ou ==3.14.* dependendo de quão estritamente você quer fixar.
Ferramentas podem entrar em conflito no mesmo arquivo?
Não. Cada seção [tool.*] é independente. Apenas os metadados [project] são compartilhados.
Como valido a sintaxe do pyproject.toml?
pip install validate-pyproject ou deixe seu gerenciador de pacotes (uv sync) relatar erros de análise.
Devo fazer commit do pyproject.toml?
Sempre. É o manifesto do projeto. Arquivos de lock (uv.lock, poetry.lock) também devem ser commitados.
Relacionado
- uv - A Toolchain Rápida - fluxo de trabalho do dia a dia
- Resolução de Dependências e Arquivos de Lock - fixação de versão
- Instalações Editáveis e Pacotes Locais - layout src
- Backends de Build - hatchling vs setuptools
Versões da Stack: Esta página foi escrita para Python 3.14.0, FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, e uv 0.6+.