
Passo 1 de 8
Criar a primeira sessão Nox
Crie um noxfile.py mínimo e execute uma sessão isolada que instala o Ruff e consulta sua versão.
Trilha de aprendizado · Nível 15 · Tutorial 9
Criar uma rotina reproduzível que execute formatação, lint, tipagem, testes e validação da distribuição, sinalizando falhas antes da entrega.
Criar a primeira sessão Nox
Crie um noxfile.py mínimo e execute uma sessão isolada que instala o Ruff e consulta sua versão. 3 min
Declarar dependências e centralizar configurações
Separe ferramentas de verificação das dependências da aplicação e mantenha cada configuração no lugar responsável por ela. 3 min
Verificar formatação e lint sem corrigir arquivos
Crie sessões Ruff de validação que detectam desvios, preservam os arquivos-fonte e sinalizam falhas pelo código de saída. 3 min
Executar tipagem e testes com dependências explícitas
Adicione sessões independentes para verificar tipos e executar a suíte unitária sem depender das ferramentas ou do projeto instalados no seu ambiente de desenvolvimento. 3 min
Encadear a construção e a validação da distribuição
Monte uma sessão de entrega que cria artefatos novos e valida a wheel exata que acabou de ser construída. 4 min
Validar as versões de Python selecionadas
Parametrize as sessões que executam a aplicação e transforme a ausência de um interpretador exigido em falha explícita. 3 min
Definir um comando único de validação
Configure a execução padrão do Nox para validar a entrega inteira com um único comando reproduzível. 3 min
Consolidar e testar a rotina completa
Reúna a configuração, execute a validação completa, provoque uma falha de formatação controlada e confirme que a rotina se recupera sem alterar o código automaticamente. 4 min

Passo 1 de 8
Crie um noxfile.py mínimo e execute uma sessão isolada que instala o Ruff e consulta sua versão.
O Nox lê um arquivo chamado noxfile.py e executa as sessões declaradas nele. Cada sessão prepara um ambiente isolado, instala o que precisa e roda comandos.
Ele não substitui as ferramentas: Ruff continua formatando e analisando código; mypy verifica tipos; pytest executa testes; build cria artefatos. O papel do Nox é tornar essa sequência explícita e reproduzível.
A sessão usa seu próprio ambiente, mas trabalha sobre os mesmos arquivos do projeto.

O Nox é iniciado no seu ambiente local; cada sessão recebe um ambiente isolado e acessa a árvore compartilhada do projeto.
No computador, crie uma pasta vazia para a prática. Dentro dela, crie pyproject.toml e src/saudacao/__init__.py com os conteúdos abaixo. Esta base é instalável, mas nesta primeira sessão ainda não vamos instalar nem testar o pacote.
Metadados mínimos para identificar o projeto.
[build-system]
requires = ["setuptools>=68"]
build-backend = "setuptools.build_meta"
[project]
name = "saudacao-nox"
version = "0.1.0"
requires-python = ">=3.11"
[tool.setuptools.packages.find]
where = ["src"]Um módulo mínimo compartilhado pela futura rotina de verificações.
def mensagem(nome: str) -> str:
return f"Olá, {nome}!"Dica
Abra o terminal na raiz do projeto: a pasta que contém pyproject.toml. Os próximos arquivos e comandos pressupõem essa localização.
No noxfile.py, o decorador @nox.session registra uma função como sessão. Dentro dela, session.install(...) instala dependências no ambiente da sessão. Já session.run(...) executa um comando nesse ambiente.
Vamos apenas consultar a versão do Ruff. Isso confirma o isolamento e a instalação sem iniciar as verificações de qualidade ainda.
Crie este arquivo na raiz do projeto, ao lado de pyproject.toml.
import nox
@nox.session
def ruff_version(session: nox.Session) -> None:
session.install("ruff==0.9.10")
session.run("ruff", "--version")Crie e ative, se desejar, um ambiente virtual dedicado ao Nox. Então instale uma versão definida e execute os comandos a partir da raiz do projeto.
python -m venv .venv-nox
# macOS/Linux
source .venv-nox/bin/activate
# Windows (PowerShell)
# .venv-nox\Scripts\Activate.ps1
python -m pip install "nox==2025.2.9"
python -m nox -l
python -m nox -s ruff_versionDica
A listagem deve mostrar ruff_version. Na execução, o Nox cria ou reutiliza o ambiente da sessão, instala a versão fixada do Ruff e exibe a versão retornada pelo comando. Nenhum arquivo-fonte do projeto deve ser alterado por essa sessão.
Relacione cada elemento à sua função.
Toque em um item e depois no par correspondente.

