Resposta rápida
O Poetry gerencia dependências e ambientes virtuais de projetos Python. Você cria o projeto (poetry new), adiciona bibliotecas (poetry add requests) e o Poetry registra tudo no pyproject.toml, trava as versões no poetry.lock e cria o ambiente sozinho. Para executar, use poetry run.
1
2
3
4
$ poetry new meu-projeto # cria pyproject.toml, src/ e tests/
$ cd meu-projeto
$ poetry add requests # instala e grava no pyproject.toml e no poetry.lock
$ poetry run python -c "import requests; print(requests.__version__)" # 2.34.2
Resumo em 30 segundos:
- Instale com
pipx install poetry(recomendação oficial), nunca no Python do sistema. -
pyproject.toml+poetry.lockvão para o Git; o ambiente virtual não. -
poetry add --group dev pytestsepara as ferramentas de desenvolvimento. - No Poetry 2.x,
poetry shellvirou plugin: useeval $(poetry env activate)oupoetry run. -
poetry buildepoetry publishgeram e enviam o pacote para o PyPI.
Salve salve Pythonista!
Clonou um projeto com pyproject.toml e um poetry.lock de 400 linhas? Ou quer publicar uma biblioteca no PyPI sem sofrimento? Este é o guia do Poetry para os dois casos: instalação, pyproject.toml no formato atual, dependências, lockfile, ambiente virtual, publicação e exportação. No final, Pipenv e Pipfile e uma tabela honesta comparando pip, Pipenv, Poetry e uv.
Todos os comandos foram executados com Poetry 2.5.1 e Python 3.10 no Linux, e as saídas mostradas são as reais (só encurtamos caminhos de pasta e trocamos nome e email do autor).
Então… Bora pro post! ![]()
Vá Direto ao Assunto…
- O que é o Poetry?
- Como instalar o Poetry
- poetry new vs poetry init
- O pyproject.toml do Poetry 2.x
- Adicionando dependências com poetry add
- O poetry.lock e o poetry install
- Onde fica o ambiente virtual do Poetry
- poetry run e como ativar o ambiente
- Vendo e atualizando dependências
- Publicando pacotes com poetry build e poetry publish
- Exportando requirements.txt (plugin export)
- Pipenv e Pipfile: o que são e comandos equivalentes
- pip + venv vs Pipenv vs Poetry vs uv: qual usar?
- Erros comuns
- Exercícios resolvidos
- Conclusão
O que é o Poetry?
O que é o Poetry? O Poetry é uma ferramenta de gerenciamento de dependências e de empacotamento para Python. Você declara as bibliotecas que o projeto usa, e ele resolve as versões compatíveis, grava o resultado exato num lockfile (
poetry.lock), cria um ambiente virtual isolado e instala tudo nele. O mesmo comando que gerencia as dependências também gera e publica o pacote no PyPI.
Sem ele, o fluxo tradicional é python -m venv, ativar, pip install e manter um requirements.txt na mão (se ainda não domina essa base, veja o guia de ambientes virtuais com venv e virtualenv). Nesse fluxo o pip freeze mistura o que você pediu com as dependências das dependências, nada garante que o colega instale as mesmas versões e publicar exige outras ferramentas (build, twine).
O Poetry resolve os três pontos. Hoje ele não é o mais rápido (falamos do uv no final), mas é maduro e está em muitos projetos que você vai herdar.
Como instalar o Poetry
O Poetry deve ficar isolado dos seus projetos, para que as dependências dele não briguem com as suas. A documentação de instalação recomenda o pipx:
1
$ pipx install poetry
A alternativa é o instalador oficial, que cria um ambiente só para o Poetry:
1
2
3
4
5
# Linux, macOS e WSL
$ curl -sSL https://install.python-poetry.org | python3 -
# Windows (PowerShell)
PS> (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | py -
Uma terceira forma documentada é um venv só para ele. Foi o que usamos neste post:
1
2
3
$ python3 -m venv ~/venv-poetry
$ ~/venv-poetry/bin/pip install poetry
$ ~/venv-poetry/bin/poetry --version
1
Poetry (version 2.5.1)
O Poetry 2.x exige Python 3.10 ou mais novo para rodar. Não rode pip install poetry no Python do sistema: em distros Linux recentes isso nem funciona (PEP 668). Para atualizar, pipx upgrade poetry ou, com o instalador oficial, poetry self update.
poetry new vs poetry init
poetry new: projeto do zero
1
$ poetry new meu-projeto
1
Created package meu_projeto in meu-projeto
A estrutura criada usa o layout src/:
1
2
3
4
5
6
7
8
meu-projeto/
├── pyproject.toml
├── README.md
├── src/
│ └── meu_projeto/
│ └── __init__.py
└── tests/
└── __init__.py
O projeto usa hífen (meu-projeto) e o pacote, underline (meu_projeto), porque hífen não vale em import. A pasta meu_projeto é um pacote graças ao __init__.py (entenda o papel dele em para que serve o __init__.py). Se preferir o pacote na raiz, sem src/, use poetry new --flat meu-projeto.
poetry init: projeto que já existe
Num projeto que já tem código, rode poetry init na pasta. Ele faz perguntas (nome, versão, dependências) e cria só o pyproject.toml. Com -n ele pula as perguntas:
1
2
$ cd legado
$ poetry init -n --name legado --dependency requests
1
Using version ^2.34.2 for requests
poetry new |
poetry init |
|
|---|---|---|
| Quando usar | Projeto novo | Projeto que já tem código |
| Cria pastas e arquivos |
pyproject.toml, README.md, src/, tests/
|
Só o pyproject.toml
|
| Modo | Direto | Interativo (ou -n para aceitar os padrões) |
| Cuidado | Nenhum | Se o projeto não é um pacote, configure package-mode = false (veja em Erros comuns) |
O pyproject.toml do Poetry 2.x
Este é o pyproject.toml que o poetry new gerou:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
[project]
name = "meu-projeto"
version = "0.1.0"
description = ""
authors = [
{name = "Seu Nome",email = "[email protected]"}
]
readme = "README.md"
requires-python = ">=3.10"
dependencies = [
]
[tool.poetry]
packages = [{include = "meu_projeto", from = "src"}]
[build-system]
requires = ["poetry-core>=2.0.0,<3.0.0"]
build-backend = "poetry.core.masonry.api"
A grande mudança do Poetry 2.0: nome, versão, autores, requires-python e dependências ficam na tabela padrão [project] da PEP 621, a mesma que o pip e o uv entendem. O [tool.poetry] guarda só o que é do Poetry, como o packages (onde está o código).
-
requires-python: as versões do Python aceitas. O Poetry resolve dependências para todas elas (veja o erro de conflito mais abaixo). -
[build-system]: o pacote é construído pelopoetry-core, o que permite instalar compip install .sem ter o Poetry.
Herdou um projeto com [tool.poetry.dependencies]?
Projetos criados antes do Poetry 2.0 colocam tudo dentro de [tool.poetry], com a sintaxe antiga:
1
2
3
4
5
6
7
8
9
10
11
12
13
[tool.poetry]
name = "antigo"
version = "0.1.0"
description = ""
authors = ["Fulano <[email protected]>"]
readme = "README.md"
[tool.poetry.dependencies]
python = "^3.10"
requests = "^2.31"
[tool.poetry.group.dev.dependencies]
pytest = "^8.0"
O Poetry 2.5 ainda instala esse formato (testamos), mas o poetry check avisa que está obsoleto:
1
2
3
Warning: [tool.poetry.name] is deprecated. Use [project.name] instead.
Warning: [tool.poetry.description] is deprecated. Use [project.description] instead.
Warning: [tool.poetry.authors] is deprecated. Use [project.authors] instead.
Não precisa migrar às pressas, mas quando mexer no projeto, mova esses campos para [project]. Os guias de migração para o 2.0 e do pyproject mostram a correspondência campo a campo.
Adicionando dependências com poetry add
Esqueça o pip install. Num projeto Poetry, quem instala é o poetry add:
1
$ poetry add requests
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
Creating virtualenv meu-projeto-FsF8QyNg-py3.10 in /home/voce/.cache/pypoetry/virtualenvs
Using version ^2.34.2 for requests
Updating dependencies
Resolving dependencies...
Package operations: 5 installs, 0 updates, 0 removals
- Installing certifi (2026.7.22)
- Installing charset-normalizer (3.5.1)
- Installing idna (3.20)
- Installing urllib3 (2.8.0)
- Installing requests (2.34.2)
Writing lock file
Um comando criou o ambiente virtual, escolheu a versão mais nova, instalou o requests com as dependências dele e gravou tudo no pyproject.toml e no poetry.lock:
1
2
3
dependencies = [
"requests (>=2.34.2,<3.0.0)"
]
O ^2.34.2 (caret) vira >=2.34.2,<3.0.0: aceita correções e versões menores, mas não a próxima maior, que pode quebrar a API. Você escolhe a restrição ao adicionar. Testamos estas:
| Comando | O que foi gravado no pyproject.toml
|
Significado |
|---|---|---|
poetry add requests |
requests (>=2.34.2,<3.0.0) |
Mais nova, até a próxima maior |
poetry add "rich@^13.7.0" |
rich (>=13.7.0,<14.0.0) |
Qualquer 13.x a partir de 13.7.0 |
poetry add "rich@~13.7.0" |
rich (>=13.7.0,<13.8.0) |
Só correções da 13.7 |
poetry add "pendulum>=3.0" |
pendulum (>=3.0) |
Sem teto (use com cuidado) |
poetry add "click==8.1.8" |
click (==8.1.8) |
Versão exata |
poetry add rich@latest |
rich (>=15.0.0,<16.0.0) |
Força a mais nova, mudando a restrição |
Dependências de desenvolvimento com --group dev
pytest, Ruff e mypy só servem para quem desenvolve. Coloque-as num grupo:
1
$ poetry add --group dev pytest
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Using version ^9.1.1 for pytest
Updating dependencies
Resolving dependencies...
Package operations: 8 installs, 0 updates, 0 removals
- Installing typing-extensions (4.16.0)
- Installing exceptiongroup (1.3.1)
- Installing iniconfig (2.3.0)
- Installing packaging (26.3)
- Installing pluggy (1.6.0)
- Installing pygments (2.21.0)
- Installing tomli (2.4.1)
- Installing pytest (9.1.1)
Writing lock file
O Poetry 2.5 grava o grupo na tabela padrão [dependency-groups] (PEP 735):
1
2
3
4
[dependency-groups]
dev = [
"pytest (>=9.1.1,<10.0.0)"
]
Projetos antigos usam [tool.poetry.group.dev.dependencies]; as duas sintaxes funcionam. O atalho poetry add -D pytest equivale a --group dev, e você pode criar quantos grupos quiser (poetry add --group docs mkdocs). Para escrever os testes em si, veja nosso guia de testes com pytest.
O poetry remove tira o pacote do pyproject.toml, do lock e do ambiente, com as dependências que só ele usava:
1
$ poetry remove rich
1
2
3
4
5
6
7
Package operations: 0 installs, 0 updates, 3 removals
- Removing markdown-it-py (4.2.0)
- Removing mdurl (0.1.2)
- Removing rich (15.0.0)
Writing lock file
Está curtindo esse conteúdo? ![]()
Que tal receber 30 dias de conteúdo direto na sua Caixa de Entrada?
O poetry.lock e o poetry install
O poetry.lock é o retrato exato do ambiente: versão, grupos e hashes de cada pacote. Ele começa assim:
1
2
3
4
5
6
7
8
9
# This file is automatically @generated by Poetry 2.5.1 and should not be changed by hand.
[[package]]
name = "certifi"
version = "2026.7.22"
description = "Python package for providing Mozilla's CA Bundle."
optional = false
python-versions = ">=3.7"
groups = ["main"]
A primeira linha avisa: não edite à mão. E a documentação manda commitar o poetry.lock com o pyproject.toml. Quem clonar ganha as mesmas versões com um comando:
1
2
3
$ git clone https://github.com/voce/meu-projeto.git
$ cd meu-projeto
$ poetry install
1
2
3
4
5
Installing dependencies from lock file
No dependencies to install or update
Installing the current project: meu-projeto (0.1.0)
(Num ambiente vazio, a saída lista cada pacote instalado.) A última linha mostra que o poetry install também instala o seu projeto em modo editável, para o import meu_projeto funcionar; --no-root evita isso.
poetry install vs poetry sync
A diferença entre os dois pega muita gente. Instalamos o six “por fora” (poetry run pip install six) e rodamos ambos:
1
2
3
4
5
6
7
8
9
10
11
$ poetry install
Installing dependencies from lock file
No dependencies to install or update
$ poetry sync
Installing dependencies from lock file
Package operations: 0 installs, 0 updates, 1 removal
- Removing six (1.17.0)
O install só adiciona e atualiza; o sync deixa o ambiente idêntico ao lock. Vale para grupos também: poetry install --without dev não desinstalou o pytest (testamos), já poetry sync --without dev removeu os 8 pacotes do grupo dev.
| Comando | O que faz |
|---|---|
poetry install |
Instala o que está no lock (cria o lock se não existir) |
poetry install --without dev |
Pula o grupo dev (não remove o que já está instalado) |
poetry install --only main |
Só as dependências principais |
poetry install --no-root |
Só as dependências, sem o seu projeto |
poetry sync |
Deixa o ambiente idêntico ao lock, removendo extras |
poetry lock |
Atualiza o lock a partir do pyproject.toml, sem instalar |
poetry check --lock |
Confere o pyproject.toml e se o lock está em dia |
Em produção e em Dockerfiles, use poetry sync --only main. Para o resto do caminho até o servidor, veja o guia de deploy de Django em produção.
Onde fica o ambiente virtual do Poetry
Por padrão o ambiente não fica no projeto, e sim numa pasta de cache, com nome formado por projeto, hash e versão do Python:
| Sistema | Pasta padrão dos ambientes |
|---|---|
| Linux | ~/.cache/pypoetry/virtualenvs |
| macOS | ~/Library/Caches/pypoetry/virtualenvs |
| Windows | C:\Users\<usuario>\AppData\Local\pypoetry\Cache\virtualenvs |
Para saber qual ambiente o projeto está usando:
1
$ poetry env info
1
2
3
4
5
6
7
8
9
10
11
12
13
Virtualenv
Python: 3.10.12
Implementation: CPython
Path: /home/voce/.cache/pypoetry/virtualenvs/meu-projeto-FsF8QyNg-py3.10
Executable: /home/voce/.cache/pypoetry/virtualenvs/meu-projeto-FsF8QyNg-py3.10/bin/python
Valid: True
Base
Platform: linux
OS: posix
Python: 3.10.12
Path: /usr
Executable: /usr/bin/python3.10
poetry env info --path mostra só o caminho (útil para configurar o VS Code ou o PyCharm).
Ambiente dentro do projeto com virtualenvs.in-project
Para ter a pasta .venv dentro do projeto (os editores a encontram sozinhos), configure com --local, que grava um poetry.toml:
1
2
$ poetry config virtualenvs.in-project true --local
$ cat poetry.toml
1
2
[virtualenvs]
in-project = true
A opção não move o ambiente que já existe. Remova o antigo e instale de novo:
1
2
3
$ poetry env list
$ poetry env remove python3
$ poetry install
1
2
3
4
meu-projeto-FsF8QyNg-py3.10 (Activated)
Deleted virtualenv: /home/voce/.cache/pypoetry/virtualenvs/meu-projeto-FsF8QyNg-py3.10
Creating virtualenv meu-projeto in /home/voce/meu-projeto/.venv
Installing dependencies from lock file
Sem --local, vale para a máquina toda. Coloque .venv no .gitignore (o poetry new não cria esse arquivo).
Escolhendo a versão do Python
O Poetry usa o Python que encontra no PATH. Para outra versão instalada, use poetry env use:
1
2
$ poetry env use python3.12
$ poetry run python --version
1
2
3
Creating virtualenv antigo-XkB8hwbg-py3.12 in /home/voce/.cache/pypoetry/virtualenvs
Using virtualenv: /home/voce/.cache/pypoetry/virtualenvs/antigo-XkB8hwbg-py3.12
Python 3.12.13
A versão precisa caber no requires-python. O poetry python install existe, mas ainda é experimental no 2.5.
poetry run e como ativar o ambiente
Vamos dar ao projeto um comando de verdade. Em src/meu_projeto/__init__.py:
1
2
3
4
5
6
7
8
9
10
11
12
13
import sys
import requests
def saudacao(nome: str) -> str:
return f"Olá, {nome}!"
def main() -> None:
print(saudacao("Pythonista"))
print(f"Python {sys.version_info.major}.{sys.version_info.minor}")
print(f"requests {requests.__version__}")
E no pyproject.toml, uma seção que cria o comando meu-projeto apontando para a função main:
1
2
[project.scripts]
meu-projeto = "meu_projeto:main"
Depois de mudar [project.scripts], rode poetry install de novo para o comando ser criado (sem isso, o Poetry responde Command not found: meu-projeto). Aí sim:
1
2
3
$ poetry install
$ poetry run meu-projeto
$ poetry run pytest -q
1
2
3
4
5
Olá, Pythonista!
Python 3.10
requests 2.34.2
. [100%]
1 passed in 0.05s
(O teste, em tests/test_saudacao.py, é assert saudacao("Ana") == "Olá, Ana!".) O poetry run executa qualquer comando no ambiente sem ativá-lo, e é o jeito mais seguro em scripts e no CI.
poetry shell não existe mais? Use poetry env activate
No Poetry 2.x, o velho poetry shell responde assim:
1
2
3
4
5
6
Looks like you're trying to use a Poetry command that is not available.
Since Poetry (2.0.0), the shell command is not installed by default. You can use,
- the new env activate command (recommended); or
- the shell plugin to install the shell command
O substituto é o poetry env activate. Ele não ativa nada sozinho: só imprime o comando de ativação.
1
$ poetry env activate
1
source /home/voce/meu-projeto/.venv/bin/activate
Para ativar de fato, execute a saída dele no seu shell, como mostra a documentação de ambientes:
1
2
3
4
5
6
7
8
# bash e zsh
$ eval $(poetry env activate)
# fish
$ eval (poetry env activate)
# Windows (PowerShell)
PS> Invoke-Expression (poetry env activate)
Com o ambiente ativo, python e pytest funcionam direto; para sair, deactivate. Quem faz questão do comando antigo instala o plugin com poetry self add poetry-plugin-shell (ou pipx inject poetry poetry-plugin-shell); testamos a versão 1.0.1 e o shell voltou ao poetry list.
Vendo e atualizando dependências
O poetry show --tree mostra quem depende de quem, algo que o pip freeze não entrega:
1
$ poetry show --tree
1
2
3
4
5
6
7
8
9
10
11
12
13
14
pytest 9.1.1 pytest: simple powerful testing with Python
├── colorama >=0.4
├── exceptiongroup >=1
│ └── typing-extensions >=4.6.0
├── iniconfig >=1.0.1
├── packaging >=22
├── pluggy >=1.5,<2
├── pygments >=2.7.2
└── tomli >=1
requests 2.34.2 Python HTTP for Humans.
├── certifi >=2023.5.7
├── charset-normalizer >=2,<4
├── idna >=2.5,<4
└── urllib3 >=1.26,<3
poetry show --top-level lista só o que você pediu. Para atualizar, veja o que está velho (travamos o rich em ~13.7.0 para ter o que atualizar):
1
$ poetry show --outdated
1
rich 13.7.1 15.0.0 Render rich text, tables, progress bars, syntax highlight...
O poetry update respeita as restrições do pyproject.toml. Como ~13.7.0 não aceita a 15, nada muda:
1
$ poetry update rich
1
2
3
4
Updating dependencies
Resolving dependencies...
No dependencies to install or update
Para pular de versão maior, mude a restrição com poetry add:
1
$ poetry add rich@latest
1
2
3
4
5
6
7
8
9
10
Using version ^15.0.0 for rich
Updating dependencies
Resolving dependencies...
Package operations: 0 installs, 1 update, 0 removals
- Updating rich (13.7.1 -> 15.0.0)
Writing lock file
Resumindo: poetry update atualiza dentro das faixas, --dry-run só mostra o que faria e poetry add pacote@latest muda a faixa. Rode os testes antes de commitar o lock novo.
Publicando pacotes com poetry build e poetry publish
Aqui o Poetry brilha. Primeiro ajuste a versão (ele entende patch, minor e major):
1
2
$ poetry version patch
$ poetry build
1
2
3
4
5
6
7
8
Bumping version from 0.1.0 to 0.1.1
Building meu-projeto (0.1.1)
Building sdist
- Building sdist
- Built meu_projeto-0.1.1.tar.gz
Building wheel
- Building wheel
- Built meu_projeto-0.1.1-py3-none-any.whl
A dist/ tem o wheel (.whl, pronto para instalar) e o sdist (.tar.gz, código-fonte). poetry build --clean apaga a dist/ antes, para não publicar versões velhas.
Para publicar, crie um token de API na sua conta do PyPI e configure-o uma vez:
1
2
$ poetry config pypi-token.pypi pypi-SEU-TOKEN-AQUI
$ poetry publish
Antes, treine no TestPyPI, um servidor de testes com cadastro e token próprios:
1
2
3
$ poetry config repositories.testpypi https://test.pypi.org/legacy/
$ poetry config pypi-token.testpypi pypi-SEU-TOKEN-DE-TESTE
$ poetry publish -r testpypi --dry-run
1
2
3
Publishing meu-projeto (0.1.1) to testpypi
- Uploading meu_projeto-0.1.1.tar.gz 100%
- Uploading meu_projeto-0.1.1-py3-none-any.whl 100%
O --dry-run simula tudo sem enviar (foi o que executamos). poetry publish --build constrói e publica de uma vez. Uma versão publicada não pode ser substituída: se errou, poetry version patch e publique de novo.
Exportando requirements.txt (plugin export)
Algumas plataformas de deploy e alguns Dockerfiles só entendem requirements.txt. No Poetry 2.x o comando de exportação saiu do núcleo:
1
2
$ poetry export -f requirements.txt
The requested command export does not exist.
Ele agora vem do plugin oficial poetry-plugin-export, que você instala no ambiente do próprio Poetry (não no projeto):
1
2
3
4
$ poetry self add poetry-plugin-export
# se instalou pelo pipx: pipx inject poetry poetry-plugin-export
$ poetry export -f requirements.txt --output requirements.txt --without-hashes
$ cat requirements.txt
1
2
3
4
5
6
7
8
9
certifi==2026.7.22 ; python_version >= "3.10"
charset-normalizer==3.5.1 ; python_version >= "3.10"
idna==3.20 ; python_version >= "3.10"
markdown-it-py==4.2.0 ; python_version >= "3.10"
mdurl==0.1.2 ; python_version >= "3.10"
pygments==2.21.0 ; python_version >= "3.10"
requests==2.34.2 ; python_version >= "3.10"
rich==15.0.0 ; python_version >= "3.10"
urllib3==2.8.0 ; python_version >= "3.10"
Usamos o plugin 1.10.1. Por padrão ele exporta só as dependências principais, com hashes (tire o --without-hashes para o pip conferir cada download). Para incluir o grupo de desenvolvimento, use --with dev.
Não importa se o projeto usa Poetry, Pipenv ou uv: o que muda o jogo é entender ambientes virtuais e dependências de verdade - isso a Jornada Python ensina desde o início:
Pipenv e Pipfile: o que são e comandos equivalentes
Antes do Poetry se popularizar, o Pipenv era a resposta mais comum para “pip + venv + lockfile”. Ele ainda é mantido (usamos a versão 2026.8.0) e aparece em muitas aplicações criadas entre 2018 e 2021. No lugar do pyproject.toml ele usa o Pipfile (o que você pediu) e o Pipfile.lock (JSON com versões exatas e hashes). Depois de pipenv install requests e pipenv install --dev pytest, o Pipfile ficou assim:
1
2
3
4
5
6
7
8
9
10
11
12
13
[[source]]
url = "https://pypi.org/simple"
verify_ssl = true
name = "pypi"
[packages]
requests = "*"
[dev-packages]
pytest = "*"
[requires]
python_version = "3.10"
Repare no "*": o Pipenv não grava faixa de versão, e só o Pipfile.lock garante a reprodutibilidade. No Linux os ambientes ficam em ~/.local/share/virtualenvs (PIPENV_VENV_IN_PROJECT=1 usa um .venv no projeto). A documentação do Pipenv recomenda instalá-lo num venv próprio ou com pipx install pipenv, e desaconselha o antigo pip install --user pipenv.
Esta tabela traduz os comandos (os de Pipenv foram todos executados):
| Tarefa | Pipenv | Poetry |
|---|---|---|
| Adicionar dependência | pipenv install requests |
poetry add requests |
| Dependência de desenvolvimento | pipenv install --dev pytest |
poetry add --group dev pytest |
| Instalar tudo do lock | pipenv sync |
poetry install ou poetry sync
|
| Falhar se o lock estiver velho (CI) | pipenv install --deploy |
poetry check --lock e depois poetry sync
|
| Rodar comando no ambiente | pipenv run python app.py |
poetry run python app.py |
| Ativar o ambiente | pipenv shell |
eval $(poetry env activate) |
| Árvore de dependências | pipenv graph |
poetry show --tree |
| Atualizar | pipenv update |
poetry update |
| Gerar requirements.txt | pipenv requirements |
poetry export (plugin) |
| Caminho do ambiente | pipenv --venv |
poetry env info --path |
| Remover dependência | pipenv uninstall requests |
poetry remove requests |
O Pipenv também acusa lockfile desatualizado. Editamos o Pipfile à mão e rodamos pipenv install --deploy:
1
2
3
4
5
Your Pipfile.lock
(12e0a7b6163a40c904f82c68027f806352f02f364b39e14a9ca7c1fbc1c73450) is out of
date. Expected:
(be5bacd2afbefea18530598eb0ce4f1fbaf25623ee4a0a966de11c745a56e4b7).
ERROR:: Aborting deploy
A correção é pipenv lock e commitar o lock novo. O Pipenv não constrói nem publica pacotes.
pip + venv vs Pipenv vs Poetry vs uv: qual usar?
As quatro isolam dependências; muda o que cada uma faz sozinha. Versões de setembro de 2026:
| Critério | pip + venv | Pipenv | Poetry | uv |
|---|---|---|---|---|
| Já vem com o Python | Sim | Não | Não | Não |
| Arquivo de dependências | requirements.txt |
Pipfile |
pyproject.toml |
pyproject.toml |
| Lockfile com versões exatas | Não nativo | Pipfile.lock |
poetry.lock |
uv.lock |
Formato padrão [project]
|
Não se aplica | Não | Sim, desde o 2.0 | Sim |
| Cria o ambiente sozinho | Não | Sim | Sim | Sim |
| Instala versões do Python | Não | Via pyenv ou asdf | Experimental | Sim |
| Build e publicação no PyPI | Com build e twine
|
Não |
poetry build e poetry publish
|
uv build e uv publish
|
| Plugins | Não se aplica | Não | Sim (export, shell e outros) | Não |
| Velocidade | Referência | Mais lento | Mais rápido que o pip | Muito mais rápido |
| Melhor para | Aprender, scripts, servidores antigos | Projetos que já usam Pipenv | Projetos que já usam Poetry e bibliotecas publicadas | Projetos novos e CI |
A velocidade vem da medição do post sobre o uv (cache preenchido: Pipenv cerca de 11,5 s, pip 8,5 s, Poetry 2,4 s, uv 0,2 s).
Nossa recomendação honesta:
- Projeto novo: comece com o uv. Veja o guia do uv, o gerenciador de pacotes Python mais rápido.
-
Projeto que já usa Poetry: continue com ele. É mantido e estável, e o formato
[project]facilita uma eventual migração. -
Projeto com Pipenv: funciona, mas é o mais lento e não empacota. Se for migrar, o destino natural é o uv (o post do uv mostra o
migrate-to-uv). -
Está aprendendo: domine
python -m venvepip installprimeiro; é o que cai em prova e roda em qualquer servidor.
Erros comuns
Os erros mais frequentes no Poetry 2.x, com a mensagem real.
poetry shell não encontrado no Poetry 2.x
1
$ poetry shell
1
2
3
4
5
6
Looks like you're trying to use a Poetry command that is not available.
Since Poetry (2.0.0), the shell command is not installed by default. You can use,
- the new env activate command (recommended); or
- the shell plugin to install the shell command
Correção: use eval $(poetry env activate) (bash e zsh), Invoke-Expression (poetry env activate) (PowerShell) ou simplesmente poetry run. Se quiser o comando antigo de volta, poetry self add poetry-plugin-shell.
Lockfile desatualizado depois de editar o pyproject.toml à mão
Alguém adicionou "rich (>=14.0.0)" direto no dependencies e fez commit sem atualizar o lock. Quem clona e roda poetry install recebe:
1
$ poetry install
1
2
3
Installing dependencies from lock file
pyproject.toml changed significantly since poetry.lock was last generated. Run `poetry lock` to fix the lock file.
Correção: poetry lock, depois poetry install, e commite o lock novo. Prefira poetry add e poetry remove, que atualizam os dois arquivos. No CI, poetry check --lock pega isso antes.
Conflito de versões no resolver
O projeto aceita Python 3.10 (requires-python = ">=3.10") e você tenta adicionar o Django mais novo:
1
$ poetry add django
1
2
3
4
5
6
7
8
9
10
11
Using version ^6.1.1 for django
Updating dependencies
Resolving dependencies...
The current project's supported Python range (>=3.10) is not compatible with some of the required packages Python requirement:
- django requires Python >=3.12, so it will not be installable for Python >=3.10,<3.12
Because no versions of django match >6.1.1,<7.0.0
and django (6.1.1) requires Python >=3.12, django is forbidden.
So, because meu-projeto depends on django (^6.1.1), version solving failed.
O Poetry resolve para todas as versões do Python que o projeto aceita, não só a instalada. Correção: suba o requires-python para ">=3.12" ou fixe uma versão compatível, como poetry add "django@^5.2" (resolveu para o 5.2.17). Conflito entre pacotes gera mensagem parecida: poetry add "urllib3@<1.26" termina em version solving failed., porque o requests exige urllib3 >=1.26.
No file/folder found for package depois do poetry init
Você rodou poetry init numa pasta com um app.py solto (sem pacote) e depois poetry install:
1
2
3
4
5
Installing the current project: legado (0.1.0)
Error: The current project could not be installed: No file/folder found for package legado
If you do not want to install the current project use --no-root.
If you want to use Poetry only for dependency management but not for packaging, you can disable package mode by setting package-mode = false in your pyproject.toml file.
As dependências foram instaladas; falhou instalar o seu projeto, porque não existe a pasta legado/. Para projetos que não vão para o PyPI, adicione ao pyproject.toml:
1
2
[tool.poetry]
package-mode = false
Aí o poetry install passou e o poetry check respondeu All set!.
poetry export não existe
1
The requested command export does not exist.
Correção: desde o 2.0 o export é um plugin. Rode poetry self add poetry-plugin-export (ou pipx inject poetry poetry-plugin-export).
Exercícios resolvidos
Tente responder antes de abrir a solução. Todos os comandos foram executados com o Poetry 2.5.1. Quer praticar Python em si? Veja nossa lista de exercícios de Python resolvidos.
Exercício 1. Crie um projeto chamado calc com o Poetry e adicione a biblioteca requests. Qual linha aparece em dependencies no pyproject.toml?
Ver solução
1
2
3
4
$ poetry new calc
$ cd calc
$ poetry add requests
$ grep -A2 '^dependencies' pyproject.toml
Saída:
1
2
3
dependencies = [
"requests (>=2.34.2,<3.0.0)"
]
A versão mais nova (2.34.2) com faixa até a próxima maior, no formato de [project].
Exercício 2. No projeto calc, adicione o pytest só para desenvolvimento. Depois escreva o comando que deixa o ambiente apenas com as dependências de produção, removendo o pytest se ele já estiver instalado.
Ver solução
1
2
$ poetry add --group dev pytest
$ poetry sync --without dev
Saída do segundo comando:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Installing dependencies from lock file
Package operations: 0 installs, 0 updates, 8 removals
- Removing exceptiongroup (1.3.1)
- Removing iniconfig (2.3.0)
- Removing packaging (26.3)
- Removing pluggy (1.6.0)
- Removing pygments (2.21.0)
- Removing pytest (9.1.1)
- Removing tomli (2.4.1)
- Removing typing-extensions (4.16.0)
Installing the current project: calc (0.1.0)
poetry install --without dev não serviria: ele pula o grupo, mas não remove o que já está instalado.
Exercício 3. Você quer descobrir por que o pacote urllib3 está no seu ambiente, se nunca o adicionou. Qual comando responde?
Ver solução
1
$ poetry show --why --tree urllib3
Saída:
1
2
requests 2.34.2 Python HTTP for Humans.
└── urllib3 >=1.26,<3
É uma dependência indireta do requests. Sem --tree, o comando falha com --why cannot be used without --tree when displaying a single package.
Exercício 4. Qual a diferença entre o que poetry add "rich@^13.7.0" e poetry add "rich@~13.7.0" gravam no pyproject.toml?
Ver solução
1
2
poetry add "rich@^13.7.0" -> "rich (>=13.7.0,<14.0.0)"
poetry add "rich@~13.7.0" -> "rich (>=13.7.0,<13.8.0)"
O ^ (caret) aceita qualquer 13.x a partir de 13.7.0; o ~ (til) aceita só correções da 13.7. Por isso, no nosso teste, ^13.7.0 resolveu para o rich 13.9.4 e ~13.7.0 para o 13.7.1.
Exercício 5. Você tem uma pasta com bot.py e quer usar o Poetry só para gerenciar as dependências, sem transformar o projeto em pacote. Que configuração evita o erro No file/folder found for package no poetry install?
Ver solução
1
2
[tool.poetry]
package-mode = false
Saída do poetry install depois da mudança:
1
2
3
Installing dependencies from lock file
No dependencies to install or update
O Poetry passa a instalar só as dependências. poetry install --no-root também resolve, mas precisa ser lembrado toda vez.
Exercício 6. Traduza para Poetry este fluxo de um projeto Pipenv: pipenv install requests, pipenv install --dev pytest, pipenv run python app.py e pipenv requirements > requirements.txt.
Ver solução
1
2
3
4
5
$ poetry add requests
$ poetry add --group dev pytest
$ poetry run python app.py
$ poetry self add poetry-plugin-export # uma vez só
$ poetry export --without-hashes -o requirements.txt
A diferença é o export, que no Poetry 2.x depende do plugin. As saídas estão nas seções anteriores.
Exercício 7 (estilo prova). No Poetry 2.x, qual comando imprime o comando de ativação do ambiente virtual do projeto?
a) poetry shell
b) poetry env activate
c) poetry activate
d) poetry run activate
Ver solução
Resposta: b.
1
$ poetry env activate
Saída: source /home/voce/meu-projeto/.venv/bin/activate
A a) só existe no 2.x com o plugin poetry-plugin-shell; c) e d) não existem. Para ativar no bash, eval $(poetry env activate).
Exercício 8 (estilo prova). Numa aplicação gerenciada pelo Poetry, quais arquivos devem ir para o controle de versão (Git)?
a) Só o pyproject.toml
b) O pyproject.toml e o poetry.lock
c) O pyproject.toml, o poetry.lock e a pasta .venv
d) Só o poetry.lock
Ver solução
Resposta: b.
O pyproject.toml declara as dependências e o poetry.lock guarda as versões exatas. A .venv (c) é gerada e depende da máquina; sem o pyproject.toml (d), o Poetry nem reconhece o projeto.
Conclusão
Você viu o Poetry 2.x de ponta a ponta: instalação isolada, new e init, o pyproject.toml com [project], add, lock, install e sync, o ambiente virtual e o poetry env activate, atualização, publicação e exportação, além do Pipenv e da comparação com pip e uv.
Se o projeto que caiu no seu colo usa Poetry, agora você sabe ler cada arquivo e cada erro. Se vai começar do zero, olhe o uv antes de decidir. E se quer transformar isso em hábito, com projetos guiados do básico ao Django, conheça nosso curso de Python completo.
Nos vemos no próximo post!
Perguntas frequentes
O que é o Poetry no Python?
O Poetry é uma ferramenta de gerenciamento de dependências e de empacotamento para projetos Python. Ele registra as bibliotecas do projeto no pyproject.toml, trava as versões exatas de tudo (inclusive dependências indiretas) no poetry.lock, cria e gerencia o ambiente virtual sozinho e ainda gera e publica pacotes no PyPI com poetry build e poetry publish.
Como instalar o Poetry?
A documentação oficial recomenda o pipx: pipx install poetry. A alternativa é o instalador oficial, um script em https://install.python-poetry.org que você baixa com curl (Linux, macOS e WSL) ou Invoke-WebRequest (PowerShell) e executa com o Python. Evite pip install poetry no Python do sistema: o Poetry deve ficar isolado das dependências dos seus projetos. O Poetry 2.x exige Python 3.10 ou mais novo.
O comando poetry shell não funciona mais. O que usar no lugar?
Desde o Poetry 2.0 o poetry shell não vem instalado; ele virou o plugin poetry-plugin-shell. O substituto recomendado é o poetry env activate, que imprime o comando de ativação do ambiente. No bash ou zsh rode eval $(poetry env activate); no PowerShell, Invoke-Expression (poetry env activate). Para rodar um comando sem ativar nada, use poetry run, como em poetry run pytest.
Devo commitar o poetry.lock no Git?
Sim. O poetry.lock guarda a versão exata e os hashes de cada pacote instalado, e a documentação do Poetry diz que commitar esse arquivo é importante para que todo mundo que instalar o projeto use exatamente as mesmas versões. Ele vai para o Git junto com o pyproject.toml. A pasta do ambiente virtual (como .venv) não vai. Nunca edite o poetry.lock à mão: use poetry add, poetry remove ou poetry lock.
Qual a diferença entre poetry install e poetry sync?
Os dois instalam as versões do poetry.lock. A diferença é o que sobra: o poetry install só adiciona e atualiza pacotes, deixando no ambiente qualquer coisa instalada por fora. O poetry sync deixa o ambiente idêntico ao lockfile e remove o que não estiver nele. Por isso poetry sync --without dev é o jeito certo de tirar as dependências de desenvolvimento de um ambiente que já as tinha. O antigo poetry install --sync foi descontinuado em favor do poetry sync.
Qual a diferença entre Poetry e Pipenv?
Os dois criam ambientes virtuais e travam versões num lockfile. O Pipenv usa os arquivos Pipfile e Pipfile.lock e foca em aplicações. O Poetry usa o pyproject.toml padrão do Python e o poetry.lock, e também constrói e publica pacotes no PyPI, coisa que o Pipenv não faz. Os comandos se parecem: pipenv install requests equivale a poetry add requests, e pipenv run equivale a poetry run.
Poetry ou uv: qual usar em 2026?
Para projetos novos, o uv costuma ser a escolha mais simples: é bem mais rápido, instala versões do Python e roda ferramentas com uvx. O Poetry continua sólido e mantido, com um sistema de plugins maduro e fluxo consolidado de publicação. Se o seu projeto já usa Poetry e funciona bem, não há urgência em migrar. Os dois usam o pyproject.toml no formato [project] da PEP 621.
No Poetry 2.x, qual comando adiciona o pytest apenas como dependência de desenvolvimento?
É o poetry add --group dev pytest (o atalho poetry add -D pytest faz o mesmo). O pacote vai para o grupo dev, que o Poetry 2.5 grava na tabela [dependency-groups] do pyproject.toml, fora das dependências principais em [project]. Assim, quem instalar o seu pacote pelo PyPI não baixa o pytest, e você pode pular o grupo com poetry install --without dev.
"Porque o Senhor dá a sabedoria, e da sua boca vem a inteligência e o entendimento" Pv 2:6