The go-to resource for upgrading Python, Django, Flask, and your dependencies.

poetry add vs pip install: When Lock Files Prevent Production Dependency Conflicts


When we manage Python dependencies, we aim for reliable production deployments. pip install can lead to version conflicts — what some call “dependency hell” — where transitive dependencies cause builds to fail in CI/CD pipelines or staging environments. Tools like Poetry offer a declarative approach with pyproject.toml for declarations and poetry.lock for pinning resolved versions, helping to create more reproducible environments.

In this guide, we’ll compare poetry add and pip install, examine how lock files help manage dependencies, and discuss steps for using Poetry along with other tools.

What is Dependency Hell and Why Does It Plague Production?

You might encounter dependency hell when transitive dependencies conflict. For example:

  • Package A requires numpy >=1.20
  • Package B requires numpy <1.22

pip install resolves at install time based on the current environment, but:

# On dev machine (numpy 1.21 works)
$ pip install package-a package-b

# In production Docker build (different resolver order)
$ pip install package-b package-a  # Fails: numpy conflict

This can lead to failed deploys and debugging time. Lock files address this by capturing the exact resolved versions and hashes used.

How Pip Install Works

When you run pip install, it installs packages directly into your environment:

  1. pip install requests → Adds to site-packages, updates pip freeze.
  2. Lock: pip freeze > requirements.txt (unpinned versions unless manual).
  3. Install: pip install -r requirements.txt.

Considerations:

  • requirements.txt typically uses loose constraints (e.g., requests>=2.25), which can allow version drift over time.
  • Without hashes, there’s risk from supply chain attacks, though tools like pip-tools can add them.
  • Resolver behavior can vary across Python versions or OS.

This leads to the common “It works on my machine” issue in production.

Poetry Add: Declarative with Lock Files

Poetry uses pyproject.toml for dependency declarations and poetry.lock to record the resolved versions:

  1. poetry add requests → Updates [tool.poetry.dependencies] and poetry.lock.
  2. poetry.lock pins exact versions + hashes (SHA256).
  3. Install: poetry install → Reproducible, ignores PyPI changes.

Example pyproject.toml:

[tool.poetry.dependencies]
python = "^3.11"
requests = "^2.31"
numpy = "^1.24"

Snippet from poetry.lock:

[[package]]
name = "requests"
version = "2.31.0"
source = {registry = "https://pypi.org/simple/"}
dependencies = [
  {name = "charset-normalizer", version = "3.3.2"},
]
files = [
  {file = "requests-2.31.0.tar.gz", hash = "sha256:..."},
]

Poetry offers:

  • Reproducible installs via poetry install.
  • Content-addressed hashes for verification.
  • Separate groups for dev and prod dependencies (e.g., poetry add --group dev pytest).
  • Lock file that you commit to version control.

Comparing Poetry and Pip

AspectPip with requirements.txtPoetry with pyproject.toml/poetry.lock
WorkflowImperative (install modifies env)Declarative (lock resolved versions)
Lock FileLoose constraints (needs pip-compile for pins/hashes)Exact versions + hashes
ReproducibilityVariable; better with pinned reqsHigh, via committed lock
Prod SafetyRelies on resolver; hashes optionalHashes included; verifies integrity
Conflict ResolutionAt install timeAt lock time

Example Comparison:

# Pip
$ echo "requests>=2.31 numpy>=1.24" > requirements.txt
$ pip install -r requirements.txt

# Poetry
$ poetry add requests numpy
$ poetry install

Both can work locally, but reproducibility depends on pinning in pip case.

Real-World Production Conflict: How Poetry Fixes It

Consider this scenario: an ML app with tensorflow (needs old numpy) and pandas (needs new).

With pip, builds fail sporadically.

With Poetry:

$ poetry init
$ poetry add tensorflow pandas  # Resolves compatible versions
$ git add pyproject.toml poetry.lock
# Team/CI: poetry install → Same env

Dockerfile:

COPY pyproject.toml poetry.lock ./
RUN pip install poetry && poetry install --no-dev --no-interaction

Conflicts are resolved at lock time, reducing surprises.

Other Approaches to Dependency Locking

While Poetry provides a full-featured solution, other tools address similar concerns:

Pip-tools (pip-compile):

  • Generates pinned requirements.txt from loose requirements.in.
  • Adds hashes for security.
  • Trade-off: Separate lock step; integrates with existing pip workflows.

uv:

  • Fast resolver and installer.
  • uv pip sync for reproducible envs from lockfiles.
  • Trade-off: Newer tool; lighter than full Poetry but less mature ecosystem.

Choose based on your needs: Poetry for integrated pyproject.toml management, pip-tools for minimal changes, uv for speed.

Migrating from Pip to Poetry

  1. Init: $ poetry init (interactive pyproject.toml).
  2. Add from reqs: $ poetry add $(grep -v '^#' requirements.txt | cut -d= -f1).
  3. Lock: $ poetry lock.
  4. Remove pip-tools: Delete requirements.txt, use $ poetry export -f requirements.txt --output requirements.txt for Docker if needed.
  5. CI/CD: $ poetry install.
  6. Virtualenvs: $ poetry shell or $ poetry run python.

Note: You can configure Poetry to create .venv in your project root with $ poetry config virtualenvs.in-project true.

Best Practices for Lock Files in Production

  • Commit poetry.lock (always).
  • $ poetry lock --no-update for reproducible locks.
  • Use dependency groups: prod/dev/test.
  • Audit: $ poetry check, $ poetry show --tree.
  • Docker multi-stage: Install prod deps only.
  • GitHub Actions: Cache .venv.

Conclusion

Lock files help manage dependencies reproducibly across tools like pip-compile, Poetry, and uv. We encourage you to evaluate options based on your project’s needs and workflow for more reliable deployments.

<RelatedLinks {relatedLinks} />

Sponsored by Durable Programming

Need help maintaining or upgrading your Python application? Durable Programming specializes in keeping Python apps secure, performant, and up-to-date.

Hire Durable Programming