Passo 2 de 8
Separe ferramentas de verificação das dependências da aplicação e mantenha cada configuração no lugar responsável por ela.
As dependências em [project.dependencies] são necessárias para quem instala e usa sua aplicação. Já Nox, Ruff, mypy e pytest servem para desenvolver e validar o projeto; mantenha suas versões em arquivos de requisitos de verificação, separados.
Fixar uma versão direta, como ruff==0.9.10, torna a ferramenta escolhida explícita. O próprio Nox também deve ter uma versão controlada no ambiente local que o executa.

A aplicação declara o que precisa para rodar; cada sessão instala apenas a ferramenta necessária para sua verificação.
Dica
Uma sessão de lint não precisa instalar pytest, e uma sessão de testes não precisa instalar mypy. Declare somente o que o comando daquela sessão realmente usa; isso reduz acoplamento e torna falhas de preparação mais fáceis de diagnosticar.
Crie estes arquivos no projeto. As versões são exemplos: escolha e atualize versões de acordo com a política do seu projeto.
# requirements/nox.txt
nox==2025.2.9
# requirements/lint.txt
ruff==0.9.10
# requirements/typecheck.txt
mypy==1.15.0
# requirements/test.txt
pytest==8.3.5Mantenha as opções das ferramentas no pyproject.toml. O Nox coordena instalações e comandos, mas não deve virar um segundo arquivo de configuração do Ruff, mypy ou pytest.
[project]
name = "tarefas-cli"
version = "0.1.0"
requires-python = ">=3.11"
dependencies = [
"platformdirs>=4.0,<5",
]
[tool.ruff]
line-length = 88
[tool.ruff.lint]
select = ["E", "F", "I"]
[tool.mypy]
python_version = "3.11"
files = ["src"]
strict = true
[tool.pytest.ini_options]
testpaths = ["tests/unit"]
addopts = "-q"Cada sessão instala seu requisito direto. Os nomes dos alvos ficam explícitos; a implementação dos comandos de verificação será acrescentada nos próximos steps.
import nox
@nox.session
def format_check(session: nox.Session) -> None:
session.install("-r", "requirements/lint.txt")
# A verificação de formatação será incluída no próximo step.
@nox.session
def lint(session: nox.Session) -> None:
session.install("-r", "requirements/lint.txt")
# O comando de lint será incluído no próximo step.
@nox.session
def typecheck(session: nox.Session) -> None:
session.install("-r", "requirements/typecheck.txt")
# O comando de tipagem será incluído em seguida.
@nox.session
def test(session: nox.Session) -> None:
session.install("-r", "requirements/test.txt")
session.install(".")
# Os testes unitários serão incluídos em seguida.
@nox.session
def package(session: nox.Session) -> None:
session.install("-r", "requirements/test.txt")
# Construção e testes de aceitação da wheel serão incluídos depois.Configure a sessão test para a suíte unitária, por exemplo em tests/unit. Mantenha os testes de aceitação da distribuição em outro alvo, como tests/acceptance, reservado à futura sessão package.
Esses testes dependem de uma wheel construída na própria execução; portanto, executá-los junto dos unitários poderia tentar validá-los antes de existir um artefato.
Atenção
Ambientes isolados e versões diretas fixadas melhoram a repetição, mas não congelam tudo: dependências transitivas, interpretadores disponíveis, sistema operacional e o ambiente isolado usado pelo backend de construção continuam influenciando o resultado. Não conclua compatibilidade total apenas porque uma sessão foi aprovada em uma máquina.
Complete com os três destinos abaixo, separados por vírgulas e nesta ordem: [project.dependencies], requirements/lint.txt, [tool.ruff].
A dependência de execução platformdirs pertence a _; a versão ruff==0.9.10 pertence a _; e line-length = 88 pertence a ___.

