Python Packaging
Deep Knowledge: Use mcp__documentation__fetch_docs with technology: python topic: packaging for complete documentation.
Tool Comparison (2026)
Tool Speed Lock Files PEP 621 Best For
uv Fastest (10-100x pip) Yes Full New projects, speed
Poetry Good Yes (strong) Partial Complex deps
PDM Fast (can use uv) Yes Full Standards compliance
pip Baseline No N/A Basic installation
Recommendation: Use uv for new projects.
uv Quick Start
Install uv
curl -LsSf https://astral.sh/uv/install.sh | sh
Windows: powershell -c "irm https://astral.sh/uv/install.ps1 | iex"
Create project
uv init my-project cd my-project
Add dependencies
uv add fastapi pydantic uv add --dev pytest ruff mypy
Run commands
uv run python main.py uv run pytest
Sync dependencies from lock
uv sync
uv Commands Cheatsheet
Command Description
uv init
Create new project
uv add <pkg>
Add dependency
uv add --dev <pkg>
Add dev dependency
uv remove <pkg>
Remove dependency
uv sync
Install from lockfile
uv lock
Update lockfile
uv run <cmd>
Run in venv
uv pip install
pip-compatible install
uv python install 3.12
Install Python version
uv tool install ruff
Install global tool
uvx ruff check .
Run tool without install
pyproject.toml (PEP 621)
[project] name = "my-project" version = "1.0.0" description = "Project description" readme = "README.md" license = {text = "MIT"} requires-python = ">=3.10" authors = [ {name = "Your Name", email = "you@example.com"} ]
dependencies = [ "fastapi>=0.115.0", "pydantic>=2.0", "sqlalchemy>=2.0", ]
[project.optional-dependencies] dev = [ "pytest>=8.0", "pytest-asyncio>=0.23", "pytest-cov>=4.0", "ruff>=0.14", "mypy>=1.0", ]
[project.scripts] my-cli = "my_project.cli:main"
[build-system] requires = ["hatchling"] build-backend = "hatchling.build"
[tool.uv] dev-dependencies = [ "pytest>=8.0", "ruff>=0.14", ]
Virtual Environments
uv (recommended)
uv venv source .venv/bin/activate # Unix .venv\Scripts\activate # Windows
Standard library
python -m venv .venv source .venv/bin/activate
Check active environment
which python # Unix where python # Windows
Poetry (Alternative)
Install
curl -sSL https://install.python-poetry.org | python3 -
Create project
poetry new my-project poetry init # In existing directory
Add dependencies
poetry add fastapi poetry add --group dev pytest
Run commands
poetry run python main.py poetry shell # Activate venv
Install from lock
poetry install
Poetry pyproject.toml
[tool.poetry] name = "my-project" version = "1.0.0" description = "" authors = ["Your Name <you@example.com>"]
[tool.poetry.dependencies] python = "^3.10" fastapi = "^0.115.0"
[tool.poetry.group.dev.dependencies] pytest = "^8.0" ruff = "^0.14"
[build-system] requires = ["poetry-core"] build-backend = "poetry.core.masonry.api"
Dependency Versioning
Exact version
"package==1.2.3"
Minimum version (recommended for apps)
"package>=1.2.0"
Compatible release (recommended for libraries)
"package>=1.2,<2.0" "package~=1.2" # Same as >=1.2,<2.0
Exclude versions
"package>=1.0,!=1.5.0"
Lock Files
Tool Lock File Purpose
uv uv.lock
Cross-platform, deterministic
Poetry poetry.lock
Strong resolution
pip-tools requirements.lock
Simple
Generate lock (uv)
uv lock
Update all dependencies
uv lock --upgrade
Update specific package
uv lock --upgrade-package fastapi
Migration Guides
From requirements.txt to uv
In project with requirements.txt
uv init uv add $(cat requirements.txt | grep -v "^#" | tr '\n' ' ') rm requirements.txt
From Poetry to uv
Export from poetry
poetry export -f requirements.txt > requirements.txt
Import to uv
uv init uv add $(cat requirements.txt | cut -d'=' -f1 | tr '\n' ' ')
Project Structure (src Layout)
my-project/ ├── src/ │ └── my_package/ │ ├── init.py │ ├── main.py │ └── core.py ├── tests/ │ ├── init.py │ └── test_core.py ├── pyproject.toml ├── uv.lock └── README.md
Benefits of src layout:
-
Tests run against installed package
-
Prevents accidental imports from cwd
-
Cleaner package distribution
Anti-Patterns
Anti-Pattern Why It's Bad Solution
No lockfile Non-reproducible builds Always commit lockfile
pip freeze > requirements.txt
Includes transitive deps Use proper tool (uv, poetry)
Global pip installs Version conflicts Always use virtual environments
Pinning to exact versions everywhere Hard to update Use ranges for libraries
Not separating dev dependencies Bloated production Use optional-dependencies or groups
Quick Troubleshooting
Issue Cause Solution
"No module found" Not in venv Activate venv or use uv run
Version conflicts Incompatible deps Check uv pip compile --dry-run
"Permission denied" Global install attempt Use virtual environment
Slow install Using pip Switch to uv
Lock file conflicts Concurrent edits Regenerate with uv lock