poetry review
Poetry 2.4.1 is a command-line owner for a Python project's dependency constraints, lock file, virtual environment, build artifacts, and package publication. It resolves `pyproject.toml` into `poetry.lock`, installs selected dependency groups, runs commands in the chosen environment, and builds through poetry-core. Current projects can keep publishable metadata in the standard `[project]` table and use `[tool.poetry]` only for Poetry-specific settings. Version 2.4 introduced a minimum release age policy for dependency solving. Patch 2.4.1 restores installer 0.7.0 compatibility and fixes `poetry update <name>` when the named package is transitive.
Poetry 2.4.1 installed in 1.5 seconds but brought 46 packages and 56 MB into our sandbox, with 0 audit findings. Adopt it when one established CLI should own locking, environments, builds, and publishing; compare uv first if resolver and install speed dominate the decision.
We installed it
| Install | ✓ · 1.5s | 46 packages on disk · 56 MB |
| Import | ✓ | import poetry in 0.02s · pure Python · py.typed · requires Python >=3.10,<4.0 |
| Known vulns | 0 | (pip-audit) |
Answers from our run
Does poetry install cleanly?
Yes. In a fresh container with an empty cache, pip install poetry finished in 2 seconds, leaving 46 packages and 56 MB on disk. pip-audit reported no known vulnerabilities.
What does poetry need to run?
Python >=3.10,<4.0, and nothing compiled: it is pure Python. In our run import poetry succeeded in 0.02s, and the package ships py.typed for type checkers.
poetry or uv: which should you use?
uv: Choose it when fast resolution, Python installation, and pip-compatible commands outweigh Poetry's mature plugin workflow. Poetry 2.4.1 installed in 1.5 seconds but brought 46 packages and 56 MB into our sandbox, with 0 audit findings.
When should you not use poetry?
Dependency resolution speed is the main pain. Benchmark uv against the real lock graph before adding Poetry's 46-package tool environment.
Use it if
- One committed lock file should reproduce a Python application across laptops, CI, and deployment images.
- Runtime, test, documentation, and tooling dependencies need selectable named groups.
- The team wants the same CLI for environment creation, dependency updates, wheel builds, and registry publishing.
- Private indexes and Poetry plugins are already part of the organization's packaging workflow.
- Dependency resolution speed is the main pain. Benchmark uv against the real lock graph before adding Poetry's 46-package tool environment.
- You only publish a library and do not need Poetry to manage environments or lock application dependencies. Hatch may be a narrower packaging fit.
- The build needs C, Cython, or Rust compilation that poetry-core cannot express. Select a backend made for that native build.
- Automation still assumes Poetry 1 commands. In version 2, shell and export live in plugins, and metadata guidance moved toward PEP 621.
- CI cannot provide private-index credentials through an approved secret and keyring setup. Authentication is required before resolution can reach that source.
Setup reality
We installed Poetry 2.4.1 in a clean Python 3.12 Bookworm container in 1.5 seconds. It left 46 packages using 56 MB, while import poetry completed in 0.02 seconds. pip-audit reported 0 known vulnerabilities. The pure-Python package declares 22 direct dependencies, requires Python >=3.10 and <4.0, and includes py.typed. Its measured PyPI metadata did not declare a license.
Install Poetry as a standalone tool with pipx, the official installer, or a pinned tool image. Putting it inside the application environment mixes Poetry's resolver, VCS, keyring, and virtualenv dependencies with production packages. The interpreter running Poetry can differ from the Python range declared for the project. Pin Poetry itself in CI so every runner interprets the lock file with the same release.
Choose the environment location deliberately. The default cache keeps it outside the checkout; virtualenvs.in-project true creates .venv, which many editors discover easily. poetry install adds what is missing but can leave unrelated packages present. poetry sync removes packages outside the selected lock groups. Version 2's poetry env activate prints shell code, and the old poetry shell requires a plugin.
Private repositories need a source priority plus credentials. In headless CI, inject POETRY_HTTP_BASIC_* values from the secret manager and choose a non-interactive keyring policy. For Docker caching, install from pyproject.toml and poetry.lock with --no-root before copying application source. Run poetry check --lock in CI so edited constraints cannot travel with an outdated lock file.
Patterns
Create or initialize project metadata create-project
poetry new service --src
cd existing-project
poetry init
poetry check --lock`poetry init` writes metadata but does not install packages. `poetry check --lock` fails when pyproject.toml and poetry.lock disagree.
Add runtime and development packages add-dependency
poetry add 'httpx>=0.28,<0.29'
poetry add --group dev pytest ruff
poetry add 'uvicorn[standard]'add changes project metadata, resolves the graph, updates the lock, and installs the result. Review the chosen constraint in the diff.
Install only selected lock groups install-groups
poetry install --only main --no-root
poetry install --with docs --without dev
poetry sync --only mainsync removes packages outside the selected lock set; install can leave unrelated packages already present in the environment.
Control how locked versions move update-lock
poetry lock
poetry lock --regenerate
poetry update requests
poetry updateIn Poetry 2, lock preserves compatible existing pins by default. `--regenerate` resolves without using them as a starting point.
Choose the project interpreter select-python
poetry env use 3.12
poetry env info --path
poetry run python -V
poetry run pytest -qPoetry's own Python >=3.10 requirement is separate from the interpreter range declared by the project.
Put the environment in .venv use-in-project-venv
poetry config virtualenvs.in-project true --local
poetry install
poetry env info --pathLocal config changes where Poetry creates the environment. Ignore `.venv` in version control.
Use standard project metadata declare-pep621
[project]
name = "my-service"
version = "1.0.0"
requires-python = ">=3.10"
dependencies = ["httpx>=0.28,<0.29"]
[build-system]
requires = ["poetry-core>=2.0,<3.0"]
build-backend = "poetry.core.masonry.api"Keep publishable fields in `[project]`. Use `[tool.poetry]` only where Poetry needs extra configuration.
Add a supplemental package source configure-private-index
poetry source add --priority=supplemental internal https://packages.example.com/simple/
export POETRY_HTTP_BASIC_INTERNAL_USERNAME=ci
export POETRY_HTTP_BASIC_INTERNAL_PASSWORD="$PACKAGE_TOKEN"The environment suffix comes from the uppercased source name. Supply the password through CI secrets, never pyproject.toml.
Build a reusable dependency layer cache-docker-install
COPY pyproject.toml poetry.lock ./
RUN poetry install --only main --no-root --no-directory
COPY src/ ./src/
RUN poetry install --only mainCopy lock metadata before source code so ordinary code changes do not invalidate the dependency layer.
Find why a package is installed inspect-transitive
poetry show --tree --why urllib3
poetry show --outdated
poetry show --only main --top-level`--why` identifies the parent requirement that holds a transitive version in the graph.
Build wheel and source distribution build-package
poetry check --lock
poetry build
python -m zipfile -l dist/*.whlInspect the wheel before publishing, especially when source layout or explicit package inclusion is configured.
Restore shell and export commands install-plugins
poetry self add poetry-plugin-shell
poetry self add poetry-plugin-export
poetry self show plugins
poetry export -f requirements.txt -o requirements.txt`self add` changes Poetry's tool environment, not the project's virtualenv. Pin plugin versions in reproducible CI images.
Alternatives
| Package | Registry | Pick it when |
|---|---|---|
| uv | PyPI | Choose it when fast resolution, Python installation, and pip-compatible commands outweigh Poetry's mature plugin workflow. |
| pipenv | PyPI | Choose it when the team already standardizes on Pipfile and Pipfile.lock for application environments. |
| hatch | PyPI | Choose it for library packaging, test matrices, and environment scripts without making Poetry's resolver the center. |
More cli & tooling guides
commander · chalk · typescript · esbuild · yargs · click · the whole shelf →
How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.