Passo 3 de 8
Crie sessões Ruff de validação que detectam desvios, preservam os arquivos-fonte e sinalizam falhas pelo código de saída.
Mantenha duas sessões: uma confere a formatação e outra executa o lint. Na rotina de entrega, use ruff format --check, que apenas compara o arquivo com a formatação esperada, e ruff check, sem --fix, que apenas relata problemas.
Assim, um desvio produz uma falha visível em vez de uma alteração silenciosa no código analisado.
Cada sessão cria seu próprio ambiente, executa o Ruff e lê os arquivos compartilhados do projeto. Os comandos de verificação não reescrevem esses arquivos.

Ambientes e caches podem ser criados pelo Nox ou pelas ferramentas; isso é diferente de modificar o código-fonte.
Dica
Durante o desenvolvimento, você pode rodar deliberadamente ruff format . ou ruff check --fix .. Não coloque esses comandos nas sessões que validam uma entrega: elas precisam revelar o desvio, não escondê-lo.
No noxfile.py, use o arquivo de requisitos de verificação que você organizou no step anterior. Abaixo, ele está em requirements/verificacao.txt; ajuste somente esse caminho se o seu projeto adotou outro nome.
Adicione estas sessões ao arquivo. Elas instalam somente o Ruff e executam verificações sem opções de correção.
import nox
@nox.session
def format_check(session):
session.install("-r", "requirements/verificacao.txt")
session.run("ruff", "format", "--check", ".")
@nox.session
def lint(session):
session.install("-r", "requirements/verificacao.txt")
session.run("ruff", "check", ".")
Exemplo
Se ruff format --check . encontrar um arquivo fora do padrão, o Ruff retorna código diferente de zero. Como session.run aceita apenas sucesso por padrão, ele interrompe a sessão format_check naquele ponto e o Nox a marca como falha. O arquivo permanece como estava: não há --fix nem execução de ruff format ..
Crie temporariamente o arquivo formatacao_demo.py na raiz do projeto com o conteúdo abaixo. Em seguida, execute python -m nox -s format_check. Compare o arquivo com o conteúdo exibido: a sessão deve falhar, mas o arquivo deve continuar idêntico ao que você criou.
Este arquivo está propositalmente fora da formatação esperada.
def somar(valores:list[int])->int:
return sum(valores)
Depois de observar a falha, restaure o arquivo manualmente para a versão formatada abaixo — ou apague o arquivo temporário — antes de continuar o projeto.
python -m nox -s format_check
# Versão formatada, se quiser manter o arquivo:
# def somar(valores: list[int]) -> int:
# return sum(valores)
Após executar a sessão com o arquivo propositalmente mal formatado, qual foi o resultado esperado para a sessão e para o conteúdo de formatacao_demo.py?
Escreva pelo menos 40 caracteres (0/40).
Qual comando deve estar na sessão que valida a formatação sem modificar os arquivos?
Resumo
ruff format --check e ruff check sem --fix.session.run faz a sessão falhar; não corrige o arquivo analisado.
Passo 4 de 8
Adicione sessões independentes para verificar tipos e executar a suíte unitária sem depender das ferramentas ou do projeto instalados no seu ambiente de desenvolvimento.
Uma sessão Nox deve instalar apenas o que precisa para seu trabalho. A sessão de mypy verifica anotações nos módulos escolhidos. A sessão de pytest testa comportamentos; se os testes fazem import do seu pacote, ela também instala o projeto no ambiente isolado.
Não inclua aqui os testes de aceitação da distribuição: eles dependem de um artefato construído e serão encadeados em outra sessão.
Cada sessão prepara seu próprio ambiente antes de executar seu comando.

