| name | package-management |
| description | Guidance for Python package management, dependency resolution, virtual environments, and lockfiles.
USE FOR: installing packages, managing dependencies, choosing between pip/uv/poetry/pdm/conda, virtual environment setup, lockfile strategies, private package indexes, pipx for CLI tools
DO NOT USE FOR: configuring pyproject.toml or build backends (use project-system), building CLI applications (use cli)
|
| license | MIT |
| metadata | {"displayName":"Python Package Management","author":"Tyler-R-Kendrick","version":"1.0.0","tags":["python","pip","uv","poetry","pdm","conda","pipx","virtualenv","dependencies"]} |
| compatibility | claude, copilot, cursor |
| references | [{"title":"pip Documentation","url":"https://pip.pypa.io/en/stable/"},{"title":"uv Documentation","url":"https://docs.astral.sh/uv/"},{"title":"Poetry Documentation","url":"https://python-poetry.org/"},{"title":"Python Packaging User Guide","url":"https://packaging.python.org/en/latest/"}] |
Python Package Management
Overview
Python package management has evolved significantly. While pip remains the foundational tool, newer tools like uv, poetry, and pdm offer integrated workflows with lockfiles, virtual environment management, and faster resolution. The choice of tool depends on project complexity, team preferences, and whether you need features like lockfile support or monorepo management.
Tool Comparison
| Feature | pip | uv | poetry | pdm | conda | pipx | pip-tools |
|---|
| Install packages | Yes | Yes | Yes | Yes | Yes | Yes (global CLI tools) | Yes |
| Lockfile support | No (use pip-tools) | Yes (uv.lock) | Yes (poetry.lock) | Yes (pdm.lock) | Yes (conda-lock) | N/A | Yes (requirements.txt from *.in) |
| Virtual env management | No (use venv) | Yes (uv venv) | Yes (auto-creates) | Yes (auto-creates) | Yes (conda envs) | Yes (isolated) | No |
| Dependency resolution | Backtracking | SAT solver (fast) | SAT solver | SAT solver | SAT solver | N/A | Backtracking |
| Speed | Moderate | Very fast (Rust) | Moderate | Fast | Slow | Fast | Moderate |
| Monorepo/workspace | No | Yes (workspaces) | No (limited) | No | No | No | No |
| Python version management | No | Yes (uv python) | No | No | Yes | No | No |
| PEP 621 native | Yes | Yes | Partial | Yes | N/A | N/A | Yes |
| Private indexes | Yes | Yes | Yes | Yes | Yes (channels) | Yes | Yes |
Recommendation: Use uv for new projects. It is the fastest tool, supports lockfiles, manages virtual environments and Python versions, and is fully PEP 621-compatible. Use poetry if your team is already invested in its workflow. Use conda for scientific computing with non-Python dependencies.
pip Essentials
pip is the default package installer for Python, included with every Python installation.
Basic Commands
pip install httpx
pip install httpx==0.27.0
pip install "httpx>=0.27,<1.0"
pip install -r requirements.txt
pip install -e .
pip install -e ".[dev,docs]"
pip uninstall httpx
pip list
pip show httpx
pip list --outdated
pip install --upgrade httpx
requirements.txt
The traditional way to pin dependencies:
# requirements.txt -- production dependencies
httpx==0.27.0
pydantic==2.9.2
rich==13.9.4
# requirements-dev.txt -- development dependencies
-r requirements.txt
pytest==8.3.3
pytest-cov==5.0.0
mypy==1.13.0
ruff==0.7.4
Constraints Files
Constraints files limit versions without requiring installation:
# constraints.txt
# Ensures these versions are used IF the package is installed
urllib3>=2.0,<3
certifi>=2024.0
pip install -r requirements.txt -c constraints.txt
pip Configuration
[global]
timeout = 60
index-url = https://pypi.org/simple
trusted-host = pypi.org
[install]
require-virtualenv = true
uv Deep Dive
uv is an extremely fast Python package manager written in Rust. It is a drop-in replacement for pip, venv, pip-tools, and more.
Installation
curl -LsSf https://astral.sh/uv/install.sh | sh
pip install uv
brew install uv
Python Version Management
uv python list
uv python install 3.12
uv python pin 3.12
Virtual Environment Management
uv venv
uv venv --python 3.12
source .venv/bin/activate
.venv\Scripts\activate
Package Installation (pip-compatible interface)
uv pip install httpx pydantic rich
uv pip install -r requirements.txt
uv pip install -e ".[dev]"
uv pip compile requirements.in -o requirements.txt
uv pip sync requirements.txt
uv pip freeze > requirements.txt
Project Management (uv lock / uv sync / uv run)
uv has built-in project management that uses pyproject.toml and creates a cross-platform lockfile:
uv init my-project
cd my-project
uv add httpx
uv add pydantic "rich>=13.0"
uv add --dev pytest pytest-cov mypy ruff
uv remove httpx
uv lock
uv sync
uv sync --all-extras
uv run python -m pytest
uv run my-cli --help
uv run python script.py
uv Tool Management (replaces pipx)
uv tool install ruff
uv tool install httpie
uv tool run black --check .
uvx ruff check .
uv tool list
uv tool upgrade ruff
uv Workspaces (Monorepos)
[tool.uv.workspace]
members = ["packages/*"]
uv sync
uv run --package api python -m pytest
uv Cache Management
uv cache dir
uv cache clean
uv cache prune
Poetry Workflow
Poetry provides an all-in-one solution for dependency management, packaging, and publishing.
Installation
curl -sSL https://install.python-poetry.org | python3 -
pipx install poetry
Project Lifecycle
poetry new my-project
cd my-project
poetry init
poetry add httpx
poetry add pydantic "rich>=13.0"
poetry add --group dev pytest pytest-cov mypy ruff
poetry remove httpx
poetry update
poetry update httpx
poetry lock
poetry install
poetry install --without dev
poetry run python script.py
poetry run pytest
poetry shell
poetry show --tree
poetry export -f requirements.txt -o requirements.txt --without-hashes
poetry.lock
The poetry.lock file pins exact versions of all dependencies (direct and transitive). Always commit this file to version control.
poetry lock --no-update
poetry check
Publishing with Poetry
poetry build
poetry config pypi-token.pypi pypi-AgEIcHlwaS...
poetry publish
poetry publish --build
Poetry Configuration
poetry config virtualenvs.in-project true
poetry env use python3.12
poetry env info
pdm Workflow
pdm is a modern Python package manager that supports PEP 621 natively and pioneered PEP 582 (local packages directory, now withdrawn).
Basic Workflow
pip install pdm
pipx install pdm
pdm init
pdm add httpx pydantic
pdm add -dG dev pytest mypy ruff
pdm install
pdm update
pdm run python script.py
pdm run pytest
pdm build
pdm publish
pdm.lock
pdm generates a cross-platform lockfile (pdm.lock). Commit it to version control.
pdm lock
pdm export -f requirements -o requirements.txt
conda for Scientific Computing
conda manages packages, dependencies, and environments with support for non-Python libraries (C, Fortran, CUDA).
Basic Workflow
conda create -n myproject python=3.12
conda activate myproject
conda install numpy pandas scikit-learn
conda install -c conda-forge polars
conda env export > environment.yml
conda env create -f environment.yml
conda env list
conda env remove -n myproject
environment.yml
name: myproject
channels:
- conda-forge
- defaults
dependencies:
- python=3.12
- numpy>=1.26
- pandas>=2.2
- scikit-learn>=1.5
- matplotlib>=3.9
- pip:
- httpx>=0.27
- pydantic>=2.0
conda vs pip
| Aspect | conda | pip |
|---|
| Package types | Any (C, Fortran, Python, R, CUDA) | Python-only |
| Dependency resolution | Includes system libraries | Python packages only |
| Speed | Slower | Faster (especially with uv) |
| Channels | conda-forge, defaults, custom | PyPI, custom indexes |
| Best for | Scientific computing, ML, data science | General Python development |
Recommendation: Use conda when you need non-Python dependencies (CUDA, MKL, system libraries). For everything else, prefer uv or pip.
pipx for CLI Tool Isolation
pipx installs Python CLI tools in isolated environments so they do not conflict with project dependencies.
pip install pipx
pipx ensurepath
pipx install ruff
pipx install httpie
pipx install cookiecutter
pipx install pre-commit
pipx run cowsay "Hello!"
pipx upgrade ruff
pipx upgrade-all
pipx list
pipx uninstall ruff
Note: uv can replace pipx with uv tool install and uvx (see the uv section above).
Virtual Environment Strategies
Standard Library venv
python -m venv .venv
source .venv/bin/activate
.venv\Scripts\activate
deactivate
python -m venv --system-site-packages .venv
uv venv (Recommended)
uv venv
uv venv --python 3.12
uv venv myenv
virtualenv (Third-Party)
pip install virtualenv
virtualenv .venv
virtualenv -p python3.12 .venv
Conventions
- Name:
.venv (hidden directory, widely recognized by tools and IDEs)
- Location: Project root directory
- Git: Add
.venv/ to .gitignore
- CI: Recreate from lockfile on each run, do not cache the entire venv
Dependency Resolution and Lockfiles
Why Lockfiles Matter
A lockfile pins the exact version of every dependency (direct and transitive) to ensure reproducible installs:
- Without lockfile:
pip install httpx may install different transitive dependency versions on different machines or at different times.
- With lockfile: Every install produces the identical environment.
Lockfile Formats
| Tool | Lockfile | Cross-Platform | Format |
|---|
| uv | uv.lock | Yes | TOML |
| poetry | poetry.lock | Yes | TOML |
| pdm | pdm.lock | Yes | TOML |
| pip-tools | requirements.txt | No (per-platform) | Text |
| conda-lock | conda-lock.yml | Yes | YAML |
pip-tools Workflow
pip-tools compiles *.in files into pinned requirements.txt:
pip install pip-tools
pip-compile requirements.in
pip-sync requirements.txt
pip-compile --upgrade requirements.in
pip-compile --upgrade-package httpx requirements.in
Private Package Indexes
Configuring pip
pip install my-internal-package --index-url https://private.pypi.example.com/simple/
pip install my-internal-package --extra-index-url https://private.pypi.example.com/simple/
pip.conf / pip.ini
[global]
index-url = https://private.pypi.example.com/simple/
extra-index-url = https://pypi.org/simple/
trusted-host = private.pypi.example.com
Authentication with keyring
pip install keyring keyrings.google-artifactregistry-auth
pip install my-package --index-url https://us-central1-python.pkg.dev/my-project/my-repo/simple/
pyproject.toml Configuration
uv:
[[tool.uv.index]]
name = "internal"
url = "https://private.pypi.example.com/simple/"
[[tool.uv.index]]
name = "pypi"
url = "https://pypi.org/simple/"
poetry:
[[tool.poetry.source]]
name = "internal"
url = "https://private.pypi.example.com/simple/"
priority = "primary"
devpi (Private PyPI Server)
pip install devpi-server devpi-client
devpi-server --init
devpi-server --start
devpi use http://localhost:3141
devpi login root --password=""
devpi index -c root/internal
devpi use root/internal
devpi upload
Best Practices
-
Always use a virtual environment. Never install project dependencies into the system Python. Set require-virtualenv = true in pip configuration.
-
Commit your lockfile. Whether it is uv.lock, poetry.lock, pdm.lock, or a compiled requirements.txt, commit it to version control for reproducible builds.
-
Separate dependency groups. Use optional dependency groups ([project.optional-dependencies]) or tool-specific groups to keep production dependencies lean:
[project.optional-dependencies]
dev = ["pytest", "mypy", "ruff"]
docs = ["sphinx"]
-
Use >= with minimum versions for libraries, exact pins for applications:
- Library:
dependencies = ["httpx>=0.27"]
- Application: Use a lockfile to pin exact versions
-
Prefer uv for speed. uv is 10-100x faster than pip for resolution and installation. It is a drop-in replacement.
-
Use pipx or uv tool for global CLI tools. Do not install ruff, black, httpie, etc. into your project virtual environment if they are only needed as standalone tools.
-
Regularly update dependencies:
uv lock --upgrade
poetry update
pip-compile --upgrade requirements.in
-
Audit for vulnerabilities:
pip install pip-audit
pip-audit
uv pip audit
-
Use hash checking for high-security environments:
pip-compile --generate-hashes requirements.in
pip install --require-hashes -r requirements.txt