Poetry no Python: gerencie dependências, ambientes virtuais e publique pacotes

Cansado de programar?

Conheça a melhor e mais completa formação de Python e Django e sinta-se um programador verdadeiramente competente. Além de Python e Django, você também vai aprender Banco de Dados, SQL, HTML, CSS, Javascript, Bootstrap e muito mais!

Quero aprender Python e Django de Verdade! Quero aprender!
Suporte

Tire suas dúvidas diretamente com o professor

Projetos práticos

Projetos práticos voltados para o mercado de trabalho

Prática profissional

Formação moderna com foco na prática profissional

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.lock vão para o Git; o ambiente virtual não.
  • poetry add --group dev pytest separa as ferramentas de desenvolvimento.
  • No Poetry 2.x, poetry shell virou plugin: use eval $(poetry env activate) ou poetry run.
  • poetry build e poetry publish geram 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! :rocket:

Vá Direto ao Assunto…

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 pelo poetry-core, o que permite instalar com pip 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? :thumbsup:

Que tal receber 30 dias de conteúdo direto na sua Caixa de Entrada?

Sua assinatura não pôde ser validada.
Você fez sua assinatura com sucesso.

Assine as PyDicas e receba 30 dias do melhor conteúdo Python na sua Caixa de Entrada: direto e sem enrolação!

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 venv e pip install primeiro; é 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.

Começe agora sua Jornada na Programação!

Não deixe para amanhã o sucesso que você pode começar a construir hoje!

#newsletter Olá :wave: Curtiu o artigo? Então faça parte da nossa Newsletter! Privacidade Não se preocupe, respeitamos sua privacidade. Você pode se descadastrar a qualquer momento.