Mypy analisa alvos definidos; pytest executa a suíte unitária contra o pacote instalado no ambiente da sessão.
Partindo dos requisitos de verificação organizados anteriormente, acrescente sessões como estas ao seu noxfile.py. Ajuste src e tests/unit se os diretórios do seu projeto tiverem outros nomes.
A instalação session.install(".") usa o projeto local no ambiente da sessão. Ela é necessária quando os testes importam o pacote, especialmente em layout src.
import nox
@nox.session
def typecheck(session: nox.Session) -> None:
session.install("-r", "requirements/typecheck.txt")
session.run("mypy", "src")
@nox.session
def tests(session: nox.Session) -> None:
session.install("-r", "requirements/tests.txt")
session.install(".")
session.run("pytest", "tests/unit")
Exemplo
Exemplo de divisão mínima:
requirements/typecheck.txt
mypy==1.13.0
types-requests==2.32.0.20241016requirements/tests.txt
pytest==8.3.3Inclua stubs ou bibliotecas adicionais em requirements/typecheck.txt somente se o mypy precisar deles para analisar seus imports. As opções das ferramentas continuam no pyproject.toml; o noxfile apenas prepara e aciona cada verificação.
Na raiz do projeto, execute:
python -m nox -s typecheck
python -m nox -s testsSe uma chamada de session.install(...) falhar, o problema ocorreu na preparação do ambiente: requisito inexistente, versão incompatível ou erro ao instalar o projeto. Se mypy ou pytest iniciar e retornar código não zero, a falha pertence à verificação indicada no diagnóstico. Nox preserva esse resultado como falha da sessão; não o oculte.
Considere este resumo:
nox > Running session tests
nox > python -m pip install .
ERROR: Package 'agenda-cli' requires a different Python
nox > Command python -m pip install . failed with exit code 1Explique se a falha é de preparação ou de teste e qual seria sua primeira investigação.
Escreva pelo menos 80 caracteres (0/80).
Resumo
typecheck instala mypy e os stubs ou dependências necessários, depois analisa os alvos definidos.tests instala pytest e o projeto local quando a suíte importa o pacote.No seu projeto, os testes em tests/unit importam módulos do pacote localizado em src. Descreva os dois comandos para executar as sessões e justifique a instalação explícita do projeto na sessão tests.
Escreva pelo menos 100 caracteres (0/100).

Passo 5 de 8
Monte uma sessão de entrega que cria artefatos novos e valida a wheel exata que acabou de ser construída.
A sessão delivery deve conter toda a cadeia: instalar as ferramentas de verificação, construir a sdist e a wheel em uma pasta nova, localizar uma única wheel e executar os testes de aceitação apontando para ela.
Como session.run() interrompe a sessão quando um comando retorna código diferente de zero, uma falha no build impede automaticamente os testes seguintes. Isso é mais confiável do que supor uma ordem entre sessões independentes.
O ambiente da sessão contém build e pytest; o ambiente temporário criado pelo teste contém somente a aplicação instalada e suas dependências de execução.

A wheel recém-criada atravessa a fronteira entre o ambiente de validação e o ambiente limpo da aplicação.
Atenção
Não construa em uma pasta persistente como dist/ e depois escolha “a primeira” wheel encontrada. Um artefato antigo pode ser selecionado e dar uma aprovação enganosa. Crie um diretório temporário de saída por execução e exija exatamente uma wheel.
Crie um arquivo de requisitos específico para a entrega. Ele controla as versões de build e pytest usadas no ambiente da sessão, sem adicioná-las às dependências normais da aplicação.
A sessão cria uma pasta temporária, constrói nela e transforma o caminho da wheel em caminho absoluto antes de passá-lo como WHEEL_PATH.
Crie este arquivo no projeto.
build==1.2.2.post1
pytest==8.3.4
Adicione esta sessão ao noxfile.py. Ajuste somente o caminho de tests/acceptance se sua suíte estiver em outro local.
from pathlib import Path
import nox
@nox.session
def delivery(session: nox.Session) -> None:
"""Constrói a distribuição e testa a wheel recém-gerada."""
session.install("-r", "requirements/delivery.txt")
output_dir = Path(session.create_tmp()) / "artifacts"
output_dir.mkdir()
session.run(
"python",
"-m",
"build",
"--outdir",
str(output_dir),
)
wheels = list(output_dir.glob("*.whl"))
if len(wheels) != 1:
session.error(
f"Esperava exatamente uma wheel em {output_dir}, "
f"mas encontrei {len(wheels)}: {wheels}"
)
wheel_path = str(wheels[0].resolve())
session.run(
"pytest",
"tests/acceptance",
env={"WHEEL_PATH": wheel_path},
)
O teste lê WHEEL_PATH, rejeita um valor ausente ou que não aponte para uma wheel existente e instala exatamente esse arquivo. O diretório de trabalho fica fora da árvore do projeto e PYTHONPATH é removido: assim, as fontes locais não podem substituir a distribuição instalada.
O exemplo usa o comando tarefas, definido anteriormente em [project.scripts]. Se o seu projeto usa outro ponto de entrada, substitua apenas esse nome e os argumentos esperados.
Este teste é autocontido: ele cria o ambiente limpo, instala a wheel recebida e executa o comando instalado.
import os
import subprocess
import sys
import venv
from pathlib import Path
import pytest
def executable_in(venv_dir: Path, name: str) -> Path:
directory = "Scripts" if os.name == "nt" else "bin"
suffix = ".exe" if os.name == "nt" and name != "python" else ""
return venv_dir / directory / f"{name}{suffix}"
def test_wheel_instalada_exibe_ajuda(tmp_path: Path) -> None:
wheel_value = os.environ.get("WHEEL_PATH")
if not wheel_value:
pytest.fail("WHEEL_PATH não foi definida pela sessão de entrega")
wheel_path = Path(wheel_value)
if not wheel_path.is_absolute() or not wheel_path.is_file():
pytest.fail(f"WHEEL_PATH deve apontar para uma wheel existente: {wheel_path}")
if wheel_path.suffix != ".whl":
pytest.fail(f"O artefato informado não é uma wheel: {wheel_path}")
app_environment = tmp_path / "app-env"
venv.EnvBuilder(with_pip=True).create(app_environment)
python = executable_in(app_environment, "python")
command = executable_in(app_environment, "tarefas")
clean_environment = os.environ.copy()
clean_environment.pop("PYTHONPATH", None)
subprocess.run(
[str(python), "-m", "pip", "install", str(wheel_path)],
cwd=tmp_path,
env=clean_environment,
check=True,
text=True,
capture_output=True,
timeout=60,
)
result = subprocess.run(
[str(command), "--help"],
cwd=tmp_path,
env=clean_environment,
text=True,
capture_output=True,
timeout=30,
)
assert result.returncode == 0, result.stderr
assert "uso:" in result.stdout.lower()
Coloque as ações na ordem em que devem ocorrer dentro da sessão delivery.
Quais duas evidências mostrariam que sua suíte validou a wheel recém-construída, e não as fontes locais ou uma wheel antiga?
Escreva pelo menos 80 caracteres (0/80).

Passo 6 de 8
Parametrize as sessões que executam a aplicação e transforme a ausência de um interpretador exigido em falha explícita.
Considere um projeto com requires-python = ">=3.10". A rotina deve incluir obrigatoriamente o Python 3.10, pois ele é o limite mínimo prometido. Selecione também versões concretas que você realmente consegue executar, por exemplo 3.10 e 3.12.
O Python que inicia o Nox pode ser diferente dos interpretadores das sessões. Ferramentas estáticas, como Ruff e mypy, podem usar um único interpretador de referência — aqui, 3.12. Já os testes e a validação da distribuição devem rodar na matriz escolhida, porque executam a aplicação.

O interpretador do Nox, o interpretador de referência estático e os interpretadores que executam a aplicação têm responsabilidades distintas.
O argumento python de @nox.session expande uma função em sessões independentes. Com a matriz abaixo, python -m nox -l mostrará, entre outras, tests-3.10, tests-3.12, delivery-3.10 e delivery-3.12.
A sessão delivery continua construindo e validando a wheel como no passo anterior. Como o pytest dessa sessão é executado no ambiente Nox parametrizado, o teste de aceitação deve criar o ambiente limpo da aplicação a partir do interpretador atual dele — por exemplo, usando sys.executable ou venv.EnvBuilder dentro do teste. Assim, uma entrega em delivery-3.10 é instalada e executada com Python 3.10, não apenas analisada por outra versão.
Ajuste os comandos e os arquivos de requisitos aos que você já criou nas sessões anteriores.
from pathlib import Path
import nox
PYTHONS = ["3.10", "3.12"]
REFERENCE_PYTHON = "3.12"
# Uma versão selecionada, mas indisponível, não pode ser ignorada.
nox.options.error_on_missing_interpreters = True
@nox.session(python=REFERENCE_PYTHON)
def format_check(session: nox.Session) -> None:
session.install("-r", "requirements/quality.txt")
session.run("ruff", "format", "--check", "src", "tests")
@nox.session(python=REFERENCE_PYTHON)
def lint(session: nox.Session) -> None:
session.install("-r", "requirements/quality.txt")
session.run("ruff", "check", "src", "tests")
@nox.session(python=REFERENCE_PYTHON)
def typecheck(session: nox.Session) -> None:
session.install("-r", "requirements/typecheck.txt")
session.run("mypy", "src")
@nox.session(python=PYTHONS)
def tests(session: nox.Session) -> None:
session.install("-r", "requirements/test.txt")
session.install(".")
session.run("pytest", "tests/unit")
@nox.session(python=PYTHONS)
def delivery(session: nox.Session) -> None:
session.install("build", "pytest")
output = Path(session.create_tmp()) / "dist"
output.mkdir()
session.run("python", "-m", "build", "--outdir", str(output))
wheels = list(output.glob("*.whl"))
if len(wheels) != 1:
session.error("A construção atual deve produzir exatamente uma wheel.")
session.run(
"pytest",
"tests/acceptance",
env={"WHEEL_PATH": str(wheels[0].resolve())},
)Dica
Você pode definir a política no arquivo, com nox.options.error_on_missing_interpreters = True, ou aplicá-la na chamada: python -m nox --error-on-missing-interpreters. Sem isso, uma sessão de uma versão ausente pode ser ignorada; ela não vira evidência de compatibilidade.
O projeto declara requires-python = ">=3.10", a matriz contém ["3.10", "3.12"] e o computador não possui Python 3.10. Qual conclusão é correta ao executar a rotina com erro para interpretadores ausentes?
Para um projeto que declara requires-python = ">=3.10", proponha uma matriz concreta, diga quais sessões devem ser parametrizadas e explique por que um interpretador ausente impede a aprovação da rotina.
Escreva pelo menos 120 caracteres (0/120).

Passo 7 de 8
Configure a execução padrão do Nox para validar a entrega inteira com um único comando reproduzível.
Defina em noxfile.py quais sessões formam a validação obrigatória. Ao executar Nox sem -s, ele usará nox.options.sessions.
Inclua as verificações estáticas uma vez, no interpretador de referência, e as sessões parametrizadas de teste e entrega para cada versão que você decidiu cobrir. Os nomes com parênteses correspondem às expansões da matriz.
No início do noxfile.py, depois de importar nox:
import nox
nox.options.sessions = (
"format",
"lint",
"typecheck",
"tests-3.11",
"tests-3.12",
"delivery-3.11",
"delivery-3.12",
)
nox.options.error_on_missing_interpreters = TrueAs verificações estáticas não precisam se repetir em cada Python, mas os testes e a validação da wheel precisam usar cada interpretador selecionado.

Uma execução padrão reúne sessões estáticas e as expansões relevantes da matriz de Python.
Com o ambiente que contém Nox ativado, execute este comando na raiz — onde estão noxfile.py e pyproject.toml:
python -m nox --error-on-missing-interpretersExemplo
nox.options.error_on_missing_interpreters = True registra a política no projeto. A opção --error-on-missing-interpreters a torna explícita no comando canônico. Em ambos os casos, faltar um interpretador obrigatório é falha, não evidência de compatibilidade.
Uma automação só precisa preparar os mesmos interpretadores selecionados e o ambiente que executa Nox; depois, chama exatamente esse comando. Não é necessário criar aqui uma configuração específica de provedor.
Dica
Durante o desenvolvimento, python -m nox -s lint ou python -m nox -s tests-3.12 é útil para feedback rápido. Porém, isso não substitui o comando canônico: sessões não executadas não foram aprovadas.
Se um comando chamado por session.run termina com código diferente de zero, aquela sessão falha. Ao final, basta uma sessão obrigatória falhar para o processo global do Nox terminar com código diferente de zero.
Sem uma política adicional, Nox pode continuar executando outras sessões independentes e mostrar mais diagnósticos. Isso não transforma a execução em sucesso.
Use esta variação apenas quando quiser privilegiar rapidez em vez de coletar todas as falhas da mesma execução:
python -m nox --error-on-missing-interpreters --stop-on-first-errorAtenção
--stop-on-first-error encerra a execução global após a primeira sessão que falhar. Ele é uma política de execução, não um requisito para validar corretamente. Sem essa opção, uma sessão posterior aprovada não compensa a falha anterior.
Exemplo
nox > Session format was successful.
nox > Session lint was successful.
nox > Session typecheck was successful.
nox > Session tests-3.11 was successful.
nox > Session tests-3.12 failed.
nox > Session delivery-3.11 was successful.
nox > Session delivery-3.12 was successful.
nox > Ran 7 sessions: 6 successful, 1 failed.Apesar de seis aprovações, a validação completa falhou: tests-3.12 era obrigatória. O código de saída global deve sinalizar falha ao ambiente que chamou Nox.
No resumo exibido, a entrega pode ser considerada validada porque as sessões de delivery foram aprovadas.

Passo 8 de 8
Reúna a configuração, execute a validação completa, provoque uma falha de formatação controlada e confirme que a rotina se recupera sem alterar o código automaticamente.
Ao final, a validação completa é acionada da raiz do projeto com:
python -m nox --error-on-missing-interpretersCada arquivo tem uma responsabilidade: pyproject.toml reúne metadados e opções das ferramentas; os arquivos em requirements/ fixam as versões das ferramentas; e noxfile.py cria ambientes isolados e coordena os comandos. A suíte de aceitação criada anteriormente continua responsável por instalar e exercitar a wheel em um ambiente limpo.
A execução padrão percorre verificações estáticas, testes em mais de uma versão do Python e a entrega testada a partir da wheel recém-construída.

As configurações, versões e orquestração são separadas, mas o resultado final depende de todas as sessões obrigatórias.
Mantenha os metadados de seu projeto já existentes e confirme que as opções abaixo estão em pyproject.toml. Os diretórios src, tests/unit e tests/acceptance correspondem à estrutura usada na prática anterior.
Acrescente estas tabelas ao seu pyproject.toml, preservando as demais tabelas de construção e de metadados do projeto.
[project]
requires-python = ">=3.11"
[tool.ruff]
target-version = "py311"
[tool.ruff.lint]
select = ["E", "F", "I"]
[tool.mypy]
python_version = "3.11"
strict = true
files = ["src"]
[tool.pytest.ini_options]
addopts = "-ra"
testpaths = ["tests/unit"]Crie cada arquivo com o respectivo conteúdo. Essas dependências não pertencem a project.dependencies: elas existem para executar a validação.
# requirements/nox.txt
nox==2024.10.9
# requirements/quality.txt
ruff==0.9.10
mypy==1.15.0
# requirements/test.txt
pytest==8.3.5
# requirements/delivery.txt
build==1.2.2.post1
pytest==8.3.5Este arquivo torna Python 3.11 e 3.12 obrigatórios para os testes e para a validação da distribuição. As ferramentas estáticas usam Python 3.11 como interpretador de referência. A sessão delivery cria um diretório novo, exige exatamente uma wheel e entrega seu caminho absoluto à suíte de aceitação por PACKAGE_WHEEL.
Substitua ou complete seu noxfile.py por esta configuração. Ela pressupõe que tests/acceptance já lê PACKAGE_WHEEL, rejeita um caminho ausente ou inválido e instala a wheel indicada em um ambiente limpo.
from pathlib import Path
import tempfile
import nox
PYTHONS = ["3.11", "3.12"]
nox.options.error_on_missing_interpreters = True
nox.options.sessions = [
"format",
"lint",
"typecheck",
"tests-3.11",
"tests-3.12",
"delivery-3.11",
"delivery-3.12",
]
@nox.session(python="3.11")
def format(session: nox.Session) -> None:
session.install("-r", "requirements/quality.txt")
session.run("ruff", "format", "--check", ".")
@nox.session(python="3.11")
def lint(session: nox.Session) -> None:
session.install("-r", "requirements/quality.txt")
session.run("ruff", "check", ".")
@nox.session(python="3.11")
def typecheck(session: nox.Session) -> None:
session.install("-r", "requirements/quality.txt")
session.install(".")
session.run("mypy", "src")
@nox.session(python=PYTHONS)
def tests(session: nox.Session) -> None:
session.install("-r", "requirements/test.txt")
session.install(".")
session.run("pytest", "tests/unit")
@nox.session(python=PYTHONS)
def delivery(session: nox.Session) -> None:
session.install("-r", "requirements/delivery.txt")
output_dir = Path(tempfile.mkdtemp(prefix="nox-dist-")).resolve()
session.run("python", "-m", "build", "--outdir", str(output_dir))
wheels = list(output_dir.glob("*.whl"))
if len(wheels) != 1:
session.error(
f"Esperada exatamente uma wheel em {output_dir}; encontradas: {wheels}"
)
session.run(
"pytest",
"tests/acceptance",
env={"PACKAGE_WHEEL": str(wheels[0])},
)python -m pip install -r requirements/nox.txt.python -m nox --error-on-missing-interpreters. Registre o resumo: todas as sessões devem passar e o processo deve terminar com código zero.src/, escolha uma atribuição simples, como valor = 1, e introduza deliberadamente um espaço extra: valor = 1.format deve falhar. Compare o arquivo: ele ainda contém o espaço extra, pois ruff format --check apenas verifica; não corrige.A aprovação só é completa se as sessões obrigatórias, incluindo cada versão selecionada e cada delivery, forem aprovadas. Um interpretador ausente, uma sessão ignorada ou a execução de apenas uma sessão não comprovam a entrega.
Qual comando você executou? Qual sessão detectou a alteração de formatação? O arquivo foi modificado automaticamente? Após restaurá-lo, quais evidências permitem afirmar — ou negar — que a entrega foi aprovada por completo?
Escreva pelo menos 180 caracteres (0/180).
Resumo
Use esta síntese para revisar a rotina antes de considerar a entrega validada.
pyproject.toml concentra opções de Ruff, mypy e pytest; requisitos fixados controlam as versões das ferramentas; noxfile.py coordena ambientes e comandos.ruff format --check e ruff check validam sem aplicar correções deliberadamente; um código de saída não zero faz a sessão falhar.Parabéns! Você concluiu: Automatizar as verificações do projeto com Nox
Milhares de cursos online em vídeo, ebooks e áudiobooks.
Para testar seus conhecimentos no decorrer dos cursos online
Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail
Baixe nosso aplicativo pelo QR Code ou pelos links abaixo:.
+ de 10 milhões
de alunos
Certificado grátis e
válido em todo o Brasil
60 mil exercícios
gratuitos
4,8/5 classificação
nas lojas de apps
Cursos gratuitos em
vídeo, ebooks e audiobooks